Merge pull request #7057 from sethalves/grab-then-equip

Grab then equip
This commit is contained in:
Andrew Meadows 2016-02-10 14:16:31 -08:00
commit d121dab937
4 changed files with 52 additions and 25 deletions

View file

@ -148,7 +148,7 @@ function AttachedEntitiesManager() {
this.checkIfWearable = function(grabbedEntity, releasedFromJoint) { this.checkIfWearable = function(grabbedEntity, releasedFromJoint) {
var allowedJoints = getEntityCustomData('wearable', grabbedEntity, DEFAULT_WEARABLE_DATA).joints; var allowedJoints = getEntityCustomData('wearable', grabbedEntity, DEFAULT_WEARABLE_DATA).joints;
var props = Entities.getEntityProperties(grabbedEntity, ["position", "parentID"]); var props = Entities.getEntityProperties(grabbedEntity, ["position", "parentID", "parentJointIndex"]);
if (props.parentID === NULL_UUID || props.parentID === MyAvatar.sessionUUID) { if (props.parentID === NULL_UUID || props.parentID === MyAvatar.sessionUUID) {
var bestJointName = ""; var bestJointName = "";
var bestJointIndex = -1; var bestJointIndex = -1;
@ -192,10 +192,14 @@ function AttachedEntitiesManager() {
} }
Entities.editEntity(grabbedEntity, wearProps); Entities.editEntity(grabbedEntity, wearProps);
} else if (props.parentID != NULL_UUID) { } else if (props.parentID != NULL_UUID) {
// drop the entity with no parent (not on the avatar) // drop the entity and set it to have no parent (not on the avatar), unless it's being equipped in a hand.
Entities.editEntity(grabbedEntity, { if (props.parentID === MyAvatar.sessionUUID &&
parentID: NULL_UUID (props.parentJointIndex == MyAvatar.getJointIndex("RightHand") ||
}); props.parentJointIndex == MyAvatar.getJointIndex("LeftHand"))) {
// this is equipped on a hand -- don't clear the parent.
} else {
Entities.editEntity(grabbedEntity, { parentID: NULL_UUID });
}
} }
} }
} }

View file

