基于Away3D实现全景的相机控制器。

   最近研究打算做个全景的Demo,发现Away3D本身的天空盒跟全景属于两种完全不同东西。最后只能基于HoverController来扩展(原因是HoverController能提供的距离控制,类似拉近拉远的效果)等不够好用。下面直接贴出扩展的代码,命名RotateController。

   其实也就是在HoverController的基础上添加了对distance的距离判断,添加了对负值的显示控制..

package away3d.controllers
{
    import away3d.core.math.MathConsts;
    import away3d.core.render.PositionRenderer;
    import away3d.entities.Entity;
    
    import flash.geom.Matrix3D;
    import flash.geom.Vector3D;
    
    public class RotateController extends ControllerBase
    {
        private var _distance:Number = 100;
        
        private var _panAngle:Number = 0;
        
        private var _tiltAngle:Number = 0;
        
        private var _currentTiltAngle:Number = 0;
        
        private var _currentPanAngle:Number = 0;
        
        public function RotateController(targetObject:Entity=null)
        {
            super(targetObject);
        }
        
        override public function update(interpolate:Boolean=false):void
        {
            if (_invalid) {
                _invalid = false;
                
                if (_panAngle < 0) {
                    _currentPanAngle += _panAngle%360 + 360 - _panAngle;
                    _panAngle = _panAngle%360 + 360;
                } else {
                    _currentPanAngle += _panAngle%360 - _panAngle;
                    _panAngle = _panAngle%360;
                }
                
                while (_panAngle - _currentPanAngle < -180)
                    _currentPanAngle -= 360;
                
                while (_panAngle - _currentPanAngle > 180)
                    _currentPanAngle += 360;
                
                _currentPanAngle = _panAngle;
                _currentTiltAngle = _tiltAngle;
                
                
                if(targetObject)
                {
                    var tempMatrix3d:Matrix3D = targetObject.transform;
                    tempMatrix3d.identity();
                    
                    tempMatrix3d.appendRotation(_currentTiltAngle, Vector3D.X_AXIS);
                    tempMatrix3d.appendRotation(_currentPanAngle, Vector3D.Y_AXIS);
                    
                    var pos:Vector3D = new Vector3D;
                    pos.x = distance*Math.sin(_currentPanAngle*MathConsts.DEGREES_TO_RADIANS)*Math.cos(_currentTiltAngle*MathConsts.DEGREES_TO_RADIANS);
                    pos.z = distance*Math.cos(_currentPanAngle*MathConsts.DEGREES_TO_RADIANS)*Math.cos(_currentTiltAngle*MathConsts.DEGREES_TO_RADIANS);
                    pos.y = distance*Math.sin(_currentTiltAngle*MathConsts.DEGREES_TO_RADIANS);
                    
                    tempMatrix3d.appendTranslation(pos.x, -pos.y, pos.z);
                    
                    targetObject.transform = tempMatrix3d;
                    
                }
            }
        }

        public function get distance():Number
        {
            return _distance;
        }

        public function set distance(value:Number):void
        {
            _distance = value;
            _invalid = true;
            notifyUpdate();
        }

        public function get panAngle():Number
        {
            return _panAngle;
        }

        public function set panAngle(value:Number):void
        {
            _panAngle = value;
            _invalid = true;
            notifyUpdate();
        }

        public function get tiltAngle():Number
        {
            return _tiltAngle;
        }

        public function set tiltAngle(value:Number):void
        {
            _tiltAngle = Math.max(-90, Math.min(90, value));
            _invalid = true;
            notifyUpdate();
        }


        private var _invalid:Boolean = false;
    }
}
原文地址:https://www.cnblogs.com/xignzou/p/3603544.html