最近研究打算作個全景的Demo,發現Away3D自己的天空盒跟全景屬於兩種徹底不一樣東西。最後只能基於HoverController來擴展(緣由是HoverController能提供的距離控制,相似拉近拉遠的效果)等不夠好用。下面直接貼出擴展的代碼,命名RotateController。app
其實也就是在HoverController的基礎上添加了對distance的距離判斷,添加了對負值的顯示控制..ide
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; } }