package_9 alternativa.tanks.game.camera

This commit is contained in:
Pyogenics
2025-01-27 18:00:14 +00:00
parent 37b64f353c
commit 608f91dc7a
10 changed files with 86 additions and 85 deletions

View File

@@ -11,7 +11,7 @@ package alternativa.tanks
import package_18.name_44;
import package_19.name_53;
import alternativa.tanks.game.entities.map.A3DMapComponent;
import package_9.name_20;
import alternativa.tanks.game.camera.FreeCameraController;
public class InitBattleTask extends GameTask
{
@@ -35,7 +35,7 @@ package alternativa.tanks
override public function run() : void
{
var _loc1_:name_44 = this.gameKernel.name_5();
var _loc2_:name_20 = new name_20(_loc1_.name_27(),this.gameKernel.name_66());
var _loc2_:FreeCameraController = new FreeCameraController(_loc1_.name_27(),this.gameKernel.name_66());
_loc1_.name_63(_loc2_);
_loc2_.name_75(0,0,1000);
_loc2_.name_76(0,2000,0);

View File

@@ -93,9 +93,9 @@ package alternativa.tanks
import package_87.name_267;
import package_88.name_268;
import package_89.name_266;
import package_9.name_20;
import package_9.name_298;
import package_9.name_299;
import alternativa.tanks.game.camera.FreeCameraController;
import alternativa.tanks.game.camera.OrbitCameraController;
import alternativa.tanks.game.camera.FollowCameraController;
import package_90.name_273;
import package_91.name_296;
import package_91.name_349;
@@ -144,11 +144,11 @@ package alternativa.tanks
private var var_73:BitmapData;
private var var_67:name_299;
private var var_67:FollowCameraController;
private var var_69:name_298;
private var var_69:OrbitCameraController;
private var freeCameraController:name_20;
private var freeCameraController:FreeCameraController;
private var var_68:name_102;
@@ -178,7 +178,7 @@ package alternativa.tanks
private var var_80:name_293 = new name_293();
public function TankTestTask(param1:int, param2:Config, param3:GameKernel, param4:name_20, param5:Preloader)
public function TankTestTask(param1:int, param2:Config, param3:GameKernel, param4:FreeCameraController, param5:Preloader)
{
super(param1);
this.preloader = param5;
@@ -202,8 +202,8 @@ package alternativa.tanks
_loc1_.name_94(KeyboardEventType.KEY_DOWN,this.onKeyDown);
var _loc2_:name_56 = name_56(var_4.getTaskInterface(name_56));
_loc2_.addEventListener(name_253.TANK_CLICK,this);
this.var_67 = new name_299(this.gameKernel.name_5().name_27(),this.gameKernel.method_112().name_246().collisionDetector,name_257.STATIC,_loc1_);
this.var_69 = new name_298(this.gameKernel.name_5().name_27(),this.gameKernel.method_112().name_246().collisionDetector,name_257.STATIC,_loc1_);
this.var_67 = new FollowCameraController(this.gameKernel.name_5().name_27(),this.gameKernel.method_112().name_246().collisionDetector,name_257.STATIC,_loc1_);
this.var_69 = new OrbitCameraController(this.gameKernel.name_5().name_27(),this.gameKernel.method_112().name_246().collisionDetector,name_257.STATIC,_loc1_);
this.var_81 = new name_290(this.gameKernel.name_5());
this.var_75 = new name_285();
this.gameKernel.stage.addChild(this.var_75);
@@ -305,10 +305,10 @@ package alternativa.tanks
case Keyboard.N:
if(this.var_68 == this.freeCameraController)
{
name_20.targeted = !name_20.targeted;
FreeCameraController.targeted = !FreeCameraController.targeted;
break;
}
name_20.targeted = true;
FreeCameraController.targeted = true;
this.setCameraController(this.freeCameraController);
break;
case Keyboard.ENTER:

View File

@@ -0,0 +1,46 @@
package alternativa.tanks.game.camera
{
import flash.display.Shape;
import package_18.name_90;
public class AxisIndicator extends Shape
{
private var var_32:int;
private var axis:Vector.<Number> = Vector.<Number>([0,0,0,0,0,0]);
public function AxisIndicator(size:int)
{
super();
this.var_32 = size;
}
public function update(camera:name_90) : void
{
var kx:Number = NaN;
var ky:Number = NaN;
graphics.clear();
this.axis[0] = camera.xAxis.x;
this.axis[1] = camera.yAxis.x;
this.axis[2] = camera.xAxis.y;
this.axis[3] = camera.yAxis.y;
this.axis[4] = camera.xAxis.z;
this.axis[5] = camera.yAxis.z;
var halfSize:int = this.var_32 / 2;
for(var i:int = 0,var bitOffset:int = 16; i < 6; i += 2,bitOffset -= 8)
{
kx = this.axis[i] + 1;
ky = this.axis[int(i + 1)] + 1;
graphics.lineStyle(0,255 << bitOffset);
graphics.moveTo(halfSize,halfSize);
graphics.lineTo(halfSize * kx,halfSize * ky);
}
}
public function get size() : int
{
return this.var_32;
}
}
}

View File

@@ -0,0 +1,51 @@
package alternativa.tanks.game.camera
{
import package_18.name_90;
import package_46.name_194;
public class CameraControllerBase
{
protected var camera:name_90;
public function CameraControllerBase()
{
super();
}
protected function name_201(position:name_194) : void
{
this.camera.x = position.x;
this.camera.y = position.y;
this.camera.z = position.z;
}
protected function name_352(eulerAngles:name_194) : void
{
this.camera.rotationX = eulerAngles.x;
this.camera.rotationY = eulerAngles.y;
this.camera.rotationZ = eulerAngles.z;
}
protected function method_479(rx:Number, ry:Number, rz:Number) : void
{
this.camera.rotationX = rx;
this.camera.rotationY = ry;
this.camera.rotationZ = rz;
}
protected function method_532(dx:Number, dy:Number, dz:Number) : void
{
this.camera.x += dx;
this.camera.y += dy;
this.camera.z += dz;
}
protected function method_533(rx:Number, ry:Number, rz:Number) : void
{
this.camera.rotationX += rx;
this.camera.rotationY += ry;
this.camera.rotationZ += rz;
}
}
}

View File

@@ -0,0 +1,473 @@
package alternativa.tanks.game.camera
{
import flash.ui.Keyboard;
import flash.utils.getTimer;
import alternativa.osgi.service.console.variables.ConsoleVarFloat;
import alternativa.osgi.service.console.variables.ConsoleVarInt;
import alternativa.tanks.game.Entity;
import package_18.name_102;
import package_18.name_90;
import package_19.name_380;
import package_21.name_78;
import alternativa.tanks.game.subsystems.inputsystem.IInput;
import package_27.name_501;
import package_45.name_182;
import package_46.Matrix3;
import package_46.Matrix4;
import package_46.name_194;
import package_47.name_193;
import package_76.name_256;
import package_90.name_273;
public class FollowCameraController extends CameraControllerBase implements name_102
{
private static var parentMatrix:Matrix4 = new Matrix4();
private static var matrix:Matrix4 = new Matrix4();
public static var maxPositionError:Number = 10;
public static var maxAngleError:Number = Math.PI / 180;
public static var camSpeedThreshold:Number = 10;
private static var fixedPitch:ConsoleVarFloat = new ConsoleVarFloat("cam_fixedpitch",10 * Math.PI / 180,-1,1);
private static var noPitchCorrection:ConsoleVarInt = new ConsoleVarInt("cam_nopitchcorrection",1,0,1);
private static var pitchCorrectionCoeff:ConsoleVarFloat = new ConsoleVarFloat("cam_pitchcorrectioncoeff",1,0,10);
private static var reboundDelay:ConsoleVarInt = new ConsoleVarInt("cam_rebound",1000,0,2000);
private static var elevationAngles:Vector.<Number> = new Vector.<Number>(1,true);
private static var rotationMatrix:Matrix3 = new Matrix3();
private static var axis:name_194 = new name_194();
private static var rayDirection:name_194 = new name_194();
private static const MIN_CAMERA_ANGLE:Number = 5 * Math.PI / 180;
private static const KEY_CAMERA_UP:uint = Keyboard.PAGE_UP;
private static const ALT_KEY_CAMERA_UP:uint = 221;
private static const KEY_CAMERA_DOWN:uint = Keyboard.PAGE_DOWN;
private static const ALT_KEY_CAMERA_DOWN:uint = 219;
private static const HEIGHT_CHANGE_STEP:Number = 50;
private static const MIN_HEIGHT:Number = 150;
private static const MAX_HEIGHT:Number = 3100;
private static const MIN_DISTANCE:Number = 300;
private static const COLLISION_OFFSET:Number = 50;
private static var currentPosition:name_194 = new name_194();
private static var currentRotation:name_194 = new name_194();
private static var rayOrigin:name_194 = new name_194();
private static var flatDirection:name_194 = new name_194();
private static var positionDelta:name_194 = new name_194();
private static var rayHit:name_273 = new name_273();
private var collisionDetector:name_256;
private var collisionMask:int;
private var var_510:Number = 0;
private var var_511:Number = 0;
private var locked:Boolean;
private var position:name_194 = new name_194();
private var rotation:name_194 = new name_194();
private var targetPosition:name_194 = new name_194();
private var targetDirection:name_194 = new name_194();
private var var_526:Number = 0;
private var var_525:Number = 0;
private var var_527:Number = 0;
private var var_518:Number = 10000000;
private var var_522:int;
private var cameraPositionData:CameraPositionData = new CameraPositionData();
private var var_521:Number;
private var var_528:Number = 0;
private var input:IInput;
private var var_515:name_380;
public function FollowCameraController(camera:name_90, collisionDetector:name_256, collisionMask:int, input:IInput)
{
super();
this.camera = camera;
if(collisionDetector == null)
{
throw new ArgumentError("Parameter collisionDetector cannot be null");
}
this.collisionDetector = collisionDetector;
this.collisionMask = collisionMask;
this.input = input;
this.method_534 = 600;
}
public function name_108() : void
{
}
public function method_115(target:Entity) : void
{
if(target == null)
{
this.var_515 = null;
}
else
{
this.var_515 = name_193(target.getComponentStrict(name_193)).name_198;
}
}
public function method_545() : void
{
noPitchCorrection.value = 1;
}
public function method_544() : void
{
noPitchCorrection.value = 0;
}
public function method_548(targetPosition:name_194, targetDirection:name_194) : void
{
this.targetPosition.copy(targetPosition);
this.targetDirection.copy(targetDirection);
this.var_522 = 0;
this.getCameraPositionData(targetPosition,targetDirection,false,10000,this.cameraPositionData);
this.position.copy(this.cameraPositionData.position);
this.rotation.x = this.getPitchAngle(this.cameraPositionData) - 0.5 * Math.PI;
this.rotation.z = Math.atan2(-targetDirection.x,targetDirection.y);
name_201(this.position);
name_352(this.rotation);
}
public function method_549() : void
{
this.position.reset(camera.x,camera.y,camera.z);
this.rotation.reset(camera.rotationX,camera.rotationY,camera.rotationZ);
}
public function update() : void
{
if(this.var_515 == null)
{
throw new Error("Target is not set");
}
if(camera == null)
{
throw new Error("Camera is not set");
}
var dt:Number = name_182.timeDeltaSeconds;
if(dt > 0.1)
{
dt = 0.1;
}
this.updateHeight();
if(!this.locked)
{
this.updateTargetState();
}
this.getCameraPositionData(this.targetPosition,this.targetDirection,true,dt,this.cameraPositionData);
positionDelta.method_366(this.cameraPositionData.position,this.position);
var positionError:Number = positionDelta.length();
if(positionError > maxPositionError)
{
this.var_526 = this.getLinearSpeed(positionError - maxPositionError);
}
var distance:Number = this.var_526 * dt;
if(distance > positionError)
{
distance = positionError;
}
positionDelta.normalize().scale(distance);
var targetPitchAngle:Number = this.getPitchAngle(this.cameraPositionData);
var targetYawAngle:Number = Number(Math.atan2(-this.targetDirection.x,this.targetDirection.y));
var currentPitchAngle:Number = name_501.name_506(this.rotation.x + 0.5 * Math.PI);
var currentYawAngle:Number = name_501.name_506(this.rotation.z);
var pitchError:Number = name_501.name_628(targetPitchAngle - currentPitchAngle);
this.var_525 = this.getAngularSpeed(pitchError,this.var_525);
var deltaPitch:Number = this.var_525 * dt;
if(pitchError > 0 && deltaPitch > pitchError || pitchError < 0 && deltaPitch < pitchError)
{
deltaPitch = pitchError;
}
var yawError:Number = name_501.name_628(targetYawAngle - currentYawAngle);
this.var_527 = this.getAngularSpeed(yawError,this.var_527);
var deltaYaw:Number = this.var_527 * dt;
if(yawError > 0 && deltaYaw > yawError || yawError < 0 && deltaYaw < yawError)
{
deltaYaw = yawError;
}
this.var_526 = this.snap(this.var_526,0,camSpeedThreshold);
this.var_525 = this.snap(this.var_525,0,camSpeedThreshold);
this.var_527 = this.snap(this.var_527,0,camSpeedThreshold);
this.position.add(positionDelta);
this.rotation.x += deltaPitch;
this.rotation.z += deltaYaw;
currentPosition.copy(this.position);
currentRotation.copy(this.rotation);
name_201(currentPosition);
name_352(currentRotation);
}
public function method_550(locked:Boolean) : void
{
this.locked = locked;
}
public function get method_534() : Number
{
return this.var_510;
}
public function set method_534(value:Number) : void
{
this.var_510 = name_501.clamp(value,MIN_HEIGHT,MAX_HEIGHT);
var d:Number = this.getCamDistance(this.var_510);
this.var_521 = Math.atan2(this.var_510,d);
this.var_511 = Math.sqrt(this.var_510 * this.var_510 + d * d);
this.var_522 = 0;
}
public function method_546(targetPosition:name_194, targetDirection:name_194, resultingPosition:name_194, resultingAngles:name_194) : void
{
this.getCameraPositionData(targetPosition,targetDirection,false,10000,this.cameraPositionData);
resultingAngles.x = this.getPitchAngle(this.cameraPositionData) - 0.5 * Math.PI;
resultingAngles.z = Math.atan2(-targetDirection.x,targetDirection.y);
resultingPosition.copy(this.cameraPositionData.position);
}
private function getCameraPositionData(targetPosition:name_194, targetDirection:name_194, useReboundDelay:Boolean, dt:Number, result:CameraPositionData) : void
{
var angle:Number = NaN;
var now:int = 0;
var delta:Number = NaN;
var actualElevation:Number = this.var_521;
var xyLength:Number = Number(Math.sqrt(targetDirection.x * targetDirection.x + targetDirection.y * targetDirection.y));
if(xyLength < 0.00001)
{
flatDirection.x = 1;
flatDirection.y = 0;
}
else
{
flatDirection.x = targetDirection.x / xyLength;
flatDirection.y = targetDirection.y / xyLength;
}
result.extraPitch = 0;
result.t = 1;
var minCollisionDistance:Number = this.var_511;
rayOrigin.copy(targetPosition);
elevationAngles[0] = actualElevation;
axis.x = flatDirection.y;
axis.y = -flatDirection.x;
flatDirection.reverse();
for each(angle in elevationAngles)
{
rotationMatrix.method_344(axis,-angle);
rotationMatrix.method_345(flatDirection,rayDirection);
minCollisionDistance = this.getCollisionDistance(rayOrigin,rayDirection,this.var_511,minCollisionDistance);
}
if(useReboundDelay)
{
now = int(getTimer());
if(minCollisionDistance <= this.var_518 + 0.001)
{
this.var_518 = minCollisionDistance;
this.var_522 = now;
}
else if(now - this.var_522 < reboundDelay.value)
{
minCollisionDistance = this.var_518;
}
else
{
this.var_518 = minCollisionDistance;
}
}
if(minCollisionDistance < this.var_511)
{
result.t = minCollisionDistance / this.var_511;
if(minCollisionDistance < MIN_DISTANCE)
{
rayOrigin.method_362(minCollisionDistance,rayDirection);
delta = MIN_DISTANCE - minCollisionDistance;
if(this.collisionDetector.raycast(rayOrigin,name_194.Z_AXIS,this.collisionMask,delta,null,rayHit))
{
delta = rayHit.t - 10;
if(delta < 0)
{
delta = 0;
}
}
result.position.copy(rayOrigin).method_362(delta,name_194.Z_AXIS);
}
else
{
result.position.copy(rayOrigin).method_362(minCollisionDistance,rayDirection);
}
}
else
{
result.position.copy(rayOrigin).method_362(this.var_511,rayDirection);
}
}
private function getCollisionDistance(rayOrigin:name_194, rayDirection:name_194, rayLength:Number, minCollisionDistance:Number) : Number
{
var distance:Number = NaN;
if(this.collisionDetector.raycast(rayOrigin,rayDirection,this.collisionMask,rayLength,null,rayHit))
{
distance = rayHit.t;
if(distance < COLLISION_OFFSET)
{
distance = 0;
}
else
{
distance -= COLLISION_OFFSET;
}
if(distance < minCollisionDistance)
{
return distance;
}
}
return minCollisionDistance;
}
private function updateTargetState() : void
{
this.setMatrix(this.var_515.parent,parentMatrix);
this.setMatrix(this.var_515,matrix);
matrix.append(parentMatrix);
matrix.getAxis(3,this.targetPosition);
this.targetDirection.reset(matrix.b,matrix.f,matrix.j);
}
private function setMatrix(object:name_78, matrix:Matrix4) : void
{
matrix.name_196(object.rotationX,object.rotationY,object.rotationZ);
matrix.name_75(object.x,object.y,object.z);
}
private function updateHeight() : void
{
var heightChangeDir:int = this.input.name_192(KEY_CAMERA_UP) - this.input.name_192(KEY_CAMERA_DOWN);
if(heightChangeDir != 0)
{
this.method_534 = this.var_510 + heightChangeDir * HEIGHT_CHANGE_STEP;
}
}
private function getCamDistance(h:Number) : Number
{
var hMid:Number = 0.5 * (3300 + 200);
var a:Number = hMid;
var v:Number = 200 - hMid;
var k:Number = (1300 - 600) / (v * v);
return -k * (h - a) * (h - a) + 1300;
}
private function getLinearSpeed(positionError:Number) : Number
{
return 3 * positionError;
}
private function getAngularSpeed(angleError:Number, currentSpeed:Number) : Number
{
if(angleError < -maxAngleError)
{
return 3 * (angleError + maxAngleError);
}
if(angleError > maxAngleError)
{
return 3 * (angleError - maxAngleError);
}
return currentSpeed;
}
private function snap(value:Number, snapValue:Number, epsilon:Number) : Number
{
if(value > snapValue - epsilon && value < snapValue + epsilon)
{
return snapValue;
}
return value;
}
private function getPitchAngle(cameraPositionData:CameraPositionData) : Number
{
var angle:Number = this.var_521 - fixedPitch.value;
if(angle < 0)
{
angle = 0;
}
var t:Number = cameraPositionData.t;
if(t >= 1 || angle < MIN_CAMERA_ANGLE || noPitchCorrection.value == 1)
{
return cameraPositionData.extraPitch - angle;
}
return cameraPositionData.extraPitch - Math.atan2(t * this.var_510,pitchCorrectionCoeff.value * this.var_510 * (1 / Math.tan(angle) - (1 - t) / Math.tan(this.var_521)));
}
private function moveValueTowards(value:Number, targetValue:Number, delta:Number) : Number
{
if(value < targetValue)
{
value += delta;
return value > targetValue ? targetValue : value;
}
if(value > targetValue)
{
value -= delta;
return value < targetValue ? targetValue : value;
}
return value;
}
}
}
import package_46.name_194;
class CameraPositionData
{
public var t:Number;
public var extraPitch:Number;
public var position:name_194 = new name_194();
public function CameraPositionData()
{
super();
}
}

View File

@@ -0,0 +1,206 @@
package alternativa.tanks.game.camera
{
import flash.geom.Vector3D;
import alternativa.tanks.game.ObjectController;
import alternativa.tanks.game.Entity;
import package_15.name_191;
import package_18.name_102;
import package_18.name_90;
import package_21.name_78;
import alternativa.tanks.game.subsystems.inputsystem.IInput;
import package_45.name_182;
import package_46.Matrix3;
import package_46.Matrix4;
import package_46.name_194;
import package_47.name_193;
public class FreeCameraController implements name_102
{
public static var smoothing:Number = 20;
public static var targeted:Boolean = false;
private static const KEY_FORWARD:int = name_191.W;
private static const KEY_BACK:int = name_191.S;
private static const KEY_LEFT:int = name_191.A;
private static const KEY_RIGHT:int = name_191.D;
private static const KEY_UP:int = name_191.E;
private static const KEY_DOWN:int = name_191.C;
private static const KEY_SPEED:int = name_191.SHIFT;
private static var matrix:Matrix3 = new Matrix3();
private static var vector:name_194 = new name_194();
public var var_50:Number = 0.01;
public var var_48:Number = 0.01;
public var speed:Number = 500;
public var var_49:Number = 3;
private var var_47:Number = 0;
private var var_46:Number = 0;
private var currentPosition:Vector3D = new Vector3D();
private var input:IInput;
private var controller:ObjectController;
private var target:name_78;
private var parentMatrix:Matrix4 = new Matrix4();
private var var_45:Matrix4 = new Matrix4();
public function FreeCameraController(camera:name_90, input:IInput)
{
super();
this.input = input;
this.controller = new ObjectController();
this.controller.object = camera;
this.var_46 = camera.rotationX;
this.var_47 = camera.rotationZ;
this.currentPosition.x = camera.x;
this.currentPosition.y = camera.y;
this.currentPosition.z = camera.z;
}
public function name_108() : void
{
var object:name_78 = this.controller.object;
this.var_46 = object.rotationX;
this.var_47 = object.rotationZ;
this.currentPosition.x = object.x;
this.currentPosition.y = object.y;
this.currentPosition.z = object.z;
}
public function name_75(x:Number, y:Number, z:Number) : void
{
this.controller.name_201(x,y,z);
this.currentPosition.x = this.controller.object.x;
this.currentPosition.y = this.controller.object.y;
this.currentPosition.z = this.controller.object.z;
}
public function name_76(x:Number, y:Number, z:Number) : void
{
this.controller.name_76(x,y,z);
this.var_46 = this.controller.object.rotationX;
this.var_47 = this.controller.object.rotationZ;
}
public function method_115(value:Entity) : void
{
if(value == null)
{
this.target = null;
}
else
{
this.target = name_193(value.getComponentStrict(name_193)).name_198;
}
}
public function update() : void
{
var dx:Number = NaN;
var dy:Number = NaN;
var dz:Number = NaN;
var k:Number = NaN;
var yaw:Number = NaN;
var pitch:Number = NaN;
var timeDelta:Number = name_182.timeDeltaSeconds;
if(smoothing > 0)
{
k = 100 / smoothing * timeDelta;
k = k > 1 ? 1 : k;
}
if(this.input.name_199())
{
yaw = -this.input.name_197() * this.var_50;
pitch = -this.input.name_200() * this.var_48;
this.var_47 += yaw;
this.var_46 += pitch;
}
var object:name_78 = this.controller.object;
var drX:Number = this.var_46 - object.rotationX;
var drZ:Number = this.var_47 - object.rotationZ;
if(drX != 0 || drZ != 0)
{
if(smoothing > 0)
{
drX *= k;
drZ *= k;
}
object.rotationX += drX;
object.rotationZ += drZ;
}
vector.x = this.input.name_192(KEY_RIGHT) - this.input.name_192(KEY_LEFT);
vector.y = this.input.name_192(KEY_DOWN) - this.input.name_192(KEY_UP);
vector.z = this.input.name_192(KEY_FORWARD) - this.input.name_192(KEY_BACK);
var moved:Boolean = vector.x != 0 || vector.y != 0 || vector.z != 0;
if(moved)
{
vector.normalize();
vector.scale(this.speed * timeDelta * (1 + this.input.name_192(KEY_SPEED) * (this.var_49 - 1)));
}
matrix.name_196(object.rotationX,object.rotationY,object.rotationZ);
vector.reset(vector.x,vector.y,vector.z);
vector.transform3(matrix);
this.currentPosition.x += vector.x;
this.currentPosition.y += vector.y;
this.currentPosition.z += vector.z;
vector.reset();
dx = this.currentPosition.x - object.x;
dy = this.currentPosition.y - object.y;
dz = this.currentPosition.z - object.z;
if(smoothing > 0)
{
object.x += dx * k;
object.y += dy * k;
object.z += dz * k;
}
else
{
object.x += dx;
object.y += dy;
object.z += dz;
}
if(targeted && this.target != null)
{
this.updateTargetState();
dx = this.var_45.d - object.x;
dy = this.var_45.h - object.y;
dz = this.var_45.l - object.z;
object.rotationX = Math.atan2(dz,Math.sqrt(dx * dx + dy * dy)) - 0.5 * Math.PI;
object.rotationY = 0;
object.rotationZ = -Math.atan2(dx,dy);
}
}
private function updateTargetState() : void
{
this.setMatrixFromObject(this.target.parent,this.parentMatrix);
this.setMatrixFromObject(this.target,this.var_45);
this.var_45.append(this.parentMatrix);
}
private function setMatrixFromObject(object:name_78, matrix:Matrix4) : void
{
matrix.name_196(object.rotationX,object.rotationY,object.rotationZ);
matrix.name_75(object.x,object.y,object.z);
}
}
}

View File

@@ -0,0 +1,443 @@
package alternativa.tanks.game.camera
{
import flash.ui.Keyboard;
import flash.utils.getTimer;
import alternativa.osgi.service.console.variables.ConsoleVarFloat;
import alternativa.osgi.service.console.variables.ConsoleVarInt;
import alternativa.tanks.game.Entity;
import package_18.name_102;
import package_18.name_90;
import package_19.name_380;
import package_21.name_78;
import alternativa.tanks.game.subsystems.inputsystem.IInput;
import package_27.name_501;
import package_45.name_182;
import package_46.Matrix3;
import package_46.Matrix4;
import package_46.name_194;
import package_47.name_193;
import package_76.name_256;
import package_90.name_273;
public class OrbitCameraController extends CameraControllerBase implements name_102
{
private static var parentMatrix:Matrix4 = new Matrix4();
private static var matrix:Matrix4 = new Matrix4();
private static var maxPositionError:Number = 10;
private static var maxAngleError:Number = Math.PI / 180;
private static var camSpeedThreshold:Number = 10;
private static var fixedPitch:ConsoleVarFloat = new ConsoleVarFloat("cam_fixedpitch",10 * Math.PI / 180,-1,1);
private static var noPitchCorrection:ConsoleVarInt = new ConsoleVarInt("cam_nopitchcorrection",1,0,1);
private static var pitchCorrectionCoeff:ConsoleVarFloat = new ConsoleVarFloat("cam_pitchcorrectioncoeff",1,0,10);
private static var reboundDelay:ConsoleVarInt = new ConsoleVarInt("cam_rebound",1000,0,2000);
private static var elevationAngles:Vector.<Number> = new Vector.<Number>(1,true);
private static var rotationMatrix:Matrix3 = new Matrix3();
private static var axis:name_194 = new name_194();
private static var rayDirection:name_194 = new name_194();
private static const MIN_CAMERA_ANGLE:Number = 5 * Math.PI / 180;
private static const KEY_CAMERA_UP:uint = Keyboard.PAGE_UP;
private static const KEY_CAMERA_DOWN:uint = Keyboard.PAGE_DOWN;
private static const HEIGHT_CHANGE_STEP:Number = 50;
private static const MIN_HEIGHT:Number = 150;
private static const MAX_HEIGHT:Number = 3100;
private static const MIN_DISTANCE:Number = 300;
private static const COLLISION_OFFSET:Number = 100;
private static const targetOffset:name_194 = new name_194(0,0,50);
private static var currentPosition:name_194 = new name_194();
private static var currentRotation:name_194 = new name_194();
private static var rayOrigin:name_194 = new name_194();
private static var flatDirection:name_194 = new name_194();
private static var positionDelta:name_194 = new name_194();
private static var rayHit:name_273 = new name_273();
private var collisionDetector:name_256;
private var collisionMask:int;
private var var_510:Number = 0;
private var var_511:Number = 0;
private var locked:Boolean;
private var position:name_194 = new name_194();
private var rotation:name_194 = new name_194();
private var targetPosition:name_194 = new name_194();
private var targetDirection:name_194 = new name_194();
private var var_526:Number = 0;
private var var_525:Number = 0;
private var var_527:Number = 0;
private var var_518:Number = 10000000;
private var var_522:int;
private var cameraPositionData:CameraPositionData = new CameraPositionData();
private var var_521:Number;
private var input:IInput;
private var var_515:name_380;
private var var_514:Number = 0;
private var var_513:Number = 0;
private var var_516:Number = 1000;
private var var_519:Number = 0;
private var var_520:Number = 0;
private var var_517:Number = 1000;
public var smoothing:Number = 40;
private var angles:name_194 = new name_194();
private var var_512:name_194 = new name_194();
private var rotationMatrix:Matrix4 = new Matrix4();
private var var_524:Matrix4 = new Matrix4();
private var var_523:name_194 = new name_194();
public function OrbitCameraController(camera:name_90, collisionDetector:name_256, collisionMask:int, input:IInput)
{
super();
this.camera = camera;
if(collisionDetector == null)
{
throw new ArgumentError("Parameter collisionDetector cannot be null");
}
this.collisionDetector = collisionDetector;
this.collisionMask = collisionMask;
this.input = input;
this.cameraHeight = 600;
}
public function name_108() : void
{
}
public function method_115(target:Entity) : void
{
if(target == null)
{
this.var_515 = null;
}
else
{
this.var_515 = name_193(target.getComponentStrict(name_193)).name_198;
}
}
public function update() : void
{
if(this.var_515 == null)
{
throw new Error("Target is not set");
}
if(camera == null)
{
throw new Error("Camera is not set");
}
var dt:Number = name_182.timeDeltaSeconds;
if(dt > 0.1)
{
dt = 0.1;
}
this.updateTargetState();
matrix.method_353(targetOffset,this.var_512);
var distanceChangeDir:int = this.input.name_192(KEY_CAMERA_UP) - this.input.name_192(KEY_CAMERA_DOWN) - this.input.method_261();
if(distanceChangeDir != 0)
{
this.var_517 *= Math.pow(10,distanceChangeDir * 0.02);
}
if(this.input.name_199())
{
this.var_519 -= this.input.name_200() * 0.01;
this.var_520 -= this.input.name_197() * 0.01;
}
var k:Number = 1;
if(this.smoothing > 0)
{
k = 100 / this.smoothing * dt;
k = k > 1 ? 1 : k;
this.var_514 += (this.var_519 - this.var_514) * k;
this.var_513 += (this.var_520 - this.var_513) * k;
}
else
{
this.var_514 = this.var_519;
this.var_513 = this.var_520;
}
this.rotationMatrix.name_196(this.var_514,0,this.var_513);
this.rotationMatrix.name_75(matrix.d,matrix.h,matrix.l);
matrix.getAxis(3,rayOrigin);
this.rotationMatrix.method_345(name_194.Y_AXIS,rayDirection);
rayDirection.reverse();
var distance:Number = this.var_517;
if(this.collisionDetector.raycast(rayOrigin,rayDirection,this.collisionMask,distance,null,rayHit))
{
distance = rayHit.t - COLLISION_OFFSET;
}
if(distanceChangeDir != 0)
{
this.var_517 = distance;
}
if(this.smoothing > 0)
{
this.var_516 += (distance - this.var_516) * k;
}
else
{
this.var_516 = distance;
}
this.position.x = 0;
this.position.y = -this.var_516;
this.position.z = 0;
this.rotationMatrix.method_353(this.position,currentPosition);
camera.x = currentPosition.x;
camera.y = currentPosition.y;
camera.z = currentPosition.z;
var dx:Number = this.var_512.x - camera.x;
var dy:Number = this.var_512.y - camera.y;
var dz:Number = this.var_512.z - camera.z;
camera.rotationX = Math.atan2(dz,Math.sqrt(dx * dx + dy * dy)) - 0.5 * Math.PI;
camera.rotationY = 0;
camera.rotationZ = -Math.atan2(dx,dy);
}
private function set cameraHeight(value:Number) : void
{
this.var_510 = name_501.clamp(value,MIN_HEIGHT,MAX_HEIGHT);
var d:Number = this.getCamDistance(this.var_510);
this.var_521 = Math.atan2(this.var_510,d);
this.var_511 = Math.sqrt(this.var_510 * this.var_510 + d * d);
this.var_522 = 0;
}
private function getCameraPositionData(targetPosition:name_194, targetDirection:name_194, useReboundDelay:Boolean, dt:Number, result:CameraPositionData) : void
{
var angle:Number = NaN;
var now:int = 0;
var delta:Number = NaN;
var actualElevation:Number = this.var_521;
var xyLength:Number = Number(Math.sqrt(targetDirection.x * targetDirection.x + targetDirection.y * targetDirection.y));
if(xyLength < 0.00001)
{
flatDirection.x = 1;
flatDirection.y = 0;
}
else
{
flatDirection.x = targetDirection.x / xyLength;
flatDirection.y = targetDirection.y / xyLength;
}
result.extraPitch = 0;
result.t = 1;
var minCollisionDistance:Number = this.var_511;
rayOrigin.copy(targetPosition);
elevationAngles[0] = actualElevation;
axis.x = flatDirection.y;
axis.y = -flatDirection.x;
flatDirection.reverse();
for each(angle in elevationAngles)
{
this.rotationMatrix.method_344(axis,-angle);
this.rotationMatrix.method_345(flatDirection,rayDirection);
minCollisionDistance = this.getMinCollisionDistance(rayOrigin,rayDirection,this.var_511,minCollisionDistance);
}
if(useReboundDelay)
{
now = int(getTimer());
if(minCollisionDistance <= this.var_518 + 0.001)
{
this.var_518 = minCollisionDistance;
this.var_522 = now;
}
else if(now - this.var_522 < reboundDelay.value)
{
minCollisionDistance = this.var_518;
}
else
{
this.var_518 = minCollisionDistance;
}
}
if(minCollisionDistance < this.var_511)
{
result.t = minCollisionDistance / this.var_511;
if(minCollisionDistance < MIN_DISTANCE)
{
rayOrigin.method_362(minCollisionDistance,rayDirection);
delta = MIN_DISTANCE - minCollisionDistance;
if(this.collisionDetector.raycast(rayOrigin,name_194.Z_AXIS,this.collisionMask,delta,null,rayHit))
{
delta = rayHit.t - 10;
if(delta < 0)
{
delta = 0;
}
}
result.position.copy(rayOrigin).method_362(delta,name_194.Z_AXIS);
}
else
{
result.position.copy(rayOrigin).method_362(minCollisionDistance,rayDirection);
}
}
else
{
result.position.copy(rayOrigin).method_362(this.var_511,rayDirection);
}
}
private function getMinCollisionDistance(rayOrigin:name_194, rayDirection:name_194, rayLength:Number, minCollisionDistance:Number) : Number
{
var distance:Number = NaN;
if(this.collisionDetector.raycast(rayOrigin,rayDirection,this.collisionMask,rayLength,null,rayHit))
{
distance = rayHit.t;
if(distance < COLLISION_OFFSET)
{
distance = 0;
}
else
{
distance -= COLLISION_OFFSET;
}
if(distance < minCollisionDistance)
{
return distance;
}
}
return minCollisionDistance;
}
private function updateTargetState() : void
{
this.setMatrixFromObject(this.var_515.parent,parentMatrix);
this.setMatrixFromObject(this.var_515,matrix);
matrix.append(parentMatrix);
matrix.getAxis(3,this.targetPosition);
this.targetDirection.reset(matrix.b,matrix.f,matrix.j);
}
private function setMatrixFromObject(object:name_78, matrix:Matrix4) : void
{
matrix.name_196(object.rotationX,object.rotationY,object.rotationZ);
matrix.name_75(object.x,object.y,object.z);
}
private function updateHeight() : void
{
var heightChangeDir:int = this.input.name_192(KEY_CAMERA_UP) - this.input.name_192(KEY_CAMERA_DOWN);
if(heightChangeDir != 0)
{
this.cameraHeight = this.var_510 + heightChangeDir * HEIGHT_CHANGE_STEP;
}
}
private function getCamDistance(h:Number) : Number
{
var v:Number = 200 - 1750;
var k:Number = (1300 - 600) / (v * v);
return -k * (h - 1750) * (h - 1750) + 1300;
}
private function getLinearSpeed(positionError:Number) : Number
{
return 3 * positionError;
}
private function getAngularSpeed(angleError:Number, currentSpeed:Number) : Number
{
if(angleError < -maxAngleError)
{
return 3 * (angleError + maxAngleError);
}
if(angleError > maxAngleError)
{
return 3 * (angleError - maxAngleError);
}
return currentSpeed;
}
private function snap(value:Number, snapValue:Number, epsilon:Number) : Number
{
if(value > snapValue - epsilon && value < snapValue + epsilon)
{
return snapValue;
}
return value;
}
private function getPitchAngle(cameraPositionData:CameraPositionData) : Number
{
var angle:Number = this.var_521 - fixedPitch.value;
if(angle < 0)
{
angle = 0;
}
var t:Number = cameraPositionData.t;
if(t >= 1 || angle < MIN_CAMERA_ANGLE || noPitchCorrection.value == 1)
{
return cameraPositionData.extraPitch - angle;
}
return cameraPositionData.extraPitch - Math.atan2(t * this.var_510,pitchCorrectionCoeff.value * this.var_510 * (1 / Math.tan(angle) - (1 - t) / Math.tan(this.var_521)));
}
}
}
import package_46.name_194;
class CameraPositionData
{
public var t:Number;
public var extraPitch:Number;
public var position:name_194 = new name_194();
public function CameraPositionData()
{
super();
}
}