mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 15:49:24 +02:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
bec7bef8df
6 changed files with 94 additions and 53 deletions
|
@ -87,15 +87,18 @@ function getTag() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function entityIsGrabbedByOther(entityID) {
|
function entityIsGrabbedByOther(entityID) {
|
||||||
|
// by convention, a distance grab sets the tag of its action to be grab-*owner-session-id*.
|
||||||
var actionIDs = Entities.getActionIDs(entityID);
|
var actionIDs = Entities.getActionIDs(entityID);
|
||||||
for (var actionIndex = 0; actionIndex < actionIDs.length; actionIndex++) {
|
for (var actionIndex = 0; actionIndex < actionIDs.length; actionIndex++) {
|
||||||
var actionID = actionIDs[actionIndex];
|
var actionID = actionIDs[actionIndex];
|
||||||
var actionArguments = Entities.getActionArguments(entityID, actionID);
|
var actionArguments = Entities.getActionArguments(entityID, actionID);
|
||||||
var tag = actionArguments["tag"];
|
var tag = actionArguments["tag"];
|
||||||
if (tag == getTag()) {
|
if (tag == getTag()) {
|
||||||
|
// we see a grab-*uuid* shaped tag, but it's our tag, so that's okay.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (tag.slice(0, 5) == "grab-") {
|
if (tag.slice(0, 5) == "grab-") {
|
||||||
|
// we see a grab-*uuid* shaped tag and it's not ours, so someone else is grabbing it.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,6 +167,12 @@ function MyController(hand, triggerAction) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.setState = function(newState) {
|
||||||
|
// print("STATE: " + this.state + " --> " + newState);
|
||||||
|
this.state = newState;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
this.lineOn = function(closePoint, farPoint, color) {
|
this.lineOn = function(closePoint, farPoint, color) {
|
||||||
// draw a line
|
// draw a line
|
||||||
if (this.pointer === null) {
|
if (this.pointer === null) {
|
||||||
|
@ -217,14 +226,14 @@ function MyController(hand, triggerAction) {
|
||||||
|
|
||||||
this.off = function() {
|
this.off = function() {
|
||||||
if (this.triggerSmoothedSqueezed()) {
|
if (this.triggerSmoothedSqueezed()) {
|
||||||
this.state = STATE_SEARCHING;
|
this.setState(STATE_SEARCHING);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.search = function() {
|
this.search = function() {
|
||||||
if (this.triggerSmoothedReleased()) {
|
if (this.triggerSmoothedReleased()) {
|
||||||
this.state = STATE_RELEASE;
|
this.setState(STATE_RELEASE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,6 +244,8 @@ function MyController(hand, triggerAction) {
|
||||||
direction: Quat.getUp(this.getHandRotation())
|
direction: Quat.getUp(this.getHandRotation())
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.lineOn(pickRay.origin, Vec3.multiply(pickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR);
|
||||||
|
|
||||||
var defaultGrabbableData = {
|
var defaultGrabbableData = {
|
||||||
grabbable: true
|
grabbable: true
|
||||||
};
|
};
|
||||||
|
@ -250,20 +261,20 @@ function MyController(hand, triggerAction) {
|
||||||
|
|
||||||
var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, intersection.entityID, defaultGrabbableData);
|
var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, intersection.entityID, defaultGrabbableData);
|
||||||
if (grabbableData.grabbable === false) {
|
if (grabbableData.grabbable === false) {
|
||||||
|
this.grabbedEntity = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (intersectionDistance < NEAR_PICK_MAX_DISTANCE) {
|
if (intersectionDistance < NEAR_PICK_MAX_DISTANCE) {
|
||||||
// the hand is very close to the intersected object. go into close-grabbing mode.
|
// the hand is very close to the intersected object. go into close-grabbing mode.
|
||||||
this.state = STATE_NEAR_GRABBING;
|
this.setState(STATE_NEAR_GRABBING);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
// don't allow two people to distance grab the same object
|
||||||
if (entityIsGrabbedByOther(intersection.entityID)) {
|
if (entityIsGrabbedByOther(intersection.entityID)) {
|
||||||
// don't allow two people to distance grab the same object
|
this.grabbedEntity = null;
|
||||||
return;
|
} else {
|
||||||
|
// the hand is far from the intersected object. go into distance-holding mode
|
||||||
|
this.setState(STATE_DISTANCE_HOLDING);
|
||||||
}
|
}
|
||||||
// the hand is far from the intersected object. go into distance-holding mode
|
|
||||||
this.state = STATE_DISTANCE_HOLDING;
|
|
||||||
this.lineOn(pickRay.origin, Vec3.multiply(pickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// forward ray test failed, try sphere test.
|
// forward ray test failed, try sphere test.
|
||||||
|
@ -287,15 +298,14 @@ function MyController(hand, triggerAction) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.grabbedEntity === null) {
|
if (this.grabbedEntity === null) {
|
||||||
this.lineOn(pickRay.origin, Vec3.multiply(pickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR);
|
// this.lineOn(pickRay.origin, Vec3.multiply(pickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR);
|
||||||
} else if (props.locked === 0 && props.collisionsWillMove === 1) {
|
} else if (props.locked === 0 && props.collisionsWillMove === 1) {
|
||||||
this.state = STATE_NEAR_GRABBING;
|
this.setState(STATE_NEAR_GRABBING);
|
||||||
} else if (props.collisionsWillMove === 0) {
|
} else if (props.collisionsWillMove === 0) {
|
||||||
// We have grabbed a non-physical object, so we want to trigger a non-colliding event as opposed to a grab event
|
// We have grabbed a non-physical object, so we want to trigger a non-colliding event as opposed to a grab event
|
||||||
this.state = STATE_NEAR_GRABBING_NON_COLLIDING;
|
this.setState(STATE_NEAR_GRABBING_NON_COLLIDING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.distanceHolding = function() {
|
this.distanceHolding = function() {
|
||||||
|
@ -325,7 +335,7 @@ function MyController(hand, triggerAction) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.actionID !== null) {
|
if (this.actionID !== null) {
|
||||||
this.state = STATE_CONTINUE_DISTANCE_HOLDING;
|
this.setState(STATE_CONTINUE_DISTANCE_HOLDING);
|
||||||
this.activateEntity(this.grabbedEntity);
|
this.activateEntity(this.grabbedEntity);
|
||||||
if (this.hand === RIGHT_HAND) {
|
if (this.hand === RIGHT_HAND) {
|
||||||
Entities.callEntityMethod(this.grabbedEntity, "setRightHand");
|
Entities.callEntityMethod(this.grabbedEntity, "setRightHand");
|
||||||
|
@ -342,7 +352,7 @@ function MyController(hand, triggerAction) {
|
||||||
|
|
||||||
this.continueDistanceHolding = function() {
|
this.continueDistanceHolding = function() {
|
||||||
if (this.triggerSmoothedReleased()) {
|
if (this.triggerSmoothedReleased()) {
|
||||||
this.state = STATE_RELEASE;
|
this.setState(STATE_RELEASE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,7 +410,7 @@ function MyController(hand, triggerAction) {
|
||||||
var now = Date.now();
|
var now = Date.now();
|
||||||
var deltaTime = (now - this.currentObjectTime) / MSEC_PER_SEC; // convert to seconds
|
var deltaTime = (now - this.currentObjectTime) / MSEC_PER_SEC; // convert to seconds
|
||||||
this.computeReleaseVelocity(deltaPosition, deltaTime, false);
|
this.computeReleaseVelocity(deltaPosition, deltaTime, false);
|
||||||
|
|
||||||
this.currentObjectPosition = newObjectPosition;
|
this.currentObjectPosition = newObjectPosition;
|
||||||
this.currentObjectTime = now;
|
this.currentObjectTime = now;
|
||||||
|
|
||||||
|
@ -423,7 +433,7 @@ function MyController(hand, triggerAction) {
|
||||||
this.nearGrabbing = function() {
|
this.nearGrabbing = function() {
|
||||||
|
|
||||||
if (this.triggerSmoothedReleased()) {
|
if (this.triggerSmoothedReleased()) {
|
||||||
this.state = STATE_RELEASE;
|
this.setState(STATE_RELEASE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,7 +464,7 @@ function MyController(hand, triggerAction) {
|
||||||
if (this.actionID === NULL_ACTION_ID) {
|
if (this.actionID === NULL_ACTION_ID) {
|
||||||
this.actionID = null;
|
this.actionID = null;
|
||||||
} else {
|
} else {
|
||||||
this.state = STATE_CONTINUE_NEAR_GRABBING;
|
this.setState(STATE_CONTINUE_NEAR_GRABBING);
|
||||||
if (this.hand === RIGHT_HAND) {
|
if (this.hand === RIGHT_HAND) {
|
||||||
Entities.callEntityMethod(this.grabbedEntity, "setRightHand");
|
Entities.callEntityMethod(this.grabbedEntity, "setRightHand");
|
||||||
} else {
|
} else {
|
||||||
|
@ -471,7 +481,7 @@ function MyController(hand, triggerAction) {
|
||||||
|
|
||||||
this.continueNearGrabbing = function() {
|
this.continueNearGrabbing = function() {
|
||||||
if (this.triggerSmoothedReleased()) {
|
if (this.triggerSmoothedReleased()) {
|
||||||
this.state = STATE_RELEASE;
|
this.setState(STATE_RELEASE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,7 +508,7 @@ function MyController(hand, triggerAction) {
|
||||||
|
|
||||||
this.nearGrabbingNonColliding = function() {
|
this.nearGrabbingNonColliding = function() {
|
||||||
if (this.triggerSmoothedReleased()) {
|
if (this.triggerSmoothedReleased()) {
|
||||||
this.state = STATE_RELEASE;
|
this.setState(STATE_RELEASE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.hand === RIGHT_HAND) {
|
if (this.hand === RIGHT_HAND) {
|
||||||
|
@ -507,12 +517,12 @@ function MyController(hand, triggerAction) {
|
||||||
Entities.callEntityMethod(this.grabbedEntity, "setLeftHand");
|
Entities.callEntityMethod(this.grabbedEntity, "setLeftHand");
|
||||||
}
|
}
|
||||||
Entities.callEntityMethod(this.grabbedEntity, "startNearGrabNonColliding");
|
Entities.callEntityMethod(this.grabbedEntity, "startNearGrabNonColliding");
|
||||||
this.state = STATE_CONTINUE_NEAR_GRABBING_NON_COLLIDING;
|
this.setState(STATE_CONTINUE_NEAR_GRABBING_NON_COLLIDING);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.continueNearGrabbingNonColliding = function() {
|
this.continueNearGrabbingNonColliding = function() {
|
||||||
if (this.triggerSmoothedReleased()) {
|
if (this.triggerSmoothedReleased()) {
|
||||||
this.state = STATE_RELEASE;
|
this.setState(STATE_RELEASE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Entities.callEntityMethod(this.grabbedEntity, "continueNearGrabbingNonColliding");
|
Entities.callEntityMethod(this.grabbedEntity, "continueNearGrabbingNonColliding");
|
||||||
|
@ -623,7 +633,7 @@ function MyController(hand, triggerAction) {
|
||||||
this.grabbedVelocity = ZERO_VEC;
|
this.grabbedVelocity = ZERO_VEC;
|
||||||
this.grabbedEntity = null;
|
this.grabbedEntity = null;
|
||||||
this.actionID = null;
|
this.actionID = null;
|
||||||
this.state = STATE_OFF;
|
this.setState(STATE_OFF);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.cleanup = function() {
|
this.cleanup = function() {
|
||||||
|
|
|
@ -45,26 +45,25 @@ var IDENTITY_QUAT = {
|
||||||
z: 0,
|
z: 0,
|
||||||
w: 0
|
w: 0
|
||||||
};
|
};
|
||||||
var ACTION_LIFETIME = 120; // 2 minutes
|
var ACTION_LIFETIME = 10; // seconds
|
||||||
|
|
||||||
function getTag() {
|
function getTag() {
|
||||||
return "grab-" + MyAvatar.sessionUUID;
|
return "grab-" + MyAvatar.sessionUUID;
|
||||||
}
|
}
|
||||||
|
|
||||||
function entityIsGrabbedByOther(entityID) {
|
function entityIsGrabbedByOther(entityID) {
|
||||||
|
// by convention, a distance grab sets the tag of its action to be grab-*owner-session-id*.
|
||||||
var actionIDs = Entities.getActionIDs(entityID);
|
var actionIDs = Entities.getActionIDs(entityID);
|
||||||
var actionIndex;
|
for (var actionIndex = 0; actionIndex < actionIDs.length; actionIndex++) {
|
||||||
var actionID;
|
var actionID = actionIDs[actionIndex];
|
||||||
var actionArguments;
|
var actionArguments = Entities.getActionArguments(entityID, actionID);
|
||||||
var tag;
|
var tag = actionArguments["tag"];
|
||||||
for (actionIndex = 0; actionIndex < actionIDs.length; actionIndex++) {
|
if (tag == getTag()) {
|
||||||
actionID = actionIDs[actionIndex];
|
// we see a grab-*uuid* shaped tag, but it's our tag, so that's okay.
|
||||||
actionArguments = Entities.getActionArguments(entityID, actionID);
|
|
||||||
tag = actionArguments.tag;
|
|
||||||
if (tag === getTag()) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (tag.slice(0, 5) === "grab-") {
|
if (tag.slice(0, 5) == "grab-") {
|
||||||
|
// we see a grab-*uuid* shaped tag and it's not ours, so someone else is grabbing it.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -530,4 +529,4 @@ Controller.mousePressEvent.connect(pressEvent);
|
||||||
Controller.mouseMoveEvent.connect(moveEvent);
|
Controller.mouseMoveEvent.connect(moveEvent);
|
||||||
Controller.mouseReleaseEvent.connect(releaseEvent);
|
Controller.mouseReleaseEvent.connect(releaseEvent);
|
||||||
Controller.keyPressEvent.connect(keyPressEvent);
|
Controller.keyPressEvent.connect(keyPressEvent);
|
||||||
Controller.keyReleaseEvent.connect(keyReleaseEvent);
|
Controller.keyReleaseEvent.connect(keyReleaseEvent);
|
||||||
|
|
|
@ -65,9 +65,9 @@ EntityActionPointer InterfaceActionFactory::factoryBA(EntityItemPointer ownerEnt
|
||||||
|
|
||||||
if (action) {
|
if (action) {
|
||||||
action->deserialize(data);
|
action->deserialize(data);
|
||||||
}
|
if (action->lifetimeIsOver()) {
|
||||||
if (action->lifetimeIsOver()) {
|
return nullptr;
|
||||||
return nullptr;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return action;
|
return action;
|
||||||
|
|
|
@ -48,6 +48,8 @@ public:
|
||||||
|
|
||||||
virtual bool lifetimeIsOver() { return false; }
|
virtual bool lifetimeIsOver() { return false; }
|
||||||
|
|
||||||
|
bool locallyAddedButNotYetReceived = false;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual glm::vec3 getPosition() = 0;
|
virtual glm::vec3 getPosition() = 0;
|
||||||
virtual void setPosition(glm::vec3 position) = 0;
|
virtual void setPosition(glm::vec3 position) = 0;
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
bool EntityItem::_sendPhysicsUpdates = true;
|
bool EntityItem::_sendPhysicsUpdates = true;
|
||||||
int EntityItem::_maxActionsDataSize = 800;
|
int EntityItem::_maxActionsDataSize = 800;
|
||||||
|
quint64 EntityItem::_rememberDeletedActionTime = 20 * USECS_PER_SECOND;
|
||||||
|
|
||||||
EntityItem::EntityItem(const EntityItemID& entityItemID) :
|
EntityItem::EntityItem(const EntityItemID& entityItemID) :
|
||||||
_type(EntityTypes::Unknown),
|
_type(EntityTypes::Unknown),
|
||||||
|
@ -1505,6 +1506,8 @@ bool EntityItem::addAction(EntitySimulation* simulation, EntityActionPointer act
|
||||||
result = addActionInternal(simulation, action);
|
result = addActionInternal(simulation, action);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
removeActionInternal(action->getID());
|
removeActionInternal(action->getID());
|
||||||
|
} else {
|
||||||
|
action->locallyAddedButNotYetReceived = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1525,7 +1528,8 @@ bool EntityItem::addActionInternal(EntitySimulation* simulation, EntityActionPoi
|
||||||
simulation->addAction(action);
|
simulation->addAction(action);
|
||||||
|
|
||||||
bool success;
|
bool success;
|
||||||
QByteArray newDataCache = serializeActions(success);
|
QByteArray newDataCache;
|
||||||
|
serializeActions(success, newDataCache);
|
||||||
if (success) {
|
if (success) {
|
||||||
_allActionsDataCache = newDataCache;
|
_allActionsDataCache = newDataCache;
|
||||||
_dirtyFlags |= EntityItem::DIRTY_PHYSICS_ACTIVATION;
|
_dirtyFlags |= EntityItem::DIRTY_PHYSICS_ACTIVATION;
|
||||||
|
@ -1546,7 +1550,7 @@ bool EntityItem::updateAction(EntitySimulation* simulation, const QUuid& actionI
|
||||||
|
|
||||||
success = action->updateArguments(arguments);
|
success = action->updateArguments(arguments);
|
||||||
if (success) {
|
if (success) {
|
||||||
_allActionsDataCache = serializeActions(success);
|
serializeActions(success, _allActionsDataCache);
|
||||||
_dirtyFlags |= EntityItem::DIRTY_PHYSICS_ACTIVATION;
|
_dirtyFlags |= EntityItem::DIRTY_PHYSICS_ACTIVATION;
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "EntityItem::updateAction failed";
|
qDebug() << "EntityItem::updateAction failed";
|
||||||
|
@ -1566,6 +1570,7 @@ bool EntityItem::removeAction(EntitySimulation* simulation, const QUuid& actionI
|
||||||
|
|
||||||
bool EntityItem::removeActionInternal(const QUuid& actionID, EntitySimulation* simulation) {
|
bool EntityItem::removeActionInternal(const QUuid& actionID, EntitySimulation* simulation) {
|
||||||
assertWriteLocked();
|
assertWriteLocked();
|
||||||
|
_previouslyDeletedActions.insert(actionID, usecTimestampNow());
|
||||||
if (_objectActions.contains(actionID)) {
|
if (_objectActions.contains(actionID)) {
|
||||||
if (!simulation) {
|
if (!simulation) {
|
||||||
EntityTreePointer entityTree = _element ? _element->getTree() : nullptr;
|
EntityTreePointer entityTree = _element ? _element->getTree() : nullptr;
|
||||||
|
@ -1581,7 +1586,7 @@ bool EntityItem::removeActionInternal(const QUuid& actionID, EntitySimulation* s
|
||||||
}
|
}
|
||||||
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
_allActionsDataCache = serializeActions(success);
|
serializeActions(success, _allActionsDataCache);
|
||||||
_dirtyFlags |= EntityItem::DIRTY_PHYSICS_ACTIVATION;
|
_dirtyFlags |= EntityItem::DIRTY_PHYSICS_ACTIVATION;
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
@ -1618,6 +1623,8 @@ void EntityItem::deserializeActions() {
|
||||||
void EntityItem::deserializeActionsInternal() {
|
void EntityItem::deserializeActionsInternal() {
|
||||||
assertWriteLocked();
|
assertWriteLocked();
|
||||||
|
|
||||||
|
quint64 now = usecTimestampNow();
|
||||||
|
|
||||||
if (!_element) {
|
if (!_element) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1643,6 +1650,10 @@ void EntityItem::deserializeActionsInternal() {
|
||||||
QUuid actionID;
|
QUuid actionID;
|
||||||
serializedActionStream >> actionType;
|
serializedActionStream >> actionType;
|
||||||
serializedActionStream >> actionID;
|
serializedActionStream >> actionID;
|
||||||
|
if (_previouslyDeletedActions.contains(actionID)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
updated << actionID;
|
updated << actionID;
|
||||||
|
|
||||||
if (_objectActions.contains(actionID)) {
|
if (_objectActions.contains(actionID)) {
|
||||||
|
@ -1650,14 +1661,14 @@ void EntityItem::deserializeActionsInternal() {
|
||||||
// TODO: make sure types match? there isn't currently a way to
|
// TODO: make sure types match? there isn't currently a way to
|
||||||
// change the type of an existing action.
|
// change the type of an existing action.
|
||||||
action->deserialize(serializedAction);
|
action->deserialize(serializedAction);
|
||||||
|
action->locallyAddedButNotYetReceived = false;
|
||||||
} else {
|
} else {
|
||||||
auto actionFactory = DependencyManager::get<EntityActionFactoryInterface>();
|
auto actionFactory = DependencyManager::get<EntityActionFactoryInterface>();
|
||||||
|
|
||||||
// EntityItemPointer entity = entityTree->findEntityByEntityItemID(_id, false);
|
|
||||||
EntityItemPointer entity = shared_from_this();
|
EntityItemPointer entity = shared_from_this();
|
||||||
EntityActionPointer action = actionFactory->factoryBA(entity, serializedAction);
|
EntityActionPointer action = actionFactory->factoryBA(entity, serializedAction);
|
||||||
if (action) {
|
if (action) {
|
||||||
entity->addActionInternal(simulation, action);
|
entity->addActionInternal(simulation, action);
|
||||||
|
action->locallyAddedButNotYetReceived = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1667,11 +1678,27 @@ void EntityItem::deserializeActionsInternal() {
|
||||||
while (i != _objectActions.end()) {
|
while (i != _objectActions.end()) {
|
||||||
QUuid id = i.key();
|
QUuid id = i.key();
|
||||||
if (!updated.contains(id)) {
|
if (!updated.contains(id)) {
|
||||||
_actionsToRemove << id;
|
EntityActionPointer action = i.value();
|
||||||
|
// if we've just added this action, don't remove it due to lack of mention in an incoming packet.
|
||||||
|
if (! action->locallyAddedButNotYetReceived) {
|
||||||
|
_actionsToRemove << id;
|
||||||
|
_previouslyDeletedActions.insert(id, now);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// trim down _previouslyDeletedActions
|
||||||
|
QMutableHashIterator<QUuid, quint64> _previouslyDeletedIter(_previouslyDeletedActions);
|
||||||
|
while (_previouslyDeletedIter.hasNext()) {
|
||||||
|
_previouslyDeletedIter.next();
|
||||||
|
if (now - _previouslyDeletedIter.value() > _rememberDeletedActionTime) {
|
||||||
|
_previouslyDeletedActions.remove(_previouslyDeletedIter.key());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_actionDataDirty = true;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1697,13 +1724,13 @@ void EntityItem::setActionDataInternal(QByteArray actionData) {
|
||||||
deserializeActionsInternal();
|
deserializeActionsInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray EntityItem::serializeActions(bool& success) const {
|
void EntityItem::serializeActions(bool& success, QByteArray& result) const {
|
||||||
assertLocked();
|
assertLocked();
|
||||||
QByteArray result;
|
|
||||||
|
|
||||||
if (_objectActions.size() == 0) {
|
if (_objectActions.size() == 0) {
|
||||||
success = true;
|
success = true;
|
||||||
return QByteArray();
|
result.clear();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<QByteArray> serializedActions;
|
QVector<QByteArray> serializedActions;
|
||||||
|
@ -1721,21 +1748,20 @@ QByteArray EntityItem::serializeActions(bool& success) const {
|
||||||
|
|
||||||
if (result.size() >= _maxActionsDataSize) {
|
if (result.size() >= _maxActionsDataSize) {
|
||||||
success = false;
|
success = false;
|
||||||
return result;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
success = true;
|
success = true;
|
||||||
return result;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QByteArray EntityItem::getActionDataInternal() const {
|
const QByteArray EntityItem::getActionDataInternal() const {
|
||||||
if (_actionDataDirty) {
|
if (_actionDataDirty) {
|
||||||
bool success;
|
bool success;
|
||||||
QByteArray newDataCache = serializeActions(success);
|
serializeActions(success, _allActionsDataCache);
|
||||||
if (success) {
|
if (success) {
|
||||||
_allActionsDataCache = newDataCache;
|
_actionDataDirty = false;
|
||||||
}
|
}
|
||||||
_actionDataDirty = false;
|
|
||||||
}
|
}
|
||||||
return _allActionsDataCache;
|
return _allActionsDataCache;
|
||||||
}
|
}
|
||||||
|
|
|
@ -508,17 +508,21 @@ protected:
|
||||||
bool addActionInternal(EntitySimulation* simulation, EntityActionPointer action);
|
bool addActionInternal(EntitySimulation* simulation, EntityActionPointer action);
|
||||||
bool removeActionInternal(const QUuid& actionID, EntitySimulation* simulation = nullptr);
|
bool removeActionInternal(const QUuid& actionID, EntitySimulation* simulation = nullptr);
|
||||||
void deserializeActionsInternal();
|
void deserializeActionsInternal();
|
||||||
QByteArray serializeActions(bool& success) const;
|
void serializeActions(bool& success, QByteArray& result) const;
|
||||||
QHash<QUuid, EntityActionPointer> _objectActions;
|
QHash<QUuid, EntityActionPointer> _objectActions;
|
||||||
|
|
||||||
static int _maxActionsDataSize;
|
static int _maxActionsDataSize;
|
||||||
mutable QByteArray _allActionsDataCache;
|
mutable QByteArray _allActionsDataCache;
|
||||||
|
|
||||||
// when an entity-server starts up, EntityItem::setActionData is called before the entity-tree is
|
// when an entity-server starts up, EntityItem::setActionData is called before the entity-tree is
|
||||||
// ready. This means we can't find our EntityItemPointer or add the action to the simulation. These
|
// ready. This means we can't find our EntityItemPointer or add the action to the simulation. These
|
||||||
// are used to keep track of and work around this situation.
|
// are used to keep track of and work around this situation.
|
||||||
void checkWaitingToRemove(EntitySimulation* simulation = nullptr);
|
void checkWaitingToRemove(EntitySimulation* simulation = nullptr);
|
||||||
mutable QSet<QUuid> _actionsToRemove;
|
mutable QSet<QUuid> _actionsToRemove;
|
||||||
mutable bool _actionDataDirty = false;
|
mutable bool _actionDataDirty = false;
|
||||||
|
// _previouslyDeletedActions is used to avoid an action being re-added due to server round-trip lag
|
||||||
|
static quint64 _rememberDeletedActionTime;
|
||||||
|
mutable QHash<QUuid, quint64> _previouslyDeletedActions;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_EntityItem_h
|
#endif // hifi_EntityItem_h
|
||||||
|
|
Loading…
Reference in a new issue