mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 10:33:10 +02:00
attempting to figure out why physics motion object doesn't get updated when collision model url changes
This commit is contained in:
parent
bb8c83d49a
commit
6e3be26013
16 changed files with 172 additions and 40 deletions
|
@ -22,6 +22,7 @@
|
|||
#include "EntityTreeRenderer.h"
|
||||
#include "RenderableModelEntityItem.h"
|
||||
|
||||
|
||||
EntityItem* RenderableModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return new RenderableModelEntityItem(entityID, properties);
|
||||
}
|
||||
|
@ -266,6 +267,50 @@ bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& ori
|
|||
return _model->findRayIntersectionAgainstSubMeshes(origin, direction, distance, face, extraInfo, precisionPicking);
|
||||
}
|
||||
|
||||
// void RenderableModelEntityItem::setCollisionModelURL(const QString& url) {
|
||||
|
||||
// // XXX PhysicsEngine::entityChangedInternal(this);
|
||||
// // EntityTree* x = this->getElement()->_myTree;
|
||||
// // EntityTreeRenderer* _myRenderer;
|
||||
|
||||
// qDebug() << "--------------------------------";
|
||||
// this->ModelEntityItem::setCollisionModelURL(url);
|
||||
|
||||
// if ((_dirtyFlags & (EntityItem::DIRTY_SHAPE | EntityItem::DIRTY_MASS)) ==
|
||||
// (EntityItem::DIRTY_SHAPE | EntityItem::DIRTY_MASS)) {
|
||||
|
||||
// EntityTreeElement* element = this->getElement();
|
||||
// if (element) {
|
||||
// qDebug() << "element =" << element;
|
||||
// EntityTree* tree = element->getTree();
|
||||
// qDebug() << "tree =" << tree;
|
||||
// tree->reconfigureEntity(this);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
void RenderableModelEntityItem::setCollisionModelURL(const QString& url) {
|
||||
ModelEntityItem::setCollisionModelURL(url);
|
||||
_model->setCollisionModelURL(QUrl(url));
|
||||
}
|
||||
|
||||
|
||||
bool RenderableModelEntityItem::hasCollisionModel() const {
|
||||
// return !_collisionModelURL.isEmpty();
|
||||
return ! _model->getCollisionURL().isEmpty();
|
||||
}
|
||||
|
||||
|
||||
const QString& RenderableModelEntityItem::getCollisionModelURL() const {
|
||||
// return _collisionModelURL;
|
||||
_collisionModelURL = _model->getCollisionURL().toString();
|
||||
return _collisionModelURL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void RenderableModelEntityItem::updateDimensions(const glm::vec3& value) {
|
||||
if (glm::distance(_dimensions, value) > MIN_DIMENSIONS_DELTA) {
|
||||
_dimensions = value;
|
||||
|
@ -288,6 +333,7 @@ bool RenderableModelEntityItem::isReadyToComputeShape() {
|
|||
const QSharedPointer<NetworkGeometry> collisionNetworkGeometry = _model->getCollisionGeometry();
|
||||
if (! collisionNetworkGeometry.isNull() && collisionNetworkGeometry->isLoadedWithTextures()) {
|
||||
// we have a _collisionModelURL AND a collisionNetworkGeometry AND it's fully loaded.
|
||||
// _dirtyFlags |= (EntityItem::DIRTY_SHAPE | EntityItem::DIRTY_MASS);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -296,9 +342,12 @@ bool RenderableModelEntityItem::isReadyToComputeShape() {
|
|||
}
|
||||
|
||||
void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||
qDebug() << "RenderableModelEntityItem::computeShapeInfo";
|
||||
if (_model->getCollisionURL().isEmpty()) {
|
||||
qDebug() << " _model->getCollisionURL().isEmpty()";
|
||||
info.setParams(getShapeType(), 0.5f * getDimensions());
|
||||
} else {
|
||||
qDebug() << " _model->getCollisionURL() wasn't empty.";
|
||||
const QSharedPointer<NetworkGeometry> collisionNetworkGeometry = _model->getCollisionGeometry();
|
||||
const FBXGeometry& fbxGeometry = collisionNetworkGeometry->getFBXGeometry();
|
||||
|
||||
|
|
|
@ -49,9 +49,15 @@ public:
|
|||
void** intersectedObject, bool precisionPicking) const;
|
||||
|
||||
Model* getModel(EntityTreeRenderer* renderer);
|
||||
// virtual void setCollisionModelURL(const QString& url);
|
||||
|
||||
bool needsToCallUpdate() const;
|
||||
|
||||
virtual void setCollisionModelURL(const QString& url);
|
||||
virtual bool hasCollisionModel() const;
|
||||
virtual const QString& getCollisionModelURL() const;
|
||||
|
||||
|
||||
virtual void updateDimensions(const glm::vec3& value);
|
||||
|
||||
bool isReadyToComputeShape();
|
||||
|
|
|
@ -126,11 +126,11 @@ void EntitySimulation::addEntity(EntityItem* entity) {
|
|||
if (entity->needsToCallUpdate()) {
|
||||
_updateableEntities.insert(entity);
|
||||
}
|
||||
addEntityInternal(entity);
|
||||
|
||||
// DirtyFlags are used to signal changes to entities that have already been added,
|
||||
// so we can clear them for this entity which has just been added.
|
||||
entity->clearDirtyFlags();
|
||||
if (addEntityInternal(entity)) {
|
||||
// DirtyFlags are used to signal changes to entities that have already been added,
|
||||
// so we can clear them for this entity which has just been added.
|
||||
entity->clearDirtyFlags();
|
||||
}
|
||||
}
|
||||
|
||||
void EntitySimulation::removeEntity(EntityItem* entity) {
|
||||
|
|
|
@ -63,6 +63,10 @@ public:
|
|||
|
||||
EntityTree* getEntityTree() { return _entityTree; }
|
||||
|
||||
/* virtual void reconfigureEntity(EntityItem* entity) { */
|
||||
/* qDebug() << "EntitySimulation::reconfigureEntity"; */
|
||||
/* } */
|
||||
|
||||
signals:
|
||||
void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
|
||||
|
||||
|
@ -74,7 +78,7 @@ protected:
|
|||
// NOTE: updateEntitiesInternal() should clear all dirty flags on each changed entity as side effect
|
||||
virtual void updateEntitiesInternal(const quint64& now) = 0;
|
||||
|
||||
virtual void addEntityInternal(EntityItem* entity) = 0;
|
||||
virtual bool addEntityInternal(EntityItem* entity) = 0;
|
||||
|
||||
virtual void removeEntityInternal(EntityItem* entity) = 0;
|
||||
|
||||
|
|
|
@ -315,6 +315,12 @@ void EntityTree::deleteEntities(QSet<EntityItemID> entityIDs, bool force, bool i
|
|||
}
|
||||
}
|
||||
|
||||
void EntityTree::reconfigureEntity(EntityItem* entity) {
|
||||
qDebug() << "EntityTree::reconfigureEntity";
|
||||
// _simulation->reconfigureEntity(entity);
|
||||
_simulation->entityChanged(entity);
|
||||
}
|
||||
|
||||
void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator) {
|
||||
const RemovedEntities& entities = theOperator.getEntities();
|
||||
if (_simulation) {
|
||||
|
|
|
@ -95,7 +95,8 @@ public:
|
|||
|
||||
void deleteEntity(const EntityItemID& entityID, bool force = false, bool ignoreWarnings = false);
|
||||
void deleteEntities(QSet<EntityItemID> entityIDs, bool force = false, bool ignoreWarnings = false);
|
||||
void removeEntityFromSimulation(EntityItem* entity);
|
||||
// void removeEntityFromSimulation(EntityItem* entity);
|
||||
void reconfigureEntity(EntityItem* entity);
|
||||
|
||||
/// \param position point of query in world-frame (meters)
|
||||
/// \param targetRadius radius of query (meters)
|
||||
|
@ -161,6 +162,7 @@ public:
|
|||
void emitEntityScriptChanging(const EntityItemID& entityItemID);
|
||||
|
||||
void setSimulation(EntitySimulation* simulation);
|
||||
EntitySimulation* getSimulation() { return _simulation; }
|
||||
|
||||
bool wantEditLogging() const { return _wantEditLogging; }
|
||||
void setWantEditLogging(bool value) { _wantEditLogging = value; }
|
||||
|
|
|
@ -147,6 +147,7 @@ public:
|
|||
bool hasEntities() const { return _entityItems ? _entityItems->size() > 0 : false; }
|
||||
|
||||
void setTree(EntityTree* tree) { _myTree = tree; }
|
||||
EntityTree* getTree() { return _myTree; }
|
||||
|
||||
bool updateEntity(const EntityItem& entity);
|
||||
void addEntityItem(EntityItem* entity);
|
||||
|
|
|
@ -74,7 +74,7 @@ bool ModelEntityItem::setProperties(const EntityItemProperties& properties) {
|
|||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(shapeType, updateShapeType);
|
||||
|
||||
if (somethingChanged) {
|
||||
bool wantDebug = false;
|
||||
bool wantDebug = true;
|
||||
if (wantDebug) {
|
||||
uint64_t now = usecTimestampNow();
|
||||
int elapsed = now - getLastEdited();
|
||||
|
@ -281,6 +281,18 @@ void ModelEntityItem::updateShapeType(ShapeType type) {
|
|||
}
|
||||
}
|
||||
|
||||
void ModelEntityItem::setCollisionModelURL(const QString& url)
|
||||
{
|
||||
if (_collisionModelURL != url) {
|
||||
|
||||
qDebug() << "\n\n----";
|
||||
qDebug() << "ModelEntityItem::setCollisionModelURL";
|
||||
|
||||
_collisionModelURL = url;
|
||||
_dirtyFlags |= EntityItem::DIRTY_SHAPE | EntityItem::DIRTY_MASS;
|
||||
}
|
||||
}
|
||||
|
||||
void ModelEntityItem::setAnimationURL(const QString& url) {
|
||||
_dirtyFlags |= EntityItem::DIRTY_UPDATEABLE;
|
||||
_animationURL = url;
|
||||
|
|
|
@ -57,13 +57,13 @@ public:
|
|||
const rgbColor& getColor() const { return _color; }
|
||||
xColor getXColor() const { xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color; }
|
||||
bool hasModel() const { return !_modelURL.isEmpty(); }
|
||||
bool hasCollisionModel() const { return !_collisionModelURL.isEmpty(); }
|
||||
virtual bool hasCollisionModel() const { return !_collisionModelURL.isEmpty(); }
|
||||
|
||||
static const QString DEFAULT_MODEL_URL;
|
||||
const QString& getModelURL() const { return _modelURL; }
|
||||
|
||||
static const QString DEFAULT_COLLISION_MODEL_URL;
|
||||
const QString& getCollisionModelURL() const { return _collisionModelURL; }
|
||||
virtual const QString& getCollisionModelURL() const { return _collisionModelURL; }
|
||||
|
||||
bool hasAnimation() const { return !_animationURL.isEmpty(); }
|
||||
static const QString DEFAULT_ANIMATION_URL;
|
||||
|
@ -78,7 +78,7 @@ public:
|
|||
|
||||
// model related properties
|
||||
void setModelURL(const QString& url) { _modelURL = url; }
|
||||
void setCollisionModelURL(const QString& url) { _collisionModelURL = url; }
|
||||
virtual void setCollisionModelURL(const QString& url);
|
||||
void setAnimationURL(const QString& url);
|
||||
static const float DEFAULT_ANIMATION_FRAME_INDEX;
|
||||
void setAnimationFrameIndex(float value);
|
||||
|
|
|
@ -29,12 +29,13 @@ void SimpleEntitySimulation::updateEntitiesInternal(const quint64& now) {
|
|||
}
|
||||
}
|
||||
|
||||
void SimpleEntitySimulation::addEntityInternal(EntityItem* entity) {
|
||||
bool SimpleEntitySimulation::addEntityInternal(EntityItem* entity) {
|
||||
if (entity->isMoving()) {
|
||||
_movingEntities.insert(entity);
|
||||
} else if (entity->getCollisionsWillMove()) {
|
||||
_movableButStoppedEntities.insert(entity);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SimpleEntitySimulation::removeEntityInternal(EntityItem* entity) {
|
||||
|
|
|
@ -23,7 +23,7 @@ public:
|
|||
|
||||
protected:
|
||||
virtual void updateEntitiesInternal(const quint64& now);
|
||||
virtual void addEntityInternal(EntityItem* entity);
|
||||
virtual bool addEntityInternal(EntityItem* entity);
|
||||
virtual void removeEntityInternal(EntityItem* entity);
|
||||
virtual void entityChangedInternal(EntityItem* entity);
|
||||
virtual void clearEntitiesInternal();
|
||||
|
|
|
@ -168,8 +168,12 @@ void EntityMotionState::updateObjectVelocities() {
|
|||
}
|
||||
}
|
||||
|
||||
void EntityMotionState::computeShapeInfo(ShapeInfo& shapeInfo) {
|
||||
_entity->computeShapeInfo(shapeInfo);
|
||||
bool EntityMotionState::computeShapeInfo(ShapeInfo& shapeInfo) {
|
||||
if (_entity->isReadyToComputeShape()) {
|
||||
_entity->computeShapeInfo(shapeInfo);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
float EntityMotionState::computeMass(const ShapeInfo& shapeInfo) const {
|
||||
|
|
|
@ -53,7 +53,7 @@ public:
|
|||
virtual void updateObjectEasy(uint32_t flags, uint32_t frame);
|
||||
virtual void updateObjectVelocities();
|
||||
|
||||
virtual void computeShapeInfo(ShapeInfo& shapeInfo);
|
||||
virtual bool computeShapeInfo(ShapeInfo& shapeInfo);
|
||||
virtual float computeMass(const ShapeInfo& shapeInfo) const;
|
||||
|
||||
virtual void sendUpdate(OctreeEditPacketSender* packetSender, uint32_t frame);
|
||||
|
|
|
@ -67,7 +67,7 @@ public:
|
|||
MotionStateType getType() const { return _type; }
|
||||
virtual MotionType getMotionType() const { return _motionType; }
|
||||
|
||||
virtual void computeShapeInfo(ShapeInfo& info) = 0;
|
||||
virtual bool computeShapeInfo(ShapeInfo& info) = 0;
|
||||
virtual float computeMass(const ShapeInfo& shapeInfo) const = 0;
|
||||
|
||||
void setFriction(float friction);
|
||||
|
|
|
@ -58,31 +58,49 @@ void PhysicsEngine::updateEntitiesInternal(const quint64& now) {
|
|||
}
|
||||
}
|
||||
|
||||
void PhysicsEngine::addEntityInternal(EntityItem* entity) {
|
||||
bool PhysicsEngine::addEntityInternal(EntityItem* entity) {
|
||||
|
||||
qDebug() << "PhysicsEngine::addEntityInternal";
|
||||
|
||||
assert(entity);
|
||||
void* physicsInfo = entity->getPhysicsInfo();
|
||||
if (!physicsInfo) {
|
||||
if (entity->isReadyToComputeShape()) {
|
||||
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() << " PhysicsEngine::addEntityInternal no physicsInfo";
|
||||
if (! entity->isReadyToComputeShape()) {
|
||||
qDebug() << " PhysicsEngine::addEntityInternal not ready to compute";
|
||||
return false;
|
||||
}
|
||||
qDebug() << " PhysicsEngine::addEntityInternal ready to compute";
|
||||
ShapeInfo shapeInfo;
|
||||
entity->computeShapeInfo(shapeInfo);
|
||||
|
||||
DoubleHashKey hkey = shapeInfo.getHash();
|
||||
qDebug() << " shapeInfo hash:" << hkey.getHash() << hkey.getHash2();
|
||||
|
||||
btCollisionShape* shape = _shapeManager.getShape(shapeInfo);
|
||||
if (shape) {
|
||||
qDebug() << " got a shape";
|
||||
EntityMotionState* motionState = new EntityMotionState(entity);
|
||||
entity->setPhysicsInfo(static_cast<void*>(motionState));
|
||||
_entityMotionStates.insert(motionState);
|
||||
addObject(shapeInfo, shape, motionState);
|
||||
} else if (entity->isMoving()) {
|
||||
qDebug() << " no shape but is moving";
|
||||
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";
|
||||
} else {
|
||||
qDebug() << " no shape and not moving";
|
||||
}
|
||||
} else {
|
||||
qDebug() << " PhysicsEngine::addEntityInternal already had physicsInfo";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void PhysicsEngine::removeEntityInternal(EntityItem* entity) {
|
||||
|
@ -105,18 +123,28 @@ void PhysicsEngine::removeEntityInternal(EntityItem* entity) {
|
|||
}
|
||||
|
||||
void PhysicsEngine::entityChangedInternal(EntityItem* entity) {
|
||||
|
||||
qDebug() << "PhysicsEngine::entityChangedInternal";
|
||||
|
||||
// queue incoming changes: from external sources (script, EntityServer, etc) to physics engine
|
||||
assert(entity);
|
||||
void* physicsInfo = entity->getPhysicsInfo();
|
||||
if (physicsInfo) {
|
||||
qDebug() << " PhysicsEngine::entityChangedInternal had physicsInfo";
|
||||
ObjectMotionState* motionState = static_cast<ObjectMotionState*>(physicsInfo);
|
||||
_incomingChanges.insert(motionState);
|
||||
} else {
|
||||
qDebug() << " PhysicsEngine::entityChangedInternal had no physicsInfo";
|
||||
// try to add this entity again (maybe something changed such that it will work this time)
|
||||
addEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
// void PhysicsEngine::reconfigureEntity(EntityItem* entity) {
|
||||
// qDebug() << "PhysicsEngine::reconfigureEntity";
|
||||
// entityChangedInternal(entity);
|
||||
// }
|
||||
|
||||
void PhysicsEngine::sortEntitiesThatMovedInternal() {
|
||||
// entities that have been simulated forward (hence in the _entitiesToBeSorted list)
|
||||
// also need to be put in the outgoingPackets list
|
||||
|
@ -509,8 +537,20 @@ bool PhysicsEngine::updateObjectHard(btRigidBody* body, ObjectMotionState* motio
|
|||
// get new shape
|
||||
btCollisionShape* oldShape = body->getCollisionShape();
|
||||
ShapeInfo shapeInfo;
|
||||
motionState->computeShapeInfo(shapeInfo);
|
||||
|
||||
|
||||
bool computeShapeInfoResult = motionState->computeShapeInfo(shapeInfo);
|
||||
qDebug() << "\n\n---";
|
||||
qDebug() << "PhysicsEngine::updateObjectHard #1 computeShapeInfoResult =" << computeShapeInfoResult;
|
||||
|
||||
|
||||
btCollisionShape* newShape = _shapeManager.getShape(shapeInfo);
|
||||
|
||||
DoubleHashKey hkey = shapeInfo.getHash();
|
||||
qDebug() << " shapeInfo hash:" << hkey.getHash() << hkey.getHash2();
|
||||
qDebug() << " newShape =" << newShape;
|
||||
|
||||
|
||||
if (!newShape) {
|
||||
// FAIL! we are unable to support these changes!
|
||||
_shapeManager.releaseShape(oldShape);
|
||||
|
@ -563,7 +603,12 @@ bool PhysicsEngine::updateObjectHard(btRigidBody* body, ObjectMotionState* motio
|
|||
if (! (flags & EntityItem::DIRTY_MASS)) {
|
||||
// always update mass properties when going dynamic (unless it's already been done above)
|
||||
ShapeInfo shapeInfo;
|
||||
motionState->computeShapeInfo(shapeInfo);
|
||||
bool computeShapeInfoResult = motionState->computeShapeInfo(shapeInfo);
|
||||
|
||||
qDebug() << "\n\n---";
|
||||
qDebug() << "PhysicsEngine::updateObjectHard #2 computeShapeInfoResult =" << computeShapeInfoResult;
|
||||
|
||||
|
||||
float mass = motionState->computeMass(shapeInfo);
|
||||
btVector3 inertia(0.0f, 0.0f, 0.0f);
|
||||
body->getCollisionShape()->calculateLocalInertia(mass, inertia);
|
||||
|
|
|
@ -60,7 +60,7 @@ public:
|
|||
|
||||
// overrides for EntitySimulation
|
||||
void updateEntitiesInternal(const quint64& now);
|
||||
void addEntityInternal(EntityItem* entity);
|
||||
bool addEntityInternal(EntityItem* entity);
|
||||
void removeEntityInternal(EntityItem* entity);
|
||||
void entityChangedInternal(EntityItem* entity);
|
||||
void sortEntitiesThatMovedInternal();
|
||||
|
@ -88,6 +88,8 @@ public:
|
|||
|
||||
void setAvatarData(AvatarData *avatarData);
|
||||
|
||||
// virtual void reconfigureEntity(EntityItem* entity);
|
||||
|
||||
private:
|
||||
/// \param motionState pointer to Object's MotionState
|
||||
void removeObjectFromBullet(ObjectMotionState* motionState);
|
||||
|
|
Loading…
Reference in a new issue