mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 14:08:51 +02:00
keep hokey paddle in playing field
This commit is contained in:
parent
1f8008e5b5
commit
257a730029
1 changed files with 111 additions and 31 deletions
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
// grab.js
|
// grab.js
|
||||||
// examples
|
// examples
|
||||||
//
|
//
|
||||||
|
@ -11,12 +10,38 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// these are hand-measured bounds of the AirHockey table
|
||||||
|
var fieldMaxOffset = {
|
||||||
|
x: 0.475,
|
||||||
|
y: 0.315,
|
||||||
|
z: 0.830
|
||||||
|
};
|
||||||
|
var fieldMinOffset = {
|
||||||
|
x: -0.475,
|
||||||
|
y: 0.315,
|
||||||
|
z: -0.830
|
||||||
|
};
|
||||||
|
|
||||||
|
// parameters for storing the table playing field
|
||||||
|
var fieldMax = {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
var fieldMin = {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
|
||||||
var isGrabbing = false;
|
var isGrabbing = false;
|
||||||
var grabbedEntity = null;
|
var grabbedEntity = null;
|
||||||
var prevMouse = {};
|
var prevMouse = {};
|
||||||
var deltaMouse = {
|
var deltaMouse = {
|
||||||
z: 0
|
z: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var TABLE_SEARCH_RANGE = 10;
|
||||||
var entityProps;
|
var entityProps;
|
||||||
var moveUpDown = false;
|
var moveUpDown = false;
|
||||||
var CLOSE_ENOUGH = 0.001;
|
var CLOSE_ENOUGH = 0.001;
|
||||||
|
@ -26,8 +51,13 @@ var DAMPING_RATE = 0.80;
|
||||||
var ANGULAR_DAMPING_RATE = 0.40;
|
var ANGULAR_DAMPING_RATE = 0.40;
|
||||||
var SCREEN_TO_METERS = 0.001;
|
var SCREEN_TO_METERS = 0.001;
|
||||||
var currentPosition, currentVelocity, cameraEntityDistance, currentRotation;
|
var currentPosition, currentVelocity, cameraEntityDistance, currentRotation;
|
||||||
|
var grabHeight;
|
||||||
var velocityTowardTarget, desiredVelocity, addedVelocity, newVelocity, dPosition, camYaw, distanceToTarget, targetPosition;
|
var velocityTowardTarget, desiredVelocity, addedVelocity, newVelocity, dPosition, camYaw, distanceToTarget, targetPosition;
|
||||||
var originalGravity = {x: 0, y: 0, z: 0};
|
var originalGravity = {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
var shouldRotate = false;
|
var shouldRotate = false;
|
||||||
var dQ, theta, axisAngle, dT;
|
var dQ, theta, axisAngle, dT;
|
||||||
var angularVelocity = {
|
var angularVelocity = {
|
||||||
|
@ -75,9 +105,15 @@ function mousePressEvent(event) {
|
||||||
if (!event.isLeftButton) {
|
if (!event.isLeftButton) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
prevMouse.x = event.x;
|
||||||
|
prevMouse.y = event.y;
|
||||||
|
|
||||||
var pickRay = Camera.computePickRay(event.x, event.y);
|
var pickRay = Camera.computePickRay(event.x, event.y);
|
||||||
var intersection = Entities.findRayIntersection(pickRay, true); // accurate picking
|
var intersection = Entities.findRayIntersection(pickRay, true); // accurate picking
|
||||||
if (intersection.intersects && intersection.properties.collisionsWillMove) {
|
if (!intersection.intersects) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (intersection.properties.collisionsWillMove) {
|
||||||
grabbedEntity = intersection.entityID;
|
grabbedEntity = intersection.entityID;
|
||||||
var props = Entities.getEntityProperties(grabbedEntity)
|
var props = Entities.getEntityProperties(grabbedEntity)
|
||||||
isGrabbing = true;
|
isGrabbing = true;
|
||||||
|
@ -87,14 +123,34 @@ function mousePressEvent(event) {
|
||||||
currentVelocity = props.velocity;
|
currentVelocity = props.velocity;
|
||||||
updateDropLine(targetPosition);
|
updateDropLine(targetPosition);
|
||||||
|
|
||||||
|
// remember the height of the object when first grabbed
|
||||||
|
// we'll try to maintain this height during the rest of this grab
|
||||||
|
grabHeight = currentPosition.y;
|
||||||
|
|
||||||
Entities.editEntity(grabbedEntity, {
|
Entities.editEntity(grabbedEntity, {
|
||||||
gravity: {x: 0, y: 0, z: 0}
|
gravity: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
z: 0
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Audio.playSound(grabSound, {
|
Audio.playSound(grabSound, {
|
||||||
position: props.position,
|
position: props.position,
|
||||||
volume: VOLUME
|
volume: VOLUME
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//We want to detect table once user grabs something that may be on a table...
|
||||||
|
var potentialTables = Entities.findEntities(MyAvatar.position, TABLE_SEARCH_RANGE);
|
||||||
|
potentialTables.forEach(function(table) {
|
||||||
|
var props = Entities.getEntityProperties(table);
|
||||||
|
if (props.name === "table") {
|
||||||
|
var tablePosition = props.position;
|
||||||
|
// when we know the table's position we can compute the X-Z bounds of its field
|
||||||
|
fieldMax = Vec3.sum(tablePosition, fieldMaxOffset);
|
||||||
|
fieldMin = Vec3.sum(tablePosition, fieldMinOffset);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,6 +200,7 @@ function mouseReleaseEvent() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// new mouseMoveEvent
|
||||||
function mouseMoveEvent(event) {
|
function mouseMoveEvent(event) {
|
||||||
if (isGrabbing) {
|
if (isGrabbing) {
|
||||||
// see if something added/restored gravity
|
// see if something added/restored gravity
|
||||||
|
@ -152,6 +209,7 @@ function mouseMoveEvent(event) {
|
||||||
originalGravity = props.gravity;
|
originalGravity = props.gravity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shouldRotate) {
|
||||||
deltaMouse.x = event.x - prevMouse.x;
|
deltaMouse.x = event.x - prevMouse.x;
|
||||||
if (!moveUpDown) {
|
if (!moveUpDown) {
|
||||||
deltaMouse.z = event.y - prevMouse.y;
|
deltaMouse.z = event.y - prevMouse.y;
|
||||||
|
@ -160,16 +218,6 @@ function mouseMoveEvent(event) {
|
||||||
deltaMouse.y = (event.y - prevMouse.y) * -1;
|
deltaMouse.y = (event.y - prevMouse.y) * -1;
|
||||||
deltaMouse.z = 0;
|
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 = {
|
var transformedDeltaMouse = {
|
||||||
x: deltaMouse.z,
|
x: deltaMouse.z,
|
||||||
y: deltaMouse.x,
|
y: deltaMouse.x,
|
||||||
|
@ -180,15 +228,37 @@ function mouseMoveEvent(event) {
|
||||||
theta = 2 * Math.acos(dQ.w);
|
theta = 2 * Math.acos(dQ.w);
|
||||||
axisAngle = Quat.axis(dQ);
|
axisAngle = Quat.axis(dQ);
|
||||||
angularVelocity = Vec3.multiply((theta / dT), axisAngle);
|
angularVelocity = Vec3.multiply((theta / dT), axisAngle);
|
||||||
}
|
} else {
|
||||||
|
var relativePosition = Vec3.subtract(currentPosition, Camera.getPosition());
|
||||||
|
if (relativePosition.y < 0) {
|
||||||
|
// grabee is below camera, so movement is valid
|
||||||
|
// compute intersectionPoint where mouse ray hits grabee's current x-z plane
|
||||||
|
var pickRay = Camera.computePickRay(event.x, event.y);
|
||||||
|
var mousePosition = pickRay.direction;
|
||||||
|
var length = relativePosition.y / mousePosition.y;
|
||||||
|
mousePosition = Vec3.multiply(mousePosition, length);
|
||||||
|
mousePosition = Vec3.sum(Camera.getPosition(), mousePosition);
|
||||||
|
|
||||||
|
// clamp mousePosition to table field
|
||||||
|
if (mousePosition.x < fieldMin.x) {
|
||||||
|
mousePosition.x = fieldMin.x;
|
||||||
|
} else if (mousePosition.x > fieldMax.x) {
|
||||||
|
mousePosition.x = fieldMax.x;
|
||||||
|
}
|
||||||
|
if (mousePosition.z < fieldMin.z) {
|
||||||
|
mousePosition.z = fieldMin.z;
|
||||||
|
} else if (mousePosition.z > fieldMax.z) {
|
||||||
|
mousePosition.z = fieldMax.z;
|
||||||
|
}
|
||||||
|
mousePosition.y = grabHeight;
|
||||||
|
targetPosition = mousePosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
prevMouse.x = event.x;
|
prevMouse.x = event.x;
|
||||||
prevMouse.y = event.y;
|
prevMouse.y = event.y;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function keyReleaseEvent(event) {
|
function keyReleaseEvent(event) {
|
||||||
if (event.text === "SHIFT") {
|
if (event.text === "SHIFT") {
|
||||||
moveUpDown = false;
|
moveUpDown = false;
|
||||||
|
@ -237,7 +307,11 @@ function update(deltaTime) {
|
||||||
newVelocity = Vec3.subtract(newVelocity, Vec3.multiply(newVelocity, DAMPING_RATE));
|
newVelocity = Vec3.subtract(newVelocity, Vec3.multiply(newVelocity, DAMPING_RATE));
|
||||||
// Update entity
|
// Update entity
|
||||||
} else {
|
} else {
|
||||||
newVelocity = {x: 0, y: 0, z: 0};
|
newVelocity = {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
}
|
}
|
||||||
if (shouldRotate) {
|
if (shouldRotate) {
|
||||||
angularVelocity = Vec3.subtract(angularVelocity, Vec3.multiply(angularVelocity, ANGULAR_DAMPING_RATE));
|
angularVelocity = Vec3.subtract(angularVelocity, Vec3.multiply(angularVelocity, ANGULAR_DAMPING_RATE));
|
||||||
|
@ -245,6 +319,12 @@ function update(deltaTime) {
|
||||||
angularVelocity = entityProps.angularVelocity;
|
angularVelocity = entityProps.angularVelocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// enforce that grabee's rotation is only about y-axis while being grabbed
|
||||||
|
currentRotation.x = 0;
|
||||||
|
currentRotation.z = 0;
|
||||||
|
currentRotation.y = Math.sqrt(1.0 - currentRotation.w * currentRotation.w);
|
||||||
|
// Hrm... slamming the currentRotation doesn't seem to work
|
||||||
|
|
||||||
Entities.editEntity(grabbedEntity, {
|
Entities.editEntity(grabbedEntity, {
|
||||||
position: currentPosition,
|
position: currentPosition,
|
||||||
rotation: currentRotation,
|
rotation: currentRotation,
|
||||||
|
|
Loading…
Reference in a new issue