mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-05 07:00:27 +02:00
attempt to handle collision models in the same way as render models
This commit is contained in:
parent
906f082a2a
commit
9161cc8b83
7 changed files with 68 additions and 28 deletions
|
@ -417,6 +417,26 @@ const Model* EntityTreeRenderer::getModelForEntityItem(const EntityItem* entityI
|
|||
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);
|
||||
assert(modelEntityItem); // we need this!!! Why?!!
|
||||
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 +611,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 +624,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 +657,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,46 @@ bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& ori
|
|||
}
|
||||
|
||||
bool RenderableModelEntityItem::isReadyToComputeShape() {
|
||||
if (_collisionModelURL == "") {
|
||||
|
||||
if (!_model) {
|
||||
qDebug() << "O#O#O#O#O#O RenderableModelEntityItem::isReadyToComputeShape --> no _model, false";
|
||||
return false; // hmm...
|
||||
}
|
||||
|
||||
if (_model->getCollisionURL().toString() == "") {
|
||||
qDebug() << "O#O#O#O#O#O RenderableModelEntityItem::isReadyToComputeShape --> no _model->_collisionUrl, true";
|
||||
// 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.
|
||||
qDebug() << "O#O#O#O#O#O RenderableModelEntityItem::isReadyToComputeShape --> model is ready, true";
|
||||
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;
|
||||
}
|
||||
if (collisionNetworkGeometry.isNull()) {
|
||||
qDebug() << "O#O#O#O#O#O RenderableModelEntityItem::isReadyToComputeShape --> started download, false";
|
||||
// we have a _collisionModelURL but we don't yet have a collisionNetworkGeometry.
|
||||
// kick-off the download so that we'll have it at some future re-attempt.
|
||||
DependencyManager::get<GeometryCache>()->getGeometry(_collisionModelURL, QUrl(), false, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
// the model is still being downloaded.
|
||||
qDebug() << "O#O#O#O#O#O RenderableModelEntityItem::isReadyToComputeShape --> model not ready, false";
|
||||
return false;
|
||||
}
|
||||
|
||||
void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||
if (_collisionModelURL == "") {
|
||||
if (_model->getCollisionURL().toString() == "") {
|
||||
qDebug() << "O#O#O#O#O#O RenderableModelEntityItem::computeShapeInfo --> default";
|
||||
info.setParams(getShapeType(), 0.5f * getDimensions());
|
||||
} else {
|
||||
const FBXGeometry& fbxGeometry = _collisionNetworkGeometry->getFBXGeometry();
|
||||
qDebug() << "O#O#O#O#O#O RenderableModelEntityItem::computeShapeInfo --> hull points";
|
||||
const QSharedPointer<NetworkGeometry> collisionNetworkGeometry = _model->getCollisionGeometry();
|
||||
const FBXGeometry& fbxGeometry = collisionNetworkGeometry->getFBXGeometry();
|
||||
|
||||
_points.clear();
|
||||
foreach (const FBXMesh& mesh, fbxGeometry.meshes) {
|
||||
|
@ -310,9 +320,11 @@ 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().toString() == "") {
|
||||
qDebug() << "O#O#O#O#O#O RenderableModelEntityItem::getShapeType -->" << _shapeType;
|
||||
return _shapeType;
|
||||
} else {
|
||||
qDebug() << "O#O#O#O#O#O RenderableModelEntityItem::getShapeType -->" << SHAPE_TYPE_CONVEX_HULL;
|
||||
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();
|
||||
|
||||
|
@ -68,7 +67,7 @@ private:
|
|||
QStringList _originalTextures;
|
||||
bool _originalTexturesRead;
|
||||
|
||||
QSharedPointer<NetworkGeometry> _collisionNetworkGeometry;
|
||||
// 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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1087,6 +1087,7 @@ int Model::getLastFreeJointIndex(int jointIndex) const {
|
|||
}
|
||||
|
||||
void Model::setURL(const QUrl& url, const QUrl& fallback, bool retainCurrent, bool delayLoad) {
|
||||
qDebug() << "|||||||||||||| Model::setURL" << url.toString();
|
||||
// don't recreate the geometry if it's the same URL
|
||||
if (_url == url) {
|
||||
return;
|
||||
|
@ -1102,6 +1103,7 @@ void Model::setURL(const QUrl& url, const QUrl& fallback, bool retainCurrent, bo
|
|||
}
|
||||
|
||||
void Model::setCollisionModelURL(const QUrl& url, const QUrl& fallback, bool delayLoad) {
|
||||
qDebug() << "|||||||||||||| Model::setCollisionModelURL" << url.toString();
|
||||
if (_collisionUrl == url) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -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