mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 04:44:11 +02:00
Merge pull request #4471 from sethalves/avatars-can-collide
Avatars can collide redux
This commit is contained in:
commit
46fb9cd615
7 changed files with 52 additions and 33 deletions
|
@ -410,13 +410,30 @@ const Model* EntityTreeRenderer::getModelForEntityItem(const EntityItem* entityI
|
|||
if (entityItem->getType() == EntityTypes::Model) {
|
||||
const RenderableModelEntityItem* constModelEntityItem = dynamic_cast<const RenderableModelEntityItem*>(entityItem);
|
||||
RenderableModelEntityItem* modelEntityItem = const_cast<RenderableModelEntityItem*>(constModelEntityItem);
|
||||
assert(modelEntityItem); // we need this!!!
|
||||
|
||||
result = modelEntityItem->getModel(this);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const FBXGeometry* EntityTreeRenderer::getCollisionGeometryForEntity(const EntityItem* entityItem) {
|
||||
const FBXGeometry* result = NULL;
|
||||
|
||||
if (entityItem->getType() == EntityTypes::Model) {
|
||||
const RenderableModelEntityItem* constModelEntityItem = dynamic_cast<const RenderableModelEntityItem*>(entityItem);
|
||||
if (constModelEntityItem->hasCollisionModel()) {
|
||||
RenderableModelEntityItem* modelEntityItem = const_cast<RenderableModelEntityItem*>(constModelEntityItem);
|
||||
Model* model = modelEntityItem->getModel(this);
|
||||
if (model) {
|
||||
const QSharedPointer<NetworkGeometry> collisionNetworkGeometry = model->getCollisionGeometry();
|
||||
if (!collisionNetworkGeometry.isNull()) {
|
||||
result = &collisionNetworkGeometry->getFBXGeometry();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::renderElementProxy(EntityTreeElement* entityTreeElement) {
|
||||
glm::vec3 elementCenter = entityTreeElement->getAACube().calcCenter();
|
||||
float elementSize = entityTreeElement->getScale();
|
||||
|
@ -591,7 +608,7 @@ void EntityTreeRenderer::processEraseMessage(const QByteArray& dataByteArray, co
|
|||
static_cast<EntityTree*>(_tree)->processEraseMessage(dataByteArray, sourceNode);
|
||||
}
|
||||
|
||||
Model* EntityTreeRenderer::allocateModel(const QString& url) {
|
||||
Model* EntityTreeRenderer::allocateModel(const QString& url, const QString& collisionUrl) {
|
||||
Model* model = NULL;
|
||||
// Make sure we only create and delete models on the thread that owns the EntityTreeRenderer
|
||||
if (QThread::currentThread() != thread()) {
|
||||
|
@ -604,10 +621,11 @@ Model* EntityTreeRenderer::allocateModel(const QString& url) {
|
|||
model = new Model();
|
||||
model->init();
|
||||
model->setURL(QUrl(url));
|
||||
model->setCollisionModelURL(QUrl(collisionUrl));
|
||||
return model;
|
||||
}
|
||||
|
||||
Model* EntityTreeRenderer::updateModel(Model* original, const QString& newUrl) {
|
||||
Model* EntityTreeRenderer::updateModel(Model* original, const QString& newUrl, const QString& collisionUrl) {
|
||||
Model* model = NULL;
|
||||
|
||||
// The caller shouldn't call us if the URL doesn't need to change. But if they
|
||||
|
@ -636,6 +654,7 @@ Model* EntityTreeRenderer::updateModel(Model* original, const QString& newUrl) {
|
|||
model = new Model();
|
||||
model->init();
|
||||
model->setURL(QUrl(newUrl));
|
||||
model->setCollisionModelURL(QUrl(collisionUrl));
|
||||
|
||||
return model;
|
||||
}
|
||||
|
|
|
@ -59,15 +59,16 @@ public:
|
|||
|
||||
virtual const FBXGeometry* getGeometryForEntity(const EntityItem* entityItem);
|
||||
virtual const Model* getModelForEntityItem(const EntityItem* entityItem);
|
||||
virtual const FBXGeometry* getCollisionGeometryForEntity(const EntityItem* entityItem);
|
||||
|
||||
/// clears the tree
|
||||
virtual void clear();
|
||||
|
||||
/// if a renderable entity item needs a model, we will allocate it for them
|
||||
Q_INVOKABLE Model* allocateModel(const QString& url);
|
||||
Q_INVOKABLE Model* allocateModel(const QString& url, const QString& collisionUrl);
|
||||
|
||||
/// if a renderable entity item needs to update the URL of a model, we will handle that for the entity
|
||||
Q_INVOKABLE Model* updateModel(Model* original, const QString& newUrl);
|
||||
Q_INVOKABLE Model* updateModel(Model* original, const QString& newUrl, const QString& collisionUrl);
|
||||
|
||||
/// if a renderable entity item is done with a model, it should return it to us
|
||||
void releaseModel(Model* model);
|
||||
|
|
|
@ -223,10 +223,10 @@ Model* RenderableModelEntityItem::getModel(EntityTreeRenderer* renderer) {
|
|||
// if we have a previously allocated model, but it's URL doesn't match
|
||||
// then we need to let our renderer update our model for us.
|
||||
if (_model && QUrl(getModelURL()) != _model->getURL()) {
|
||||
result = _model = _myRenderer->updateModel(_model, getModelURL());
|
||||
result = _model = _myRenderer->updateModel(_model, getModelURL(), getCollisionModelURL());
|
||||
_needsInitialSimulation = true;
|
||||
} else if (!_model) { // if we don't yet have a model, then we want our renderer to allocate one
|
||||
result = _model = _myRenderer->allocateModel(getModelURL());
|
||||
result = _model = _myRenderer->allocateModel(getModelURL(), getCollisionModelURL());
|
||||
_needsInitialSimulation = true;
|
||||
} else { // we already have the model we want...
|
||||
result = _model;
|
||||
|
@ -267,36 +267,32 @@ bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& ori
|
|||
}
|
||||
|
||||
bool RenderableModelEntityItem::isReadyToComputeShape() {
|
||||
if (_collisionModelURL == "") {
|
||||
|
||||
if (!_model) {
|
||||
return false; // hmm...
|
||||
}
|
||||
|
||||
if (_model->getCollisionURL().isEmpty()) {
|
||||
// no model url, so we're ready to compute a shape.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (! _collisionNetworkGeometry.isNull() && _collisionNetworkGeometry->isLoadedWithTextures()) {
|
||||
// we have a _collisionModelURL AND a _collisionNetworkGeometry AND it's fully loaded.
|
||||
const QSharedPointer<NetworkGeometry> collisionNetworkGeometry = _model->getCollisionGeometry();
|
||||
if (! collisionNetworkGeometry.isNull() && collisionNetworkGeometry->isLoadedWithTextures()) {
|
||||
// we have a _collisionModelURL AND a collisionNetworkGeometry AND it's fully loaded.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_collisionNetworkGeometry.isNull()) {
|
||||
// we have a _collisionModelURL but we don't yet have a _collisionNetworkGeometry.
|
||||
_collisionNetworkGeometry =
|
||||
DependencyManager::get<GeometryCache>()->getGeometry(_collisionModelURL, QUrl(), false, false);
|
||||
|
||||
if (! _collisionNetworkGeometry.isNull() && _collisionNetworkGeometry->isLoadedWithTextures()) {
|
||||
// shortcut in case it's already loaded.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// the model is still being downloaded.
|
||||
return false;
|
||||
}
|
||||
|
||||
void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||
if (_collisionModelURL == "") {
|
||||
if (_model->getCollisionURL().isEmpty()) {
|
||||
info.setParams(getShapeType(), 0.5f * getDimensions());
|
||||
} else {
|
||||
const FBXGeometry& fbxGeometry = _collisionNetworkGeometry->getFBXGeometry();
|
||||
const QSharedPointer<NetworkGeometry> collisionNetworkGeometry = _model->getCollisionGeometry();
|
||||
const FBXGeometry& fbxGeometry = collisionNetworkGeometry->getFBXGeometry();
|
||||
|
||||
_points.clear();
|
||||
foreach (const FBXMesh& mesh, fbxGeometry.meshes) {
|
||||
|
@ -310,9 +306,9 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
|||
|
||||
ShapeType RenderableModelEntityItem::getShapeType() const {
|
||||
// XXX make hull an option in edit.js ?
|
||||
if (_collisionModelURL != "") {
|
||||
return SHAPE_TYPE_CONVEX_HULL;
|
||||
} else {
|
||||
if (!_model || _model->getCollisionURL().isEmpty()) {
|
||||
return _shapeType;
|
||||
} else {
|
||||
return SHAPE_TYPE_CONVEX_HULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,8 +30,7 @@ public:
|
|||
_needsInitialSimulation(true),
|
||||
_needsModelReload(true),
|
||||
_myRenderer(NULL),
|
||||
_originalTexturesRead(false),
|
||||
_collisionNetworkGeometry(QSharedPointer<NetworkGeometry>()) { }
|
||||
_originalTexturesRead(false) { }
|
||||
|
||||
virtual ~RenderableModelEntityItem();
|
||||
|
||||
|
@ -67,8 +66,6 @@ private:
|
|||
QString _currentTextures;
|
||||
QStringList _originalTextures;
|
||||
bool _originalTexturesRead;
|
||||
|
||||
QSharedPointer<NetworkGeometry> _collisionNetworkGeometry;
|
||||
QVector<glm::vec3> _points;
|
||||
};
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ class EntityItemFBXService {
|
|||
public:
|
||||
virtual const FBXGeometry* getGeometryForEntity(const EntityItem* entityItem) = 0;
|
||||
virtual const Model* getModelForEntityItem(const EntityItem* entityItem) = 0;
|
||||
virtual const FBXGeometry* getCollisionGeometryForEntity(const EntityItem* entityItem) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -298,6 +298,7 @@ void PhysicsEngine::stepSimulation() {
|
|||
_clock.reset();
|
||||
float timeStep = btMin(dt, MAX_TIMESTEP);
|
||||
|
||||
_avatarData->lockForRead();
|
||||
if (_avatarData->isPhysicsEnabled()) {
|
||||
// update character controller
|
||||
glm::quat rotation = _avatarData->getOrientation();
|
||||
|
@ -307,6 +308,7 @@ void PhysicsEngine::stepSimulation() {
|
|||
btVector3 walkVelocity = glmToBullet(_avatarData->getVelocity());
|
||||
_characterController->setVelocityForTimeInterval(walkVelocity, timeStep);
|
||||
}
|
||||
_avatarData->unlock();
|
||||
|
||||
// This is step (2).
|
||||
int numSubsteps = _dynamicsWorld->stepSimulation(timeStep, MAX_NUM_SUBSTEPS, PHYSICS_ENGINE_FIXED_SUBSTEP);
|
||||
|
|
|
@ -106,11 +106,11 @@ public:
|
|||
/// \param delayLoad if true, don't load the model immediately; wait until actually requested
|
||||
Q_INVOKABLE void setURL(const QUrl& url, const QUrl& fallback = QUrl(),
|
||||
bool retainCurrent = false, bool delayLoad = false);
|
||||
const QUrl& getURL() const { return _url; }
|
||||
|
||||
// Set the model to use for collisions
|
||||
Q_INVOKABLE void setCollisionModelURL(const QUrl& url, const QUrl& fallback = QUrl(), bool delayLoad = false);
|
||||
|
||||
const QUrl& getURL() const { return _url; }
|
||||
const QUrl& getCollisionURL() const { return _collisionUrl; }
|
||||
|
||||
/// Sets the distance parameter used for LOD computations.
|
||||
void setLODDistance(float distance) { _lodDistance = distance; }
|
||||
|
@ -132,6 +132,9 @@ public:
|
|||
|
||||
/// Returns a reference to the shared geometry.
|
||||
const QSharedPointer<NetworkGeometry>& getGeometry() const { return _geometry; }
|
||||
|
||||
/// Returns a reference to the shared collision geometry.
|
||||
const QSharedPointer<NetworkGeometry> getCollisionGeometry() {return _collisionGeometry; }
|
||||
|
||||
/// Returns the number of joint states in the model.
|
||||
int getJointStateCount() const { return _jointStates.size(); }
|
||||
|
|
Loading…
Reference in a new issue