From 7610fe48c228d092b1a14e5ae1ea6e9057244b80 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 14 Jul 2015 09:21:42 -0700 Subject: [PATCH 1/2] filter action updates during simulation ownership This fixes a bug where actions can be thrashed (created/deleted) by late entity update echos from the entity-server. --- libraries/entities/src/EntityItem.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 7354628390..50b36ec6e2 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -610,6 +610,9 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef int bytesRead = parser.offset(); #endif + auto nodeList = DependencyManager::get(); + const QUuid& myNodeID = nodeList->getSessionUUID(); + bool weOwnSimulation = _simulationOwner.matchesValidID(myNodeID); if (args.bitstreamVersion >= VERSION_ENTITIES_HAVE_SIMULATION_OWNER_AND_ACTIONS_OVER_WIRE) { // pack SimulationOwner and terse update properties near each other @@ -632,10 +635,8 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef } { // When we own the simulation we don't accept updates to the entity's transform/velocities // but since we're using macros below we have to temporarily modify overwriteLocalData. - auto nodeList = DependencyManager::get(); - bool weOwnIt = _simulationOwner.matchesValidID(nodeList->getSessionUUID()); bool oldOverwrite = overwriteLocalData; - overwriteLocalData = overwriteLocalData && !weOwnIt; + overwriteLocalData = overwriteLocalData && !weOwnSimulation; READ_ENTITY_PROPERTY(PROP_POSITION, glm::vec3, updatePosition); READ_ENTITY_PROPERTY(PROP_ROTATION, glm::quat, updateRotation); READ_ENTITY_PROPERTY(PROP_VELOCITY, glm::vec3, updateVelocity); @@ -657,6 +658,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef READ_ENTITY_PROPERTY(PROP_REGISTRATION_POINT, glm::vec3, setRegistrationPoint); } else { // legacy order of packing here + // TODO: purge this logic in a few months from now (2015.07) READ_ENTITY_PROPERTY(PROP_POSITION, glm::vec3, updatePosition); READ_ENTITY_PROPERTY(PROP_DIMENSIONS, glm::vec3, updateDimensions); READ_ENTITY_PROPERTY(PROP_ROTATION, glm::quat, updateRotation); @@ -702,7 +704,16 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef READ_ENTITY_PROPERTY(PROP_HREF, QString, setHref); READ_ENTITY_PROPERTY(PROP_DESCRIPTION, QString, setDescription); - READ_ENTITY_PROPERTY(PROP_ACTION_DATA, QByteArray, setActionData); + { // When we own the simulation we don't accept updates to the entity's actions + // but since we're using macros below we have to temporarily modify overwriteLocalData. + // NOTE: this prevents userB from adding an action to an object1 when UserA + // has simulation ownership of it. + // TODO: figure out how to allow multiple users to update actions simultaneously + bool oldOverwrite = overwriteLocalData; + overwriteLocalData = overwriteLocalData && !weOwnSimulation; + READ_ENTITY_PROPERTY(PROP_ACTION_DATA, QByteArray, setActionData); + overwriteLocalData = oldOverwrite; + } bytesRead += readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, propertyFlags, overwriteLocalData); @@ -713,7 +724,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef // NOTE: we had a bad version of the stream that we added stream data after the subclass. We can attempt to recover // by doing this parsing here... but it's not likely going to fully recover the content. // - // TODO: Remove this conde once we've sufficiently migrated content past this damaged version + // TODO: Remove this code once we've sufficiently migrated content past this damaged version if (args.bitstreamVersion == VERSION_ENTITIES_HAS_MARKETPLACE_ID_DAMAGED) { READ_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, QString, setMarketplaceID); } @@ -738,8 +749,6 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef } } - auto nodeList = DependencyManager::get(); - const QUuid& myNodeID = nodeList->getSessionUUID(); if (overwriteLocalData) { if (!_simulationOwner.matchesValidID(myNodeID)) { From 69db9aa01ac18f1330396f9b4fd8d7f8d847fc78 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 14 Jul 2015 09:23:05 -0700 Subject: [PATCH 2/2] fix grab transitions between vert and horiz planes --- examples/grab.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/examples/grab.js b/examples/grab.js index f64aaa30ee..13c91bebb8 100644 --- a/examples/grab.js +++ b/examples/grab.js @@ -43,9 +43,10 @@ var gMaxGrabDistance; // elevationAzimuth var gGrabMode = "xzplane"; -// gGrabOffset allows the user to grab an object off-center. It points from ray's intersection -// with the move-plane to object center (at the moment the grab is initiated). Future target positions -// are relative to the ray's intersection by the same offset. +// gGrabOffset allows the user to grab an object off-center. It points from the object's center +// 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. var gGrabOffset = { x: 0, y: 0, z: 0 }; var gTargetPosition; @@ -152,7 +153,6 @@ function computeNewGrabPlane() { maybeResetMousePosition = true; } gGrabMode = "xzPlane"; - gPointOnPlane = gCurrentPosition; gPlaneNormal = { x: 0, y: 1, z: 0 }; if (gLiftKey) { if (!gRotateKey) { @@ -163,7 +163,7 @@ function computeNewGrabPlane() { gGrabMode = "rotate"; } - gPointOnPlane = Vec3.subtract(gCurrentPosition, gGrabOffset); + gPointOnPlane = Vec3.sum(gCurrentPosition, gGrabOffset); var xzOffset = Vec3.subtract(gPointOnPlane, Camera.getPosition()); xzOffset.y = 0; gXzDistanceToGrab = Vec3.length(xzOffset); @@ -220,8 +220,8 @@ function mousePressEvent(event) { nearestPoint = Vec3.multiply(distanceToGrab, pickRay.direction); gPointOnPlane = Vec3.sum(cameraPosition, nearestPoint); - // compute the grab offset - gGrabOffset = Vec3.subtract(gStartPosition, gPointOnPlane); + // compute the grab offset (points from object center to point of grab) + gGrabOffset = Vec3.subtract(gPointOnPlane, gStartPosition); computeNewGrabPlane(); @@ -258,6 +258,7 @@ function mouseMoveEvent(event) { if (Vec3.length(entityProperties.gravity) != 0) { gOriginalGravity = entityProperties.gravity; } + gCurrentPosition = entityProperties.position; var actionArgs = {}; @@ -287,6 +288,7 @@ function mouseMoveEvent(event) { var pointOnCylinder = Vec3.multiply(planeNormal, gXzDistanceToGrab); pointOnCylinder = Vec3.sum(Camera.getPosition(), pointOnCylinder); newTargetPosition = mouseIntersectionWithPlane(pointOnCylinder, planeNormal, event); + gPointOnPlane = Vec3.sum(newTargetPosition, gGrabOffset); } else { var cameraPosition = Camera.getPosition(); newTargetPosition = mouseIntersectionWithPlane(gPointOnPlane, gPlaneNormal, event); @@ -298,7 +300,7 @@ function mouseMoveEvent(event) { newTargetPosition = Vec3.sum(relativePosition, cameraPosition); } } - gTargetPosition = Vec3.sum(newTargetPosition, gGrabOffset); + gTargetPosition = Vec3.subtract(newTargetPosition, gGrabOffset); actionArgs = {targetPosition: gTargetPosition, linearTimeScale: 0.1}; } gPreviousMouse = { x: event.x, y: event.y };