From 2cf0e1ab25ed0dc1e84429fe9076db02f64c3df2 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 12 Mar 2015 15:58:09 -0700 Subject: [PATCH] break PhysicsEngine::addEntityInternal in half, making the 2nd part asynch. This is to allow a ModelEntityItem time to download its collision hull before the 2nd part runs --- libraries/entities/src/EntityItem.cpp | 7 ++- libraries/entities/src/EntityItem.h | 10 ++++- libraries/entities/src/EntitySimulation.h | 3 ++ libraries/entities/src/LightEntityItem.cpp | 4 +- libraries/entities/src/ModelEntityItem.cpp | 21 ++++++--- libraries/entities/src/ModelEntityItem.h | 4 +- libraries/physics/src/PhysicsEngine.cpp | 52 +++++++++++++++------- libraries/physics/src/PhysicsEngine.h | 7 +++ 8 files changed, 80 insertions(+), 28 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 4f74438a45..abbd878659 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1002,8 +1002,13 @@ float EntityItem::getRadius() const { return 0.5f * glm::length(_dimensions); } -void EntityItem::computeShapeInfo(ShapeInfo& info) const { +void EntityItem::getReadyToComputeShape() { + emit entityShapeReady(getID()); +} + +void EntityItem::computeShapeInfo(ShapeInfo& info) { info.setParams(getShapeType(), 0.5f * getDimensions()); + } const float MIN_POSITION_DELTA = 0.0001f; diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 5193aa4490..8a58edd058 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -43,7 +43,9 @@ class EntityTreeElementExtraEncodeData; /// EntityItem class this is the base class for all entity types. It handles the basic properties and functionality available /// to all other entity types. In particular: postion, size, rotation, age, lifetime, velocity, gravity. You can not instantiate /// one directly, instead you must only construct one of it's derived classes with additional features. -class EntityItem { +class EntityItem : public QObject { + Q_OBJECT + friend class EntityTreeElement; public: enum EntityDirtyFlags { @@ -256,7 +258,7 @@ public: virtual bool contains(const glm::vec3& point) const { return getAABox().contains(point); } virtual bool containsInDomainUnits(const glm::vec3& point) const { return getAABoxInDomainUnits().contains(point); } - virtual void computeShapeInfo(ShapeInfo& info) const; + virtual void computeShapeInfo(ShapeInfo& info); /// return preferred shape type (actual physical shape may differ) virtual ShapeType getShapeType() const { return SHAPE_TYPE_NONE; } @@ -295,6 +297,10 @@ public: static void setSendPhysicsUpdates(bool value) { _sendPhysicsUpdates = value; } static bool getSendPhysicsUpdates() { return _sendPhysicsUpdates; } + virtual void getReadyToComputeShape(); + + signals: + void entityShapeReady(QUuid entityId) const; protected: diff --git a/libraries/entities/src/EntitySimulation.h b/libraries/entities/src/EntitySimulation.h index 1eb4fdc951..9540f7a766 100644 --- a/libraries/entities/src/EntitySimulation.h +++ b/libraries/entities/src/EntitySimulation.h @@ -66,6 +66,9 @@ public: signals: void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); +public slots: + // virtual void entityShapeComputed(QUuid entityId) { } + protected: // These pure virtual methods are protected because they are not to be called will-nilly. The base class diff --git a/libraries/entities/src/LightEntityItem.cpp b/libraries/entities/src/LightEntityItem.cpp index 3265891b18..80f38e7d4d 100644 --- a/libraries/entities/src/LightEntityItem.cpp +++ b/libraries/entities/src/LightEntityItem.cpp @@ -32,7 +32,7 @@ LightEntityItem::LightEntityItem(const EntityItemID& entityItemID, const EntityI _type = EntityTypes::Light; // default property values - const quint8 MAX_COLOR = 255; + // const quint8 MAX_COLOR = 255; _color[RED_INDEX] = _color[GREEN_INDEX] = _color[BLUE_INDEX] = 0; _intensity = 1.0f; _exponent = 0.0f; @@ -112,6 +112,8 @@ int LightEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, READ_ENTITY_PROPERTY(PROP_EXPONENT, float, _exponent); READ_ENTITY_PROPERTY(PROP_CUTOFF, float, _cutoff); + + (void) ignoredAttenuation; // suppress compiler warning } else { READ_ENTITY_PROPERTY(PROP_IS_SPOTLIGHT, bool, _isSpotlight); READ_ENTITY_PROPERTY_COLOR(PROP_COLOR, _color); diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 1d9dc0dc87..0f9f9fd6fd 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -413,17 +413,26 @@ QString ModelEntityItem::getAnimationSettings() const { return jsonByteString; } -void ModelEntityItem::computeShapeInfo(ShapeInfo& info) const { - if (_collisionModelURL != "") { - QSharedPointer networkGeometry = - DependencyManager::get()->getGeometry (_collisionModelURL, QUrl(), false); +void ModelEntityItem::getReadyToComputeShape() { + qDebug() << "ModelEntityItem::getReadyToComputeShape for " << getID().toString(); + + if (_collisionModelURL != "" && _collisionNetworkGeometry.isNull()) { + qDebug() << " yes"; + // QSharedPointer networkGeometry = + _collisionNetworkGeometry = DependencyManager::get()->getGeometry (_collisionModelURL, QUrl(), false); // XXX does this do an unneeded copy? - FBXGeometry _collisionModel = networkGeometry->getFBXGeometry(); + // FBXGeometry _collisionModel = networkGeometry->getFBXGeometry(); + FBXGeometry _collisionModel = _collisionNetworkGeometry->getFBXGeometry(); // connect(networkGeometry, loaded, this, collisionGeometryLoaded); - info.setParams(getShapeType(), 0.5f * getDimensions(), NULL, _collisionModelURL); + emit entityShapeReady(getID()); } } + +void ModelEntityItem::computeShapeInfo(ShapeInfo& info) { + qDebug() << "ModelEntityItem::computeShapeInfo for " << getID().toString(); + info.setParams(getShapeType(), 0.5f * getDimensions(), NULL, _collisionModelURL); +} diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index 516ecbf1c8..4252bbd378 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -51,7 +51,7 @@ public: virtual bool needsToCallUpdate() const; virtual void debugDump() const; - virtual void computeShapeInfo(ShapeInfo& info) const; + virtual void computeShapeInfo(ShapeInfo& info); void updateShapeType(ShapeType type); virtual ShapeType getShapeType() const { @@ -132,6 +132,8 @@ public: void setTextures(const QString& textures) { _textures = textures; } static void cleanupLoadedAnimations(); + + void getReadyToComputeShape(); protected: diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 634c3707a8..d5d832874b 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -59,25 +59,43 @@ void PhysicsEngine::updateEntitiesInternal(const quint64& now) { void PhysicsEngine::addEntityInternal(EntityItem* entity) { assert(entity); void* physicsInfo = entity->getPhysicsInfo(); - if (!physicsInfo) { + if (!physicsInfo && !_busyComputingShape.contains(entity->getID())) { ShapeInfo shapeInfo; - entity->computeShapeInfo(shapeInfo); - btCollisionShape* shape = _shapeManager.getShape(shapeInfo); - if (shape) { - EntityMotionState* motionState = new EntityMotionState(entity); - entity->setPhysicsInfo(static_cast(motionState)); - _entityMotionStates.insert(motionState); - addObject(shapeInfo, shape, motionState); - } else if (entity->isMoving()) { - EntityMotionState* motionState = new EntityMotionState(entity); - entity->setPhysicsInfo(static_cast(motionState)); - _entityMotionStates.insert(motionState); - motionState->setKinematic(true, _numSubsteps); - _nonPhysicalKinematicObjects.insert(motionState); - // We failed to add the entity to the simulation. Probably because we couldn't create a shape for it. - //qDebug() << "failed to add entity " << entity->getEntityItemID() << " to physics engine"; - } + qDebug() << "in addEntityInternal ID is" << entity->getID().toString(); + + QPointer entityWptr(entity); + _busyComputingShape[entity->getID()] = entityWptr; + connect(entity, SIGNAL(entityShapeReady(QUuid)), this, SLOT(entityShapeReady(QUuid))); + entity->getReadyToComputeShape(); + } +} + +void PhysicsEngine::entityShapeReady(QUuid entityId) { + + qDebug() << "PhysicsEngine::entityShapeReady for" << entityId.toString(); + + QPointer entityPtr = _busyComputingShape[entityId]; + _busyComputingShape.remove(entityId); + + EntityItem &entity = *entityPtr; + + ShapeInfo shapeInfo; + entity.computeShapeInfo(shapeInfo); + + btCollisionShape* shape = _shapeManager.getShape(shapeInfo); + + EntityMotionState* motionState = new EntityMotionState(&entity); + entity.setPhysicsInfo(static_cast(motionState)); + _entityMotionStates.insert(motionState); + + if (shape) { + addObject(shapeInfo, shape, motionState); + } else if (entity.isMoving()) { + motionState->setKinematic(true, _numSubsteps); + _nonPhysicalKinematicObjects.insert(motionState); + // We failed to add the entity to the simulation. Probably because we couldn't create a shape for it. + //qDebug() << "failed to add entity " << entity.getEntityItemID() << " to physics engine"; } } diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index 649aec2755..924125371f 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -51,6 +51,8 @@ typedef std::map ContactMap; typedef std::pair ContactMapElement; class PhysicsEngine : public EntitySimulation { + Q_OBJECT + public: // TODO: find a good way to make this a non-static method static uint32_t getNumSubsteps(); @@ -90,6 +92,9 @@ public: void setAvatarData(AvatarData *avatarData); +public slots: + void entityShapeReady(QUuid entityId); + private: /// \param motionState pointer to Object's MotionState void removeObjectFromBullet(ObjectMotionState* motionState); @@ -126,6 +131,8 @@ private: btCharacterControllerInterface* _characterController = 0; class btPairCachingGhostObject* _avatarGhostObject = 0; AvatarData *_avatarData = 0; + + QMap> _busyComputingShape; }; #endif // hifi_PhysicsEngine_h