mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 23:01:47 +02:00
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
This commit is contained in:
parent
3c61727a22
commit
2cf0e1ab25
8 changed files with 80 additions and 28 deletions
|
@ -1002,8 +1002,13 @@ float EntityItem::getRadius() const {
|
||||||
return 0.5f * glm::length(_dimensions);
|
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());
|
info.setParams(getShapeType(), 0.5f * getDimensions());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const float MIN_POSITION_DELTA = 0.0001f;
|
const float MIN_POSITION_DELTA = 0.0001f;
|
||||||
|
|
|
@ -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
|
/// 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
|
/// 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.
|
/// 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;
|
friend class EntityTreeElement;
|
||||||
public:
|
public:
|
||||||
enum EntityDirtyFlags {
|
enum EntityDirtyFlags {
|
||||||
|
@ -256,7 +258,7 @@ public:
|
||||||
|
|
||||||
virtual bool contains(const glm::vec3& point) const { return getAABox().contains(point); }
|
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 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)
|
/// return preferred shape type (actual physical shape may differ)
|
||||||
virtual ShapeType getShapeType() const { return SHAPE_TYPE_NONE; }
|
virtual ShapeType getShapeType() const { return SHAPE_TYPE_NONE; }
|
||||||
|
@ -295,6 +297,10 @@ public:
|
||||||
static void setSendPhysicsUpdates(bool value) { _sendPhysicsUpdates = value; }
|
static void setSendPhysicsUpdates(bool value) { _sendPhysicsUpdates = value; }
|
||||||
static bool getSendPhysicsUpdates() { return _sendPhysicsUpdates; }
|
static bool getSendPhysicsUpdates() { return _sendPhysicsUpdates; }
|
||||||
|
|
||||||
|
virtual void getReadyToComputeShape();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void entityShapeReady(QUuid entityId) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,9 @@ public:
|
||||||
signals:
|
signals:
|
||||||
void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
|
void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
// virtual void entityShapeComputed(QUuid entityId) { }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// These pure virtual methods are protected because they are not to be called will-nilly. The base class
|
// These pure virtual methods are protected because they are not to be called will-nilly. The base class
|
||||||
|
|
|
@ -32,7 +32,7 @@ LightEntityItem::LightEntityItem(const EntityItemID& entityItemID, const EntityI
|
||||||
_type = EntityTypes::Light;
|
_type = EntityTypes::Light;
|
||||||
|
|
||||||
// default property values
|
// default property values
|
||||||
const quint8 MAX_COLOR = 255;
|
// const quint8 MAX_COLOR = 255;
|
||||||
_color[RED_INDEX] = _color[GREEN_INDEX] = _color[BLUE_INDEX] = 0;
|
_color[RED_INDEX] = _color[GREEN_INDEX] = _color[BLUE_INDEX] = 0;
|
||||||
_intensity = 1.0f;
|
_intensity = 1.0f;
|
||||||
_exponent = 0.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_EXPONENT, float, _exponent);
|
||||||
READ_ENTITY_PROPERTY(PROP_CUTOFF, float, _cutoff);
|
READ_ENTITY_PROPERTY(PROP_CUTOFF, float, _cutoff);
|
||||||
|
|
||||||
|
(void) ignoredAttenuation; // suppress compiler warning
|
||||||
} else {
|
} else {
|
||||||
READ_ENTITY_PROPERTY(PROP_IS_SPOTLIGHT, bool, _isSpotlight);
|
READ_ENTITY_PROPERTY(PROP_IS_SPOTLIGHT, bool, _isSpotlight);
|
||||||
READ_ENTITY_PROPERTY_COLOR(PROP_COLOR, _color);
|
READ_ENTITY_PROPERTY_COLOR(PROP_COLOR, _color);
|
||||||
|
|
|
@ -413,17 +413,26 @@ QString ModelEntityItem::getAnimationSettings() const {
|
||||||
return jsonByteString;
|
return jsonByteString;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelEntityItem::computeShapeInfo(ShapeInfo& info) const {
|
|
||||||
|
|
||||||
if (_collisionModelURL != "") {
|
void ModelEntityItem::getReadyToComputeShape() {
|
||||||
QSharedPointer<NetworkGeometry> networkGeometry =
|
qDebug() << "ModelEntityItem::getReadyToComputeShape for " << getID().toString();
|
||||||
DependencyManager::get<GeometryCache>()->getGeometry (_collisionModelURL, QUrl(), false);
|
|
||||||
|
if (_collisionModelURL != "" && _collisionNetworkGeometry.isNull()) {
|
||||||
|
qDebug() << " yes";
|
||||||
|
// QSharedPointer<NetworkGeometry> networkGeometry =
|
||||||
|
_collisionNetworkGeometry = DependencyManager::get<GeometryCache>()->getGeometry (_collisionModelURL, QUrl(), false);
|
||||||
|
|
||||||
// XXX does this do an unneeded copy?
|
// XXX does this do an unneeded copy?
|
||||||
FBXGeometry _collisionModel = networkGeometry->getFBXGeometry();
|
// FBXGeometry _collisionModel = networkGeometry->getFBXGeometry();
|
||||||
|
FBXGeometry _collisionModel = _collisionNetworkGeometry->getFBXGeometry();
|
||||||
|
|
||||||
// connect(networkGeometry, loaded, this, collisionGeometryLoaded);
|
// 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);
|
||||||
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ public:
|
||||||
virtual bool needsToCallUpdate() const;
|
virtual bool needsToCallUpdate() const;
|
||||||
virtual void debugDump() const;
|
virtual void debugDump() const;
|
||||||
|
|
||||||
virtual void computeShapeInfo(ShapeInfo& info) const;
|
virtual void computeShapeInfo(ShapeInfo& info);
|
||||||
|
|
||||||
void updateShapeType(ShapeType type);
|
void updateShapeType(ShapeType type);
|
||||||
virtual ShapeType getShapeType() const {
|
virtual ShapeType getShapeType() const {
|
||||||
|
@ -132,6 +132,8 @@ public:
|
||||||
void setTextures(const QString& textures) { _textures = textures; }
|
void setTextures(const QString& textures) { _textures = textures; }
|
||||||
|
|
||||||
static void cleanupLoadedAnimations();
|
static void cleanupLoadedAnimations();
|
||||||
|
|
||||||
|
void getReadyToComputeShape();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
|
@ -59,25 +59,43 @@ void PhysicsEngine::updateEntitiesInternal(const quint64& now) {
|
||||||
void PhysicsEngine::addEntityInternal(EntityItem* entity) {
|
void PhysicsEngine::addEntityInternal(EntityItem* entity) {
|
||||||
assert(entity);
|
assert(entity);
|
||||||
void* physicsInfo = entity->getPhysicsInfo();
|
void* physicsInfo = entity->getPhysicsInfo();
|
||||||
if (!physicsInfo) {
|
if (!physicsInfo && !_busyComputingShape.contains(entity->getID())) {
|
||||||
ShapeInfo shapeInfo;
|
ShapeInfo shapeInfo;
|
||||||
entity->computeShapeInfo(shapeInfo);
|
|
||||||
btCollisionShape* shape = _shapeManager.getShape(shapeInfo);
|
|
||||||
if (shape) {
|
|
||||||
EntityMotionState* motionState = new EntityMotionState(entity);
|
|
||||||
entity->setPhysicsInfo(static_cast<void*>(motionState));
|
|
||||||
_entityMotionStates.insert(motionState);
|
|
||||||
addObject(shapeInfo, shape, motionState);
|
|
||||||
} else if (entity->isMoving()) {
|
|
||||||
EntityMotionState* motionState = new EntityMotionState(entity);
|
|
||||||
entity->setPhysicsInfo(static_cast<void*>(motionState));
|
|
||||||
_entityMotionStates.insert(motionState);
|
|
||||||
|
|
||||||
motionState->setKinematic(true, _numSubsteps);
|
qDebug() << "in addEntityInternal ID is" << entity->getID().toString();
|
||||||
_nonPhysicalKinematicObjects.insert(motionState);
|
|
||||||
// We failed to add the entity to the simulation. Probably because we couldn't create a shape for it.
|
QPointer<EntityItem> entityWptr(entity);
|
||||||
//qDebug() << "failed to add entity " << entity->getEntityItemID() << " to physics engine";
|
_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<EntityItem> 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<void*>(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";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,8 @@ typedef std::map<ContactKey, ContactInfo> ContactMap;
|
||||||
typedef std::pair<ContactKey, ContactInfo> ContactMapElement;
|
typedef std::pair<ContactKey, ContactInfo> ContactMapElement;
|
||||||
|
|
||||||
class PhysicsEngine : public EntitySimulation {
|
class PhysicsEngine : public EntitySimulation {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// TODO: find a good way to make this a non-static method
|
// TODO: find a good way to make this a non-static method
|
||||||
static uint32_t getNumSubsteps();
|
static uint32_t getNumSubsteps();
|
||||||
|
@ -90,6 +92,9 @@ public:
|
||||||
|
|
||||||
void setAvatarData(AvatarData *avatarData);
|
void setAvatarData(AvatarData *avatarData);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void entityShapeReady(QUuid entityId);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// \param motionState pointer to Object's MotionState
|
/// \param motionState pointer to Object's MotionState
|
||||||
void removeObjectFromBullet(ObjectMotionState* motionState);
|
void removeObjectFromBullet(ObjectMotionState* motionState);
|
||||||
|
@ -126,6 +131,8 @@ private:
|
||||||
btCharacterControllerInterface* _characterController = 0;
|
btCharacterControllerInterface* _characterController = 0;
|
||||||
class btPairCachingGhostObject* _avatarGhostObject = 0;
|
class btPairCachingGhostObject* _avatarGhostObject = 0;
|
||||||
AvatarData *_avatarData = 0;
|
AvatarData *_avatarData = 0;
|
||||||
|
|
||||||
|
QMap<QUuid, QPointer<EntityItem>> _busyComputingShape;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_PhysicsEngine_h
|
#endif // hifi_PhysicsEngine_h
|
||||||
|
|
Loading…
Reference in a new issue