mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
fixed farGrab parent grabbing and laser LockEndUUID
This commit is contained in:
parent
e432e62a39
commit
3b15897b12
7 changed files with 78 additions and 61 deletions
|
@ -25,7 +25,7 @@ LaserPointer::LaserPointer(const QVariant& rayProps, const RenderStateMap& rende
|
||||||
_distanceScaleEnd(distanceScaleEnd),
|
_distanceScaleEnd(distanceScaleEnd),
|
||||||
_rayPickUID(DependencyManager::get<RayPickScriptingInterface>()->createRayPick(rayProps))
|
_rayPickUID(DependencyManager::get<RayPickScriptingInterface>()->createRayPick(rayProps))
|
||||||
{
|
{
|
||||||
|
_offsetMat = glm::mat4();
|
||||||
|
|
||||||
for (auto& state : _renderStates) {
|
for (auto& state : _renderStates) {
|
||||||
if (!enabled || state.first != _currentRenderState) {
|
if (!enabled || state.first != _currentRenderState) {
|
||||||
|
@ -134,8 +134,10 @@ void LaserPointer::updateRenderState(const RenderState& renderState, const Inter
|
||||||
registrationPoint = glm::vec3(0.5f);
|
registrationPoint = glm::vec3(0.5f);
|
||||||
} else {
|
} else {
|
||||||
EntityItemProperties props = DependencyManager::get<EntityScriptingInterface>()->getEntityProperties(_objectLockEnd.first);
|
EntityItemProperties props = DependencyManager::get<EntityScriptingInterface>()->getEntityProperties(_objectLockEnd.first);
|
||||||
pos = props.getPosition();
|
glm::mat4 entityMat = createMatFromQuatAndPos(props.getRotation(), props.getPosition());
|
||||||
rot = props.getRotation();
|
glm::mat4 finalPosAndRotMat = entityMat * _offsetMat;
|
||||||
|
pos = extractTranslation(finalPosAndRotMat);
|
||||||
|
rot = glmExtractRotation(finalPosAndRotMat);
|
||||||
dim = props.getDimensions();
|
dim = props.getDimensions();
|
||||||
registrationPoint = props.getRegistrationPoint();
|
registrationPoint = props.getRegistrationPoint();
|
||||||
}
|
}
|
||||||
|
@ -233,9 +235,10 @@ void LaserPointer::setLaserLength(const float laserLength) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointer::setLockEndUUID(QUuid objectID, const bool isOverlay, const glm::mat4& offset) {
|
void LaserPointer::setLockEndUUID(QUuid objectID, const bool isOverlay, const glm::mat4& offsetMat) {
|
||||||
withWriteLock([&] {
|
withWriteLock([&] {
|
||||||
_objectLockEnd = std::pair<QUuid, bool>(objectID, isOverlay);
|
_objectLockEnd = std::pair<QUuid, bool>(objectID, isOverlay);
|
||||||
|
_offsetMat = offsetMat;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ public:
|
||||||
|
|
||||||
void setPrecisionPicking(const bool precisionPicking);
|
void setPrecisionPicking(const bool precisionPicking);
|
||||||
void setLaserLength(const float laserLength);
|
void setLaserLength(const float laserLength);
|
||||||
void setLockEndUUID(QUuid objectID, const bool isOverlay, const glm::mat4& offset = glm::mat4());
|
void setLockEndUUID(QUuid objectID, const bool isOverlay, const glm::mat4& offsetMat = glm::mat4());
|
||||||
|
|
||||||
void setIgnoreItems(const QVector<QUuid>& ignoreItems) const;
|
void setIgnoreItems(const QVector<QUuid>& ignoreItems) const;
|
||||||
void setIncludeItems(const QVector<QUuid>& includeItems) const;
|
void setIncludeItems(const QVector<QUuid>& includeItems) const;
|
||||||
|
@ -91,6 +91,7 @@ private:
|
||||||
bool _centerEndY;
|
bool _centerEndY;
|
||||||
bool _lockEnd;
|
bool _lockEnd;
|
||||||
bool _distanceScaleEnd;
|
bool _distanceScaleEnd;
|
||||||
|
glm::mat4 _offsetMat;
|
||||||
std::pair<QUuid, bool> _objectLockEnd { std::pair<QUuid, bool>(QUuid(), false)};
|
std::pair<QUuid, bool> _objectLockEnd { std::pair<QUuid, bool>(QUuid(), false)};
|
||||||
|
|
||||||
const QUuid _rayPickUID;
|
const QUuid _rayPickUID;
|
||||||
|
|
|
@ -113,9 +113,9 @@ void LaserPointerManager::setIncludeItems(const QUuid& uid, const QVector<QUuid>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaserPointerManager::setLockEndUUID(const QUuid& uid, const QUuid& objectID, const bool isOverlay) const {
|
void LaserPointerManager::setLockEndUUID(const QUuid& uid, const QUuid& objectID, const bool isOverlay, const glm::mat4& offsetMat) const {
|
||||||
auto laserPointer = find(uid);
|
auto laserPointer = find(uid);
|
||||||
if (laserPointer) {
|
if (laserPointer) {
|
||||||
laserPointer->setLockEndUUID(objectID, isOverlay);
|
laserPointer->setLockEndUUID(objectID, isOverlay, offsetMat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ public:
|
||||||
void setIgnoreItems(const QUuid& uid, const QVector<QUuid>& ignoreEntities) const;
|
void setIgnoreItems(const QUuid& uid, const QVector<QUuid>& ignoreEntities) const;
|
||||||
void setIncludeItems(const QUuid& uid, const QVector<QUuid>& includeEntities) const;
|
void setIncludeItems(const QUuid& uid, const QVector<QUuid>& includeEntities) const;
|
||||||
|
|
||||||
void setLockEndUUID(const QUuid& uid, const QUuid& objectID, const bool isOverlay) const;
|
void setLockEndUUID(const QUuid& uid, const QUuid& objectID, const bool isOverlay, const glm::mat4& offsetMat = glm::mat4()) const;
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ public slots:
|
||||||
Q_INVOKABLE void setIgnoreItems(const QUuid& uid, const QScriptValue& ignoreEntities) const;
|
Q_INVOKABLE void setIgnoreItems(const QUuid& uid, const QScriptValue& ignoreEntities) const;
|
||||||
Q_INVOKABLE void setIncludeItems(const QUuid& uid, const QScriptValue& includeEntities) const;
|
Q_INVOKABLE void setIncludeItems(const QUuid& uid, const QScriptValue& includeEntities) const;
|
||||||
|
|
||||||
Q_INVOKABLE void setLockEndUUID(const QUuid& uid, const QUuid& objectID, bool isOverlay) const { qApp->getLaserPointerManager().setLockEndUUID(uid, objectID, isOverlay); }
|
Q_INVOKABLE void setLockEndUUID(const QUuid& uid, const QUuid& objectID, bool isOverlay, const glm::mat4& offsetMat = glm::mat4()) const { qApp->getLaserPointerManager().setLockEndUUID(uid, objectID, isOverlay, offsetMat); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static RenderState buildRenderState(const QVariantMap& propMap);
|
static RenderState buildRenderState(const QVariantMap& propMap);
|
||||||
|
|
|
@ -13,13 +13,13 @@
|
||||||
makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION,
|
makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION,
|
||||||
PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD,
|
PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD,
|
||||||
DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic,
|
DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic,
|
||||||
getControllerWorldLocation, projectOntoEntityXYPlane, ContextOverlay, HMD, Reticle, Overlays, isPointingAtUI
|
getControllerWorldLocation, projectOntoEntityXYPlane, ContextOverlay, HMD, Reticle, Overlays, isPointingAtUI, Xform, getEntityParents
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
Script.include("/~/system/libraries/controllers.js");
|
Script.include("/~/system/libraries/controllers.js");
|
||||||
Script.include("/~/system/libraries/Xform.hs");
|
Script.include("/~/system/libraries/Xform.js");
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var PICK_WITH_HAND_RAY = true;
|
var PICK_WITH_HAND_RAY = true;
|
||||||
|
@ -115,32 +115,53 @@ Script.include("/~/system/libraries/Xform.hs");
|
||||||
|
|
||||||
var MARGIN = 25;
|
var MARGIN = 25;
|
||||||
|
|
||||||
function TargetObject(entityID) {
|
function TargetObject(entityID, entityProps) {
|
||||||
this.entityID = entityID;
|
this.entityID = entityID;
|
||||||
this.entityProps = null;
|
this.entityProps = entityProps;
|
||||||
this.parentID = null;
|
this.targetEntityID = null;
|
||||||
this.parentProps = [];
|
this.targetEntityProps = null;
|
||||||
this.childrenProps = [];
|
this.previousCollisionStatus = null;
|
||||||
this.parentsCollisionStatus = [];
|
|
||||||
this.childrenCollisionStatus = [];
|
|
||||||
this.madeDynamic = null;
|
this.madeDynamic = null;
|
||||||
this.parentEntityProps = null;
|
|
||||||
|
|
||||||
this.makeDynamic = function() {
|
this.makeDynamic = function() {
|
||||||
|
if (this.targetEntityID) {
|
||||||
|
var newProps = {
|
||||||
|
dynamic: true,
|
||||||
|
collisionless: true
|
||||||
|
};
|
||||||
|
this.previousCollisionStatus = this.targetEntityProps.collisionless;
|
||||||
|
Entities.editEntity(this.targetEntityID, newProps);
|
||||||
|
this.madeDynamic = true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.saveCollisionStatus = function() {
|
this.restoreTargetEntityOriginalProps = function() {
|
||||||
};
|
if (this.madeDynamic) {
|
||||||
|
var props = {};
|
||||||
this.restoreEntitiesProperties = function() {
|
props.dynamic = false;
|
||||||
|
props.collisionless = this.previousCollisionStatus;
|
||||||
|
var zeroVector = {x: 0, y: 0, z:0};
|
||||||
|
props.localVelocity = zeroVector;
|
||||||
|
props.localRotation = zeroVector;
|
||||||
|
Entities.editEntity(this.targetEntityID, props);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getTargetEntity = function() {
|
this.getTargetEntity = function() {
|
||||||
var parentPropsLength = this.parentProps.length;
|
var parentPropsLength = this.parentProps.length;
|
||||||
if (parentPropsLength !== 0) {
|
if (parentPropsLength !== 0) {
|
||||||
return this.parentProps[parentPropsLength].id;
|
var targetEntity = {
|
||||||
|
id: this.parentProps[parentPropsLength - 1].id,
|
||||||
|
props: this.parentProps[parentPropsLength - 1]};
|
||||||
|
this.targetEntityID = targetEntity.id;
|
||||||
|
this.targetEntityProps = targetEntity.props;
|
||||||
|
return targetEntity;
|
||||||
}
|
}
|
||||||
return this.entityID;
|
this.targetEntityID = this.entityID;
|
||||||
|
this.targetEntityProps = this.entityProps;
|
||||||
|
return {
|
||||||
|
id: this.entityID,
|
||||||
|
props: this.entityProps};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,11 +174,11 @@ Script.include("/~/system/libraries/Xform.hs");
|
||||||
this.entityWithContextOverlay = false;
|
this.entityWithContextOverlay = false;
|
||||||
this.contextOverlayTimer = false;
|
this.contextOverlayTimer = false;
|
||||||
this.previousCollisionStatus = false;
|
this.previousCollisionStatus = false;
|
||||||
|
this.locked = false;
|
||||||
this.reticleMinX = MARGIN;
|
this.reticleMinX = MARGIN;
|
||||||
this.reticleMaxX;
|
this.reticleMaxX;
|
||||||
this.reticleMinY = MARGIN;
|
this.reticleMinY = MARGIN;
|
||||||
this.reticleMaxY;
|
this.reticleMaxY;
|
||||||
this.madeDynamic = false;
|
|
||||||
|
|
||||||
var ACTION_TTL = 15; // seconds
|
var ACTION_TTL = 15; // seconds
|
||||||
|
|
||||||
|
@ -191,10 +212,25 @@ Script.include("/~/system/libraries/Xform.hs");
|
||||||
LaserPointers.enableLaserPointer(laserPointerID);
|
LaserPointers.enableLaserPointer(laserPointerID);
|
||||||
LaserPointers.setRenderState(laserPointerID, mode);
|
LaserPointers.setRenderState(laserPointerID, mode);
|
||||||
if (this.distanceHolding || this.distanceRotating) {
|
if (this.distanceHolding || this.distanceRotating) {
|
||||||
// calculate offset
|
if (!this.locked) {
|
||||||
LaserPointers.setLockEndUUID(laserPointerID, this.entityToLockOnto, this.grabbedIsOverlay);
|
// calculate offset
|
||||||
|
var targetProps = Entities.getEntityProperties(this.targetObject.entityID, [
|
||||||
|
"position",
|
||||||
|
"rotation"
|
||||||
|
]);
|
||||||
|
var zeroVector = { x: 0, y: 0, z:0, w: 0 };
|
||||||
|
var intersection = controllerData.rayPicks[this.hand].intersection;
|
||||||
|
var intersectionMat = new Xform(zeroVector, intersection);
|
||||||
|
var modelMat = new Xform(targetProps.rotation, targetProps.position);
|
||||||
|
var modelMatInv = modelMat.inv();
|
||||||
|
var xformMat = Xform.mul(modelMatInv, intersectionMat);
|
||||||
|
var offsetMat = Mat4.createFromRotAndTrans(xformMat.rot, xformMat.pos);
|
||||||
|
LaserPointers.setLockEndUUID(laserPointerID, this.targetObject.entityID, this.grabbedIsOverlay, offsetMat);
|
||||||
|
this.locked = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LaserPointers.setLockEndUUID(laserPointerID, null, false);
|
LaserPointers.setLockEndUUID(laserPointerID, null, false);
|
||||||
|
this.locked = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -373,22 +409,15 @@ Script.include("/~/system/libraries/Xform.hs");
|
||||||
|
|
||||||
var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID];
|
var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID];
|
||||||
Entities.callEntityMethod(this.grabbedThingID, "releaseGrab", args);
|
Entities.callEntityMethod(this.grabbedThingID, "releaseGrab", args);
|
||||||
|
if (this.targetObject) {
|
||||||
if (this.madeDynamic) {
|
this.targetObject.restoreTargetEntityOriginalProps();
|
||||||
var props = {};
|
|
||||||
props.dynamic = false;
|
|
||||||
props.collisionless = this.previousCollisionStatus;
|
|
||||||
props.localVelocity = {x: 0, y: 0, z: 0};
|
|
||||||
props.localRotation = {x: 0, y: 0, z: 0};
|
|
||||||
Entities.editEntity(this.grabbedThingID, props);
|
|
||||||
this.madeDynamic = false;
|
|
||||||
}
|
}
|
||||||
this.actionID = null;
|
this.actionID = null;
|
||||||
this.grabbedThingID = null;
|
this.grabbedThingID = null;
|
||||||
this.entityToLockOnto = null;
|
this.targetObject = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.updateRecommendedArea = function() {
|
this.updateRecommendedArea = function() {
|
||||||
var dims = Controller.getViewportDimensions();
|
var dims = Controller.getViewportDimensions();
|
||||||
this.reticleMaxX = dims.x - MARGIN;
|
this.reticleMaxX = dims.x - MARGIN;
|
||||||
this.reticleMaxY = dims.y - MARGIN;
|
this.reticleMaxY = dims.y - MARGIN;
|
||||||
|
@ -532,30 +561,24 @@ Script.include("/~/system/libraries/Xform.hs");
|
||||||
if (rayPickInfo.type === RayPick.INTERSECTED_ENTITY) {
|
if (rayPickInfo.type === RayPick.INTERSECTED_ENTITY) {
|
||||||
if (controllerData.triggerClicks[this.hand]) {
|
if (controllerData.triggerClicks[this.hand]) {
|
||||||
var entityID = rayPickInfo.objectID;
|
var entityID = rayPickInfo.objectID;
|
||||||
this.entityToLockOnto = entityID;
|
|
||||||
var targetProps = Entities.getEntityProperties(entityID, [
|
var targetProps = Entities.getEntityProperties(entityID, [
|
||||||
"dynamic", "shapeType", "position",
|
"dynamic", "shapeType", "position",
|
||||||
"rotation", "dimensions", "density",
|
"rotation", "dimensions", "density",
|
||||||
"userData", "locked", "type"
|
"userData", "locked", "type"
|
||||||
]);
|
]);
|
||||||
|
|
||||||
this.targetObject = new TargetObject(entityID);
|
this.targetObject = new TargetObject(entityID, targetProps);
|
||||||
|
this.targetObject.parentProps = getEntityParents(targetProps);
|
||||||
if (entityID !== this.entityWithContextOverlay) {
|
if (entityID !== this.entityWithContextOverlay) {
|
||||||
this.destroyContextOverlay();
|
this.destroyContextOverlay();
|
||||||
}
|
}
|
||||||
|
var targetEntity = this.targetObject.getTargetEntity();
|
||||||
|
entityID = targetEntity.id;
|
||||||
|
targetProps = targetEntity.props;
|
||||||
|
|
||||||
if (entityIsGrabbable(targetProps)) {
|
if (entityIsGrabbable(targetProps)) {
|
||||||
var groupRootProps = findGroupParent(controllerData, targetProps);
|
|
||||||
if (entityIsGrabbable(groupRootProps)) {
|
|
||||||
targetProps = groupRootProps;
|
|
||||||
entityID = targetProps.id;
|
|
||||||
}
|
|
||||||
if (!entityIsDistanceGrabbable(targetProps)) {
|
if (!entityIsDistanceGrabbable(targetProps)) {
|
||||||
targetProps.dynamic = true;
|
this.targetObject.makeDynamic();
|
||||||
this.previousCollisionStatus = targetProps.collisionless;
|
|
||||||
targetProps.collisionless = true;
|
|
||||||
Entities.editEntity(entityID, targetProps);
|
|
||||||
this.madeDynamic = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.distanceRotating) {
|
if (!this.distanceRotating) {
|
||||||
|
|
|
@ -308,16 +308,6 @@ findGroupParent = function (controllerData, targetProps) {
|
||||||
return targetProps;
|
return targetProps;
|
||||||
};
|
};
|
||||||
|
|
||||||
getChildrenProps = function(entityID) {
|
|
||||||
var childrenProps = [];
|
|
||||||
var childrenIDs = Entities.getChildrenIDs(entityID);
|
|
||||||
for (var index = 0; index < childrenIDs.length; index++) {
|
|
||||||
var childProps = Entities.getEntityProperties(childrenIDs[index]);
|
|
||||||
childrenProps.push(childProps);
|
|
||||||
}
|
|
||||||
return childrenProps;
|
|
||||||
};
|
|
||||||
|
|
||||||
getEntityParents = function(targetProps) {
|
getEntityParents = function(targetProps) {
|
||||||
var parentProperties = [];
|
var parentProperties = [];
|
||||||
while (targetProps.parentID &&
|
while (targetProps.parentID &&
|
||||||
|
|
Loading…
Reference in a new issue