mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 14:52:46 +02:00
Prevent mouse grab from grabbing ungrabbable objects
This commit is contained in:
parent
f5743aa770
commit
e615c62bd3
1 changed files with 125 additions and 31 deletions
146
examples/grab.js
146
examples/grab.js
|
@ -9,11 +9,29 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
/*global print, MouseMyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt, pointInExtents, vec3equal, setEntityCustomData, getEntityCustomData */
|
||||
|
||||
var MAX_SOLID_ANGLE = 0.01; // objects that appear smaller than this can't be grabbed
|
||||
var ZERO_VEC3 = {x: 0, y: 0, z: 0};
|
||||
var IDENTITY_QUAT = {x: 0, y: 0, z: 0, w: 0};
|
||||
Script.include("libraries/utils.js");
|
||||
// objects that appear smaller than this can't be grabbed
|
||||
var MAX_SOLID_ANGLE = 0.01;
|
||||
|
||||
var ZERO_VEC3 = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
};
|
||||
var IDENTITY_QUAT = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0,
|
||||
w: 0
|
||||
};
|
||||
var GRABBABLE_DATA_KEY = "grabbableKey";
|
||||
|
||||
|
||||
var defaultGrabbableData = {
|
||||
grabbable: true
|
||||
};
|
||||
|
||||
// helper function
|
||||
function mouseIntersectionWithPlane(pointOnPlane, planeNormal, event, maxDistance) {
|
||||
|
@ -59,36 +77,72 @@ function mouseIntersectionWithPlane(pointOnPlane, planeNormal, event, maxDistanc
|
|||
|
||||
// Mouse class stores mouse click and drag info
|
||||
Mouse = function() {
|
||||
this.current = {x: 0, y: 0 };
|
||||
this.previous = {x: 0, y: 0 };
|
||||
this.rotateStart = {x: 0, y: 0 };
|
||||
this.cursorRestore = {x: 0, y: 0};
|
||||
this.current = {
|
||||
x: 0,
|
||||
y: 0
|
||||
};
|
||||
this.previous = {
|
||||
x: 0,
|
||||
y: 0
|
||||
};
|
||||
this.rotateStart = {
|
||||
x: 0,
|
||||
y: 0
|
||||
};
|
||||
this.cursorRestore = {
|
||||
x: 0,
|
||||
y: 0
|
||||
};
|
||||
}
|
||||
|
||||
Mouse.prototype.startDrag = function(position) {
|
||||
this.current = {x: position.x, y: position.y};
|
||||
this.current = {
|
||||
x: position.x,
|
||||
y: position.y
|
||||
};
|
||||
this.startRotateDrag();
|
||||
}
|
||||
|
||||
Mouse.prototype.updateDrag = function(position) {
|
||||
this.current = {x: position.x, y: position.y };
|
||||
this.current = {
|
||||
x: position.x,
|
||||
y: position.y
|
||||
};
|
||||
}
|
||||
|
||||
Mouse.prototype.startRotateDrag = function() {
|
||||
this.previous = {x: this.current.x, y: this.current.y};
|
||||
this.rotateStart = {x: this.current.x, y: this.current.y};
|
||||
this.cursorRestore = { x: Window.getCursorPositionX(), y: Window.getCursorPositionY() };
|
||||
this.previous = {
|
||||
x: this.current.x,
|
||||
y: this.current.y
|
||||
};
|
||||
this.rotateStart = {
|
||||
x: this.current.x,
|
||||
y: this.current.y
|
||||
};
|
||||
this.cursorRestore = {
|
||||
x: Window.getCursorPositionX(),
|
||||
y: Window.getCursorPositionY()
|
||||
};
|
||||
}
|
||||
|
||||
Mouse.prototype.getDrag = function() {
|
||||
var delta = {x: this.current.x - this.previous.x, y: this.current.y - this.previous.y};
|
||||
this.previous = {x: this.current.x, y: this.current.y};
|
||||
var delta = {
|
||||
x: this.current.x - this.previous.x,
|
||||
y: this.current.y - this.previous.y
|
||||
};
|
||||
this.previous = {
|
||||
x: this.current.x,
|
||||
y: this.current.y
|
||||
};
|
||||
return delta;
|
||||
}
|
||||
|
||||
Mouse.prototype.restoreRotateCursor = function() {
|
||||
Window.setCursorPosition(this.cursorRestore.x, this.cursorRestore.y);
|
||||
this.current = {x: this.rotateStart.x, y: this.rotateStart.y};
|
||||
this.current = {
|
||||
x: this.rotateStart.x,
|
||||
y: this.rotateStart.y
|
||||
};
|
||||
}
|
||||
|
||||
var mouse = new Mouse();
|
||||
|
@ -98,7 +152,11 @@ var mouse = new Mouse();
|
|||
Beacon = function() {
|
||||
this.height = 0.10;
|
||||
this.overlayID = Overlays.addOverlay("line3d", {
|
||||
color: {red: 200, green: 200, blue: 200},
|
||||
color: {
|
||||
red: 200,
|
||||
green: 200,
|
||||
blue: 200
|
||||
},
|
||||
alpha: 1,
|
||||
visible: false,
|
||||
lineWidth: 2
|
||||
|
@ -106,11 +164,15 @@ Beacon = function() {
|
|||
}
|
||||
|
||||
Beacon.prototype.enable = function() {
|
||||
Overlays.editOverlay(this.overlayID, { visible: true });
|
||||
Overlays.editOverlay(this.overlayID, {
|
||||
visible: true
|
||||
});
|
||||
}
|
||||
|
||||
Beacon.prototype.disable = function() {
|
||||
Overlays.editOverlay(this.overlayID, { visible: false });
|
||||
Overlays.editOverlay(this.overlayID, {
|
||||
visible: false
|
||||
});
|
||||
}
|
||||
|
||||
Beacon.prototype.updatePosition = function(position) {
|
||||
|
@ -163,7 +225,11 @@ Grabber = function() {
|
|||
// to the point where the ray intersects the grab plane (at the moment the grab is initiated).
|
||||
// Future target positions of the ray intersection are on the same plane, and the offset is subtracted
|
||||
// to compute the target position of the object's center.
|
||||
this.offset = {x: 0, y: 0, z: 0 };
|
||||
this.offset = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
};
|
||||
|
||||
this.targetPosition;
|
||||
this.targetRotation;
|
||||
|
@ -179,7 +245,11 @@ Grabber.prototype.computeNewGrabPlane = function() {
|
|||
|
||||
var modeWasRotate = (this.mode == "rotate");
|
||||
this.mode = "xzPlane";
|
||||
this.planeNormal = {x: 0, y: 1, z: 0 };
|
||||
this.planeNormal = {
|
||||
x: 0,
|
||||
y: 1,
|
||||
z: 0
|
||||
};
|
||||
if (this.rotateKey) {
|
||||
this.mode = "rotate";
|
||||
mouse.startRotateDrag();
|
||||
|
@ -217,6 +287,12 @@ Grabber.prototype.pressEvent = function(event) {
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, pickResults.entityID, defaultGrabbableData);
|
||||
if (grabbableData.grabbable === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
mouse.startDrag(event);
|
||||
|
||||
var clickedEntity = pickResults.entityID;
|
||||
|
@ -233,13 +309,19 @@ Grabber.prototype.pressEvent = function(event) {
|
|||
return;
|
||||
}
|
||||
|
||||
Entities.editEntity(clickedEntity, { gravity: ZERO_VEC3 });
|
||||
Entities.editEntity(clickedEntity, {
|
||||
gravity: ZERO_VEC3
|
||||
});
|
||||
this.isGrabbing = true;
|
||||
|
||||
this.entityID = clickedEntity;
|
||||
this.currentPosition = entityProperties.position;
|
||||
this.originalGravity = entityProperties.gravity;
|
||||
this.targetPosition = {x: this.startPosition.x, y: this.startPosition.y, z: this.startPosition.z};
|
||||
this.targetPosition = {
|
||||
x: this.startPosition.x,
|
||||
y: this.startPosition.y,
|
||||
z: this.startPosition.z
|
||||
};
|
||||
|
||||
// compute the grab point
|
||||
var nearestPoint = Vec3.subtract(this.startPosition, cameraPosition);
|
||||
|
@ -261,7 +343,9 @@ Grabber.prototype.pressEvent = function(event) {
|
|||
Grabber.prototype.releaseEvent = function() {
|
||||
if (this.isGrabbing) {
|
||||
if (Vec3.length(this.originalGravity) != 0) {
|
||||
Entities.editEntity(this.entityID, { gravity: this.originalGravity});
|
||||
Entities.editEntity(this.entityID, {
|
||||
gravity: this.originalGravity
|
||||
});
|
||||
}
|
||||
|
||||
this.isGrabbing = false
|
||||
|
@ -303,7 +387,10 @@ Grabber.prototype.moveEvent = function(event) {
|
|||
// var qZero = entityProperties.rotation;
|
||||
//var qZero = this.lastRotation;
|
||||
this.lastRotation = Quat.multiply(deltaQ, this.lastRotation);
|
||||
actionArgs = {targetRotation: this.lastRotation, angularTimeScale: 0.1};
|
||||
actionArgs = {
|
||||
targetRotation: this.lastRotation,
|
||||
angularTimeScale: 0.1
|
||||
};
|
||||
} else {
|
||||
var newPointOnPlane;
|
||||
if (this.mode === "verticalCylinder") {
|
||||
|
@ -314,7 +401,11 @@ Grabber.prototype.moveEvent = function(event) {
|
|||
var pointOnCylinder = Vec3.multiply(planeNormal, this.xzDistanceToGrab);
|
||||
pointOnCylinder = Vec3.sum(Camera.getPosition(), pointOnCylinder);
|
||||
this.pointOnPlane = mouseIntersectionWithPlane(pointOnCylinder, planeNormal, mouse.current, this.maxDistance);
|
||||
newPointOnPlane = {x: this.pointOnPlane.x, y: this.pointOnPlane.y, z: this.pointOnPlane.z};
|
||||
newPointOnPlane = {
|
||||
x: this.pointOnPlane.x,
|
||||
y: this.pointOnPlane.y,
|
||||
z: this.pointOnPlane.z
|
||||
};
|
||||
} else {
|
||||
var cameraPosition = Camera.getPosition();
|
||||
newPointOnPlane = mouseIntersectionWithPlane(this.pointOnPlane, this.planeNormal, mouse.current, this.maxDistance);
|
||||
|
@ -327,7 +418,10 @@ Grabber.prototype.moveEvent = function(event) {
|
|||
}
|
||||
}
|
||||
this.targetPosition = Vec3.subtract(newPointOnPlane, this.offset);
|
||||
actionArgs = {targetPosition: this.targetPosition, linearTimeScale: 0.1};
|
||||
actionArgs = {
|
||||
targetPosition: this.targetPosition,
|
||||
linearTimeScale: 0.1
|
||||
};
|
||||
|
||||
beacon.updatePosition(this.targetPosition);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue