mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 19:55:07 +02:00
Merge pull request #4867 from PhilipRosedale/hockeygame
first version, air hockey game
This commit is contained in:
commit
5a0f0972da
2 changed files with 530 additions and 0 deletions
252
examples/example/games/airHockey.js
Normal file
252
examples/example/games/airHockey.js
Normal file
|
@ -0,0 +1,252 @@
|
|||
//
|
||||
// AirHockey.js
|
||||
//
|
||||
// Created by Philip Rosedale on January 26, 2015
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// AirHockey table and pucks
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
var debugVisible = false;
|
||||
|
||||
var FIELD_WIDTH = 1.21;
|
||||
var FIELD_LENGTH = 1.92;
|
||||
var FLOOR_THICKNESS = 0.20;
|
||||
var EDGE_THICKESS = 0.10;
|
||||
var EDGE_HEIGHT = 0.10;
|
||||
var DROP_HEIGHT = 0.3;
|
||||
var PUCK_SIZE = 0.15;
|
||||
var PUCK_THICKNESS = 0.03;
|
||||
var PADDLE_SIZE = 0.12;
|
||||
var PADDLE_THICKNESS = 0.03;
|
||||
|
||||
var GOAL_WIDTH = 0.35;
|
||||
|
||||
var GRAVITY = -9.8;
|
||||
var LIFETIME = 6000;
|
||||
var PUCK_DAMPING = 0.03;
|
||||
var PADDLE_DAMPING = 0.35;
|
||||
var ANGULAR_DAMPING = 0.10;
|
||||
var PADDLE_ANGULAR_DAMPING = 0.35;
|
||||
var MODEL_SCALE = 1.52;
|
||||
var MODEL_OFFSET = { x: 0, y: -0.18, z: 0 };
|
||||
|
||||
var scoreSound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/Collisions-hitsandslaps/airhockey_score.wav");
|
||||
|
||||
var polyTable = "https://hifi-public.s3.amazonaws.com/ozan/props/airHockeyTable/airHockeyTableForPolyworld.fbx"
|
||||
var normalTable = "https://hifi-public.s3.amazonaws.com/ozan/props/airHockeyTable/airHockeyTable.fbx"
|
||||
var hitSound1 = "https://s3.amazonaws.com/hifi-public/sounds/Collisions-hitsandslaps/airhockey_hit1.wav"
|
||||
var hitSound2 = "https://s3.amazonaws.com/hifi-public/sounds/Collisions-hitsandslaps/airhockey_hit2.wav"
|
||||
var hitSideSound = "https://s3.amazonaws.com/hifi-public/sounds/Collisions-hitsandslaps/airhockey_hit3.wav"
|
||||
|
||||
var center = Vec3.sum(MyAvatar.position, Vec3.multiply((FIELD_WIDTH + FIELD_LENGTH) * 0.60, Quat.getFront(Camera.getOrientation())));
|
||||
|
||||
var floor = Entities.addEntity(
|
||||
{ type: "Box",
|
||||
position: Vec3.subtract(center, { x: 0, y: 0, z: 0 }),
|
||||
dimensions: { x: FIELD_WIDTH, y: FLOOR_THICKNESS, z: FIELD_LENGTH },
|
||||
color: { red: 128, green: 128, blue: 128 },
|
||||
gravity: { x: 0, y: 0, z: 0 },
|
||||
ignoreCollisions: false,
|
||||
locked: true,
|
||||
visible: debugVisible,
|
||||
lifetime: LIFETIME });
|
||||
|
||||
var edge1 = Entities.addEntity(
|
||||
{ type: "Box",
|
||||
collisionSoundURL: hitSideSound,
|
||||
position: Vec3.sum(center, { x: FIELD_WIDTH / 2.0, y: FLOOR_THICKNESS / 2.0, z: 0 }),
|
||||
dimensions: { x: EDGE_THICKESS, y: EDGE_HEIGHT, z: FIELD_LENGTH + EDGE_THICKESS },
|
||||
color: { red: 100, green: 100, blue: 100 },
|
||||
gravity: { x: 0, y: 0, z: 0 },
|
||||
ignoreCollisions: false,
|
||||
visible: debugVisible,
|
||||
locked: true,
|
||||
lifetime: LIFETIME });
|
||||
|
||||
var edge2 = Entities.addEntity(
|
||||
{ type: "Box",
|
||||
collisionSoundURL: hitSideSound,
|
||||
position: Vec3.sum(center, { x: -FIELD_WIDTH / 2.0, y: FLOOR_THICKNESS / 2.0, z: 0 }),
|
||||
dimensions: { x: EDGE_THICKESS, y: EDGE_HEIGHT, z: FIELD_LENGTH + EDGE_THICKESS },
|
||||
color: { red: 100, green: 100, blue: 100 },
|
||||
gravity: { x: 0, y: 0, z: 0 },
|
||||
ignoreCollisions: false,
|
||||
visible: debugVisible,
|
||||
locked: true,
|
||||
lifetime: LIFETIME });
|
||||
|
||||
var edge3a = Entities.addEntity(
|
||||
{ type: "Box",
|
||||
collisionSoundURL: hitSideSound,
|
||||
position: Vec3.sum(center, { x: FIELD_WIDTH / 4.0 + (GOAL_WIDTH / 4.0), y: FLOOR_THICKNESS / 2.0, z: -FIELD_LENGTH / 2.0 }),
|
||||
dimensions: { x: FIELD_WIDTH / 2.0 - GOAL_WIDTH / 2.0, y: EDGE_HEIGHT, z: EDGE_THICKESS },
|
||||
color: { red: 100, green: 100, blue: 100 },
|
||||
gravity: { x: 0, y: 0, z: 0 },
|
||||
ignoreCollisions: false,
|
||||
visible: debugVisible,
|
||||
locked: true,
|
||||
lifetime: LIFETIME });
|
||||
|
||||
var edge3b = Entities.addEntity(
|
||||
{ type: "Box",
|
||||
collisionSoundURL: hitSideSound,
|
||||
position: Vec3.sum(center, { x: -FIELD_WIDTH / 4.0 - (GOAL_WIDTH / 4.0), y: FLOOR_THICKNESS / 2.0, z: -FIELD_LENGTH / 2.0 }),
|
||||
dimensions: { x: FIELD_WIDTH / 2.0 - GOAL_WIDTH / 2.0, y: EDGE_HEIGHT, z: EDGE_THICKESS },
|
||||
color: { red: 100, green: 100, blue: 100 },
|
||||
gravity: { x: 0, y: 0, z: 0 },
|
||||
ignoreCollisions: false,
|
||||
visible: debugVisible,
|
||||
locked: true,
|
||||
lifetime: LIFETIME });
|
||||
|
||||
var edge4a = Entities.addEntity(
|
||||
{ type: "Box",
|
||||
collisionSoundURL: hitSideSound,
|
||||
position: Vec3.sum(center, { x: FIELD_WIDTH / 4.0 + (GOAL_WIDTH / 4.0), y: FLOOR_THICKNESS / 2.0, z: FIELD_LENGTH / 2.0 }),
|
||||
dimensions: { x: FIELD_WIDTH / 2.0 - GOAL_WIDTH / 2.0, y: EDGE_HEIGHT, z: EDGE_THICKESS },
|
||||
color: { red: 100, green: 100, blue: 100 },
|
||||
gravity: { x: 0, y: 0, z: 0 },
|
||||
ignoreCollisions: false,
|
||||
visible: debugVisible,
|
||||
locked: true,
|
||||
lifetime: LIFETIME });
|
||||
|
||||
var edge4b = Entities.addEntity(
|
||||
{ type: "Box",
|
||||
collisionSoundURL: hitSideSound,
|
||||
position: Vec3.sum(center, { x: -FIELD_WIDTH / 4.0 - (GOAL_WIDTH / 4.0), y: FLOOR_THICKNESS / 2.0, z: FIELD_LENGTH / 2.0 }),
|
||||
dimensions: { x: FIELD_WIDTH / 2.0 - GOAL_WIDTH / 2.0, y: EDGE_HEIGHT, z: EDGE_THICKESS },
|
||||
color: { red: 100, green: 100, blue: 100 },
|
||||
gravity: { x: 0, y: 0, z: 0 },
|
||||
ignoreCollisions: false,
|
||||
visible: debugVisible,
|
||||
locked: true,
|
||||
lifetime: LIFETIME });
|
||||
|
||||
var table = Entities.addEntity(
|
||||
{ type: "Model",
|
||||
modelURL: polyTable,
|
||||
dimensions: Vec3.multiply({ x: 0.8, y: 0.45, z: 1.31 }, MODEL_SCALE),
|
||||
position: Vec3.sum(center, MODEL_OFFSET),
|
||||
ignoreCollisions: false,
|
||||
visible: true,
|
||||
locked: true,
|
||||
lifetime: LIFETIME });
|
||||
|
||||
var puck;
|
||||
var paddle1, paddle2;
|
||||
|
||||
// Create pucks
|
||||
|
||||
function makeNewProp(which) {
|
||||
if (which == "puck") {
|
||||
return Entities.addEntity(
|
||||
{ type: "Model",
|
||||
modelURL: "http://headache.hungry.com/~seth/hifi/puck.obj",
|
||||
compoundShapeURL: "http://headache.hungry.com/~seth/hifi/puck.obj",
|
||||
collisionSoundURL: hitSound1,
|
||||
position: Vec3.sum(center, { x: 0, y: DROP_HEIGHT, z: 0 }),
|
||||
dimensions: { x: PUCK_SIZE, y: PUCK_THICKNESS, z: PUCK_SIZE },
|
||||
gravity: { x: 0, y: GRAVITY, z: 0 },
|
||||
velocity: { x: 0, y: 0.05, z: 0 },
|
||||
ignoreCollisions: false,
|
||||
damping: PUCK_DAMPING,
|
||||
angularDamping: ANGULAR_DAMPING,
|
||||
lifetime: LIFETIME,
|
||||
collisionsWillMove: true });
|
||||
}
|
||||
else if (which == "paddle1") {
|
||||
return Entities.addEntity(
|
||||
{ type: "Model",
|
||||
modelURL: "http://headache.hungry.com/~seth/hifi/puck.obj",
|
||||
compoundShapeURL: "http://headache.hungry.com/~seth/hifi/puck.obj",
|
||||
collisionSoundURL: hitSound2,
|
||||
position: Vec3.sum(center, { x: 0, y: DROP_HEIGHT, z: FIELD_LENGTH * 0.35 }),
|
||||
dimensions: { x: PADDLE_SIZE, y: PADDLE_THICKNESS, z: PADDLE_SIZE },
|
||||
gravity: { x: 0, y: GRAVITY, z: 0 },
|
||||
velocity: { x: 0, y: 0.05, z: 0 },
|
||||
ignoreCollisions: false,
|
||||
damping: PADDLE_DAMPING,
|
||||
angularDamping: PADDLE_ANGULAR_DAMPING,
|
||||
lifetime: LIFETIME,
|
||||
collisionsWillMove: true });
|
||||
}
|
||||
else if (which == "paddle2") {
|
||||
return Entities.addEntity(
|
||||
{ type: "Model",
|
||||
modelURL: "http://headache.hungry.com/~seth/hifi/puck.obj",
|
||||
compoundShapeURL: "http://headache.hungry.com/~seth/hifi/puck.obj",
|
||||
collisionSoundURL: hitSound2,
|
||||
position: Vec3.sum(center, { x: 0, y: DROP_HEIGHT, z: -FIELD_LENGTH * 0.35 }),
|
||||
dimensions: { x: PADDLE_SIZE, y: PADDLE_THICKNESS, z: PADDLE_SIZE },
|
||||
gravity: { x: 0, y: GRAVITY, z: 0 },
|
||||
velocity: { x: 0, y: 0.05, z: 0 },
|
||||
ignoreCollisions: false,
|
||||
damping: PADDLE_DAMPING,
|
||||
angularDamping: PADDLE_ANGULAR_DAMPING,
|
||||
lifetime: LIFETIME,
|
||||
collisionsWillMove: true });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
puck = makeNewProp("puck");
|
||||
paddle1 = makeNewProp("paddle1");
|
||||
paddle2 = makeNewProp("paddle2");
|
||||
|
||||
function update(deltaTime) {
|
||||
if (Math.random() < 0.1) {
|
||||
puckProps = Entities.getEntityProperties(puck);
|
||||
paddle1Props = Entities.getEntityProperties(paddle1);
|
||||
paddle2Props = Entities.getEntityProperties(paddle2);
|
||||
if (puckProps.position.y < (center.y - DROP_HEIGHT)) {
|
||||
Audio.playSound(scoreSound, {
|
||||
position: center,
|
||||
volume: 1.0
|
||||
});
|
||||
Entities.deleteEntity(puck);
|
||||
puck = makeNewProp("puck");
|
||||
}
|
||||
|
||||
if (paddle1Props.position.y < (center.y - DROP_HEIGHT)) {
|
||||
Entities.deleteEntity(paddle1);
|
||||
paddle1 = makeNewProp("paddle1");
|
||||
}
|
||||
if (paddle2Props.position.y < (center.y - DROP_HEIGHT)) {
|
||||
Entities.deleteEntity(paddle2);
|
||||
paddle2 = makeNewProp("paddle2");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function scriptEnding() {
|
||||
|
||||
Entities.editEntity(edge1, { locked: false });
|
||||
Entities.editEntity(edge2, { locked: false });
|
||||
Entities.editEntity(edge3a, { locked: false });
|
||||
Entities.editEntity(edge3b, { locked: false });
|
||||
Entities.editEntity(edge4a, { locked: false });
|
||||
Entities.editEntity(edge4b, { locked: false });
|
||||
Entities.editEntity(floor, { locked: false });
|
||||
Entities.editEntity(table, { locked: false });
|
||||
|
||||
|
||||
Entities.deleteEntity(edge1);
|
||||
Entities.deleteEntity(edge2);
|
||||
Entities.deleteEntity(edge3a);
|
||||
Entities.deleteEntity(edge3b);
|
||||
Entities.deleteEntity(edge4a);
|
||||
Entities.deleteEntity(edge4b);
|
||||
Entities.deleteEntity(floor);
|
||||
Entities.deleteEntity(puck);
|
||||
Entities.deleteEntity(paddle1);
|
||||
Entities.deleteEntity(paddle2);
|
||||
Entities.deleteEntity(table);
|
||||
}
|
||||
|
||||
Script.update.connect(update);
|
||||
Script.scriptEnding.connect(scriptEnding);
|
278
examples/example/games/grabHockey.js
Normal file
278
examples/example/games/grabHockey.js
Normal file
|
@ -0,0 +1,278 @@
|
|||
|
||||
// grab.js
|
||||
// examples
|
||||
//
|
||||
// Created by Eric Levin on May 1, 2015
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Grab's physically moveable entities with the mouse, by applying a spring force.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
var isGrabbing = false;
|
||||
var grabbedEntity = null;
|
||||
var lineEntityID = null;
|
||||
var prevMouse = {};
|
||||
var deltaMouse = {
|
||||
z: 0
|
||||
}
|
||||
var entityProps;
|
||||
var moveUpDown = false;
|
||||
var CLOSE_ENOUGH = 0.001;
|
||||
var FULL_STRENGTH = 1.0;
|
||||
var SPRING_RATE = 1.5;
|
||||
var DAMPING_RATE = 0.80;
|
||||
var ANGULAR_DAMPING_RATE = 0.40;
|
||||
var SCREEN_TO_METERS = 0.001;
|
||||
var currentPosition, currentVelocity, cameraEntityDistance, currentRotation;
|
||||
var velocityTowardTarget, desiredVelocity, addedVelocity, newVelocity, dPosition, camYaw, distanceToTarget, targetPosition;
|
||||
var originalGravity = {x: 0, y: 0, z: 0};
|
||||
var shouldRotate = false;
|
||||
var dQ, theta, axisAngle, dT;
|
||||
var angularVelocity = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
};
|
||||
|
||||
var grabSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/eric/sounds/CloseClamp.wav");
|
||||
var releaseSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/eric/sounds/ReleaseClamp.wav");
|
||||
var VOLUME = 0.10;
|
||||
|
||||
var DROP_DISTANCE = 5.0;
|
||||
var DROP_COLOR = {
|
||||
red: 200,
|
||||
green: 200,
|
||||
blue: 200
|
||||
};
|
||||
var DROP_WIDTH = 2;
|
||||
|
||||
|
||||
var dropLine = Overlays.addOverlay("line3d", {
|
||||
color: DROP_COLOR,
|
||||
alpha: 1,
|
||||
visible: false,
|
||||
lineWidth: DROP_WIDTH
|
||||
});
|
||||
|
||||
|
||||
function vectorIsZero(v) {
|
||||
return v.x == 0 && v.y == 0 && v.z == 0;
|
||||
}
|
||||
|
||||
function nearLinePoint(targetPosition) {
|
||||
// var handPosition = Vec3.sum(MyAvatar.position, {x:0, y:0.2, z:0});
|
||||
var handPosition = MyAvatar.getRightPalmPosition();
|
||||
var along = Vec3.subtract(targetPosition, handPosition);
|
||||
along = Vec3.normalize(along);
|
||||
along = Vec3.multiply(along, 0.4);
|
||||
return Vec3.sum(handPosition, along);
|
||||
}
|
||||
|
||||
|
||||
function mousePressEvent(event) {
|
||||
if (!event.isLeftButton) {
|
||||
return;
|
||||
}
|
||||
var pickRay = Camera.computePickRay(event.x, event.y);
|
||||
var intersection = Entities.findRayIntersection(pickRay, true); // accurate picking
|
||||
if (intersection.intersects && intersection.properties.collisionsWillMove) {
|
||||
grabbedEntity = intersection.entityID;
|
||||
var props = Entities.getEntityProperties(grabbedEntity)
|
||||
isGrabbing = true;
|
||||
originalGravity = props.gravity;
|
||||
targetPosition = props.position;
|
||||
currentPosition = props.position;
|
||||
currentVelocity = props.velocity;
|
||||
updateDropLine(targetPosition);
|
||||
|
||||
Entities.editEntity(grabbedEntity, {
|
||||
gravity: {x: 0, y: 0, z: 0}
|
||||
});
|
||||
|
||||
lineEntityID = Entities.addEntity({
|
||||
type: "Line",
|
||||
position: nearLinePoint(targetPosition),
|
||||
dimensions: Vec3.subtract(targetPosition, nearLinePoint(targetPosition)),
|
||||
color: { red: 255, green: 255, blue: 255 },
|
||||
lifetime: 300 // if someone crashes while moving something, don't leave the line there forever.
|
||||
});
|
||||
|
||||
Audio.playSound(grabSound, {
|
||||
position: props.position,
|
||||
volume: VOLUME
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function updateDropLine(position) {
|
||||
Overlays.editOverlay(dropLine, {
|
||||
visible: true,
|
||||
start: {
|
||||
x: position.x,
|
||||
y: position.y + DROP_DISTANCE,
|
||||
z: position.z
|
||||
},
|
||||
end: {
|
||||
x: position.x,
|
||||
y: position.y - DROP_DISTANCE,
|
||||
z: position.z
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function mouseReleaseEvent() {
|
||||
if (isGrabbing) {
|
||||
isGrabbing = false;
|
||||
|
||||
// only restore the original gravity if it's not zero. This is to avoid...
|
||||
// 1. interface A grabs an entity and locally saves off its gravity
|
||||
// 2. interface A sets the entity's gravity to zero
|
||||
// 3. interface B grabs the entity and saves off its gravity (which is zero)
|
||||
// 4. interface A releases the entity and puts the original gravity back
|
||||
// 5. interface B releases the entity and puts the original gravity back (to zero)
|
||||
if (!vectorIsZero(originalGravity)) {
|
||||
Entities.editEntity(grabbedEntity, {
|
||||
gravity: originalGravity
|
||||
});
|
||||
}
|
||||
|
||||
Overlays.editOverlay(dropLine, {
|
||||
visible: false
|
||||
});
|
||||
targetPosition = null;
|
||||
|
||||
Entities.deleteEntity(lineEntityID);
|
||||
|
||||
Audio.playSound(releaseSound, {
|
||||
position: entityProps.position,
|
||||
volume: VOLUME
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function mouseMoveEvent(event) {
|
||||
if (isGrabbing) {
|
||||
// see if something added/restored gravity
|
||||
var props = Entities.getEntityProperties(grabbedEntity);
|
||||
if (!vectorIsZero(props.gravity)) {
|
||||
originalGravity = props.gravity;
|
||||
}
|
||||
|
||||
deltaMouse.x = event.x - prevMouse.x;
|
||||
if (!moveUpDown) {
|
||||
deltaMouse.z = event.y - prevMouse.y;
|
||||
deltaMouse.y = 0;
|
||||
} else {
|
||||
deltaMouse.y = (event.y - prevMouse.y) * -1;
|
||||
deltaMouse.z = 0;
|
||||
}
|
||||
// Update the target position by the amount the mouse moved
|
||||
camYaw = Quat.safeEulerAngles(Camera.getOrientation()).y;
|
||||
dPosition = Vec3.multiplyQbyV(Quat.fromPitchYawRollDegrees(0, camYaw, 0), deltaMouse);
|
||||
if (!shouldRotate) {
|
||||
// Adjust target position for the object by the mouse move
|
||||
cameraEntityDistance = Vec3.distance(Camera.getPosition(), currentPosition);
|
||||
// Scale distance we want to move by the distance from the camera to the grabbed object
|
||||
// TODO: Correct SCREEN_TO_METERS to be correct for the actual FOV, resolution
|
||||
targetPosition = Vec3.sum(targetPosition, Vec3.multiply(dPosition, cameraEntityDistance * SCREEN_TO_METERS));
|
||||
} else if (shouldRotate) {
|
||||
var transformedDeltaMouse = {
|
||||
x: deltaMouse.z,
|
||||
y: deltaMouse.x,
|
||||
z: deltaMouse.y
|
||||
};
|
||||
transformedDeltaMouse = Vec3.multiplyQbyV(Quat.fromPitchYawRollDegrees(0, camYaw, 0), transformedDeltaMouse);
|
||||
dQ = Quat.fromVec3Degrees(transformedDeltaMouse);
|
||||
theta = 2 * Math.acos(dQ.w);
|
||||
axisAngle = Quat.axis(dQ);
|
||||
angularVelocity = Vec3.multiply((theta / dT), axisAngle);
|
||||
}
|
||||
|
||||
Entities.editEntity(lineEntityID, {
|
||||
position: nearLinePoint(targetPosition),
|
||||
dimensions: Vec3.subtract(targetPosition, nearLinePoint(targetPosition))
|
||||
});
|
||||
}
|
||||
prevMouse.x = event.x;
|
||||
prevMouse.y = event.y;
|
||||
|
||||
}
|
||||
|
||||
|
||||
function keyReleaseEvent(event) {
|
||||
if (event.text === "SHIFT") {
|
||||
moveUpDown = false;
|
||||
}
|
||||
if (event.text === "SPACE") {
|
||||
shouldRotate = false;
|
||||
}
|
||||
}
|
||||
|
||||
function keyPressEvent(event) {
|
||||
if (event.text === "SHIFT") {
|
||||
moveUpDown = true;
|
||||
}
|
||||
if (event.text === "SPACE") {
|
||||
shouldRotate = true;
|
||||
}
|
||||
}
|
||||
|
||||
function update(deltaTime) {
|
||||
dT = deltaTime;
|
||||
if (isGrabbing) {
|
||||
|
||||
entityProps = Entities.getEntityProperties(grabbedEntity);
|
||||
currentPosition = entityProps.position;
|
||||
currentVelocity = entityProps.velocity;
|
||||
currentRotation = entityProps.rotation;
|
||||
|
||||
var dPosition = Vec3.subtract(targetPosition, currentPosition);
|
||||
|
||||
distanceToTarget = Vec3.length(dPosition);
|
||||
if (distanceToTarget > CLOSE_ENOUGH) {
|
||||
// compute current velocity in the direction we want to move
|
||||
velocityTowardTarget = Vec3.dot(currentVelocity, Vec3.normalize(dPosition));
|
||||
velocityTowardTarget = Vec3.multiply(Vec3.normalize(dPosition), velocityTowardTarget);
|
||||
// compute the speed we would like to be going toward the target position
|
||||
|
||||
desiredVelocity = Vec3.multiply(dPosition, (1.0 / deltaTime) * SPRING_RATE);
|
||||
// compute how much we want to add to the existing velocity
|
||||
addedVelocity = Vec3.subtract(desiredVelocity, velocityTowardTarget);
|
||||
// If target is too far, roll off the force as inverse square of distance
|
||||
if (distanceToTarget / cameraEntityDistance > FULL_STRENGTH) {
|
||||
addedVelocity = Vec3.multiply(addedVelocity, Math.pow(FULL_STRENGTH / distanceToTarget, 2.0));
|
||||
}
|
||||
newVelocity = Vec3.sum(currentVelocity, addedVelocity);
|
||||
// Add Damping
|
||||
newVelocity = Vec3.subtract(newVelocity, Vec3.multiply(newVelocity, DAMPING_RATE));
|
||||
// Update entity
|
||||
} else {
|
||||
newVelocity = {x: 0, y: 0, z: 0};
|
||||
}
|
||||
if (shouldRotate) {
|
||||
angularVelocity = Vec3.subtract(angularVelocity, Vec3.multiply(angularVelocity, ANGULAR_DAMPING_RATE));
|
||||
} else {
|
||||
angularVelocity = entityProps.angularVelocity;
|
||||
}
|
||||
|
||||
Entities.editEntity(grabbedEntity, {
|
||||
position: currentPosition,
|
||||
rotation: currentRotation,
|
||||
velocity: newVelocity,
|
||||
angularVelocity: angularVelocity
|
||||
});
|
||||
updateDropLine(targetPosition);
|
||||
}
|
||||
}
|
||||
|
||||
Controller.mouseMoveEvent.connect(mouseMoveEvent);
|
||||
Controller.mousePressEvent.connect(mousePressEvent);
|
||||
Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
|
||||
Controller.keyPressEvent.connect(keyPressEvent);
|
||||
Controller.keyReleaseEvent.connect(keyReleaseEvent);
|
||||
Script.update.connect(update);
|
Loading…
Reference in a new issue