package away3d.cameras { import away3d.cameras.Camera3D; import away3d.core.base.Object3D; import away3d.core.math.Matrix3D; import away3d.core.math.Number3D; /** b at turbulent dot ca - http://agit8.turbulent.ca * v1 - 2009-01-21 **/ /** * A 1st and 3d person camera(depending on positionOffset!), hooked on a physical spring on an optional target. */ public class SpringCam extends Camera3D { /** * [optional] Target object3d that camera should follow. If target is null, camera behaves just like a normal Camera3D. */ public var target:Object3D; //spring stiffness /** * Stiffness of the spring, how hard is it to extend. The higher it is, the more "fixed" the cam will be. * A number between 1 and 20 is recommended. */ public var stiffness:Number = 1; /** * Damping is the spring internal friction, or how much it resists the "boinggggg" effect. Too high and you'll lose it! * A number between 1 and 20 is recommended. */ public var damping:Number = 4; /** * Mass of the camera, if over 120 and it'll be very heavy to move. */ public var mass:Number = 40; /** * Offset of spring center from target in target object space, ie: Where the camera should ideally be in the target object space. */ public var positionOffset:Number3D = new Number3D(0,5,-50); /** * offset of facing in target object space, ie: where in the target object space should the camera look. */ public var lookOffset:Number3D = new Number3D(0,2,10); //zrot to apply to the cam private var _zrot:Number = 0; //private physics members private var _velocity:Number3D = new Number3D(); private var _dv:Number3D = new Number3D(); private var _stretch:Number3D = new Number3D(); private var _force:Number3D = new Number3D(); private var _acceleration:Number3D = new Number3D(); //private target members private var _desiredPosition:Number3D = new Number3D(); private var _lookAtPosition:Number3D = new Number3D(); private var _targetTransform:Matrix3D = new Matrix3D(); //private transformed members private var _xPositionOffset:Number3D = new Number3D(); private var _xLookOffset:Number3D = new Number3D(); private var _xPosition:Number3D = new Number3D(); public function SpringCam(init:Object=null) { super(init); } /** * Rotation in degrees along the camera Z vector to apply to the camera after it turns towards the target . */ public function set zrot(n:Number):void { _zrot = n; if(_zrot < 0.001) n = 0; } public function get zrot():Number { return _zrot; } public override function get view():Matrix3D { if(target != null) { _targetTransform.szx = target.transform.szx; _targetTransform.szy = target.transform.szy; _targetTransform.szz = target.transform.szz; _targetTransform.syx = target.transform.syx; _targetTransform.syy = target.transform.syy; _targetTransform.syz = target.transform.syz; _targetTransform.sxx = target.transform.sxx; _targetTransform.sxy = target.transform.sxy; _targetTransform.sxz = target.transform.sxz; _xPositionOffset.transform(positionOffset, _targetTransform); _xLookOffset.transform(lookOffset, _targetTransform); _desiredPosition.add(target.position, _xPositionOffset); _lookAtPosition.add(target.position, _xLookOffset); _stretch.sub(this.position, _desiredPosition); _stretch.scale(_stretch, -stiffness); _dv.scale(_velocity, damping); _force.sub(_stretch, _dv); _acceleration.scale(_force, 1/mass); _velocity.add(_velocity, _acceleration); _xPosition.add(position, _velocity); x = _xPosition.x; y = _xPosition.y; z = _xPosition.z; lookAt(_lookAtPosition); if(Math.abs(_zrot) > 0) rotate(Number3D.FORWARD, _zrot); } return super.view; } } }