@ -946,13 +946,15 @@ function MyController(hand) {
return; return;
} }
// near grab or equip with action // near grab or equip with action
if (near && (grabbableData.refCount < 1 || entityHasActions(this.grabbedEntity))) { var grabData = getEntityCustomData(GRAB_USER_DATA_KEY, this.grabbedEntity, {});
var refCount = ("refCount" in grabData) ? grabData.refCount : 0;
if (near && (refCount < 1 || entityHasActions(this.grabbedEntity))) {
this.setState(this.state == STATE_SEARCHING ? STATE_NEAR_GRABBING : STATE_EQUIP); this.setState(this.state == STATE_SEARCHING ? STATE_NEAR_GRABBING : STATE_EQUIP);
return; return;
} }
// far grab or equip with action // far grab or equip with action
if ((isPhysical || this.state == STATE_EQUIP_SEARCHING) && !near) { if ((isPhysical || this.state == STATE_EQUIP_SEARCHING) && !near) {
if (entityIsGrabbedByOther(intersection.entityID)) { if (entityIsGrabbedByOther(this.grabbedEntity)) {
// don't distance grab something that is already grabbed. // don't distance grab something that is already grabbed.
if (WANT_DEBUG_SEARCH_NAME && props.name == WANT_DEBUG_SEARCH_NAME) { if (WANT_DEBUG_SEARCH_NAME && props.name == WANT_DEBUG_SEARCH_NAME) {
print("grab is skipping '" + WANT_DEBUG_SEARCH_NAME + "': already grabbed by another."); print("grab is skipping '" + WANT_DEBUG_SEARCH_NAME + "': already grabbed by another.");
@ -1449,11 +1451,12 @@ function MyController(hand) {
return; return;
} }
var props = Entities.getEntityProperties(this.grabbedEntity, ["localPosition", "parentID"]); var props = Entities.getEntityProperties(this.grabbedEntity, ["localPosition", "parentID", "position"]);
if (props.parentID == MyAvatar.sessionUUID && if (props.parentID == MyAvatar.sessionUUID &&
Vec3.length(props.localPosition) > NEAR_PICK_MAX_DISTANCE * 2.0) { Vec3.length(props.localPosition) > NEAR_PICK_MAX_DISTANCE * 2.0) {
// for whatever reason, the held/equipped entity has been pulled away. ungrab or unequip. // for whatever reason, the held/equipped entity has been pulled away. ungrab or unequip.
print("handControllerGrab -- autoreleasing held or equipped item because it is far from hand."); print("handControllerGrab -- autoreleasing held or equipped item because it is far from hand." +
props.parentID + " " + vec3toStr(props.position));
this.setState(STATE_RELEASE); this.setState(STATE_RELEASE);
this.callEntityMethodOnGrabbed(this.state == STATE_NEAR_GRABBING ? "releaseGrab" : "releaseEquip", this.callEntityMethodOnGrabbed(this.state == STATE_NEAR_GRABBING ? "releaseGrab" : "releaseEquip",
[JSON.stringify(this.hand)]); [JSON.stringify(this.hand)]);

View file

@ -659,10 +659,10 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
// but since we're using macros below we have to temporarily modify overwriteLocalData. // but since we're using macros below we have to temporarily modify overwriteLocalData.
bool oldOverwrite = overwriteLocalData; bool oldOverwrite = overwriteLocalData;
overwriteLocalData = overwriteLocalData && !weOwnSimulation; overwriteLocalData = overwriteLocalData && !weOwnSimulation;
READ_ENTITY_PROPERTY(PROP_POSITION, glm::vec3, updatePosition); READ_ENTITY_PROPERTY(PROP_POSITION, glm::vec3, updatePositionFromNetwork);
READ_ENTITY_PROPERTY(PROP_ROTATION, glm::quat, updateRotation); READ_ENTITY_PROPERTY(PROP_ROTATION, glm::quat, updateRotationFromNetwork);
READ_ENTITY_PROPERTY(PROP_VELOCITY, glm::vec3, updateVelocity); READ_ENTITY_PROPERTY(PROP_VELOCITY, glm::vec3, updateVelocityFromNetwork);
READ_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, glm::vec3, updateAngularVelocity); READ_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, glm::vec3, updateAngularVelocityFromNetwork);
READ_ENTITY_PROPERTY(PROP_ACCELERATION, glm::vec3, setAcceleration); READ_ENTITY_PROPERTY(PROP_ACCELERATION, glm::vec3, setAcceleration);
overwriteLocalData = oldOverwrite; overwriteLocalData = oldOverwrite;
} }
@ -1358,9 +1358,6 @@ void EntityItem::computeShapeInfo(ShapeInfo& info) {
} }
void EntityItem::updatePosition(const glm::vec3& value) { void EntityItem::updatePosition(const glm::vec3& value) {
if (shouldSuppressLocationEdits()) {
return;
}
if (getLocalPosition() != value) { if (getLocalPosition() != value) {
setLocalPosition(value); setLocalPosition(value);
_dirtyFlags |= Simulation::DIRTY_POSITION; _dirtyFlags |= Simulation::DIRTY_POSITION;
@ -1373,6 +1370,13 @@ void EntityItem::updatePosition(const glm::vec3& value) {
} }
} }
void EntityItem::updatePositionFromNetwork(const glm::vec3& value) {
if (shouldSuppressLocationEdits()) {
return;
}
updatePosition(value);
}
void EntityItem::updateDimensions(const glm::vec3& value) { void EntityItem::updateDimensions(const glm::vec3& value) {
if (getDimensions() != value) { if (getDimensions() != value) {
setDimensions(value); setDimensions(value);
@ -1381,9 +1385,6 @@ void EntityItem::updateDimensions(const glm::vec3& value) {
} }
void EntityItem::updateRotation(const glm::quat& rotation) { void EntityItem::updateRotation(const glm::quat& rotation) {
if (shouldSuppressLocationEdits()) {
return;
}
if (getLocalOrientation() != rotation) { if (getLocalOrientation() != rotation) {
setLocalOrientation(rotation); setLocalOrientation(rotation);
_dirtyFlags |= Simulation::DIRTY_ROTATION; _dirtyFlags |= Simulation::DIRTY_ROTATION;
@ -1397,6 +1398,13 @@ void EntityItem::updateRotation(const glm::quat& rotation) {
} }
} }
void EntityItem::updateRotationFromNetwork(const glm::quat& rotation) {
if (shouldSuppressLocationEdits()) {
return;
}
updateRotation(rotation);
}
void EntityItem::updateMass(float mass) { void EntityItem::updateMass(float mass) {
// Setting the mass actually changes the _density (at fixed volume), however // Setting the mass actually changes the _density (at fixed volume), however
// we must protect the density range to help maintain stability of physics simulation // we must protect the density range to help maintain stability of physics simulation
@ -1421,9 +1429,6 @@ void EntityItem::updateMass(float mass) {
} }
void EntityItem::updateVelocity(const glm::vec3& value) { void EntityItem::updateVelocity(const glm::vec3& value) {
if (shouldSuppressLocationEdits()) {
return;
}
glm::vec3 velocity = getLocalVelocity(); glm::vec3 velocity = getLocalVelocity();
if (velocity != value) { if (velocity != value) {
const float MIN_LINEAR_SPEED = 0.001f; const float MIN_LINEAR_SPEED = 0.001f;
@ -1437,6 +1442,13 @@ void EntityItem::updateVelocity(const glm::vec3& value) {
} }
} }
void EntityItem::updateVelocityFromNetwork(const glm::vec3& value) {
if (shouldSuppressLocationEdits()) {
return;
}
updateVelocity(value);
}
void EntityItem::updateDamping(float value) { void EntityItem::updateDamping(float value) {
auto clampedDamping = glm::clamp(value, 0.0f, 1.0f); auto clampedDamping = glm::clamp(value, 0.0f, 1.0f);
if (_damping != clampedDamping) { if (_damping != clampedDamping) {
@ -1453,9 +1465,6 @@ void EntityItem::updateGravity(const glm::vec3& value) {
} }
void EntityItem::updateAngularVelocity(const glm::vec3& value) { void EntityItem::updateAngularVelocity(const glm::vec3& value) {
if (shouldSuppressLocationEdits()) {
return;
}
glm::vec3 angularVelocity = getLocalAngularVelocity(); glm::vec3 angularVelocity = getLocalAngularVelocity();
if (angularVelocity != value) { if (angularVelocity != value) {
const float MIN_ANGULAR_SPEED = 0.0002f; const float MIN_ANGULAR_SPEED = 0.0002f;
@ -1469,6 +1478,13 @@ void EntityItem::updateAngularVelocity(const glm::vec3& value) {
} }
} }
void EntityItem::updateAngularVelocityFromNetwork(const glm::vec3& value) {
if (shouldSuppressLocationEdits()) {
return;
}
updateAngularVelocity(value);
}
void EntityItem::updateAngularDamping(float value) { void EntityItem::updateAngularDamping(float value) {
auto clampedDamping = glm::clamp(value, 0.0f, 1.0f); auto clampedDamping = glm::clamp(value, 0.0f, 1.0f);
if (_angularDamping != clampedDamping) { if (_angularDamping != clampedDamping) {

View file

@ -319,16 +319,20 @@ public:
// updateFoo() methods to be used when changes need to be accumulated in the _dirtyFlags // updateFoo() methods to be used when changes need to be accumulated in the _dirtyFlags
void updatePosition(const glm::vec3& value); void updatePosition(const glm::vec3& value);
void updatePositionFromNetwork(const glm::vec3& value);
void updateDimensions(const glm::vec3& value); void updateDimensions(const glm::vec3& value);
void updateRotation(const glm::quat& rotation); void updateRotation(const glm::quat& rotation);
void updateRotationFromNetwork(const glm::quat& rotation);
void updateDensity(float value); void updateDensity(float value);
void updateMass(float value); void updateMass(float value);
void updateVelocity(const glm::vec3& value); void updateVelocity(const glm::vec3& value);
void updateVelocityFromNetwork(const glm::vec3& value);
void updateDamping(float value); void updateDamping(float value);
void updateRestitution(float value); void updateRestitution(float value);
void updateFriction(float value); void updateFriction(float value);
void updateGravity(const glm::vec3& value); void updateGravity(const glm::vec3& value);
void updateAngularVelocity(const glm::vec3& value); void updateAngularVelocity(const glm::vec3& value);
void updateAngularVelocityFromNetwork(const glm::vec3& value);
void updateAngularDamping(float value); void updateAngularDamping(float value);
void updateCollisionless(bool value); void updateCollisionless(bool value);
void updateCollisionMask(uint8_t value); void updateCollisionMask(uint8_t value);