|
@@ -8,314 +8,326 @@ var vec3 = glmatrix.vec3;
|
|
|
|
|
|
|
|
//define an inspectorFields to make variables visible in editor
|
|
//define an inspectorFields to make variables visible in editor
|
|
|
var inspectorFields = {
|
|
var inspectorFields = {
|
|
|
- //needs default value to make editor understand type of that value
|
|
|
|
|
- speed: 1.0
|
|
|
|
|
|
|
+ //needs default value to make editor understand type of that value
|
|
|
|
|
+ speed: 1.0
|
|
|
};
|
|
};
|
|
|
//define a component AvatarController
|
|
//define a component AvatarController
|
|
|
-exports.component = function(self) {
|
|
|
|
|
- //link to the current node
|
|
|
|
|
- var node = self.node;
|
|
|
|
|
-
|
|
|
|
|
- var cameraNode;
|
|
|
|
|
-
|
|
|
|
|
- var onGround = true;
|
|
|
|
|
- var okToJump = true;
|
|
|
|
|
- var inAirTime = 0;
|
|
|
|
|
-
|
|
|
|
|
- //define constans
|
|
|
|
|
- var MOVE_FORCE = 1.8;
|
|
|
|
|
- var INAIR_MOVE_FORCE = 0.02;
|
|
|
|
|
- var BRAKE_FORCE = 0.2;
|
|
|
|
|
- var JUMP_FORCE = 7.0;
|
|
|
|
|
- var YAW_SENSITIVITY = 0.1;
|
|
|
|
|
- var INAIR_THRESHOLD_TIME = 0.1;
|
|
|
|
|
-
|
|
|
|
|
- var cameraMode = 0;
|
|
|
|
|
-
|
|
|
|
|
- var yaw = 0;
|
|
|
|
|
- var pitch = 0;
|
|
|
|
|
-
|
|
|
|
|
- var moveForward = false;
|
|
|
|
|
- var moveBackwards = false;
|
|
|
|
|
- var moveLeft = false;
|
|
|
|
|
- var moveRight = false;
|
|
|
|
|
- var mouseMoveX = 0.0;
|
|
|
|
|
- var mouseMoveY = 0.0;
|
|
|
|
|
- var button0 = false;
|
|
|
|
|
- var button1 = false;
|
|
|
|
|
-
|
|
|
|
|
- var lastButton0 = false;
|
|
|
|
|
- var lastButton1 = false;
|
|
|
|
|
-
|
|
|
|
|
- self.idle = true;
|
|
|
|
|
-
|
|
|
|
|
- self.start = function() {
|
|
|
|
|
- //get main camera and set its node to cameraNode
|
|
|
|
|
- var camera = node.scene.getMainCamera();
|
|
|
|
|
- cameraNode = camera.node;
|
|
|
|
|
-
|
|
|
|
|
- // Create rigidbody, and set non-zero mass so that the body becomes dynamic
|
|
|
|
|
- var body = node.createComponent("RigidBody");
|
|
|
|
|
- body.mass = 1.0;
|
|
|
|
|
-
|
|
|
|
|
- // Set zero angular factor so that physics doesn't turn the character on its own.
|
|
|
|
|
- // Instead we will control the character yaw manually
|
|
|
|
|
- body.angularFactor = [0, 0, 0];
|
|
|
|
|
-
|
|
|
|
|
- // Set the rigidbody to signal collision also when in rest, so that we get ground collisions properly
|
|
|
|
|
- body.collisionEventMode = Atomic.COLLISION_ALWAYS;
|
|
|
|
|
-
|
|
|
|
|
- // Set a capsule shape for collision
|
|
|
|
|
- var shape = node.createComponent("CollisionShape");
|
|
|
|
|
- shape.setCapsule(2, 4, [0, 2, 0]);
|
|
|
|
|
-
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- self.fixedUpdate = function(timestep) {
|
|
|
|
|
-
|
|
|
|
|
- //get a RigidBody component from the current node
|
|
|
|
|
- var body = node.getComponent("RigidBody");
|
|
|
|
|
- var inAirTimer = 0.0;
|
|
|
|
|
-
|
|
|
|
|
- // Update the in air timer. Reset if grounded
|
|
|
|
|
- if (!onGround)
|
|
|
|
|
- inAirTimer += timestep;
|
|
|
|
|
- else
|
|
|
|
|
- inAirTimer = 0.0;
|
|
|
|
|
-
|
|
|
|
|
- // When character has been in air less than 1/10 second, it's still interpreted as being on ground
|
|
|
|
|
- var softGrounded = inAirTimer < INAIR_THRESHOLD_TIME;
|
|
|
|
|
-
|
|
|
|
|
- // Get rotation of the current node
|
|
|
|
|
- var rot = node.getRotation();
|
|
|
|
|
-
|
|
|
|
|
- var moveDir = [0, 0, 0];
|
|
|
|
|
-
|
|
|
|
|
- // Update movement & animation
|
|
|
|
|
- var velocity = body.getLinearVelocity();
|
|
|
|
|
-
|
|
|
|
|
- // Velocity on the XZ plane
|
|
|
|
|
- var planeVelocity = [velocity[0], 0.0, velocity[2]];
|
|
|
|
|
-
|
|
|
|
|
- if (cameraMode != 2) {
|
|
|
|
|
- if (moveForward) {
|
|
|
|
|
- vec3.add(moveDir, moveDir, [0, 0, 1]);
|
|
|
|
|
- }
|
|
|
|
|
- if (moveBackwards) {
|
|
|
|
|
- vec3.add(moveDir, moveDir, [0, 0, -1]);
|
|
|
|
|
- }
|
|
|
|
|
- if (moveLeft) {
|
|
|
|
|
- vec3.add(moveDir, moveDir, [-1, 0, 0]);
|
|
|
|
|
- }
|
|
|
|
|
- if (moveRight) {
|
|
|
|
|
- vec3.add(moveDir, moveDir, [1, 0, 0]);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+exports.component = function (self) {
|
|
|
|
|
+
|
|
|
|
|
+ //link to the current node
|
|
|
|
|
+ var node = self.node;
|
|
|
|
|
+
|
|
|
|
|
+ var animModel = node.getComponent("AnimatedModel");
|
|
|
|
|
+
|
|
|
|
|
+ var cameraNode;
|
|
|
|
|
+
|
|
|
|
|
+ var onGround = true;
|
|
|
|
|
+ var okToJump = true;
|
|
|
|
|
+ var inAirTime = 0;
|
|
|
|
|
+
|
|
|
|
|
+ //define constants
|
|
|
|
|
+ var MOVE_FORCE = 1.8;
|
|
|
|
|
+ var INAIR_MOVE_FORCE = 0.02;
|
|
|
|
|
+ var BRAKE_FORCE = 0.2;
|
|
|
|
|
+ var JUMP_FORCE = 7.0;
|
|
|
|
|
+ var YAW_SENSITIVITY = 0.1;
|
|
|
|
|
+ var INAIR_THRESHOLD_TIME = 0.1;
|
|
|
|
|
+
|
|
|
|
|
+ var cameraMode = 0;
|
|
|
|
|
+
|
|
|
|
|
+ var yaw = 0;
|
|
|
|
|
+ var pitch = 0;
|
|
|
|
|
+
|
|
|
|
|
+ var moveForward = false;
|
|
|
|
|
+ var moveBackwards = false;
|
|
|
|
|
+ var moveLeft = false;
|
|
|
|
|
+ var moveRight = false;
|
|
|
|
|
+ var mouseMoveX = 0.0;
|
|
|
|
|
+ var mouseMoveY = 0.0;
|
|
|
|
|
+ var button0 = false;
|
|
|
|
|
+ var button1 = false;
|
|
|
|
|
+
|
|
|
|
|
+ var lastButton0 = false;
|
|
|
|
|
+ var lastButton1 = false;
|
|
|
|
|
+
|
|
|
|
|
+ self.idle = true;
|
|
|
|
|
+
|
|
|
|
|
+ self.start = function () {
|
|
|
|
|
+ //get main camera and set its node to cameraNode
|
|
|
|
|
+ var camera = node.scene.getMainCamera();
|
|
|
|
|
+ cameraNode = camera.node;
|
|
|
|
|
+
|
|
|
|
|
+ // Create rigidbody, and set non-zero mass so that the body becomes dynamic
|
|
|
|
|
+ var body = node.createComponent("RigidBody");
|
|
|
|
|
+ body.mass = 1.0;
|
|
|
|
|
|
|
|
- if (vec3.length(moveDir) > 0.0)
|
|
|
|
|
- vec3.normalize(moveDir, moveDir);
|
|
|
|
|
|
|
+ // Set zero angular factor so that physics doesn't turn the character on its own.
|
|
|
|
|
+ // Instead we will control the character yaw manually
|
|
|
|
|
+ body.angularFactor = [0, 0, 0];
|
|
|
|
|
|
|
|
- vec3.transformQuat(moveDir, moveDir, [rot[1], rot[2], rot[3], rot[0]]);
|
|
|
|
|
- vec3.scale(moveDir, moveDir, (softGrounded ? MOVE_FORCE : INAIR_MOVE_FORCE));
|
|
|
|
|
|
|
+ // Set the rigidbody to signal collision also when in rest, so that we get ground collisions properly
|
|
|
|
|
+ body.collisionEventMode = Atomic.COLLISION_ALWAYS;
|
|
|
|
|
|
|
|
- if (softGrounded)
|
|
|
|
|
- vec3.scale(moveDir, moveDir, self.speed);
|
|
|
|
|
|
|
+ // Set a capsule shape for collision
|
|
|
|
|
+ var shape = node.createComponent("CollisionShape");
|
|
|
|
|
+ shape.setCapsule(2, 4, [0, 2, 0]);
|
|
|
|
|
|
|
|
- body.applyImpulse(moveDir);
|
|
|
|
|
|
|
+ };
|
|
|
|
|
|
|
|
- if (softGrounded) {
|
|
|
|
|
|
|
+ self.fixedUpdate = function (timestep) {
|
|
|
|
|
|
|
|
- // When on ground, apply a braking force to limit maximum ground velocity
|
|
|
|
|
- vec3.negate(planeVelocity, planeVelocity);
|
|
|
|
|
- vec3.scale(planeVelocity, planeVelocity, BRAKE_FORCE);
|
|
|
|
|
- body.applyImpulse(planeVelocity);
|
|
|
|
|
|
|
+ //get a RigidBody component from the current node
|
|
|
|
|
+ var body = node.getComponent("RigidBody");
|
|
|
|
|
+ var inAirTimer = 0.0;
|
|
|
|
|
|
|
|
- // Jump. Must release jump control inbetween jumps
|
|
|
|
|
- if (button1) {
|
|
|
|
|
- if (okToJump) {
|
|
|
|
|
- var jumpforce = [0, 1, 0];
|
|
|
|
|
- vec3.scale(jumpforce, jumpforce, JUMP_FORCE);
|
|
|
|
|
- //Apply impulse to the body
|
|
|
|
|
- body.applyImpulse(jumpforce);
|
|
|
|
|
- okToJump = false;
|
|
|
|
|
|
|
+ // Update the in air timer. Reset if grounded
|
|
|
|
|
+ if (!onGround)
|
|
|
|
|
+ inAirTimer += timestep;
|
|
|
|
|
+ else
|
|
|
|
|
+ inAirTimer = 0.0;
|
|
|
|
|
+
|
|
|
|
|
+ // When character has been in air less than 1/10 second, it's still interpreted as being on ground
|
|
|
|
|
+ var softGrounded = inAirTimer < INAIR_THRESHOLD_TIME;
|
|
|
|
|
+
|
|
|
|
|
+ // Get rotation of the current node
|
|
|
|
|
+ var rot = node.getRotation();
|
|
|
|
|
+
|
|
|
|
|
+ var moveDir = [0, 0, 0];
|
|
|
|
|
+
|
|
|
|
|
+ // Update movement & animation
|
|
|
|
|
+ var velocity = body.getLinearVelocity();
|
|
|
|
|
+
|
|
|
|
|
+ // Velocity on the XZ plane
|
|
|
|
|
+ var planeVelocity = [velocity[0], 0.0, velocity[2]];
|
|
|
|
|
+
|
|
|
|
|
+ if (cameraMode != 2) {
|
|
|
|
|
+ if (moveForward) {
|
|
|
|
|
+ vec3.add(moveDir, moveDir, [0, 0, -1]);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (moveBackwards) {
|
|
|
|
|
+ vec3.add(moveDir, moveDir, [0, 0, 1]);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (moveLeft) {
|
|
|
|
|
+ vec3.add(moveDir, moveDir, [1, 0, 0]);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (moveRight) {
|
|
|
|
|
+ vec3.add(moveDir, moveDir, [-1, 0, 0]);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- } else {
|
|
|
|
|
- okToJump = true;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
|
|
+ if (vec3.length(moveDir) > 0.0)
|
|
|
|
|
+ vec3.normalize(moveDir, moveDir);
|
|
|
|
|
+
|
|
|
|
|
+ vec3.transformQuat(moveDir, moveDir, [rot[1], rot[2], rot[3], rot[0]]);
|
|
|
|
|
+ vec3.scale(moveDir, moveDir, (softGrounded ? MOVE_FORCE : INAIR_MOVE_FORCE));
|
|
|
|
|
+
|
|
|
|
|
+ if (softGrounded)
|
|
|
|
|
+ vec3.scale(moveDir, moveDir, self.speed);
|
|
|
|
|
+
|
|
|
|
|
+ body.applyImpulse(moveDir);
|
|
|
|
|
+
|
|
|
|
|
+ if (softGrounded) {
|
|
|
|
|
+
|
|
|
|
|
+ // When on ground, apply a braking force to limit maximum ground velocity
|
|
|
|
|
+ vec3.negate(planeVelocity, planeVelocity);
|
|
|
|
|
+ vec3.scale(planeVelocity, planeVelocity, BRAKE_FORCE);
|
|
|
|
|
+ body.applyImpulse(planeVelocity);
|
|
|
|
|
|
|
|
- if (softGrounded && vec3.length(moveDir) > 0.0)
|
|
|
|
|
- self.idle = false;
|
|
|
|
|
- else
|
|
|
|
|
- self.idle = true;
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- // Reset grounded flag for next frame
|
|
|
|
|
- onGround = true;
|
|
|
|
|
-
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- function MoveCamera(timeStep) {
|
|
|
|
|
-
|
|
|
|
|
- // Movement speed as world units per second
|
|
|
|
|
- var MOVE_SPEED = 10.0;
|
|
|
|
|
- // Mouse sensitivity as degrees per pixel
|
|
|
|
|
- var MOUSE_SENSITIVITY = 0.1;
|
|
|
|
|
-
|
|
|
|
|
- yaw = yaw + MOUSE_SENSITIVITY * mouseMoveX;
|
|
|
|
|
- pitch = pitch + MOUSE_SENSITIVITY * mouseMoveY;
|
|
|
|
|
-
|
|
|
|
|
- if (pitch < -90)
|
|
|
|
|
- pitch = -90;
|
|
|
|
|
-
|
|
|
|
|
- if (pitch > 90)
|
|
|
|
|
- pitch = 90;
|
|
|
|
|
-
|
|
|
|
|
- // Construct new orientation for the camera scene node from yaw and pitch. Roll is fixed to zero
|
|
|
|
|
- cameraNode.rotation = QuatFromEuler(pitch, yaw, 0.0);
|
|
|
|
|
-
|
|
|
|
|
- var speed = MOVE_SPEED * timeStep;
|
|
|
|
|
-
|
|
|
|
|
- //translate camera on the amount of speed value
|
|
|
|
|
- if (moveForward)
|
|
|
|
|
- cameraNode.translate([0.0, 0.0, speed]);
|
|
|
|
|
- if (moveBackwards)
|
|
|
|
|
- cameraNode.translate([0.0, 0.0, -speed]);
|
|
|
|
|
- if (moveLeft)
|
|
|
|
|
- cameraNode.translate([-speed, 0.0, 0.0]);
|
|
|
|
|
- if (moveRight)
|
|
|
|
|
- cameraNode.translate([speed, 0.0, 0.0]);
|
|
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- function UpdateControls() {
|
|
|
|
|
-
|
|
|
|
|
- var input = Atomic.input;
|
|
|
|
|
-
|
|
|
|
|
- moveForward = false;
|
|
|
|
|
- moveBackwards = false;
|
|
|
|
|
- moveLeft = false;
|
|
|
|
|
- moveRight = false;
|
|
|
|
|
- mouseMoveX = 0.0;
|
|
|
|
|
- mouseMoveY = 0.0;
|
|
|
|
|
- button0 = false;
|
|
|
|
|
- button1 = false;
|
|
|
|
|
-
|
|
|
|
|
- // Movement speed as world units per second
|
|
|
|
|
- var MOVE_SPEED = 20.0;
|
|
|
|
|
- // Mouse sensitivity as degrees per pixel
|
|
|
|
|
- var MOUSE_SENSITIVITY = 0.1;
|
|
|
|
|
-
|
|
|
|
|
- //check input
|
|
|
|
|
- if (input.getKeyDown(Atomic.KEY_W) || input.getKeyDown(Atomic.KEY_UP))
|
|
|
|
|
- moveForward = true;
|
|
|
|
|
- if (input.getKeyDown(Atomic.KEY_S) || input.getKeyDown(Atomic.KEY_DOWN))
|
|
|
|
|
- moveBackwards = true;
|
|
|
|
|
- if (input.getKeyDown(Atomic.KEY_A) || input.getKeyDown(Atomic.KEY_LEFT))
|
|
|
|
|
- moveLeft = true;
|
|
|
|
|
- if (input.getKeyDown(Atomic.KEY_D) || input.getKeyDown(Atomic.KEY_RIGHT))
|
|
|
|
|
- moveRight = true;
|
|
|
|
|
-
|
|
|
|
|
- if (input.getKeyPress(Atomic.KEY_F))
|
|
|
|
|
- button0 = true;
|
|
|
|
|
- if (input.getKeyPress(Atomic.KEY_SPACE))
|
|
|
|
|
- button1 = true;
|
|
|
|
|
-
|
|
|
|
|
- //if we are on mobile
|
|
|
|
|
- if(Atomic.platform == "Android" || Atomic.platform == "iOS") {
|
|
|
|
|
- //iterate through each TouchState, if it doesn't touch any widgets, use it as a `mouse`
|
|
|
|
|
- for(var i = 0; i < Atomic.input.getNumTouches(); i++) {
|
|
|
|
|
- var touchState = Atomic.input.getTouch(i);
|
|
|
|
|
- if(touchState.touchedWidget == null) {
|
|
|
|
|
- var delta = touchState.delta;
|
|
|
|
|
- mouseMoveX = delta[0];
|
|
|
|
|
- mouseMoveY = delta[1];
|
|
|
|
|
|
|
+ // Jump. Must release jump control inbetween jumps
|
|
|
|
|
+ if (button1) {
|
|
|
|
|
+ if (okToJump) {
|
|
|
|
|
+ var jumpforce = [0, 1, 0];
|
|
|
|
|
+ vec3.scale(jumpforce, jumpforce, JUMP_FORCE);
|
|
|
|
|
+ //Apply impulse to the body
|
|
|
|
|
+ body.applyImpulse(jumpforce);
|
|
|
|
|
+ okToJump = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ okToJump = true;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- //if its a desktop
|
|
|
|
|
- } else {
|
|
|
|
|
- // update mouse coordinates
|
|
|
|
|
- mouseMoveX = input.getMouseMoveX();
|
|
|
|
|
- mouseMoveY = input.getMouseMoveY();
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- self.update = function(timeStep) {
|
|
|
|
|
|
|
+ if (softGrounded && vec3.length(moveDir) > 0.0)
|
|
|
|
|
+ self.idle = false;
|
|
|
|
|
+ else
|
|
|
|
|
+ self.idle = true;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ // Reset grounded flag for next frame
|
|
|
|
|
+ onGround = true;
|
|
|
|
|
+
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ function MoveCamera(timeStep) {
|
|
|
|
|
+
|
|
|
|
|
+ // Movement speed as world units per second
|
|
|
|
|
+ var MOVE_SPEED = 15.0;
|
|
|
|
|
+ // Mouse sensitivity as degrees per pixel
|
|
|
|
|
+ var MOUSE_SENSITIVITY = 0.1;
|
|
|
|
|
+
|
|
|
|
|
+ yaw = yaw + MOUSE_SENSITIVITY * mouseMoveX;
|
|
|
|
|
+ pitch = pitch + MOUSE_SENSITIVITY * mouseMoveY;
|
|
|
|
|
|
|
|
- UpdateControls();
|
|
|
|
|
|
|
+ if (pitch < -90)
|
|
|
|
|
+ pitch = -90;
|
|
|
|
|
+
|
|
|
|
|
+ if (pitch > 90)
|
|
|
|
|
+ pitch = 90;
|
|
|
|
|
+
|
|
|
|
|
+ // Construct new orientation for the camera scene node from yaw and pitch. Roll is fixed to zero
|
|
|
|
|
+ cameraNode.rotation = QuatFromEuler(pitch, yaw, 0.0);
|
|
|
|
|
+
|
|
|
|
|
+ var speed = MOVE_SPEED * timeStep;
|
|
|
|
|
+
|
|
|
|
|
+ if (Atomic.input.getKeyDown(Atomic.KEY_LSHIFT))
|
|
|
|
|
+ speed *= 2.0;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ //translate camera on the amount of speed value
|
|
|
|
|
+ if (moveForward)
|
|
|
|
|
+ cameraNode.translate([0.0, 0.0, speed]);
|
|
|
|
|
+ if (moveBackwards)
|
|
|
|
|
+ cameraNode.translate([0.0, 0.0, -speed]);
|
|
|
|
|
+ if (moveLeft)
|
|
|
|
|
+ cameraNode.translate([-speed, 0.0, 0.0]);
|
|
|
|
|
+ if (moveRight)
|
|
|
|
|
+ cameraNode.translate([speed, 0.0, 0.0]);
|
|
|
|
|
|
|
|
- //if it's a free view
|
|
|
|
|
- if (cameraMode != 2) {
|
|
|
|
|
- yaw += mouseMoveX * YAW_SENSITIVITY;
|
|
|
|
|
- pitch += mouseMoveY * YAW_SENSITIVITY;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (pitch < -80)
|
|
|
|
|
- pitch = -80;
|
|
|
|
|
- if (pitch > 80)
|
|
|
|
|
- pitch = 80;
|
|
|
|
|
|
|
+ function UpdateControls() {
|
|
|
|
|
+
|
|
|
|
|
+ var input = Atomic.input;
|
|
|
|
|
+
|
|
|
|
|
+ moveForward = false;
|
|
|
|
|
+ moveBackwards = false;
|
|
|
|
|
+ moveLeft = false;
|
|
|
|
|
+ moveRight = false;
|
|
|
|
|
+ mouseMoveX = 0.0;
|
|
|
|
|
+ mouseMoveY = 0.0;
|
|
|
|
|
+ button0 = false;
|
|
|
|
|
+ button1 = false;
|
|
|
|
|
+
|
|
|
|
|
+ // Movement speed as world units per second
|
|
|
|
|
+ var MOVE_SPEED = 20.0;
|
|
|
|
|
+ // Mouse sensitivity as degrees per pixel
|
|
|
|
|
+ var MOUSE_SENSITIVITY = 0.1;
|
|
|
|
|
+
|
|
|
|
|
+ //check input
|
|
|
|
|
+ if (input.getKeyDown(Atomic.KEY_W) || input.getKeyDown(Atomic.KEY_UP))
|
|
|
|
|
+ moveForward = true;
|
|
|
|
|
+ if (input.getKeyDown(Atomic.KEY_S) || input.getKeyDown(Atomic.KEY_DOWN))
|
|
|
|
|
+ moveBackwards = true;
|
|
|
|
|
+ if (input.getKeyDown(Atomic.KEY_A) || input.getKeyDown(Atomic.KEY_LEFT))
|
|
|
|
|
+ moveLeft = true;
|
|
|
|
|
+ if (input.getKeyDown(Atomic.KEY_D) || input.getKeyDown(Atomic.KEY_RIGHT))
|
|
|
|
|
+ moveRight = true;
|
|
|
|
|
+
|
|
|
|
|
+ if (input.getKeyPress(Atomic.KEY_F))
|
|
|
|
|
+ button0 = true;
|
|
|
|
|
+ if (input.getKeyPress(Atomic.KEY_SPACE))
|
|
|
|
|
+ button1 = true;
|
|
|
|
|
+
|
|
|
|
|
+ //if we are on mobile
|
|
|
|
|
+ if (Atomic.platform == "Android" || Atomic.platform == "iOS") {
|
|
|
|
|
+ //iterate through each TouchState, if it doesn't touch any widgets, use it as a `mouse`
|
|
|
|
|
+ for (var i = 0; i < Atomic.input.getNumTouches(); i++) {
|
|
|
|
|
+ var touchState = Atomic.input.getTouch(i);
|
|
|
|
|
+ if (touchState.touchedWidget == null) {
|
|
|
|
|
+ var delta = touchState.delta;
|
|
|
|
|
+ mouseMoveX = delta[0];
|
|
|
|
|
+ mouseMoveY = delta[1];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ //if its a desktop
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // update mouse coordinates
|
|
|
|
|
+ mouseMoveX = input.getMouseMoveX();
|
|
|
|
|
+ mouseMoveY = input.getMouseMoveY();
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if (button0) {
|
|
|
|
|
- cameraMode++;
|
|
|
|
|
- if (cameraMode == 3)
|
|
|
|
|
- cameraMode = 0;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ self.update = function (timeStep) {
|
|
|
|
|
|
|
|
- //that function called right after update function
|
|
|
|
|
- self.postUpdate = function(timestep) {
|
|
|
|
|
|
|
+ UpdateControls();
|
|
|
|
|
|
|
|
- // Get camera lookat dir from character yaw + pitch
|
|
|
|
|
- var rot = node.getRotation();
|
|
|
|
|
|
|
+ //if it's a free view
|
|
|
|
|
+ if (cameraMode != 2) {
|
|
|
|
|
+ yaw += mouseMoveX * YAW_SENSITIVITY;
|
|
|
|
|
+ pitch += mouseMoveY * YAW_SENSITIVITY;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- //create quaternion
|
|
|
|
|
- var dir = quat.create();
|
|
|
|
|
- //set X value
|
|
|
|
|
- quat.setAxisAngle(dir, [1, 0, 0], (pitch * Math.PI / 180.0));
|
|
|
|
|
|
|
+ if (pitch < -80)
|
|
|
|
|
+ pitch = -80;
|
|
|
|
|
+ if (pitch > 80)
|
|
|
|
|
+ pitch = 80;
|
|
|
|
|
+
|
|
|
|
|
+ if (button0) {
|
|
|
|
|
+ cameraMode++;
|
|
|
|
|
+ if (cameraMode == 3)
|
|
|
|
|
+ cameraMode = 0;
|
|
|
|
|
+ if (cameraMode == 1)
|
|
|
|
|
+ animModel.enabled = false;
|
|
|
|
|
+ else
|
|
|
|
|
+ animModel.enabled = true;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- quat.multiply(dir, [rot[1], rot[2], rot[3], rot[0]], dir);
|
|
|
|
|
|
|
+ };
|
|
|
|
|
|
|
|
- var headNode = node.getChild("Head_Tip", true);
|
|
|
|
|
|
|
+ //that function called right after update function
|
|
|
|
|
+ self.postUpdate = function (timestep) {
|
|
|
|
|
|
|
|
- //if it's a FPS view
|
|
|
|
|
- if (cameraMode == 1) {
|
|
|
|
|
|
|
+ // Get camera lookat dir from character yaw + pitch
|
|
|
|
|
+ var rot = node.getRotation();
|
|
|
|
|
|
|
|
- var headPos = headNode.getWorldPosition();
|
|
|
|
|
- var offset = [0.0, 0.15, 0.2];
|
|
|
|
|
- vec3.add(headPos, headPos, vec3.transformQuat(offset, offset, [rot[1], rot[2], rot[3], rot[0]]));
|
|
|
|
|
- cameraNode.setPosition(headPos);
|
|
|
|
|
- cameraNode.setRotation([dir[3], dir[0], dir[1], dir[2]]);
|
|
|
|
|
- quat.setAxisAngle(dir, [0, 1, 0], (yaw * Math.PI / 180.0));
|
|
|
|
|
- node.setRotation([dir[3], dir[0], dir[1], dir[2]]);
|
|
|
|
|
|
|
+ //create quaternion
|
|
|
|
|
+ var dir = quat.create();
|
|
|
|
|
|
|
|
- }
|
|
|
|
|
- //if it's a third person view
|
|
|
|
|
- if (cameraMode == 0) {
|
|
|
|
|
|
|
+ quat.setAxisAngle(dir, [1, 0, 0], (-pitch * Math.PI / 180.0));
|
|
|
|
|
+ quat.rotateY(dir, dir, 3.14);
|
|
|
|
|
+ quat.multiply(dir, [rot[1], rot[2], rot[3], rot[0]], dir);
|
|
|
|
|
|
|
|
- var aimPoint = node.getWorldPosition();
|
|
|
|
|
- var aimOffset = [0, 1.7, 0];
|
|
|
|
|
- vec3.transformQuat(aimOffset, aimOffset, dir);
|
|
|
|
|
- vec3.add(aimPoint, aimPoint, aimOffset);
|
|
|
|
|
|
|
+ var headNode = node.getChild("Head_Tip", true);
|
|
|
|
|
|
|
|
- var rayDir = vec3.create();
|
|
|
|
|
- vec3.transformQuat(rayDir, [0, 0, -1], dir);
|
|
|
|
|
- vec3.scale(rayDir, rayDir, 8);
|
|
|
|
|
|
|
+ //if it's a FPS view
|
|
|
|
|
+ if (cameraMode == 1) {
|
|
|
|
|
|
|
|
- vec3.add(aimPoint, aimPoint, rayDir);
|
|
|
|
|
|
|
+ var headPos = headNode.getWorldPosition();
|
|
|
|
|
+ var offset = [0.0, 0.15, 0.2];
|
|
|
|
|
+ vec3.add(headPos, headPos, vec3.transformQuat(offset, offset, [rot[1], rot[2], rot[3], rot[0]]));
|
|
|
|
|
+ cameraNode.setPosition(headPos);
|
|
|
|
|
+ cameraNode.setRotation([dir[3], dir[0], dir[1], dir[2]]);
|
|
|
|
|
+ quat.setAxisAngle(dir, [0, 1, 0], (yaw * Math.PI / 180.0));
|
|
|
|
|
+ quat.rotateY(dir, dir, 3.14);
|
|
|
|
|
+ node.setRotation([dir[3], dir[0], dir[1], dir[2]]);
|
|
|
|
|
|
|
|
- cameraNode.setPosition(aimPoint);
|
|
|
|
|
- cameraNode.setRotation([dir[3], dir[0], dir[1], dir[2]]);
|
|
|
|
|
- quat.setAxisAngle(dir, [0, 1, 0], (yaw * Math.PI / 180.0));
|
|
|
|
|
- node.setRotation([dir[3], dir[0], dir[1], dir[2]]);
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ //if it's a third person view
|
|
|
|
|
+ if (cameraMode == 0) {
|
|
|
|
|
|
|
|
- }
|
|
|
|
|
- else{
|
|
|
|
|
- MoveCamera(timestep);
|
|
|
|
|
- }
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ var aimPoint = node.getWorldPosition();
|
|
|
|
|
+ var aimOffset = [0, 1.7, 0];
|
|
|
|
|
+ vec3.transformQuat(aimOffset, aimOffset, dir);
|
|
|
|
|
+ vec3.add(aimPoint, aimPoint, aimOffset);
|
|
|
|
|
+
|
|
|
|
|
+ var rayDir = vec3.create();
|
|
|
|
|
+ vec3.transformQuat(rayDir, [0, 0, -1], dir);
|
|
|
|
|
+ vec3.scale(rayDir, rayDir, 8);
|
|
|
|
|
+
|
|
|
|
|
+ vec3.add(aimPoint, aimPoint, rayDir);
|
|
|
|
|
+
|
|
|
|
|
+ cameraNode.setPosition(aimPoint);
|
|
|
|
|
+ cameraNode.setRotation([dir[3], dir[0], dir[1], dir[2]]);
|
|
|
|
|
+ quat.setAxisAngle(dir, [0, 1, 0], (yaw * Math.PI / 180.0));
|
|
|
|
|
+ node.setRotation([dir[3], dir[0], dir[1], dir[2]]);
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ else {
|
|
|
|
|
+ MoveCamera(timestep);
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
function QuatFromEuler(x, y, z) {
|
|
function QuatFromEuler(x, y, z) {
|