merge upstream/master into andrew/bispinor

Conflicts:
	libraries/physics/src/PhysicsEngine.cpp
This commit is contained in:
Andrew Meadows 2015-03-19 16:38:10 -07:00
commit 230a8851e7
6 changed files with 50 additions and 33 deletions

View file

@ -410,13 +410,30 @@ const Model* EntityTreeRenderer::getModelForEntityItem(const EntityItem* entityI
if (entityItem->getType() == EntityTypes::Model) { if (entityItem->getType() == EntityTypes::Model) {
const RenderableModelEntityItem* constModelEntityItem = dynamic_cast<const RenderableModelEntityItem*>(entityItem); const RenderableModelEntityItem* constModelEntityItem = dynamic_cast<const RenderableModelEntityItem*>(entityItem);
RenderableModelEntityItem* modelEntityItem = const_cast<RenderableModelEntityItem*>(constModelEntityItem); RenderableModelEntityItem* modelEntityItem = const_cast<RenderableModelEntityItem*>(constModelEntityItem);
assert(modelEntityItem); // we need this!!!
result = modelEntityItem->getModel(this); result = modelEntityItem->getModel(this);
} }
return result; 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) { void EntityTreeRenderer::renderElementProxy(EntityTreeElement* entityTreeElement) {
glm::vec3 elementCenter = entityTreeElement->getAACube().calcCenter(); glm::vec3 elementCenter = entityTreeElement->getAACube().calcCenter();
float elementSize = entityTreeElement->getScale(); float elementSize = entityTreeElement->getScale();
@ -591,7 +608,7 @@ void EntityTreeRenderer::processEraseMessage(const QByteArray& dataByteArray, co
static_cast<EntityTree*>(_tree)->processEraseMessage(dataByteArray, sourceNode); 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; Model* model = NULL;
// Make sure we only create and delete models on the thread that owns the EntityTreeRenderer // Make sure we only create and delete models on the thread that owns the EntityTreeRenderer
if (QThread::currentThread() != thread()) { if (QThread::currentThread() != thread()) {
@ -604,10 +621,11 @@ Model* EntityTreeRenderer::allocateModel(const QString& url) {
model = new Model(); model = new Model();
model->init(); model->init();
model->setURL(QUrl(url)); model->setURL(QUrl(url));
model->setCollisionModelURL(QUrl(collisionUrl));
return model; return model;
} }
Model* EntityTreeRenderer::updateModel(Model* original, const QString& newUrl) { Model* EntityTreeRenderer::updateModel(Model* original, const QString& newUrl, const QString& collisionUrl) {
Model* model = NULL; Model* model = NULL;
// The caller shouldn't call us if the URL doesn't need to change. But if they // 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 = new Model();
model->init(); model->init();
model->setURL(QUrl(newUrl)); model->setURL(QUrl(newUrl));
model->setCollisionModelURL(QUrl(collisionUrl));
return model; return model;
} }

View file

@ -59,15 +59,16 @@ public:
virtual const FBXGeometry* getGeometryForEntity(const EntityItem* entityItem); virtual const FBXGeometry* getGeometryForEntity(const EntityItem* entityItem);
virtual const Model* getModelForEntityItem(const EntityItem* entityItem); virtual const Model* getModelForEntityItem(const EntityItem* entityItem);
virtual const FBXGeometry* getCollisionGeometryForEntity(const EntityItem* entityItem);
/// clears the tree /// clears the tree
virtual void clear(); virtual void clear();
/// if a renderable entity item needs a model, we will allocate it for them /// 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 /// 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 /// if a renderable entity item is done with a model, it should return it to us
void releaseModel(Model* model); void releaseModel(Model* model);

View file

@ -223,10 +223,10 @@ Model* RenderableModelEntityItem::getModel(EntityTreeRenderer* renderer) {
// if we have a previously allocated model, but it's URL doesn't match // 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. // then we need to let our renderer update our model for us.
if (_model && QUrl(getModelURL()) != _model->getURL()) { if (_model && QUrl(getModelURL()) != _model->getURL()) {
result = _model = _myRenderer->updateModel(_model, getModelURL()); result = _model = _myRenderer->updateModel(_model, getModelURL(), getCollisionModelURL());
_needsInitialSimulation = true; _needsInitialSimulation = true;
} else if (!_model) { // if we don't yet have a model, then we want our renderer to allocate one } 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; _needsInitialSimulation = true;
} else { // we already have the model we want... } else { // we already have the model we want...
result = _model; result = _model;
@ -267,36 +267,32 @@ bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& ori
} }
bool RenderableModelEntityItem::isReadyToComputeShape() { 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. // no model url, so we're ready to compute a shape.
return true; return true;
} }
if (! _collisionNetworkGeometry.isNull() && _collisionNetworkGeometry->isLoadedWithTextures()) { const QSharedPointer<NetworkGeometry> collisionNetworkGeometry = _model->getCollisionGeometry();
// we have a _collisionModelURL AND a _collisionNetworkGeometry AND it's fully loaded. if (! collisionNetworkGeometry.isNull() && collisionNetworkGeometry->isLoadedWithTextures()) {
// we have a _collisionModelURL AND a collisionNetworkGeometry AND it's fully loaded.
return 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;
}
}
// the model is still being downloaded. // the model is still being downloaded.
return false; return false;
} }
void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
if (_collisionModelURL == "") { if (_model->getCollisionURL().isEmpty()) {
info.setParams(getShapeType(), 0.5f * getDimensions()); info.setParams(getShapeType(), 0.5f * getDimensions());
} else { } else {
const FBXGeometry& fbxGeometry = _collisionNetworkGeometry->getFBXGeometry(); const QSharedPointer<NetworkGeometry> collisionNetworkGeometry = _model->getCollisionGeometry();
const FBXGeometry& fbxGeometry = collisionNetworkGeometry->getFBXGeometry();
_points.clear(); _points.clear();
foreach (const FBXMesh& mesh, fbxGeometry.meshes) { foreach (const FBXMesh& mesh, fbxGeometry.meshes) {
@ -310,9 +306,9 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
ShapeType RenderableModelEntityItem::getShapeType() const { ShapeType RenderableModelEntityItem::getShapeType() const {
// XXX make hull an option in edit.js ? // XXX make hull an option in edit.js ?
if (_collisionModelURL != "") { if (!_model || _model->getCollisionURL().isEmpty()) {
return SHAPE_TYPE_CONVEX_HULL;
} else {
return _shapeType; return _shapeType;
} else {
return SHAPE_TYPE_CONVEX_HULL;
} }
} }

View file

@ -30,8 +30,7 @@ public:
_needsInitialSimulation(true), _needsInitialSimulation(true),
_needsModelReload(true), _needsModelReload(true),
_myRenderer(NULL), _myRenderer(NULL),
_originalTexturesRead(false), _originalTexturesRead(false) { }
_collisionNetworkGeometry(QSharedPointer<NetworkGeometry>()) { }
virtual ~RenderableModelEntityItem(); virtual ~RenderableModelEntityItem();
@ -67,8 +66,6 @@ private:
QString _currentTextures; QString _currentTextures;
QStringList _originalTextures; QStringList _originalTextures;
bool _originalTexturesRead; bool _originalTexturesRead;
QSharedPointer<NetworkGeometry> _collisionNetworkGeometry;
QVector<glm::vec3> _points; QVector<glm::vec3> _points;
}; };

View file

@ -31,6 +31,7 @@ class EntityItemFBXService {
public: public:
virtual const FBXGeometry* getGeometryForEntity(const EntityItem* entityItem) = 0; virtual const FBXGeometry* getGeometryForEntity(const EntityItem* entityItem) = 0;
virtual const Model* getModelForEntityItem(const EntityItem* entityItem) = 0; virtual const Model* getModelForEntityItem(const EntityItem* entityItem) = 0;
virtual const FBXGeometry* getCollisionGeometryForEntity(const EntityItem* entityItem) = 0;
}; };

View file

@ -106,11 +106,11 @@ public:
/// \param delayLoad if true, don't load the model immediately; wait until actually requested /// \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(), Q_INVOKABLE void setURL(const QUrl& url, const QUrl& fallback = QUrl(),
bool retainCurrent = false, bool delayLoad = false); bool retainCurrent = false, bool delayLoad = false);
const QUrl& getURL() const { return _url; }
// Set the model to use for collisions // Set the model to use for collisions
Q_INVOKABLE void setCollisionModelURL(const QUrl& url, const QUrl& fallback = QUrl(), bool delayLoad = false); Q_INVOKABLE void setCollisionModelURL(const QUrl& url, const QUrl& fallback = QUrl(), bool delayLoad = false);
const QUrl& getCollisionURL() const { return _collisionUrl; }
const QUrl& getURL() const { return _url; }
/// Sets the distance parameter used for LOD computations. /// Sets the distance parameter used for LOD computations.
void setLODDistance(float distance) { _lodDistance = distance; } void setLODDistance(float distance) { _lodDistance = distance; }
@ -132,6 +132,9 @@ public:
/// Returns a reference to the shared geometry. /// Returns a reference to the shared geometry.
const QSharedPointer<NetworkGeometry>& getGeometry() const { return _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. /// Returns the number of joint states in the model.
int getJointStateCount() const { return _jointStates.size(); } int getJointStateCount() const { return _jointStates.size(); }