mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 08:24: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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -413,17 +413,26 @@ QString ModelEntityItem::getAnimationSettings() const {
|
|||
return jsonByteString;
|
||||
}
|
||||
|
||||
void ModelEntityItem::computeShapeInfo(ShapeInfo& info) const {
|
||||
|
||||
if (_collisionModelURL != "") {
|
||||
QSharedPointer<NetworkGeometry> networkGeometry =
|
||||
DependencyManager::get<GeometryCache>()->getGeometry (_collisionModelURL, QUrl(), false);
|
||||
void ModelEntityItem::getReadyToComputeShape() {
|
||||
qDebug() << "ModelEntityItem::getReadyToComputeShape for " << getID().toString();
|
||||
|
||||
if (_collisionModelURL != "" && _collisionNetworkGeometry.isNull()) {
|
||||
qDebug() << " yes";
|
||||
// QSharedPointer<NetworkGeometry> networkGeometry =
|
||||
_collisionNetworkGeometry = DependencyManager::get<GeometryCache>()->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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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<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);
|
||||
_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<EntityItem> 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<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;
|
||||
|
||||
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<QUuid, QPointer<EntityItem>> _busyComputingShape;
|
||||
};
|
||||
|
||||
#endif // hifi_PhysicsEngine_h
|
||||
|
|
Loading…
Reference in a new issue