From cf0499e6715901d2ef3697d2f775705653becb67 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 23 Apr 2015 21:07:04 -0700 Subject: [PATCH 01/30] various physics-related experiments --- libraries/entities/src/EntityItem.cpp | 68 +++++++++++---- libraries/entities/src/EntityItem.h | 9 +- libraries/physics/src/EntityMotionState.cpp | 27 +++--- libraries/physics/src/PhysicsEngine.cpp | 91 ++++++++++++++------- libraries/physics/src/PhysicsEngine.h | 5 +- 5 files changed, 141 insertions(+), 59 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index f968244ab3..6c09569037 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -65,7 +65,13 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) : _marketplaceID(ENTITY_ITEM_DEFAULT_MARKETPLACE_ID), _physicsInfo(NULL), _dirtyFlags(0), - _element(NULL) + _element(NULL), + _previousPositionFromServer(ENTITY_ITEM_ZERO_VEC3), + _previousRotationFromServer(ENTITY_ITEM_DEFAULT_ROTATION), + _previousVelocityFromServer(ENTITY_ITEM_ZERO_VEC3), + _previousAngularVelocityFromServer(ENTITY_ITEM_ZERO_VEC3), + _previousGravityFromServer(ENTITY_ITEM_ZERO_VEC3), + _previousAccelerationFromServer(ENTITY_ITEM_ZERO_VEC3) { quint64 now = usecTimestampNow(); _lastSimulated = now; @@ -592,7 +598,10 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef #ifdef WANT_DEBUG qCDebug(entities) << "skipTimeForward:" << skipTimeForward; #endif - simulateKinematicMotion(skipTimeForward); + + // we want to extrapolate the motion forward to compensate for packet travel time, but + // we don't want the side effect of flag setting. + simulateKinematicMotion(skipTimeForward, false); } _lastSimulated = now; } @@ -725,7 +734,7 @@ void EntityItem::simulate(const quint64& now) { _lastSimulated = now; } -void EntityItem::simulateKinematicMotion(float timeElapsed) { +void EntityItem::simulateKinematicMotion(float timeElapsed, bool setFlags) { if (hasAngularVelocity()) { // angular damping if (_angularDamping > 0.0f) { @@ -740,7 +749,7 @@ void EntityItem::simulateKinematicMotion(float timeElapsed) { const float EPSILON_ANGULAR_VELOCITY_LENGTH = 0.0017453f; // 0.0017453 rad/sec = 0.1f degrees/sec if (angularSpeed < EPSILON_ANGULAR_VELOCITY_LENGTH) { - if (angularSpeed > 0.0f) { + if (setFlags && angularSpeed > 0.0f) { _dirtyFlags |= EntityItem::DIRTY_MOTION_TYPE; } _angularVelocity = ENTITY_ITEM_ZERO_VEC3; @@ -802,7 +811,7 @@ void EntityItem::simulateKinematicMotion(float timeElapsed) { const float EPSILON_LINEAR_VELOCITY_LENGTH = 0.001f; // 1mm/sec if (speed < EPSILON_LINEAR_VELOCITY_LENGTH) { setVelocity(ENTITY_ITEM_ZERO_VEC3); - if (speed > 0.0f) { + if (setFlags && speed > 0.0f) { _dirtyFlags |= EntityItem::DIRTY_MOTION_TYPE; } } else { @@ -1089,8 +1098,11 @@ void EntityItem::updatePositionInDomainUnits(const glm::vec3& value) { } void EntityItem::updatePosition(const glm::vec3& value) { - if (glm::distance(_position, value) > MIN_POSITION_DELTA) { + if (value == _previousPositionFromServer) { _position = value; + } else if (glm::distance(_position, value) > MIN_POSITION_DELTA) { + _position = value; + _previousPositionFromServer = value; _dirtyFlags |= EntityItem::DIRTY_POSITION; } } @@ -1108,8 +1120,11 @@ void EntityItem::updateDimensions(const glm::vec3& value) { } void EntityItem::updateRotation(const glm::quat& rotation) { - if (glm::dot(_rotation, rotation) < MIN_ALIGNMENT_DOT) { - _rotation = rotation; + if (rotation == _previousRotationFromServer) { + _rotation = rotation; + } else if (glm::abs(glm::dot(_rotation, rotation)) < MIN_ALIGNMENT_DOT) { + _rotation = rotation; + _previousRotationFromServer = rotation; _dirtyFlags |= EntityItem::DIRTY_POSITION; } } @@ -1144,12 +1159,19 @@ void EntityItem::updateVelocityInDomainUnits(const glm::vec3& value) { } void EntityItem::updateVelocity(const glm::vec3& value) { - if (glm::distance(_velocity, value) > MIN_VELOCITY_DELTA) { + if (value == _previousVelocityFromServer) { if (glm::length(value) < MIN_VELOCITY_DELTA) { _velocity = ENTITY_ITEM_ZERO_VEC3; } else { _velocity = value; } + } else if (glm::distance(_velocity, value) > MIN_VELOCITY_DELTA) { + if (glm::length(value) < MIN_VELOCITY_DELTA) { + _velocity = ENTITY_ITEM_ZERO_VEC3; + } else { + _velocity = value; + } + _previousVelocityFromServer = value; _dirtyFlags |= EntityItem::DIRTY_VELOCITY; } } @@ -1167,20 +1189,38 @@ void EntityItem::updateGravityInDomainUnits(const glm::vec3& value) { } void EntityItem::updateGravity(const glm::vec3& value) { - if ( glm::distance(_gravity, value) > MIN_GRAVITY_DELTA) { + if (value == _previousGravityFromServer) { _gravity = value; + } else if (glm::distance(_gravity, value) > MIN_GRAVITY_DELTA) { + _gravity = value; + _previousGravityFromServer = value; _dirtyFlags |= EntityItem::DIRTY_VELOCITY; } } void EntityItem::updateAcceleration(const glm::vec3& value) { - _acceleration = value; - _dirtyFlags |= EntityItem::DIRTY_VELOCITY; + if (value == _previousAccelerationFromServer) { + _acceleration = value; + } else if (glm::distance(_acceleration, value) > MIN_ACCELERATION_DELTA) { + _acceleration = value; + _previousAccelerationFromServer = value; + _dirtyFlags |= EntityItem::DIRTY_VELOCITY; + } } void EntityItem::updateAngularVelocity(const glm::vec3& value) { - if (glm::distance(_angularVelocity, value) > MIN_SPIN_DELTA) { - _angularVelocity = value; + if (value == _previousAngularVelocityFromServer) { + if (glm::length(value) < MIN_SPIN_DELTA) { + _angularVelocity = ENTITY_ITEM_ZERO_VEC3; + } else { + _angularVelocity = value; + } + } else if (glm::distance(_angularVelocity, value) > MIN_SPIN_DELTA) { + if (glm::length(value) < MIN_SPIN_DELTA) { + _angularVelocity = ENTITY_ITEM_ZERO_VEC3; + } else { + _angularVelocity = value; + } _dirtyFlags |= EntityItem::DIRTY_VELOCITY; } } diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index fda8167564..fa6efd72a1 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -132,7 +132,7 @@ public: // perform linear extrapolation for SimpleEntitySimulation void simulate(const quint64& now); - void simulateKinematicMotion(float timeElapsed); + void simulateKinematicMotion(float timeElapsed, bool setFlags=true); virtual bool needsToCallUpdate() const { return false; } @@ -368,6 +368,13 @@ protected: uint32_t _dirtyFlags; // things that have changed from EXTERNAL changes (via script or packet) but NOT from simulation EntityTreeElement* _element; // back pointer to containing Element + + glm::vec3 _previousPositionFromServer; + glm::quat _previousRotationFromServer; + glm::vec3 _previousVelocityFromServer; + glm::vec3 _previousAngularVelocityFromServer; + glm::vec3 _previousGravityFromServer; + glm::vec3 _previousAccelerationFromServer; }; diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index d1571fbcc5..0f4bf05fb4 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -189,21 +189,21 @@ float EntityMotionState::computeMass(const ShapeInfo& shapeInfo) const { } bool EntityMotionState::shouldSendUpdate(uint32_t simulationFrame) { + if (getShouldClaimSimulationOwnership()) { + return true; + } + bool baseResult = this->ObjectMotionState::shouldSendUpdate(simulationFrame); if (!baseResult) { return false; } - if (getShouldClaimSimulationOwnership()) { - return true; - } - auto nodeList = DependencyManager::get(); const QUuid& myNodeID = nodeList->getSessionUUID(); const QUuid& simulatorID = _entity->getSimulatorID(); - if (simulatorID != myNodeID) { + if (simulatorID != myNodeID && !simulatorID.isNull()) { // some other Node owns the simulating of this, so don't broadcast the results of local simulation. return false; } @@ -286,15 +286,18 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ QUuid myNodeID = nodeList->getSessionUUID(); QUuid simulatorID = _entity->getSimulatorID(); - if (getShouldClaimSimulationOwnership()) { - _entity->setSimulatorID(myNodeID); - properties.setSimulatorID(myNodeID); - setShouldClaimSimulationOwnership(false); + if (simulatorID.isNull() && !(zeroSpeed && zeroSpin)) { + // the entity is moving and no node has claimed simulation ownership. try to claim it. + setShouldClaimSimulationOwnership(true); } - if (simulatorID == myNodeID && zeroSpeed && zeroSpin) { - // we are the simulator and the object has stopped. give up "simulator" status - _entity->setSimulatorID(QUuid()); + if (getShouldClaimSimulationOwnership()) { + // _entity->setSimulatorID(myNodeID); + properties.setSimulatorID(myNodeID); + setShouldClaimSimulationOwnership(false); + } else if (simulatorID == myNodeID && zeroSpeed && zeroSpin) { + // we are the simulator and the entity has stopped. give up "simulator" status + // _entity->setSimulatorID(QUuid()); properties.setSimulatorID(QUuid()); } diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 45f3c97e30..9d50b71514 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -119,8 +119,10 @@ void PhysicsEngine::entityChangedInternal(EntityItem* entity) { assert(entity); void* physicsInfo = entity->getPhysicsInfo(); if (physicsInfo) { - ObjectMotionState* motionState = static_cast(physicsInfo); - _incomingChanges.insert(motionState); + if ((entity->getDirtyFlags() & (HARD_DIRTY_PHYSICS_FLAGS | EASY_DIRTY_PHYSICS_FLAGS)) > 0) { + ObjectMotionState* motionState = static_cast(physicsInfo); + _incomingChanges.insert(motionState); + } } else { // try to add this entity again (maybe something changed such that it will work this time) addEntity(entity); @@ -366,15 +368,46 @@ void PhysicsEngine::stepNonPhysicalKinematics(const quint64& now) { } } -void PhysicsEngine::computeCollisionEvents() { - BT_PROFILE("computeCollisionEvents"); + +void PhysicsEngine::doOwnershipInfection(const btCollisionObject* objectA, const btCollisionObject* objectB) { + if (!objectA || !objectB) { + return; + } auto nodeList = DependencyManager::get(); QUuid myNodeID = nodeList->getSessionUUID(); - const btCollisionObject* characterCollisionObject = _characterController ? _characterController->getCollisionObject() : NULL; + ObjectMotionState* a = static_cast(objectA->getUserPointer()); + ObjectMotionState* b = static_cast(objectB->getUserPointer()); + EntityItem* entityA = a ? a->getEntity() : NULL; + EntityItem* entityB = b ? b->getEntity() : NULL; + bool aIsDynamic = entityA && !objectA->isStaticOrKinematicObject(); + bool bIsDynamic = entityB && !objectB->isStaticOrKinematicObject(); + + // collisions cause infectious spread of simulation-ownership. we also attempt to take + // ownership of anything that collides with our avatar. + if ((aIsDynamic && entityA->getSimulatorID() == myNodeID) || + (a && a->getShouldClaimSimulationOwnership()) || + (objectA == characterCollisionObject)) { + if (bIsDynamic) { + b->setShouldClaimSimulationOwnership(true); + } + } + if ((bIsDynamic && entityB->getSimulatorID() == myNodeID) || + (b && b->getShouldClaimSimulationOwnership()) || + (objectB == characterCollisionObject)) { + if (aIsDynamic) { + a->setShouldClaimSimulationOwnership(true); + } + } +} + + +void PhysicsEngine::computeCollisionEvents() { + BT_PROFILE("computeCollisionEvents"); + // update all contacts every frame int numManifolds = _collisionDispatcher->getNumManifolds(); for (int i = 0; i < numManifolds; ++i) { @@ -393,31 +426,12 @@ void PhysicsEngine::computeCollisionEvents() { ObjectMotionState* a = static_cast(objectA->getUserPointer()); ObjectMotionState* b = static_cast(objectB->getUserPointer()); - EntityItem* entityA = a ? a->getEntity() : NULL; - EntityItem* entityB = b ? b->getEntity() : NULL; - bool aIsDynamic = entityA && !objectA->isStaticOrKinematicObject(); - bool bIsDynamic = entityB && !objectB->isStaticOrKinematicObject(); - if (a || b) { // the manifold has up to 4 distinct points, but only extract info from the first _contactMap[ContactKey(a, b)].update(_numContactFrames, contactManifold->getContactPoint(0), _originOffset); } - // collisions cause infectious spread of simulation-ownership. we also attempt to take - // ownership of anything that collides with our avatar. - if ((aIsDynamic && entityA->getSimulatorID() == myNodeID) || - (a && a->getShouldClaimSimulationOwnership()) || - (objectA == characterCollisionObject)) { - if (bIsDynamic) { - b->setShouldClaimSimulationOwnership(true); - } - } - if ((bIsDynamic && entityB->getSimulatorID() == myNodeID) || - (b && b->getShouldClaimSimulationOwnership()) || - (objectB == characterCollisionObject)) { - if (aIsDynamic) { - a->setShouldClaimSimulationOwnership(true); - } - } + + doOwnershipInfection(objectA, objectB); } } @@ -453,6 +467,16 @@ void PhysicsEngine::computeCollisionEvents() { if (type == CONTACT_EVENT_TYPE_END) { ContactMap::iterator iterToDelete = contactItr; ++contactItr; + + // const ContactKey& contactKey = (*iterToDelete).first; + // const ObjectMotionState* objectMotionStateA = static_cast(contactKey._a); + // const ObjectMotionState* objectMotionStateB = static_cast(contactKey._b); + // const btCollisionObject* objectA = + // objectMotionStateA ? static_cast(objectMotionStateA->getRigidBody()) : NULL; + // const btCollisionObject* objectB = + // objectMotionStateB ? static_cast(objectMotionStateB->getRigidBody()) : NULL; + // doOwnershipInfection(objectA, objectB); + _contactMap.erase(iterToDelete); } else { ++contactItr; @@ -576,11 +600,16 @@ void PhysicsEngine::removeObjectFromBullet(ObjectMotionState* motionState) { assert(motionState); btRigidBody* body = motionState->getRigidBody(); - // set the about-to-be-deleted entity active in order to wake up the island it's part of. this is done - // so that anything resting on top of it will fall. - // body->setActivationState(ACTIVE_TAG); - EntityItem* entity = static_cast(motionState)->getEntity(); - bump(entity); + // activate this before deleting it so that anything resting on it will begin to fall. + // + // body->activate(); + // + // motionState->setShouldClaimSimulationOwnership(true); + // computeCollisionEvents(); + // + EntityItem* entityItem = motionState ? motionState->getEntity() : NULL; + bump(entityItem); + if (body) { const btCollisionShape* shape = body->getCollisionShape(); diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index 148261c6d2..9fe632d462 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -89,16 +89,19 @@ public: void dumpNextStats() { _dumpNextStats = true; } + void bump(EntityItem* bumpEntity); + private: /// \param motionState pointer to Object's MotionState void removeObjectFromBullet(ObjectMotionState* motionState); void removeContacts(ObjectMotionState* motionState); + void doOwnershipInfection(const btCollisionObject* objectA, const btCollisionObject* objectB); + // return 'true' of update was successful bool updateObjectHard(btRigidBody* body, ObjectMotionState* motionState, uint32_t flags); void updateObjectEasy(btRigidBody* body, ObjectMotionState* motionState, uint32_t flags); - void bump(EntityItem* bumpEntity); btClock _clock; btDefaultCollisionConfiguration* _collisionConfig = NULL; From 6d151ee3ed305278585e518c5a556126bd9f3067 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 24 Apr 2015 09:29:05 -0700 Subject: [PATCH 02/30] try a different way of identifying when to claim simulation ownership of a moving entity --- libraries/physics/src/EntityMotionState.cpp | 18 +++++++++++++----- libraries/physics/src/PhysicsEngine.cpp | 5 ++--- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 0f4bf05fb4..3c424c7db9 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -108,11 +108,19 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) { getVelocity(v); _entity->setVelocity(v); - getAngularVelocity(v); + glm::vec3 av; + getAngularVelocity(av); _entity->setAngularVelocity(v); _entity->setLastSimulated(usecTimestampNow()); + bool isStill = (v == vec3(0.0f)) && (av == vec3(0.0f)); + + if (_entity->getSimulatorID().isNull() && !isStill) { + // object is moving and has no owner. attempt to claim simulation ownership. + _entity->setShouldClaimSimulationOwnership(true); + } + _outgoingPacketFlags = DIRTY_PHYSICS_FLAGS; EntityMotionState::enqueueOutgoingEntity(_entity); @@ -286,10 +294,10 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ QUuid myNodeID = nodeList->getSessionUUID(); QUuid simulatorID = _entity->getSimulatorID(); - if (simulatorID.isNull() && !(zeroSpeed && zeroSpin)) { - // the entity is moving and no node has claimed simulation ownership. try to claim it. - setShouldClaimSimulationOwnership(true); - } + // if (simulatorID.isNull() && !(zeroSpeed && zeroSpin)) { + // // the entity is moving and no node has claimed simulation ownership. try to claim it. + // setShouldClaimSimulationOwnership(true); + // } if (getShouldClaimSimulationOwnership()) { // _entity->setSimulatorID(myNodeID); diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 9d50b71514..5a86f8552e 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -370,9 +370,8 @@ void PhysicsEngine::stepNonPhysicalKinematics(const quint64& now) { void PhysicsEngine::doOwnershipInfection(const btCollisionObject* objectA, const btCollisionObject* objectB) { - if (!objectA || !objectB) { - return; - } + assert(objectA); + assert(objectB); auto nodeList = DependencyManager::get(); QUuid myNodeID = nodeList->getSessionUUID(); From 6fdbce9ee3fa609c7ddee47c8d9f0d3afa376f7d Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 24 Apr 2015 09:29:57 -0700 Subject: [PATCH 03/30] oops --- libraries/physics/src/EntityMotionState.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 3c424c7db9..37a1732ece 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -118,7 +118,7 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) { if (_entity->getSimulatorID().isNull() && !isStill) { // object is moving and has no owner. attempt to claim simulation ownership. - _entity->setShouldClaimSimulationOwnership(true); + setShouldClaimSimulationOwnership(true); } _outgoingPacketFlags = DIRTY_PHYSICS_FLAGS; From 1b84be6e10b0796cabce7395dda285d74a49c366 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 24 Apr 2015 10:55:43 -0700 Subject: [PATCH 04/30] attempting to have visual indicator of simulatorID --- .../entities-renderer/src/EntityTreeRenderer.cpp | 16 ++++++++++++++++ .../src/RenderableModelEntityItem.cpp | 15 ++++++++++++++- libraries/entities/src/EntityTree.cpp | 16 ++++++++++++---- libraries/physics/src/EntityMotionState.cpp | 2 +- 4 files changed, 43 insertions(+), 6 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index dde13552f3..fbfa882494 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -677,10 +677,26 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args) if (bigEnoughToRender) { renderProxies(entityItem, args); + + // XXX + // auto nodeList = DependencyManager::get(); + // const QUuid& myNodeID = nodeList->getSessionUUID(); + // XXX + + Glower* glower = NULL; if (entityItem->getGlowLevel() > 0.0f) { glower = new Glower(entityItem->getGlowLevel()); } + + // XXX glow things we are simulating + // if (entityItem->getSimulatorID() == myNodeID) { + // if (glower) delete glower; + // glower = new Glower(); + // } + // XXX glow things we are simulating + + entityItem->render(args); args->_itemsRendered++; if (glower) { diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 8ca6562505..1bdfa7bd1a 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -118,13 +118,26 @@ void RenderableModelEntityItem::render(RenderArgs* args) { glm::vec3 position = getPosition(); glm::vec3 dimensions = getDimensions(); float size = glm::length(dimensions); + + // XXX + auto nodeList = DependencyManager::get(); + const QUuid& myNodeID = nodeList->getSessionUUID(); + // XXX - if (drawAsModel) { + if (drawAsModel + && getSimulatorID() != myNodeID + ) { remapTextures(); glPushMatrix(); { float alpha = getLocalRenderAlpha(); + // XXX + // if (getSimulatorID() == myNodeID) { + // alpha = 1.0; + // } + // XXX + if (!_model || _needsModelReload) { // TODO: this getModel() appears to be about 3% of model render time. We should optimize PerformanceTimer perfTimer("getModel"); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 5b15aa26b4..360c783d34 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -140,16 +140,24 @@ bool EntityTree::updateEntityWithElement(EntityItem* entity, const EntityItemPro // A Node is trying to take ownership of the simulation of this entity from another Node. Only allow this // if ownership hasn't recently changed. if (usecTimestampNow() - entity->getSimulatorIDChangedTime() < SIMULATOR_CHANGE_LOCKOUT_PERIOD) { - qCDebug(entities) << "simulator_change_lockout_period:" - << entity->getSimulatorID() << "to" << properties.getSimulatorID(); + + // XXX + // qCDebug(entities) << "simulator_change_lockout_period:" + // << entity->getSimulatorID() << "to" << properties.getSimulatorID(); + // XXX + // squash the physics-related changes. properties.setSimulatorIDChanged(false); properties.setPositionChanged(false); properties.setVelocityChanged(false); properties.setAccelerationChanged(false); - } else { - qCDebug(entities) << "allowing simulatorID change"; + } + + // else { + // qCDebug(entities) << "allowing simulatorID change"; + // } + } QString entityScriptBefore = entity->getScript(); diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 37a1732ece..10d919ba2f 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -306,7 +306,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ } else if (simulatorID == myNodeID && zeroSpeed && zeroSpin) { // we are the simulator and the entity has stopped. give up "simulator" status // _entity->setSimulatorID(QUuid()); - properties.setSimulatorID(QUuid()); + // properties.setSimulatorID(QUuid()); } // RELIABLE_SEND_HACK: count number of updates for entities at rest so we can stop sending them after some limit. From b40e78311b8f8e8ae5ecff673262c783aa07e528 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 24 Apr 2015 11:00:06 -0700 Subject: [PATCH 05/30] disable hack to notice that the server is sending the same thing repeatedly --- libraries/entities/src/EntityItem.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 6c09569037..4c553201f7 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1098,7 +1098,7 @@ void EntityItem::updatePositionInDomainUnits(const glm::vec3& value) { } void EntityItem::updatePosition(const glm::vec3& value) { - if (value == _previousPositionFromServer) { + if (false && value == _previousPositionFromServer) { _position = value; } else if (glm::distance(_position, value) > MIN_POSITION_DELTA) { _position = value; @@ -1120,7 +1120,7 @@ void EntityItem::updateDimensions(const glm::vec3& value) { } void EntityItem::updateRotation(const glm::quat& rotation) { - if (rotation == _previousRotationFromServer) { + if (false && rotation == _previousRotationFromServer) { _rotation = rotation; } else if (glm::abs(glm::dot(_rotation, rotation)) < MIN_ALIGNMENT_DOT) { _rotation = rotation; @@ -1159,7 +1159,7 @@ void EntityItem::updateVelocityInDomainUnits(const glm::vec3& value) { } void EntityItem::updateVelocity(const glm::vec3& value) { - if (value == _previousVelocityFromServer) { + if (false && value == _previousVelocityFromServer) { if (glm::length(value) < MIN_VELOCITY_DELTA) { _velocity = ENTITY_ITEM_ZERO_VEC3; } else { @@ -1189,7 +1189,7 @@ void EntityItem::updateGravityInDomainUnits(const glm::vec3& value) { } void EntityItem::updateGravity(const glm::vec3& value) { - if (value == _previousGravityFromServer) { + if (false && value == _previousGravityFromServer) { _gravity = value; } else if (glm::distance(_gravity, value) > MIN_GRAVITY_DELTA) { _gravity = value; @@ -1199,7 +1199,7 @@ void EntityItem::updateGravity(const glm::vec3& value) { } void EntityItem::updateAcceleration(const glm::vec3& value) { - if (value == _previousAccelerationFromServer) { + if (false && value == _previousAccelerationFromServer) { _acceleration = value; } else if (glm::distance(_acceleration, value) > MIN_ACCELERATION_DELTA) { _acceleration = value; @@ -1209,7 +1209,7 @@ void EntityItem::updateAcceleration(const glm::vec3& value) { } void EntityItem::updateAngularVelocity(const glm::vec3& value) { - if (value == _previousAngularVelocityFromServer) { + if (false && value == _previousAngularVelocityFromServer) { if (glm::length(value) < MIN_SPIN_DELTA) { _angularVelocity = ENTITY_ITEM_ZERO_VEC3; } else { From 926694517f432864040f842108e20ca25cdd0085 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 24 Apr 2015 11:07:45 -0700 Subject: [PATCH 06/30] sync --- libraries/entities/src/EntityTree.cpp | 16 ++++------------ libraries/physics/src/EntityMotionState.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 360c783d34..5b15aa26b4 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -140,24 +140,16 @@ bool EntityTree::updateEntityWithElement(EntityItem* entity, const EntityItemPro // A Node is trying to take ownership of the simulation of this entity from another Node. Only allow this // if ownership hasn't recently changed. if (usecTimestampNow() - entity->getSimulatorIDChangedTime() < SIMULATOR_CHANGE_LOCKOUT_PERIOD) { - - // XXX - // qCDebug(entities) << "simulator_change_lockout_period:" - // << entity->getSimulatorID() << "to" << properties.getSimulatorID(); - // XXX - + qCDebug(entities) << "simulator_change_lockout_period:" + << entity->getSimulatorID() << "to" << properties.getSimulatorID(); // squash the physics-related changes. properties.setSimulatorIDChanged(false); properties.setPositionChanged(false); properties.setVelocityChanged(false); properties.setAccelerationChanged(false); - + } else { + qCDebug(entities) << "allowing simulatorID change"; } - - // else { - // qCDebug(entities) << "allowing simulatorID change"; - // } - } QString entityScriptBefore = entity->getScript(); diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 10d919ba2f..4fab75384e 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -118,7 +118,7 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) { if (_entity->getSimulatorID().isNull() && !isStill) { // object is moving and has no owner. attempt to claim simulation ownership. - setShouldClaimSimulationOwnership(true); + // setShouldClaimSimulationOwnership(true); } _outgoingPacketFlags = DIRTY_PHYSICS_FLAGS; @@ -211,7 +211,7 @@ bool EntityMotionState::shouldSendUpdate(uint32_t simulationFrame) { const QUuid& myNodeID = nodeList->getSessionUUID(); const QUuid& simulatorID = _entity->getSimulatorID(); - if (simulatorID != myNodeID && !simulatorID.isNull()) { + if (simulatorID != myNodeID /* && !simulatorID.isNull() */) { // some other Node owns the simulating of this, so don't broadcast the results of local simulation. return false; } @@ -305,8 +305,8 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ setShouldClaimSimulationOwnership(false); } else if (simulatorID == myNodeID && zeroSpeed && zeroSpin) { // we are the simulator and the entity has stopped. give up "simulator" status - // _entity->setSimulatorID(QUuid()); - // properties.setSimulatorID(QUuid()); + _entity->setSimulatorID(QUuid()); + properties.setSimulatorID(QUuid()); } // RELIABLE_SEND_HACK: count number of updates for entities at rest so we can stop sending them after some limit. From a27f8f3f10ac2e1dbb91d63713bc7813fa4e1a87 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 24 Apr 2015 11:28:44 -0700 Subject: [PATCH 07/30] sync --- libraries/entities/src/EntityItem.cpp | 2 ++ libraries/physics/src/EntityMotionState.cpp | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 4c553201f7..d39e3a9e5c 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -314,6 +314,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef glm::vec3 savePosition = _position; glm::quat saveRotation = _rotation; glm::vec3 saveVelocity = _velocity; + glm::vec3 saveAngularVelocity = _angularVelocity; glm::vec3 saveGravity = _gravity; glm::vec3 saveAcceleration = _acceleration; @@ -616,6 +617,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef _position = savePosition; _rotation = saveRotation; _velocity = saveVelocity; + _angularVelocity = saveAngularVelocity; _gravity = saveGravity; _acceleration = saveAcceleration; } diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 4fab75384e..0ebf3c0739 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -211,7 +211,7 @@ bool EntityMotionState::shouldSendUpdate(uint32_t simulationFrame) { const QUuid& myNodeID = nodeList->getSessionUUID(); const QUuid& simulatorID = _entity->getSimulatorID(); - if (simulatorID != myNodeID /* && !simulatorID.isNull() */) { + if (simulatorID != myNodeID && !simulatorID.isNull()) { // some other Node owns the simulating of this, so don't broadcast the results of local simulation. return false; } @@ -300,7 +300,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ // } if (getShouldClaimSimulationOwnership()) { - // _entity->setSimulatorID(myNodeID); + _entity->setSimulatorID(myNodeID); properties.setSimulatorID(myNodeID); setShouldClaimSimulationOwnership(false); } else if (simulatorID == myNodeID && zeroSpeed && zeroSpin) { From 902e84c7118d81f3d9502aa09bdebc3c9d2dc883 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 24 Apr 2015 13:10:38 -0700 Subject: [PATCH 08/30] sync --- libraries/physics/src/EntityMotionState.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 0ebf3c0739..cff3000868 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -211,7 +211,7 @@ bool EntityMotionState::shouldSendUpdate(uint32_t simulationFrame) { const QUuid& myNodeID = nodeList->getSessionUUID(); const QUuid& simulatorID = _entity->getSimulatorID(); - if (simulatorID != myNodeID && !simulatorID.isNull()) { + if (simulatorID != myNodeID /* && !simulatorID.isNull() */) { // some other Node owns the simulating of this, so don't broadcast the results of local simulation. return false; } @@ -300,12 +300,12 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ // } if (getShouldClaimSimulationOwnership()) { - _entity->setSimulatorID(myNodeID); + // _entity->setSimulatorID(myNodeID); properties.setSimulatorID(myNodeID); setShouldClaimSimulationOwnership(false); } else if (simulatorID == myNodeID && zeroSpeed && zeroSpin) { // we are the simulator and the entity has stopped. give up "simulator" status - _entity->setSimulatorID(QUuid()); + // _entity->setSimulatorID(QUuid()); properties.setSimulatorID(QUuid()); } From ad85837b5aa8c8db6a00762ee3bb768db49c0538 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 24 Apr 2015 13:44:34 -0700 Subject: [PATCH 09/30] sync --- libraries/entities/src/EntityItem.h | 3 ++- libraries/physics/src/EntityMotionState.cpp | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index fa6efd72a1..e726e5b11b 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -54,7 +54,8 @@ public: DIRTY_MOTION_TYPE = 0x0010, DIRTY_SHAPE = 0x0020, DIRTY_LIFETIME = 0x0040, - DIRTY_UPDATEABLE = 0x0080 + DIRTY_UPDATEABLE = 0x0080, + DIRTY_TWEAK = 0x0100 }; DONT_ALLOW_INSTANTIATION // This class can not be instantiated directly diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index cff3000868..7bed5a72af 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -114,9 +114,7 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) { _entity->setLastSimulated(usecTimestampNow()); - bool isStill = (v == vec3(0.0f)) && (av == vec3(0.0f)); - - if (_entity->getSimulatorID().isNull() && !isStill) { + if (_entity->getSimulatorID().isNull() && isMoving()) { // object is moving and has no owner. attempt to claim simulation ownership. // setShouldClaimSimulationOwnership(true); } @@ -342,6 +340,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ qCDebug(physics) << "EntityMotionState::sendUpdate()... calling queueEditEntityMessage()..."; #endif + qDebug() << "sending"; entityPacketSender->queueEditEntityMessage(PacketTypeEntityAddOrEdit, id, properties); } else { #ifdef WANT_DEBUG From fea8d846184cb0e655fbb95ba3ed575feb496366 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 24 Apr 2015 14:09:10 -0700 Subject: [PATCH 10/30] sync --- libraries/entities/src/EntityItem.cpp | 14 ++++++++------ libraries/physics/src/EntityMotionState.cpp | 17 +++++++++++------ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index d39e3a9e5c..07c7935556 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -620,6 +620,8 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef _angularVelocity = saveAngularVelocity; _gravity = saveGravity; _acceleration = saveAcceleration; + } else { + qDebug() << "accepting update"; } return bytesRead; @@ -1100,7 +1102,7 @@ void EntityItem::updatePositionInDomainUnits(const glm::vec3& value) { } void EntityItem::updatePosition(const glm::vec3& value) { - if (false && value == _previousPositionFromServer) { + if (/* false && */ value == _previousPositionFromServer) { _position = value; } else if (glm::distance(_position, value) > MIN_POSITION_DELTA) { _position = value; @@ -1122,7 +1124,7 @@ void EntityItem::updateDimensions(const glm::vec3& value) { } void EntityItem::updateRotation(const glm::quat& rotation) { - if (false && rotation == _previousRotationFromServer) { + if (/* false && */ rotation == _previousRotationFromServer) { _rotation = rotation; } else if (glm::abs(glm::dot(_rotation, rotation)) < MIN_ALIGNMENT_DOT) { _rotation = rotation; @@ -1161,7 +1163,7 @@ void EntityItem::updateVelocityInDomainUnits(const glm::vec3& value) { } void EntityItem::updateVelocity(const glm::vec3& value) { - if (false && value == _previousVelocityFromServer) { + if (/* false && */ value == _previousVelocityFromServer) { if (glm::length(value) < MIN_VELOCITY_DELTA) { _velocity = ENTITY_ITEM_ZERO_VEC3; } else { @@ -1191,7 +1193,7 @@ void EntityItem::updateGravityInDomainUnits(const glm::vec3& value) { } void EntityItem::updateGravity(const glm::vec3& value) { - if (false && value == _previousGravityFromServer) { + if (/* false && */ value == _previousGravityFromServer) { _gravity = value; } else if (glm::distance(_gravity, value) > MIN_GRAVITY_DELTA) { _gravity = value; @@ -1201,7 +1203,7 @@ void EntityItem::updateGravity(const glm::vec3& value) { } void EntityItem::updateAcceleration(const glm::vec3& value) { - if (false && value == _previousAccelerationFromServer) { + if (/* false && */ value == _previousAccelerationFromServer) { _acceleration = value; } else if (glm::distance(_acceleration, value) > MIN_ACCELERATION_DELTA) { _acceleration = value; @@ -1211,7 +1213,7 @@ void EntityItem::updateAcceleration(const glm::vec3& value) { } void EntityItem::updateAngularVelocity(const glm::vec3& value) { - if (false && value == _previousAngularVelocityFromServer) { + if (/* false && */ value == _previousAngularVelocityFromServer) { if (glm::length(value) < MIN_SPIN_DELTA) { _angularVelocity = ENTITY_ITEM_ZERO_VEC3; } else { diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 7bed5a72af..dba4cfac79 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -195,16 +195,17 @@ float EntityMotionState::computeMass(const ShapeInfo& shapeInfo) const { } bool EntityMotionState::shouldSendUpdate(uint32_t simulationFrame) { - if (getShouldClaimSimulationOwnership()) { - return true; - } - bool baseResult = this->ObjectMotionState::shouldSendUpdate(simulationFrame); if (!baseResult) { return false; } + if (getShouldClaimSimulationOwnership()) { + qDebug() << "shouldSendUpdate due to claiming ownership"; + return true; + } + auto nodeList = DependencyManager::get(); const QUuid& myNodeID = nodeList->getSessionUUID(); const QUuid& simulatorID = _entity->getSimulatorID(); @@ -303,7 +304,11 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ setShouldClaimSimulationOwnership(false); } else if (simulatorID == myNodeID && zeroSpeed && zeroSpin) { // we are the simulator and the entity has stopped. give up "simulator" status - // _entity->setSimulatorID(QUuid()); + _entity->setSimulatorID(QUuid()); + properties.setSimulatorID(QUuid()); + } else if (simulatorID == myNodeID && !_body->isActive()) { + // it's not active. don't keep simulation ownership. + _entity->setSimulatorID(QUuid()); properties.setSimulatorID(QUuid()); } @@ -340,7 +345,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ qCDebug(physics) << "EntityMotionState::sendUpdate()... calling queueEditEntityMessage()..."; #endif - qDebug() << "sending"; + qDebug() << "sending" << _body->isActive() << (_entity->getSimulatorID() == myNodeID); entityPacketSender->queueEditEntityMessage(PacketTypeEntityAddOrEdit, id, properties); } else { #ifdef WANT_DEBUG From 6b53fefebe9124b3ca839da084786aaf56d7f6e3 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 24 Apr 2015 14:21:59 -0700 Subject: [PATCH 11/30] sync --- libraries/physics/src/PhysicsEngine.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 5a86f8552e..0909ded84b 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -391,6 +391,7 @@ void PhysicsEngine::doOwnershipInfection(const btCollisionObject* objectA, const (a && a->getShouldClaimSimulationOwnership()) || (objectA == characterCollisionObject)) { if (bIsDynamic) { + qDebug() << "setShouldClaimSimulationOwnership(true) in doOwnershipInfection"; b->setShouldClaimSimulationOwnership(true); } } @@ -398,6 +399,7 @@ void PhysicsEngine::doOwnershipInfection(const btCollisionObject* objectA, const (b && b->getShouldClaimSimulationOwnership()) || (objectB == characterCollisionObject)) { if (aIsDynamic) { + qDebug() << "setShouldClaimSimulationOwnership(true) in doOwnershipInfection"; a->setShouldClaimSimulationOwnership(true); } } @@ -576,12 +578,14 @@ void PhysicsEngine::bump(EntityItem* bumpEntity) { EntityItem* entityB = entityMotionStateB ? entityMotionStateB->getEntity() : NULL; if (entityA && entityB) { if (entityA == bumpEntity) { + qDebug() << "setShouldClaimSimulationOwnership(true) in bump"; entityMotionStateB->setShouldClaimSimulationOwnership(true); if (!objectB->isActive()) { objectB->setActivationState(ACTIVE_TAG); } } if (entityB == bumpEntity) { + qDebug() << "setShouldClaimSimulationOwnership(true) in bump"; entityMotionStateA->setShouldClaimSimulationOwnership(true); if (!objectA->isActive()) { objectA->setActivationState(ACTIVE_TAG); From ea250c037a2d53efdbbde452415fe4ebd204bf07 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 24 Apr 2015 14:27:32 -0700 Subject: [PATCH 12/30] sync --- libraries/physics/src/PhysicsEngine.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 0909ded84b..235de7f172 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -391,7 +391,11 @@ void PhysicsEngine::doOwnershipInfection(const btCollisionObject* objectA, const (a && a->getShouldClaimSimulationOwnership()) || (objectA == characterCollisionObject)) { if (bIsDynamic) { - qDebug() << "setShouldClaimSimulationOwnership(true) in doOwnershipInfection"; + qDebug() << "setShouldClaimSimulationOwnership(true) in doOwnershipInfection A" + << (aIsDynamic && entityA->getSimulatorID() == myNodeID) + << (a && a->getShouldClaimSimulationOwnership()) + << (objectA == characterCollisionObject); + b->setShouldClaimSimulationOwnership(true); } } @@ -399,7 +403,11 @@ void PhysicsEngine::doOwnershipInfection(const btCollisionObject* objectA, const (b && b->getShouldClaimSimulationOwnership()) || (objectB == characterCollisionObject)) { if (aIsDynamic) { - qDebug() << "setShouldClaimSimulationOwnership(true) in doOwnershipInfection"; + qDebug() << "setShouldClaimSimulationOwnership(true) in doOwnershipInfection B" + << (bIsDynamic && entityB->getSimulatorID() == myNodeID) + << (b && b->getShouldClaimSimulationOwnership()) + << (objectB == characterCollisionObject); + a->setShouldClaimSimulationOwnership(true); } } From e7c6ee597a4c00287d3257109227c53b6899871c Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 24 Apr 2015 14:36:05 -0700 Subject: [PATCH 13/30] sync --- libraries/physics/src/PhysicsEngine.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 235de7f172..afb0e65a00 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -378,6 +378,8 @@ void PhysicsEngine::doOwnershipInfection(const btCollisionObject* objectA, const const btCollisionObject* characterCollisionObject = _characterController ? _characterController->getCollisionObject() : NULL; + assert(!myNodeID.isNull()); + ObjectMotionState* a = static_cast(objectA->getUserPointer()); ObjectMotionState* b = static_cast(objectB->getUserPointer()); EntityItem* entityA = a ? a->getEntity() : NULL; @@ -387,24 +389,23 @@ void PhysicsEngine::doOwnershipInfection(const btCollisionObject* objectA, const // collisions cause infectious spread of simulation-ownership. we also attempt to take // ownership of anything that collides with our avatar. - if ((aIsDynamic && entityA->getSimulatorID() == myNodeID) || - (a && a->getShouldClaimSimulationOwnership()) || + if ((aIsDynamic && (entityA->getSimulatorID() == myNodeID)) || + // (a && a->getShouldClaimSimulationOwnership()) || (objectA == characterCollisionObject)) { if (bIsDynamic) { qDebug() << "setShouldClaimSimulationOwnership(true) in doOwnershipInfection A" - << (aIsDynamic && entityA->getSimulatorID() == myNodeID) + << (aIsDynamic && (entityA->getSimulatorID() == myNodeID)) << (a && a->getShouldClaimSimulationOwnership()) << (objectA == characterCollisionObject); b->setShouldClaimSimulationOwnership(true); } - } - if ((bIsDynamic && entityB->getSimulatorID() == myNodeID) || - (b && b->getShouldClaimSimulationOwnership()) || + } else if ((bIsDynamic && (entityB->getSimulatorID() == myNodeID)) || + // (b && b->getShouldClaimSimulationOwnership()) || (objectB == characterCollisionObject)) { if (aIsDynamic) { qDebug() << "setShouldClaimSimulationOwnership(true) in doOwnershipInfection B" - << (bIsDynamic && entityB->getSimulatorID() == myNodeID) + << (bIsDynamic && (entityB->getSimulatorID() == myNodeID)) << (b && b->getShouldClaimSimulationOwnership()) << (objectB == characterCollisionObject); From 2a8fbeca3227434824abab7688324214927db217 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 24 Apr 2015 14:43:39 -0700 Subject: [PATCH 14/30] sync --- libraries/physics/src/EntityMotionState.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libraries/physics/src/EntityMotionState.h b/libraries/physics/src/EntityMotionState.h index 07f82aaa42..1ab3309934 100644 --- a/libraries/physics/src/EntityMotionState.h +++ b/libraries/physics/src/EntityMotionState.h @@ -67,7 +67,12 @@ public: quint8 getAccelerationNearlyGravityCount() { return _accelerationNearlyGravityCount; } virtual EntityItem* getEntity() const { return _entity; } - virtual void setShouldClaimSimulationOwnership(bool value) { _shouldClaimSimulationOwnership = value; } + virtual void setShouldClaimSimulationOwnership(bool value) { + if (value) { + qDebug() << "setShouldClaimSimulationOwnership to TRUE"; + } + _shouldClaimSimulationOwnership = value; + } virtual bool getShouldClaimSimulationOwnership() { return _shouldClaimSimulationOwnership; } protected: From 6e6793cbcc666c06db6e18a50153683f3a968937 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 24 Apr 2015 15:18:02 -0700 Subject: [PATCH 15/30] remove debugging prints --- .../src/RenderableModelEntityItem.cpp | 2 +- libraries/entities/src/EntityItem.cpp | 2 -- libraries/physics/src/EntityMotionState.cpp | 2 -- libraries/physics/src/EntityMotionState.h | 7 +------ libraries/physics/src/PhysicsEngine.cpp | 12 ------------ 5 files changed, 2 insertions(+), 23 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 1bdfa7bd1a..c4e12eb957 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -125,7 +125,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) { // XXX if (drawAsModel - && getSimulatorID() != myNodeID + && getSimulatorID() != myNodeID // XXX ) { remapTextures(); glPushMatrix(); diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 07c7935556..8db68785d0 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -620,8 +620,6 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef _angularVelocity = saveAngularVelocity; _gravity = saveGravity; _acceleration = saveAcceleration; - } else { - qDebug() << "accepting update"; } return bytesRead; diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index dba4cfac79..d0c362b852 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -202,7 +202,6 @@ bool EntityMotionState::shouldSendUpdate(uint32_t simulationFrame) { } if (getShouldClaimSimulationOwnership()) { - qDebug() << "shouldSendUpdate due to claiming ownership"; return true; } @@ -345,7 +344,6 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ qCDebug(physics) << "EntityMotionState::sendUpdate()... calling queueEditEntityMessage()..."; #endif - qDebug() << "sending" << _body->isActive() << (_entity->getSimulatorID() == myNodeID); entityPacketSender->queueEditEntityMessage(PacketTypeEntityAddOrEdit, id, properties); } else { #ifdef WANT_DEBUG diff --git a/libraries/physics/src/EntityMotionState.h b/libraries/physics/src/EntityMotionState.h index 1ab3309934..07f82aaa42 100644 --- a/libraries/physics/src/EntityMotionState.h +++ b/libraries/physics/src/EntityMotionState.h @@ -67,12 +67,7 @@ public: quint8 getAccelerationNearlyGravityCount() { return _accelerationNearlyGravityCount; } virtual EntityItem* getEntity() const { return _entity; } - virtual void setShouldClaimSimulationOwnership(bool value) { - if (value) { - qDebug() << "setShouldClaimSimulationOwnership to TRUE"; - } - _shouldClaimSimulationOwnership = value; - } + virtual void setShouldClaimSimulationOwnership(bool value) { _shouldClaimSimulationOwnership = value; } virtual bool getShouldClaimSimulationOwnership() { return _shouldClaimSimulationOwnership; } protected: diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index afb0e65a00..6d0c9c878a 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -393,22 +393,12 @@ void PhysicsEngine::doOwnershipInfection(const btCollisionObject* objectA, const // (a && a->getShouldClaimSimulationOwnership()) || (objectA == characterCollisionObject)) { if (bIsDynamic) { - qDebug() << "setShouldClaimSimulationOwnership(true) in doOwnershipInfection A" - << (aIsDynamic && (entityA->getSimulatorID() == myNodeID)) - << (a && a->getShouldClaimSimulationOwnership()) - << (objectA == characterCollisionObject); - b->setShouldClaimSimulationOwnership(true); } } else if ((bIsDynamic && (entityB->getSimulatorID() == myNodeID)) || // (b && b->getShouldClaimSimulationOwnership()) || (objectB == characterCollisionObject)) { if (aIsDynamic) { - qDebug() << "setShouldClaimSimulationOwnership(true) in doOwnershipInfection B" - << (bIsDynamic && (entityB->getSimulatorID() == myNodeID)) - << (b && b->getShouldClaimSimulationOwnership()) - << (objectB == characterCollisionObject); - a->setShouldClaimSimulationOwnership(true); } } @@ -587,14 +577,12 @@ void PhysicsEngine::bump(EntityItem* bumpEntity) { EntityItem* entityB = entityMotionStateB ? entityMotionStateB->getEntity() : NULL; if (entityA && entityB) { if (entityA == bumpEntity) { - qDebug() << "setShouldClaimSimulationOwnership(true) in bump"; entityMotionStateB->setShouldClaimSimulationOwnership(true); if (!objectB->isActive()) { objectB->setActivationState(ACTIVE_TAG); } } if (entityB == bumpEntity) { - qDebug() << "setShouldClaimSimulationOwnership(true) in bump"; entityMotionStateA->setShouldClaimSimulationOwnership(true); if (!objectA->isActive()) { objectA->setActivationState(ACTIVE_TAG); From 218393a2b3c5f26c9fe9ed289702118c917513f4 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 24 Apr 2015 17:37:19 -0700 Subject: [PATCH 16/30] rather than keeping track of previous pos/rot sent by server, use a new flag that indicates that the values should be updated in the physics engine, but that the object should not be woken --- libraries/entities/src/EntityItem.cpp | 86 ++++++++------------- libraries/entities/src/EntityItem.h | 9 +-- libraries/physics/src/EntityMotionState.cpp | 7 +- 3 files changed, 40 insertions(+), 62 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 8db68785d0..243958b4a8 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -65,13 +65,7 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) : _marketplaceID(ENTITY_ITEM_DEFAULT_MARKETPLACE_ID), _physicsInfo(NULL), _dirtyFlags(0), - _element(NULL), - _previousPositionFromServer(ENTITY_ITEM_ZERO_VEC3), - _previousRotationFromServer(ENTITY_ITEM_DEFAULT_ROTATION), - _previousVelocityFromServer(ENTITY_ITEM_ZERO_VEC3), - _previousAngularVelocityFromServer(ENTITY_ITEM_ZERO_VEC3), - _previousGravityFromServer(ENTITY_ITEM_ZERO_VEC3), - _previousAccelerationFromServer(ENTITY_ITEM_ZERO_VEC3) + _element(NULL) { quint64 now = usecTimestampNow(); _lastSimulated = now; @@ -1100,12 +1094,10 @@ void EntityItem::updatePositionInDomainUnits(const glm::vec3& value) { } void EntityItem::updatePosition(const glm::vec3& value) { - if (/* false && */ value == _previousPositionFromServer) { + if (value != _position) { + auto distance = glm::distance(_position, value); + _dirtyFlags |= (distance > MIN_POSITION_DELTA) ? EntityItem::DIRTY_POSITION : EntityItem::DIRTY_PHYSICS_NO_WAKE; _position = value; - } else if (glm::distance(_position, value) > MIN_POSITION_DELTA) { - _position = value; - _previousPositionFromServer = value; - _dirtyFlags |= EntityItem::DIRTY_POSITION; } } @@ -1122,12 +1114,10 @@ void EntityItem::updateDimensions(const glm::vec3& value) { } void EntityItem::updateRotation(const glm::quat& rotation) { - if (/* false && */ rotation == _previousRotationFromServer) { + if (rotation != _rotation) { + auto alignmentDot = glm::abs(glm::dot(_rotation, rotation)); + _dirtyFlags |= (alignmentDot < MIN_ALIGNMENT_DOT) ? EntityItem::DIRTY_POSITION : EntityItem::DIRTY_PHYSICS_NO_WAKE; _rotation = rotation; - } else if (glm::abs(glm::dot(_rotation, rotation)) < MIN_ALIGNMENT_DOT) { - _rotation = rotation; - _previousRotationFromServer = rotation; - _dirtyFlags |= EntityItem::DIRTY_POSITION; } } @@ -1161,20 +1151,15 @@ void EntityItem::updateVelocityInDomainUnits(const glm::vec3& value) { } void EntityItem::updateVelocity(const glm::vec3& value) { - if (/* false && */ value == _previousVelocityFromServer) { - if (glm::length(value) < MIN_VELOCITY_DELTA) { - _velocity = ENTITY_ITEM_ZERO_VEC3; - } else { - _velocity = value; - } - } else if (glm::distance(_velocity, value) > MIN_VELOCITY_DELTA) { - if (glm::length(value) < MIN_VELOCITY_DELTA) { - _velocity = ENTITY_ITEM_ZERO_VEC3; - } else { - _velocity = value; - } - _previousVelocityFromServer = value; + if (value != _velocity) { + auto distance = glm::distance(_velocity, value); + // _dirtyFlags |= (distance > MIN_VELOCITY_DELTA) ? EntityItem::DIRTY_VELOCITY : EntityItem::DIRTY_PHYSICS_NO_WAKE; _dirtyFlags |= EntityItem::DIRTY_VELOCITY; + if (distance < MIN_VELOCITY_DELTA) { + _velocity = ENTITY_ITEM_ZERO_VEC3; + } else { + _velocity = value; + } } } @@ -1191,39 +1176,36 @@ void EntityItem::updateGravityInDomainUnits(const glm::vec3& value) { } void EntityItem::updateGravity(const glm::vec3& value) { - if (/* false && */ value == _previousGravityFromServer) { - _gravity = value; - } else if (glm::distance(_gravity, value) > MIN_GRAVITY_DELTA) { - _gravity = value; - _previousGravityFromServer = value; + auto distance = glm::distance(_gravity, value); + // if (value != _gravity) { + if (distance > MIN_GRAVITY_DELTA) { + // _dirtyFlags |= (distance > MIN_GRAVITY_DELTA) ? EntityItem::DIRTY_VELOCITY : EntityItem::DIRTY_PHYSICS_NO_WAKE; _dirtyFlags |= EntityItem::DIRTY_VELOCITY; + _gravity = value; } } void EntityItem::updateAcceleration(const glm::vec3& value) { - if (/* false && */ value == _previousAccelerationFromServer) { - _acceleration = value; - } else if (glm::distance(_acceleration, value) > MIN_ACCELERATION_DELTA) { - _acceleration = value; - _previousAccelerationFromServer = value; + auto distance = glm::distance(_acceleration, value); + // if (value != _acceleration) { + if (distance > MIN_ACCELERATION_DELTA) { + // _dirtyFlags |= (distance > MIN_ACCELERATION_DELTA) ? EntityItem::DIRTY_VELOCITY : EntityItem::DIRTY_PHYSICS_NO_WAKE; _dirtyFlags |= EntityItem::DIRTY_VELOCITY; + _acceleration = value; } } void EntityItem::updateAngularVelocity(const glm::vec3& value) { - if (/* false && */ value == _previousAngularVelocityFromServer) { - if (glm::length(value) < MIN_SPIN_DELTA) { - _angularVelocity = ENTITY_ITEM_ZERO_VEC3; - } else { - _angularVelocity = value; - } - } else if (glm::distance(_angularVelocity, value) > MIN_SPIN_DELTA) { - if (glm::length(value) < MIN_SPIN_DELTA) { - _angularVelocity = ENTITY_ITEM_ZERO_VEC3; - } else { - _angularVelocity = value; - } + auto distance = glm::distance(_angularVelocity, value); + // if (value != _angularVelocity) { + if (distance > MIN_SPIN_DELTA) { + // _dirtyFlags |= (distance > MIN_SPIN_DELTA) ? EntityItem::DIRTY_VELOCITY : EntityItem::DIRTY_PHYSICS_NO_WAKE; _dirtyFlags |= EntityItem::DIRTY_VELOCITY; + if (glm::length(value) < MIN_SPIN_DELTA) { + _angularVelocity = ENTITY_ITEM_ZERO_VEC3; + } else { + _angularVelocity = value; + } } } diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index e726e5b11b..890134828a 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -55,7 +55,7 @@ public: DIRTY_SHAPE = 0x0020, DIRTY_LIFETIME = 0x0040, DIRTY_UPDATEABLE = 0x0080, - DIRTY_TWEAK = 0x0100 + DIRTY_PHYSICS_NO_WAKE = 0x0100 // we want to update values in physics engine without "waking" the object up }; DONT_ALLOW_INSTANTIATION // This class can not be instantiated directly @@ -369,13 +369,6 @@ protected: uint32_t _dirtyFlags; // things that have changed from EXTERNAL changes (via script or packet) but NOT from simulation EntityTreeElement* _element; // back pointer to containing Element - - glm::vec3 _previousPositionFromServer; - glm::quat _previousRotationFromServer; - glm::vec3 _previousVelocityFromServer; - glm::vec3 _previousAngularVelocityFromServer; - glm::vec3 _previousGravityFromServer; - glm::vec3 _previousAccelerationFromServer; }; diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index d0c362b852..5e863030c5 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -132,7 +132,7 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) { } void EntityMotionState::updateObjectEasy(uint32_t flags, uint32_t step) { - if (flags & (EntityItem::DIRTY_POSITION | EntityItem::DIRTY_VELOCITY)) { + if (flags & (EntityItem::DIRTY_POSITION | EntityItem::DIRTY_VELOCITY | EntityItem::DIRTY_PHYSICS_NO_WAKE)) { if (flags & EntityItem::DIRTY_POSITION) { _sentPosition = _entity->getPosition() - ObjectMotionState::getWorldOffset(); btTransform worldTrans; @@ -147,6 +147,10 @@ void EntityMotionState::updateObjectEasy(uint32_t flags, uint32_t step) { updateObjectVelocities(); } _sentStep = step; + + if (flags & (EntityItem::DIRTY_POSITION | EntityItem::DIRTY_VELOCITY)) { + _body->activate(); + } } // TODO: entity support for friction and restitution @@ -166,7 +170,6 @@ void EntityMotionState::updateObjectEasy(uint32_t flags, uint32_t step) { _body->setMassProps(mass, inertia); _body->updateInertiaTensor(); } - _body->activate(); }; void EntityMotionState::updateObjectVelocities() { From 03706359f5898b4c81797f104e36a5fb0e974b9f Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 24 Apr 2015 17:44:52 -0700 Subject: [PATCH 17/30] cleanups --- libraries/entities/src/EntityItem.cpp | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 243958b4a8..06a0cc52c2 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1151,9 +1151,8 @@ void EntityItem::updateVelocityInDomainUnits(const glm::vec3& value) { } void EntityItem::updateVelocity(const glm::vec3& value) { - if (value != _velocity) { - auto distance = glm::distance(_velocity, value); - // _dirtyFlags |= (distance > MIN_VELOCITY_DELTA) ? EntityItem::DIRTY_VELOCITY : EntityItem::DIRTY_PHYSICS_NO_WAKE; + auto distance = glm::distance(_velocity, value); + if (distance > MIN_VELOCITY_DELTA) { _dirtyFlags |= EntityItem::DIRTY_VELOCITY; if (distance < MIN_VELOCITY_DELTA) { _velocity = ENTITY_ITEM_ZERO_VEC3; @@ -1176,20 +1175,14 @@ void EntityItem::updateGravityInDomainUnits(const glm::vec3& value) { } void EntityItem::updateGravity(const glm::vec3& value) { - auto distance = glm::distance(_gravity, value); - // if (value != _gravity) { - if (distance > MIN_GRAVITY_DELTA) { - // _dirtyFlags |= (distance > MIN_GRAVITY_DELTA) ? EntityItem::DIRTY_VELOCITY : EntityItem::DIRTY_PHYSICS_NO_WAKE; + if (glm::distance(_gravity, value) > MIN_GRAVITY_DELTA) { _dirtyFlags |= EntityItem::DIRTY_VELOCITY; _gravity = value; } } void EntityItem::updateAcceleration(const glm::vec3& value) { - auto distance = glm::distance(_acceleration, value); - // if (value != _acceleration) { - if (distance > MIN_ACCELERATION_DELTA) { - // _dirtyFlags |= (distance > MIN_ACCELERATION_DELTA) ? EntityItem::DIRTY_VELOCITY : EntityItem::DIRTY_PHYSICS_NO_WAKE; + if (glm::distance(_acceleration, value) > MIN_ACCELERATION_DELTA) { _dirtyFlags |= EntityItem::DIRTY_VELOCITY; _acceleration = value; } @@ -1197,9 +1190,7 @@ void EntityItem::updateAcceleration(const glm::vec3& value) { void EntityItem::updateAngularVelocity(const glm::vec3& value) { auto distance = glm::distance(_angularVelocity, value); - // if (value != _angularVelocity) { if (distance > MIN_SPIN_DELTA) { - // _dirtyFlags |= (distance > MIN_SPIN_DELTA) ? EntityItem::DIRTY_VELOCITY : EntityItem::DIRTY_PHYSICS_NO_WAKE; _dirtyFlags |= EntityItem::DIRTY_VELOCITY; if (glm::length(value) < MIN_SPIN_DELTA) { _angularVelocity = ENTITY_ITEM_ZERO_VEC3; From ac46f84291d9325b0b41124eae6159ed6cfff76e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 24 Apr 2015 18:36:41 -0700 Subject: [PATCH 18/30] cleanups --- .../entities-renderer/src/EntityTreeRenderer.cpp | 15 --------------- .../src/RenderableModelEntityItem.cpp | 16 ++++------------ libraries/entities/src/EntityItem.cpp | 11 +++++------ 3 files changed, 9 insertions(+), 33 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index fbfa882494..586e9a50ad 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -677,26 +677,11 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args) if (bigEnoughToRender) { renderProxies(entityItem, args); - - // XXX - // auto nodeList = DependencyManager::get(); - // const QUuid& myNodeID = nodeList->getSessionUUID(); - // XXX - - Glower* glower = NULL; if (entityItem->getGlowLevel() > 0.0f) { glower = new Glower(entityItem->getGlowLevel()); } - // XXX glow things we are simulating - // if (entityItem->getSimulatorID() == myNodeID) { - // if (glower) delete glower; - // glower = new Glower(); - // } - // XXX glow things we are simulating - - entityItem->render(args); args->_itemsRendered++; if (glower) { diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index c4e12eb957..25922bed10 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -119,25 +119,17 @@ void RenderableModelEntityItem::render(RenderArgs* args) { glm::vec3 dimensions = getDimensions(); float size = glm::length(dimensions); - // XXX - auto nodeList = DependencyManager::get(); - const QUuid& myNodeID = nodeList->getSessionUUID(); - // XXX - + auto nodeList = DependencyManager::get(); // XXX for debugging + const QUuid& myNodeID = nodeList->getSessionUUID(); // XXX for debugging + if (drawAsModel - && getSimulatorID() != myNodeID // XXX + && getSimulatorID() != myNodeID // XXX for debugging ) { remapTextures(); glPushMatrix(); { float alpha = getLocalRenderAlpha(); - // XXX - // if (getSimulatorID() == myNodeID) { - // alpha = 1.0; - // } - // XXX - if (!_model || _needsModelReload) { // TODO: this getModel() appears to be about 3% of model render time. We should optimize PerformanceTimer perfTimer("getModel"); diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 06a0cc52c2..5552013ca2 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1151,14 +1151,13 @@ void EntityItem::updateVelocityInDomainUnits(const glm::vec3& value) { } void EntityItem::updateVelocity(const glm::vec3& value) { - auto distance = glm::distance(_velocity, value); - if (distance > MIN_VELOCITY_DELTA) { - _dirtyFlags |= EntityItem::DIRTY_VELOCITY; - if (distance < MIN_VELOCITY_DELTA) { + if (glm::distance(_velocity, value) > MIN_VELOCITY_DELTA) { + if (glm::length(value) < MIN_VELOCITY_DELTA) { _velocity = ENTITY_ITEM_ZERO_VEC3; } else { _velocity = value; } + _dirtyFlags |= EntityItem::DIRTY_VELOCITY; } } @@ -1176,15 +1175,15 @@ void EntityItem::updateGravityInDomainUnits(const glm::vec3& value) { void EntityItem::updateGravity(const glm::vec3& value) { if (glm::distance(_gravity, value) > MIN_GRAVITY_DELTA) { - _dirtyFlags |= EntityItem::DIRTY_VELOCITY; _gravity = value; + _dirtyFlags |= EntityItem::DIRTY_VELOCITY; } } void EntityItem::updateAcceleration(const glm::vec3& value) { if (glm::distance(_acceleration, value) > MIN_ACCELERATION_DELTA) { - _dirtyFlags |= EntityItem::DIRTY_VELOCITY; _acceleration = value; + _dirtyFlags |= EntityItem::DIRTY_VELOCITY; } } From 48ec0c833908ba73fc41f6ea9bec6ad81a0583d7 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 25 Apr 2015 06:56:19 -0700 Subject: [PATCH 19/30] formatting, re-enable code that causes an interface to attempt to claim a moving object with no current simulation-owner --- libraries/entities-renderer/src/EntityTreeRenderer.cpp | 1 - libraries/physics/src/EntityMotionState.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 586e9a50ad..dde13552f3 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -681,7 +681,6 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args) if (entityItem->getGlowLevel() > 0.0f) { glower = new Glower(entityItem->getGlowLevel()); } - entityItem->render(args); args->_itemsRendered++; if (glower) { diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 5e863030c5..31e615249c 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -116,7 +116,7 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) { if (_entity->getSimulatorID().isNull() && isMoving()) { // object is moving and has no owner. attempt to claim simulation ownership. - // setShouldClaimSimulationOwnership(true); + setShouldClaimSimulationOwnership(true); } _outgoingPacketFlags = DIRTY_PHYSICS_FLAGS; From 81ff8a4448e85e1cabefb5a8e12b3a0ecaaa7a9a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 25 Apr 2015 07:17:21 -0700 Subject: [PATCH 20/30] count steps during which an EntityItem is moving but has no simulation owner. Once the count is high enough (how high is TBD), attempt to claim ownership --- libraries/physics/src/EntityMotionState.cpp | 9 ++++++++- libraries/physics/src/EntityMotionState.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 31e615249c..c722336ca2 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -38,7 +38,8 @@ void EntityMotionState::enqueueOutgoingEntity(EntityItem* entity) { EntityMotionState::EntityMotionState(EntityItem* entity) : _entity(entity), _accelerationNearlyGravityCount(0), - _shouldClaimSimulationOwnership(false) + _shouldClaimSimulationOwnership(false), + _movingStepsWithoutSimulationOwner(0) { _type = MOTION_STATE_TYPE_ENTITY; assert(entity != NULL); @@ -116,6 +117,12 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) { if (_entity->getSimulatorID().isNull() && isMoving()) { // object is moving and has no owner. attempt to claim simulation ownership. + _movingStepsWithoutSimulationOwner++; + } else { + _movingStepsWithoutSimulationOwner = 0; + } + + if (_movingStepsWithoutSimulationOwner > 4) { // XXX maybe meters from our characterController ? setShouldClaimSimulationOwnership(true); } diff --git a/libraries/physics/src/EntityMotionState.h b/libraries/physics/src/EntityMotionState.h index 07f82aaa42..087d5b49b9 100644 --- a/libraries/physics/src/EntityMotionState.h +++ b/libraries/physics/src/EntityMotionState.h @@ -74,6 +74,7 @@ protected: EntityItem* _entity; quint8 _accelerationNearlyGravityCount; bool _shouldClaimSimulationOwnership; + quint32 _movingStepsWithoutSimulationOwner; }; #endif // hifi_EntityMotionState_h From e00761711206213e4e2cf4ce8dd16ea497a396b8 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 27 Apr 2015 09:56:24 -0700 Subject: [PATCH 21/30] hook up menu-items to control debug rendering of collision hulls and owned simulations --- interface/src/Application.cpp | 26 +++++++++---------- interface/src/Menu.cpp | 5 ++++ interface/src/Menu.h | 2 ++ .../src/EntityTreeRenderer.cpp | 7 ++--- .../src/EntityTreeRenderer.h | 3 ++- .../src/RenderableModelEntityItem.cpp | 12 +++++---- libraries/entities/src/EntityItem.cpp | 1 + libraries/octree/src/OctreeRenderer.cpp | 6 +++-- libraries/octree/src/OctreeRenderer.h | 3 ++- libraries/render-utils/src/Model.cpp | 4 +-- libraries/shared/src/RenderArgs.h | 9 ++++++- 11 files changed, 50 insertions(+), 28 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 95700f3257..c6c9514cc2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -164,8 +164,6 @@ const QString SKIP_FILENAME = QStandardPaths::writableLocation(QStandardPaths::D const QString DEFAULT_SCRIPTS_JS_URL = "http://s3.amazonaws.com/hifi-public/scripts/defaultScripts.js"; -bool renderCollisionHulls = false; - #ifdef Q_OS_WIN class MyNativeEventFilter : public QAbstractNativeEventFilter { public: @@ -1280,11 +1278,6 @@ void Application::keyPressEvent(QKeyEvent* event) { break; } - case Qt::Key_Comma: { - renderCollisionHulls = !renderCollisionHulls; - break; - } - default: event->ignore(); break; @@ -3110,13 +3103,20 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs PerformanceTimer perfTimer("entities"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... entities..."); - if (renderCollisionHulls) { - _entities.render(RenderArgs::DEBUG_RENDER_MODE, renderSide); - } else if (theCamera.getMode() == CAMERA_MODE_MIRROR) { - _entities.render(RenderArgs::MIRROR_RENDER_MODE, renderSide); - } else { - _entities.render(RenderArgs::DEFAULT_RENDER_MODE, renderSide); + + RenderArgs::DebugFlags renderDebugFlags = 0; + RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE; + + if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowHulls)) { + renderDebugFlags |= RenderArgs::RENDER_DEBUG_HULLS; } + if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowOwned)) { + renderDebugFlags |= RenderArgs::RENDER_DEBUG_SIMULATION_OWNERSHIP; + } + if (theCamera.getMode() == CAMERA_MODE_MIRROR) { + renderMode = RenderArgs::MIRROR_RENDER_MODE; + } + _entities.render(renderMode, renderSide, renderDebugFlags); } // render JS/scriptable overlays diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 9b9e93a4c9..43c63eb383 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -549,6 +549,11 @@ Menu::Menu() { statsRenderer.data(), SLOT(toggleShowInjectedStreams())); + + QMenu* physicsOptionsMenu = developerMenu->addMenu("Physics"); + addCheckableActionToQMenuAndActionHash(physicsOptionsMenu, MenuOption::PhysicsShowOwned); + addCheckableActionToQMenuAndActionHash(physicsOptionsMenu, MenuOption::PhysicsShowHulls); + QMenu* helpMenu = addMenu("Help"); addActionToQMenuAndActionHash(helpMenu, MenuOption::EditEntitiesHelp, 0, qApp, SLOT(showEditEntitiesHelp())); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 5a162d31bc..2c4e2b809f 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -187,6 +187,8 @@ namespace MenuOption { const QString OnlyDisplayTopTen = "Only Display Top Ten"; const QString PackageModel = "Package Model..."; const QString Pair = "Pair"; + const QString PhysicsShowOwned = "Highlight Simulation Ownership"; + const QString PhysicsShowHulls = "Draw Collision Hulls"; const QString PipelineWarnings = "Log Render Pipeline Warnings"; const QString Preferences = "Preferences..."; const QString Quit = "Quit"; diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index c744ec0165..5141ef3437 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -383,7 +383,9 @@ void EntityTreeRenderer::leaveAllEntities() { _lastAvatarPosition = _viewState->getAvatarPosition() + glm::vec3((float)TREE_SCALE); } } -void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) { +void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode, + RenderArgs::RenderSide renderSide, + RenderArgs::DebugFlags renderDebugFlags) { if (_tree && !_shuttingDown) { Model::startScene(renderSide); @@ -391,8 +393,7 @@ void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode, RenderArgs::R _viewState->getShadowViewFrustum() : _viewState->getCurrentViewFrustum(); RenderArgs args = { this, frustum, getSizeScale(), getBoundaryLevelAdjust(), renderMode, renderSide, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - + renderDebugFlags, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; _tree->lockForRead(); diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 8f720e5e48..20534c3e2b 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -58,7 +58,8 @@ public: virtual void init(); virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, - RenderArgs::RenderSide renderSide = RenderArgs::MONO); + RenderArgs::RenderSide renderSide = RenderArgs::MONO, + RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE); virtual const FBXGeometry* getGeometryForEntity(const EntityItem* entityItem); virtual const Model* getModelForEntityItem(const EntityItem* entityItem); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 25922bed10..b9bf1d39a8 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -119,12 +119,14 @@ void RenderableModelEntityItem::render(RenderArgs* args) { glm::vec3 dimensions = getDimensions(); float size = glm::length(dimensions); - auto nodeList = DependencyManager::get(); // XXX for debugging - const QUuid& myNodeID = nodeList->getSessionUUID(); // XXX for debugging + bool highlightSimulationOwnership = false; + if (args->_debugFlags & RenderArgs::RENDER_DEBUG_SIMULATION_OWNERSHIP) { + auto nodeList = DependencyManager::get(); + const QUuid& myNodeID = nodeList->getSessionUUID(); + highlightSimulationOwnership = (getSimulatorID() == myNodeID); + } - if (drawAsModel - && getSimulatorID() != myNodeID // XXX for debugging - ) { + if (drawAsModel && !highlightSimulationOwnership) { remapTextures(); glPushMatrix(); { diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 03ff2f1a79..5552013ca2 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1085,6 +1085,7 @@ const float MIN_ALIGNMENT_DOT = 0.999999f; const float MIN_VELOCITY_DELTA = 0.01f; const float MIN_DAMPING_DELTA = 0.001f; const float MIN_GRAVITY_DELTA = 0.001f; +const float MIN_ACCELERATION_DELTA = 0.001f; const float MIN_SPIN_DELTA = 0.0003f; void EntityItem::updatePositionInDomainUnits(const glm::vec3& value) { diff --git a/libraries/octree/src/OctreeRenderer.cpp b/libraries/octree/src/OctreeRenderer.cpp index ae40cbfa15..346d7c43f6 100644 --- a/libraries/octree/src/OctreeRenderer.cpp +++ b/libraries/octree/src/OctreeRenderer.cpp @@ -164,9 +164,11 @@ bool OctreeRenderer::renderOperation(OctreeElement* element, void* extraData) { return false; } -void OctreeRenderer::render(RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) { +void OctreeRenderer::render(RenderArgs::RenderMode renderMode, + RenderArgs::RenderSide renderSide, + RenderArgs::DebugFlags renderDebugFlags) { RenderArgs args = { this, _viewFrustum, getSizeScale(), getBoundaryLevelAdjust(), renderMode, renderSide, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + renderDebugFlags, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; if (_tree) { _tree->lockForRead(); _tree->recurseTreeWithOperation(renderOperation, &args); diff --git a/libraries/octree/src/OctreeRenderer.h b/libraries/octree/src/OctreeRenderer.h index 4ee0865243..ca0914723f 100644 --- a/libraries/octree/src/OctreeRenderer.h +++ b/libraries/octree/src/OctreeRenderer.h @@ -52,7 +52,8 @@ public: /// render the content of the octree virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, - RenderArgs::RenderSide renderSide = RenderArgs::MONO); + RenderArgs::RenderSide renderSide = RenderArgs::MONO, + RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE); ViewFrustum* getViewFrustum() const { return _viewFrustum; } void setViewFrustum(ViewFrustum* viewFrustum) { _viewFrustum = viewFrustum; } diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index fe82af6b3c..3508570d6a 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1947,14 +1947,14 @@ bool Model::renderInScene(float alpha, RenderArgs* args) { return false; } - if (args->_renderMode == RenderArgs::DEBUG_RENDER_MODE && _renderCollisionHull == false) { + if (args->_debugFlags == RenderArgs::RENDER_DEBUG_HULLS && _renderCollisionHull == false) { // turning collision hull rendering on _renderCollisionHull = true; _nextGeometry = _collisionGeometry; _saveNonCollisionGeometry = _geometry; updateGeometry(); simulate(0.0, true); - } else if (args->_renderMode != RenderArgs::DEBUG_RENDER_MODE && _renderCollisionHull == true) { + } else if (args->_debugFlags != RenderArgs::RENDER_DEBUG_HULLS && _renderCollisionHull == true) { // turning collision hull rendering off _renderCollisionHull = false; _nextGeometry = _saveNonCollisionGeometry; diff --git a/libraries/shared/src/RenderArgs.h b/libraries/shared/src/RenderArgs.h index 116fc430c2..bc3e2edb6d 100644 --- a/libraries/shared/src/RenderArgs.h +++ b/libraries/shared/src/RenderArgs.h @@ -17,16 +17,23 @@ class OctreeRenderer; class RenderArgs { public: - enum RenderMode { DEFAULT_RENDER_MODE, SHADOW_RENDER_MODE, DIFFUSE_RENDER_MODE, NORMAL_RENDER_MODE, MIRROR_RENDER_MODE, DEBUG_RENDER_MODE }; + enum RenderMode { DEFAULT_RENDER_MODE, SHADOW_RENDER_MODE, DIFFUSE_RENDER_MODE, NORMAL_RENDER_MODE, MIRROR_RENDER_MODE }; enum RenderSide { MONO, STEREO_LEFT, STEREO_RIGHT }; + enum DebugFlags { + RENDER_DEBUG_NONE=0, + RENDER_DEBUG_HULLS=1, + RENDER_DEBUG_SIMULATION_OWNERSHIP=2 + }; + OctreeRenderer* _renderer; ViewFrustum* _viewFrustum; float _sizeScale; int _boundaryLevelAdjust; RenderMode _renderMode; RenderSide _renderSide; + DebugFlags _debugFlags; int _elementsTouched; int _itemsRendered; From b23427a3c805ae5225d5db721c46925c0959faa3 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 27 Apr 2015 10:32:47 -0700 Subject: [PATCH 22/30] hook up menu-items to control debug rendering of collision hulls and owned simulations --- interface/src/Application.cpp | 7 ++++--- interface/src/ui/overlays/Overlays.cpp | 9 ++++++--- interface/src/ui/overlays/Overlays.h | 3 ++- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c6c9514cc2..c279a345ef 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3104,14 +3104,15 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... entities..."); - RenderArgs::DebugFlags renderDebugFlags = 0; + RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE; RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE; if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowHulls)) { - renderDebugFlags |= RenderArgs::RENDER_DEBUG_HULLS; + renderDebugFlags = (RenderArgs::DebugFlags) (renderDebugFlags | (int) RenderArgs::RENDER_DEBUG_HULLS); } if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowOwned)) { - renderDebugFlags |= RenderArgs::RENDER_DEBUG_SIMULATION_OWNERSHIP; + renderDebugFlags = + (RenderArgs::DebugFlags) (renderDebugFlags | (int) RenderArgs::RENDER_DEBUG_SIMULATION_OWNERSHIP); } if (theCamera.getMode() == CAMERA_MODE_MIRROR) { renderMode = RenderArgs::MIRROR_RENDER_MODE; diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 191f3f4a99..a9eb9184dd 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -90,7 +90,7 @@ void Overlays::renderHUD() { RenderArgs args = { NULL, Application::getInstance()->getViewFrustum(), lodManager->getOctreeSizeScale(), lodManager->getBoundaryLevelAdjust(), - RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO, + RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; foreach(Overlay* thisOverlay, _overlaysHUD) { @@ -108,7 +108,10 @@ void Overlays::renderHUD() { } } -void Overlays::renderWorld(bool drawFront, RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) { +void Overlays::renderWorld(bool drawFront, + RenderArgs::RenderMode renderMode, + RenderArgs::RenderSide renderSide, + RenderArgs::DebugFlags renderDebugFlags) { QReadLocker lock(&_lock); if (_overlaysWorld.size() == 0) { return; @@ -125,7 +128,7 @@ void Overlays::renderWorld(bool drawFront, RenderArgs::RenderMode renderMode, Re RenderArgs args = { NULL, Application::getInstance()->getDisplayViewFrustum(), lodManager->getOctreeSizeScale(), lodManager->getBoundaryLevelAdjust(), - renderMode, renderSide, + renderMode, renderSide, renderDebugFlags, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 42227d04f6..04e306097b 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -54,7 +54,8 @@ public: void init(); void update(float deltatime); void renderWorld(bool drawFront, RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, - RenderArgs::RenderSide renderSide = RenderArgs::MONO); + RenderArgs::RenderSide renderSide = RenderArgs::MONO, + RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE); void renderHUD(); public slots: From 8278f52a7978858a27b6117c804f9a477199eaf7 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 27 Apr 2015 10:59:51 -0700 Subject: [PATCH 23/30] cleanups --- libraries/physics/src/EntityMotionState.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index c722336ca2..4c61503d49 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -219,7 +219,7 @@ bool EntityMotionState::shouldSendUpdate(uint32_t simulationFrame) { const QUuid& myNodeID = nodeList->getSessionUUID(); const QUuid& simulatorID = _entity->getSimulatorID(); - if (simulatorID != myNodeID /* && !simulatorID.isNull() */) { + if (simulatorID != myNodeID) { // some other Node owns the simulating of this, so don't broadcast the results of local simulation. return false; } @@ -302,13 +302,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ QUuid myNodeID = nodeList->getSessionUUID(); QUuid simulatorID = _entity->getSimulatorID(); - // if (simulatorID.isNull() && !(zeroSpeed && zeroSpin)) { - // // the entity is moving and no node has claimed simulation ownership. try to claim it. - // setShouldClaimSimulationOwnership(true); - // } - if (getShouldClaimSimulationOwnership()) { - // _entity->setSimulatorID(myNodeID); properties.setSimulatorID(myNodeID); setShouldClaimSimulationOwnership(false); } else if (simulatorID == myNodeID && zeroSpeed && zeroSpin) { From e14b4c6ad4b9299f4b52d2da4676c7052ea8c10b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 27 Apr 2015 11:01:48 -0700 Subject: [PATCH 24/30] cleanups --- libraries/physics/src/PhysicsEngine.cpp | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 6d0c9c878a..27ea816440 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -467,16 +467,6 @@ void PhysicsEngine::computeCollisionEvents() { if (type == CONTACT_EVENT_TYPE_END) { ContactMap::iterator iterToDelete = contactItr; ++contactItr; - - // const ContactKey& contactKey = (*iterToDelete).first; - // const ObjectMotionState* objectMotionStateA = static_cast(contactKey._a); - // const ObjectMotionState* objectMotionStateB = static_cast(contactKey._b); - // const btCollisionObject* objectA = - // objectMotionStateA ? static_cast(objectMotionStateA->getRigidBody()) : NULL; - // const btCollisionObject* objectB = - // objectMotionStateB ? static_cast(objectMotionStateB->getRigidBody()) : NULL; - // doOwnershipInfection(objectA, objectB); - _contactMap.erase(iterToDelete); } else { ++contactItr; @@ -600,17 +590,10 @@ void PhysicsEngine::removeObjectFromBullet(ObjectMotionState* motionState) { assert(motionState); btRigidBody* body = motionState->getRigidBody(); - // activate this before deleting it so that anything resting on it will begin to fall. - // - // body->activate(); - // - // motionState->setShouldClaimSimulationOwnership(true); - // computeCollisionEvents(); - // + // wake up anything touching this object EntityItem* entityItem = motionState ? motionState->getEntity() : NULL; bump(entityItem); - if (body) { const btCollisionShape* shape = body->getCollisionShape(); _dynamicsWorld->removeRigidBody(body); From 2e5049a190e2278c8867ecc4afde620499f9e640 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 27 Apr 2015 12:20:01 -0700 Subject: [PATCH 25/30] fix bug caused by no-longer reusing a variable --- libraries/physics/src/EntityMotionState.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 4c61503d49..6338736a19 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -111,7 +111,7 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) { glm::vec3 av; getAngularVelocity(av); - _entity->setAngularVelocity(v); + _entity->setAngularVelocity(av); _entity->setLastSimulated(usecTimestampNow()); From ca16d37ce5fe70dd62cc24eafb5049a781bba73e Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Mon, 27 Apr 2015 12:46:34 -0700 Subject: [PATCH 26/30] Mac testing --- interface/resources/qml/VrMenu.qml | 42 +++++++++++++++++------------- libraries/ui/src/OffscreenUi.cpp | 2 +- tests/render-utils/src/main.cpp | 2 +- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/interface/resources/qml/VrMenu.qml b/interface/resources/qml/VrMenu.qml index 01714e9ebe..4bbcb9c498 100644 --- a/interface/resources/qml/VrMenu.qml +++ b/interface/resources/qml/VrMenu.qml @@ -108,7 +108,7 @@ Hifi.VrMenu { height: 32 color: hifi.colors.hifiBlue y: (listView.currentItem) ? listView.currentItem.y : 0; - x: 32 + x: (listView.currentItem) ? listView.currentItem.height : 0; Behavior on y { NumberAnimation { duration: 100 @@ -132,6 +132,12 @@ Hifi.VrMenu { property: "source" value: modelData when: loader.status == Loader.Ready + } + Binding { + target: loader.item + property: "border" + value: listView.parent + when: loader.status == Loader.Ready } Binding { target: loader.item @@ -147,10 +153,11 @@ Hifi.VrMenu { property var itemBuilder: Component { Text { id: thisText - x: 32 + x: height property var source property var root property var listView + property var border text: typedText() height: implicitHeight width: implicitWidth @@ -167,12 +174,6 @@ Hifi.VrMenu { } } - onVisibleChanged: { - if (listView) { - listView.recalculateSize(); - } - } - onImplicitWidthChanged: { if (listView) { listView.minWidth = Math.max(listView.minWidth, implicitWidth + 64); @@ -182,12 +183,13 @@ Hifi.VrMenu { FontAwesome { visible: source.type == 1 && source.checkable - x: -32 + x: -parent.height + size: parent.height text: checkText(); color: parent.color function checkText() { - if (source.type != 1) { - return; + if (!source || source.type != 1) { + return ""; } // FIXME this works for native QML menus but I don't think it will // for proxied QML menus @@ -199,6 +201,7 @@ Hifi.VrMenu { } FontAwesome { + size: parent.height visible: source.type == 2 x: listView.width - 32 - (hifi.layout.spacing * 2) text: "\uF0DA" @@ -206,14 +209,17 @@ Hifi.VrMenu { } function typedText() { - switch(source.type) { - case 2: - return source.title; - case 1: - return source.text; - case 0: - return "-----" + if (source) { + switch(source.type) { + case 2: + return source.title; + case 1: + return source.text; + case 0: + return "-----" + } } + return "" } MouseArea { diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp index 5db7349a02..8ba7b514e4 100644 --- a/libraries/ui/src/OffscreenUi.cpp +++ b/libraries/ui/src/OffscreenUi.cpp @@ -124,9 +124,9 @@ void OffscreenUi::resize(const QSize& newSize) { if (_quickWindow) { _quickWindow->setGeometry(QRect(QPoint(), newSize)); + _quickWindow->contentItem()->setSize(newSize); } - _quickWindow->contentItem()->setSize(newSize); // Update our members if (_rootItem) { diff --git a/tests/render-utils/src/main.cpp b/tests/render-utils/src/main.cpp index 5e45bf23a2..0ba7416b28 100644 --- a/tests/render-utils/src/main.cpp +++ b/tests/render-utils/src/main.cpp @@ -205,7 +205,7 @@ void QTestWindow::renderText() { { size.x + QUAD_OFFSET.x, QUAD_OFFSET.y }, { size.x + QUAD_OFFSET.x, size.y + QUAD_OFFSET.y }, { QUAD_OFFSET.x, size.y + QUAD_OFFSET.y }, - }; + }; QString str = QString::fromWCharArray(EXAMPLE_TEXT); for (int i = 0; i < 4; ++i) { From 1ef58139a40160a854ee555ccaaff8f760385826 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 27 Apr 2015 15:07:32 -0700 Subject: [PATCH 27/30] fix bug in parsing root element data --- libraries/octree/src/Octree.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index b1e92e2140..059c0e5bbc 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -380,9 +380,9 @@ int Octree::readElementData(OctreeElement* destinationElement, const unsigned ch } // if this is the root, and there is more data to read, allow it to read it's element data... - if (destinationElement == _rootElement && rootElementHasData() && (bytesLeftToRead - bytesRead) > 0) { + if (destinationElement == _rootElement && rootElementHasData() && bytesLeftToRead > 0) { // tell the element to read the subsequent data - int rootDataSize = _rootElement->readElementDataFromBuffer(nodeData + bytesRead, bytesLeftToRead - bytesRead, args); + int rootDataSize = _rootElement->readElementDataFromBuffer(nodeData + bytesRead, bytesLeftToRead, args); bytesRead += rootDataSize; bytesLeftToRead -= rootDataSize; } From fd28baac8c713446163a7b1e5e877e709e3c90ef Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 27 Apr 2015 15:42:20 -0700 Subject: [PATCH 28/30] Working on message box and addressbar tweaks --- interface/resources/qml/AddressBarDialog.qml | 31 ++++++---- interface/resources/qml/MessageDialog.qml | 60 +++++++------------ .../resources/qml/controls/DialogBase.qml | 6 +- 3 files changed, 45 insertions(+), 52 deletions(-) diff --git a/interface/resources/qml/AddressBarDialog.qml b/interface/resources/qml/AddressBarDialog.qml index 8d2439e5b8..e12452472a 100644 --- a/interface/resources/qml/AddressBarDialog.qml +++ b/interface/resources/qml/AddressBarDialog.qml @@ -4,12 +4,16 @@ import "controls" import "styles" Dialog { + id: root + HifiConstants { id: hifi } + title: "Go to..." objectName: "AddressBarDialog" - height: 128 - width: 512 + contentImplicitWidth: addressBarDialog.implicitWidth + contentImplicitHeight: addressBarDialog.implicitHeight destroyOnCloseButton: false + onVisibleChanged: { if (!visible) { reset(); @@ -21,6 +25,11 @@ Dialog { addressLine.forceActiveFocus(); } } + onParentChanged: { + if (enabled && visible) { + addressLine.forceActiveFocus(); + } + } function reset() { addressLine.text = "" @@ -29,24 +38,26 @@ Dialog { AddressBarDialog { id: addressBarDialog - // The client area - anchors.fill: parent - anchors.margins: parent.margins - anchors.topMargin: parent.topMargin + x: root.clientX + y: root.clientY + implicitWidth: 512 + implicitHeight: border.height + hifi.layout.spacing * 4 + Border { + id: border height: 64 anchors.left: parent.left - anchors.leftMargin: 0 + anchors.leftMargin: hifi.layout.spacing * 2 anchors.right: goButton.left - anchors.rightMargin: 8 + anchors.rightMargin: hifi.layout.spacing anchors.verticalCenter: parent.verticalCenter TextInput { id: addressLine anchors.fill: parent helperText: "domain, location, @user, /x,y,z" - anchors.margins: 8 + anchors.margins: hifi.layout.spacing onAccepted: { event.accepted addressBarDialog.loadAddress(addressLine.text) @@ -59,7 +70,7 @@ Dialog { width: 32 height: 32 anchors.right: parent.right - anchors.rightMargin: 8 + anchors.rightMargin: hifi.layout.spacing * 2 source: "../images/address-bar-submit.svg" anchors.verticalCenter: parent.verticalCenter diff --git a/interface/resources/qml/MessageDialog.qml b/interface/resources/qml/MessageDialog.qml index a2a5ba9304..02f1e4716f 100644 --- a/interface/resources/qml/MessageDialog.qml +++ b/interface/resources/qml/MessageDialog.qml @@ -3,71 +3,51 @@ import QtQuick 2.2 import QtQuick.Controls 1.2 import QtQuick.Dialogs 1.2 import "controls" +import "styles" Dialog { id: root - property real spacing: 8 - property real outerSpacing: 16 - + HifiConstants { id: hifi } + property real spacing: hifi.layout.spacing + property real outerSpacing: hifi.layout.spacing * 2 destroyOnCloseButton: true destroyOnInvisible: true - implicitHeight: content.implicitHeight + outerSpacing * 2 + 48 - implicitWidth: Math.min(200, Math.max(mainText.implicitWidth, content.buttonsRowImplicitWidth) + outerSpacing * 2); + contentImplicitWidth: content.implicitWidth + contentImplicitHeight: content.implicitHeight - onImplicitHeightChanged: root.height = implicitHeight - onImplicitWidthChanged: root.width = implicitWidth - - function calculateImplicitWidth() { - if (buttons.visibleChildren.length < 2) - return; - var calcWidth = 0; - for (var i = 0; i < buttons.visibleChildren.length; ++i) { - calcWidth += Math.max(100, buttons.visibleChildren[i].implicitWidth) + root.spacing - } - content.buttonsRowImplicitWidth = outerSpacing + calcWidth + 48 - } - Component.onCompleted: { enabled = true } - - onEnabledChanged: { - if (enabled) { - root.forceActiveFocus(); + + onParentChanged: { + if (visible && enabled) { + forceActiveFocus(); } } Hifi.MessageDialog { id: content clip: true - anchors.fill: parent - anchors.topMargin: parent.topMargin + root.outerSpacing - anchors.leftMargin: parent.margins + root.outerSpacing - anchors.rightMargin: parent.margins + root.outerSpacing - anchors.bottomMargin: parent.margins + root.outerSpacing - implicitHeight: contentColumn.implicitHeight + outerSpacing * 2 - implicitWidth: Math.max(mainText.implicitWidth, buttonsRowImplicitWidth); - property real buttonsRowImplicitWidth: Screen.pixelDensity * 50 - onImplicitWidthChanged: root.width = implicitWidth + x: root.clientX + y: root.clientY + implicitHeight: contentColumn.implicitHeight + outerSpacing * 2 + implicitWidth: mainText.implicitWidth + outerSpacing * 2 Component.onCompleted: { root.title = title } - + onTitleChanged: { root.title = title } - + Column { + anchors.fill: parent + anchors.margins: 8 id: contentColumn spacing: root.outerSpacing - anchors { - top: parent.top - left: parent.left - right: parent.right - } Item { width: parent.width @@ -83,7 +63,7 @@ Dialog { horizontalAlignment: Text.AlignLeft color: iconColor() text: iconSymbol() - + function iconSymbol() { switch (content.icon) { case Hifi.MessageDialog.Information: @@ -262,7 +242,6 @@ Dialog { onClicked: content.click(StandardButton.Help) visible: content.standardButtons & StandardButton.Help } - onVisibleChildrenChanged: root.calculateImplicitWidth() } } @@ -319,6 +298,7 @@ Dialog { ] } + Keys.onPressed: { if (event.modifiers === Qt.ControlModifier) switch (event.key) { diff --git a/interface/resources/qml/controls/DialogBase.qml b/interface/resources/qml/controls/DialogBase.qml index e5f0a8f0d1..050237c184 100644 --- a/interface/resources/qml/controls/DialogBase.qml +++ b/interface/resources/qml/controls/DialogBase.qml @@ -6,13 +6,15 @@ import "../styles" Item { id: root HifiConstants { id: hifi } - implicitHeight: 512 - implicitWidth: 512 + implicitHeight: contentImplicitHeight + titleBorder.height + hifi.styles.borderWidth + implicitWidth: contentImplicitWidth + hifi.styles.borderWidth * 2 property string title property int titleSize: titleBorder.height + 12 property string frameColor: hifi.colors.hifiBlue property string backgroundColor: hifi.colors.dialogBackground property bool active: false + property real contentImplicitWidth: 800 + property real contentImplicitHeight: 800 property alias titleBorder: titleBorder readonly property alias titleX: titleBorder.x From 1beaf18d1baf096bec57aff78c70397fb76d1597 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 27 Apr 2015 16:00:23 -0700 Subject: [PATCH 29/30] Prevent the login dialog from spawning the address bar on enter keys --- interface/resources/qml/LoginDialog.qml | 28 ++++++++++++++++--------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/interface/resources/qml/LoginDialog.qml b/interface/resources/qml/LoginDialog.qml index 1e02683c57..5653dfc7a1 100644 --- a/interface/resources/qml/LoginDialog.qml +++ b/interface/resources/qml/LoginDialog.qml @@ -60,9 +60,6 @@ Dialog { anchors.margins: 8 KeyNavigation.tab: password KeyNavigation.backtab: password - onAccepted: { - password.forceActiveFocus() - } } } @@ -78,13 +75,6 @@ Dialog { anchors.margins: 8 KeyNavigation.tab: username KeyNavigation.backtab: username - onAccepted: { - if (username.text == "") { - username.forceActiveFocus() - } else { - loginDialog.login(username.text, password.text) - } - } onFocusChanged: { if (password.focus) { password.selectAll() @@ -187,4 +177,22 @@ Dialog { } } } + Keys.onPressed: { + switch(event.key) { + case Qt.Key_Enter: + case Qt.Key_Return: + if (username.activeFocus) { + event.accepted = true + password.forceActiveFocus() + } else if (password.activeFocus) { + event.accepted = true + if (username.text == "") { + username.forceActiveFocus() + } else { + loginDialog.login(username.text, password.text) + } + } + break; + } + } } From 10b59350630553a500c912aa9d57f23c6a303787 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 27 Apr 2015 18:11:19 -0700 Subject: [PATCH 30/30] Let QML take care of more of the height/width stuff --- interface/resources/qml/VrMenu.qml | 335 +++++++++++++---------------- 1 file changed, 152 insertions(+), 183 deletions(-) diff --git a/interface/resources/qml/VrMenu.qml b/interface/resources/qml/VrMenu.qml index 4bbcb9c498..01a726d2ba 100644 --- a/interface/resources/qml/VrMenu.qml +++ b/interface/resources/qml/VrMenu.qml @@ -50,6 +50,7 @@ Hifi.VrMenu { property var menuBuilder: Component { Border { + HifiConstants { id: hifi } Component.onCompleted: { menuDepth = root.models.length - 1 if (menuDepth == 0) { @@ -64,213 +65,181 @@ Hifi.VrMenu { border.color: hifi.colors.hifiBlue color: hifi.colors.window property int menuDepth -/* - MouseArea { -// Rectangle { anchors.fill: parent; color: "#7f0000FF"; visible: enabled } - anchors.fill: parent - onClicked: { - while (parent.menuDepth != root.models.length - 1) { - root.popColumn() - } - } - } -*/ + implicitHeight: listView.implicitHeight + 16 + implicitWidth: listView.implicitWidth + 16 - ListView { - spacing: 6 - property int outerMargin: 8 - property real minWidth: 0 - anchors.fill: parent - anchors.margins: outerMargin + Column { id: listView - height: root.height - - onCountChanged: { - recalculateSize() + property real minWidth: 0 + anchors { + top: parent.top + topMargin: 8 + left: parent.left + leftMargin: 8 + right: parent.right + rightMargin: 8 } - function recalculateSize() { - var newHeight = 0 - var newWidth = minWidth; - for (var i = 0; i < children.length; ++i) { - var item = children[i]; - if (!item.visible) { - continue - } - newHeight += item.height + Repeater { + model: root.models[menuDepth] + delegate: Loader { + id: loader + sourceComponent: root.itemBuilder + Binding { + target: loader.item + property: "root" + value: root + when: loader.status == Loader.Ready + } + Binding { + target: loader.item + property: "source" + value: modelData + when: loader.status == Loader.Ready + } + Binding { + target: loader.item + property: "border" + value: listView.parent + when: loader.status == Loader.Ready + } + Binding { + target: loader.item + property: "listView" + value: listView + when: loader.status == Loader.Ready + } } - parent.height = newHeight + outerMargin * 2; - parent.width = newWidth + outerMargin * 2 - } - - highlight: Rectangle { - width: listView.minWidth - 32; - height: 32 - color: hifi.colors.hifiBlue - y: (listView.currentItem) ? listView.currentItem.y : 0; - x: (listView.currentItem) ? listView.currentItem.height : 0; - Behavior on y { - NumberAnimation { - duration: 100 - easing.type: Easing.InOutQuint - } - } - } - - model: root.models[menuDepth] - delegate: Loader { - id: loader - sourceComponent: root.itemBuilder - Binding { - target: loader.item - property: "root" - value: root - when: loader.status == Loader.Ready - } - Binding { - target: loader.item - property: "source" - value: modelData - when: loader.status == Loader.Ready - } - Binding { - target: loader.item - property: "border" - value: listView.parent - when: loader.status == Loader.Ready - } - Binding { - target: loader.item - property: "listView" - value: listView - when: loader.status == Loader.Ready - } } } } } property var itemBuilder: Component { - Text { - id: thisText - x: height + Item { property var source property var root property var listView property var border - text: typedText() - height: implicitHeight - width: implicitWidth - color: source.enabled ? hifi.colors.text : hifi.colors.disabledText - enabled: source.enabled && source.visible + implicitHeight: row.implicitHeight + 4 + implicitWidth: row.implicitWidth + label.height // FIXME uncommenting this line results in menus that have blank spots // rather than having the correct size // visible: source.visible - - onListViewChanged: { - if (listView) { - listView.minWidth = Math.max(listView.minWidth, implicitWidth + 64); - listView.recalculateSize(); + Row { + id: row + spacing: 4 + anchors { + top: parent.top + topMargin: 2 } - } + FontAwesome { + id: check + size: label.height + text: checkText() + color: label.color + function checkText() { + if (!source || source.type != 1 || !source.checkable) { + return ""; + } - onImplicitWidthChanged: { - if (listView) { - listView.minWidth = Math.max(listView.minWidth, implicitWidth + 64); - listView.recalculateSize(); - } - } - - FontAwesome { - visible: source.type == 1 && source.checkable - x: -parent.height - size: parent.height - text: checkText(); - color: parent.color - function checkText() { - if (!source || source.type != 1) { - return ""; - } - // FIXME this works for native QML menus but I don't think it will - // for proxied QML menus - if (source.exclusiveGroup) { - return source.checked ? "\uF05D" : "\uF10C" - } - return source.checked ? "\uF046" : "\uF096" - } - } - - FontAwesome { - size: parent.height - visible: source.type == 2 - x: listView.width - 32 - (hifi.layout.spacing * 2) - text: "\uF0DA" - color: parent.color - } - - function typedText() { - if (source) { - switch(source.type) { - case 2: - return source.title; - case 1: - return source.text; - case 0: - return "-----" + // FIXME this works for native QML menus but I don't think it will + // for proxied QML menus + if (source.exclusiveGroup) { + return source.checked ? "\uF05D" : "\uF10C" + } + return source.checked ? "\uF046" : "\uF096" } } - return "" - } + Text { + id: label + text: typedText() + color: source.enabled ? hifi.colors.text : hifi.colors.disabledText + enabled: source.enabled && source.visible + function typedText() { + if (source) { + switch(source.type) { + case 2: + return source.title; + case 1: + return source.text; + case 0: + return "-----" + } + } + return "" + } + } + } // row + + FontAwesome { + anchors { + top: row.top + } + id: tag + size: label.height + width: implicitWidth + visible: source.type == 2 + x: listView.width - width - 4 + text: "\uF0DA" + color: label.color + } - MouseArea { - id: mouseArea - acceptedButtons: Qt.LeftButton - anchors.left: parent.left - anchors.leftMargin: -32 - anchors.bottom: parent.bottom - anchors.bottomMargin: 0 - anchors.top: parent.top - anchors.topMargin: 0 - width: listView.width - hoverEnabled: true - Timer { - id: timer - interval: 1000 - onTriggered: parent.select(); - } - /* - * Uncomment below to have menus auto-popup - * - * FIXME if we enabled timer based menu popup, either the timer has - * to be very very short or after auto popup there has to be a small - * amount of time, or a test if the mouse has moved before a click - * will be accepted, otherwise it's too easy to accidently click on - * something immediately after the auto-popup appears underneath your - * cursor - * - */ - //onEntered: { - // if (source.type == 2 && enabled) { - // timer.start() - // } - //} - //onExited: { - // timer.stop() - //} - onClicked: { - select(); - } - function select() { - timer.stop(); - var popped = false; - while (columns.length - 1 > listView.parent.menuDepth) { - popColumn(); - popped = true; - } + MouseArea { + anchors { + top: parent.top + bottom: parent.bottom + left: parent.left + right: tag.right + } + acceptedButtons: Qt.LeftButton + hoverEnabled: true + Rectangle { + id: highlight + visible: false + anchors.fill: parent + color: "#7f0e7077" + } + Timer { + id: timer + interval: 1000 + onTriggered: parent.select(); + } + onEntered: { + /* + * Uncomment below to have menus auto-popup + * + * FIXME if we enabled timer based menu popup, either the timer has + * to be very very short or after auto popup there has to be a small + * amount of time, or a test if the mouse has moved before a click + * will be accepted, otherwise it's too easy to accidently click on + * something immediately after the auto-popup appears underneath your + * cursor + * + */ + //if (source.type == 2 && enabled) { + // timer.start() + //} + highlight.visible = source.enabled + } + onExited: { + timer.stop() + highlight.visible = false + } + onClicked: { + select(); + } + function select() { + //timer.stop(); + var popped = false; + while (columns.length - 1 > listView.parent.menuDepth) { + popColumn(); + popped = true; + } - if (!popped || source.type != 1) { - parent.root.selectItem(parent.source); - } + if (!popped || source.type != 1) { + parent.root.selectItem(parent.source); + } } } }