From 769194f046fd35d00070782b1ab911e4ea2bfaa3 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 20 Mar 2015 13:41:14 -0700 Subject: [PATCH 01/22] first stab at compound hull collisions --- .../src/RenderableModelEntityItem.cpp | 9 ++++--- .../src/RenderableModelEntityItem.h | 2 +- libraries/physics/src/ShapeInfoUtil.cpp | 24 +++++++++++++++---- libraries/shared/src/ShapeInfo.cpp | 2 +- libraries/shared/src/ShapeInfo.h | 8 +++---- 5 files changed, 31 insertions(+), 14 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index d4eefc0986..6d32b78689 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -295,12 +295,13 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { const FBXGeometry& fbxGeometry = collisionNetworkGeometry->getFBXGeometry(); _points.clear(); + unsigned int i = 0; foreach (const FBXMesh& mesh, fbxGeometry.meshes) { - _points << mesh.vertices; + _points[i++] << mesh.vertices; } info.setParams(getShapeType(), 0.5f * getDimensions(), _collisionModelURL); - info.setConvexHull(_points); + info.setConvexHulls(_points); } } @@ -308,7 +309,9 @@ ShapeType RenderableModelEntityItem::getShapeType() const { // XXX make hull an option in edit.js ? if (!_model || _model->getCollisionURL().isEmpty()) { return _shapeType; - } else { + } else if (_points.size() == 1) { return SHAPE_TYPE_CONVEX_HULL; + } else { + return SHAPE_TYPE_COMPOUND; } } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index f02dd537fb..63249f136c 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -66,7 +66,7 @@ private: QString _currentTextures; QStringList _originalTextures; bool _originalTexturesRead; - QVector _points; + QVector> _points; }; #endif // hifi_RenderableModelEntityItem_h diff --git a/libraries/physics/src/ShapeInfoUtil.cpp b/libraries/physics/src/ShapeInfoUtil.cpp index 116be984b9..2f7c0c59bd 100644 --- a/libraries/physics/src/ShapeInfoUtil.cpp +++ b/libraries/physics/src/ShapeInfoUtil.cpp @@ -70,12 +70,12 @@ void ShapeInfoUtil::collectInfoFromShape(const btCollisionShape* shape, ShapeInf const btConvexHullShape* convexHullShape = static_cast(shape); const int numPoints = convexHullShape->getNumPoints(); const btVector3* btPoints = convexHullShape->getUnscaledPoints(); - QVector points; + QVector> points; for (int i = 0; i < numPoints; i++) { glm::vec3 point(btPoints->getX(), btPoints->getY(), btPoints->getZ()); - points << point; + points[0] << point; } - info.setConvexHull(points); + info.setConvexHulls(points); } break; default: { @@ -109,13 +109,27 @@ btCollisionShape* ShapeInfoUtil::createShapeFromInfo(const ShapeInfo& info) { break; case SHAPE_TYPE_CONVEX_HULL: { shape = new btConvexHullShape(); - const QVector& points = info.getPoints(); - foreach (glm::vec3 point, points) { + const QVector>& points = info.getPoints(); + foreach (glm::vec3 point, points[0]) { btVector3 btPoint(point[0], point[1], point[2]); static_cast(shape)->addPoint(btPoint); } } break; + case SHAPE_TYPE_COMPOUND: { + shape = new btCompoundShape(); + const QVector>& points = info.getPoints(); + foreach (QVector hullPoints, info.getPoints()) { + auto hull = new btConvexHullShape(); + foreach (glm::vec3 point, hullPoints) { + btVector3 btPoint(point[0], point[1], point[2]); + hull->addPoint(btPoint); + } + btTransform trans; + static_cast(shape)->addChildShape (trans, hull); + } + } + break; } return shape; } diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index 61432830e7..afa19bcd24 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -64,7 +64,7 @@ void ShapeInfo::setEllipsoid(const glm::vec3& halfExtents) { _doubleHashKey.clear(); } -void ShapeInfo::setConvexHull(const QVector& points) { +void ShapeInfo::setConvexHulls(const QVector>& points) { _type = SHAPE_TYPE_CONVEX_HULL; _points = points; } diff --git a/libraries/shared/src/ShapeInfo.h b/libraries/shared/src/ShapeInfo.h index 0a55f7c51d..4dce121d64 100644 --- a/libraries/shared/src/ShapeInfo.h +++ b/libraries/shared/src/ShapeInfo.h @@ -44,14 +44,14 @@ public: void setBox(const glm::vec3& halfExtents); void setSphere(float radius); void setEllipsoid(const glm::vec3& halfExtents); - void setConvexHull(const QVector& points); + void setConvexHulls(const QVector>& points); void setCapsuleY(float radius, float halfHeight); const int getType() const { return _type; } const glm::vec3& getHalfExtents() const { return _halfExtents; } - const QVector& getPoints() const { return _points; } + const QVector>& getPoints() const { return _points; } void clearPoints () { _points.clear(); } void appendToPoints (const QVector& newPoints) { _points << newPoints; } @@ -64,8 +64,8 @@ protected: ShapeType _type = SHAPE_TYPE_NONE; glm::vec3 _halfExtents = glm::vec3(0.0f); DoubleHashKey _doubleHashKey; - QVector _points; // points for convex collision hull - QUrl _url; // url for model of convex collision hull + QVector> _points; // points for convex collision hulls + QUrl _url; // url for model of convex collision hulls }; #endif // hifi_ShapeInfo_h From 86d09a1607a2fee57fee73c2a01026be71560620 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 21 Mar 2015 08:55:49 -0700 Subject: [PATCH 02/22] more compound shape stuff --- .../src/RenderableModelEntityItem.cpp | 2 ++ libraries/physics/src/ShapeInfoUtil.cpp | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 6d32b78689..fed01883bd 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -297,6 +297,8 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { _points.clear(); unsigned int i = 0; foreach (const FBXMesh& mesh, fbxGeometry.meshes) { + QVector newMeshPoints; + _points << newMeshPoints; _points[i++] << mesh.vertices; } diff --git a/libraries/physics/src/ShapeInfoUtil.cpp b/libraries/physics/src/ShapeInfoUtil.cpp index 2f7c0c59bd..a5834f407a 100644 --- a/libraries/physics/src/ShapeInfoUtil.cpp +++ b/libraries/physics/src/ShapeInfoUtil.cpp @@ -29,6 +29,9 @@ int ShapeInfoUtil::toBulletShapeType(int shapeInfoType) { case SHAPE_TYPE_CONVEX_HULL: bulletShapeType = CONVEX_HULL_SHAPE_PROXYTYPE; break; + case SHAPE_TYPE_COMPOUND: + bulletShapeType = COMPOUND_SHAPE_PROXYTYPE; + break; } return bulletShapeType; } @@ -48,6 +51,9 @@ int ShapeInfoUtil::fromBulletShapeType(int bulletShapeType) { case CONVEX_HULL_SHAPE_PROXYTYPE: shapeInfoType = SHAPE_TYPE_CONVEX_HULL; break; + case COMPOUND_SHAPE_PROXYTYPE: + shapeInfoType = SHAPE_TYPE_COMPOUND; + break; } return shapeInfoType; } @@ -78,6 +84,26 @@ void ShapeInfoUtil::collectInfoFromShape(const btCollisionShape* shape, ShapeInf info.setConvexHulls(points); } break; + case SHAPE_TYPE_COMPOUND: { + const btCompoundShape* compoundShape = static_cast(shape); + const int numChildShapes = compoundShape->getNumChildShapes(); + QVector> points; + for (int i = 0; i < numChildShapes; i ++) { + const btCollisionShape* childShape = compoundShape->getChildShape(i); + const btConvexHullShape* convexHullShape = static_cast(childShape); + const int numPoints = convexHullShape->getNumPoints(); + const btVector3* btPoints = convexHullShape->getUnscaledPoints(); + + QVector childPoints; + for (int j = 0; j < numPoints; j++) { + glm::vec3 point(btPoints->getX(), btPoints->getY(), btPoints->getZ()); + childPoints << point; + } + points << childPoints; + } + info.setConvexHulls(points); + } + break; default: { info.clear(); } From bfc5cf99d6ef92de7ee6734394483fa90a416b95 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 21 Mar 2015 16:11:47 -0700 Subject: [PATCH 03/22] more code for compound hull collisions --- .../src/RenderableModelEntityItem.cpp | 31 +++++++++++++++++-- libraries/physics/src/ShapeInfoUtil.cpp | 12 +++++++ libraries/shared/src/ShapeInfo.cpp | 10 +++++- 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index fed01883bd..86332c8c07 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -297,9 +297,34 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { _points.clear(); unsigned int i = 0; foreach (const FBXMesh& mesh, fbxGeometry.meshes) { - QVector newMeshPoints; - _points << newMeshPoints; - _points[i++] << mesh.vertices; + + foreach (const FBXMeshPart &meshPart, mesh.parts) { + QVector pointsInPart; + unsigned int triangleCount = meshPart.triangleIndices.size() / 3; + for (unsigned int i = 0; i < triangleCount; i++) { + unsigned int p0Index = meshPart.triangleIndices[i*3]; + unsigned int p1Index = meshPart.triangleIndices[i*3+1]; + unsigned int p2Index = meshPart.triangleIndices[i*3+2]; + + glm::vec3 p0 = mesh.vertices[p0Index]; + glm::vec3 p1 = mesh.vertices[p1Index]; + glm::vec3 p2 = mesh.vertices[p2Index]; + + if (!pointsInPart.contains(p0)) { + pointsInPart << p0; + } + if (!pointsInPart.contains(p1)) { + pointsInPart << p1; + } + if (!pointsInPart.contains(p2)) { + pointsInPart << p2; + } + } + + QVector newMeshPoints; + _points << newMeshPoints; + _points[i++] << pointsInPart; + } } info.setParams(getShapeType(), 0.5f * getDimensions(), _collisionModelURL); diff --git a/libraries/physics/src/ShapeInfoUtil.cpp b/libraries/physics/src/ShapeInfoUtil.cpp index a5834f407a..b48bff763c 100644 --- a/libraries/physics/src/ShapeInfoUtil.cpp +++ b/libraries/physics/src/ShapeInfoUtil.cpp @@ -116,6 +116,9 @@ void ShapeInfoUtil::collectInfoFromShape(const btCollisionShape* shape, ShapeInf btCollisionShape* ShapeInfoUtil::createShapeFromInfo(const ShapeInfo& info) { btCollisionShape* shape = NULL; + + qDebug() << "\n\nHERE" << info.getType(); + switch(info.getType()) { case SHAPE_TYPE_BOX: { shape = new btBoxShape(glmToBullet(info.getHalfExtents())); @@ -145,8 +148,14 @@ btCollisionShape* ShapeInfoUtil::createShapeFromInfo(const ShapeInfo& info) { case SHAPE_TYPE_COMPOUND: { shape = new btCompoundShape(); const QVector>& points = info.getPoints(); + + qDebug() << "\n\nSHAPE_TYPE_COMPOUND" << info.getPoints().size() << "hulls."; + foreach (QVector hullPoints, info.getPoints()) { auto hull = new btConvexHullShape(); + + qDebug() << " SHAPE_TYPE_COMPOUND" << hullPoints.size() << "points in hull."; + foreach (glm::vec3 point, hullPoints) { btVector3 btPoint(point[0], point[1], point[2]); hull->addPoint(btPoint); @@ -155,6 +164,9 @@ btCollisionShape* ShapeInfoUtil::createShapeFromInfo(const ShapeInfo& info) { static_cast(shape)->addChildShape (trans, hull); } } + + qDebug() << "DONE, getNumChildShapes =" << static_cast(shape)->getNumChildShapes(); + break; } return shape; diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index afa19bcd24..09677cf36c 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -40,6 +40,10 @@ void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString _url = QUrl(url); _halfExtents = halfExtents; break; + case SHAPE_TYPE_COMPOUND: + _url = QUrl(url); + _halfExtents = halfExtents; + break; default: _halfExtents = halfExtents; break; @@ -65,7 +69,11 @@ void ShapeInfo::setEllipsoid(const glm::vec3& halfExtents) { } void ShapeInfo::setConvexHulls(const QVector>& points) { - _type = SHAPE_TYPE_CONVEX_HULL; + if (points.size() == 1) { + _type = SHAPE_TYPE_CONVEX_HULL; + } else { + _type = SHAPE_TYPE_COMPOUND; + } _points = points; } From f31ac8b968238f795e9c6b4f18f44122a757f0a9 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 23 Mar 2015 15:10:28 -0700 Subject: [PATCH 04/22] compound covex hull collisions work --- libraries/physics/src/ShapeInfoUtil.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/physics/src/ShapeInfoUtil.cpp b/libraries/physics/src/ShapeInfoUtil.cpp index b48bff763c..07fedb35ad 100644 --- a/libraries/physics/src/ShapeInfoUtil.cpp +++ b/libraries/physics/src/ShapeInfoUtil.cpp @@ -161,6 +161,7 @@ btCollisionShape* ShapeInfoUtil::createShapeFromInfo(const ShapeInfo& info) { hull->addPoint(btPoint); } btTransform trans; + trans.setIdentity(); static_cast(shape)->addChildShape (trans, hull); } } From c8ad82917e974d23c08d9732e8195cee0fc6d0e4 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 23 Mar 2015 16:54:36 -0700 Subject: [PATCH 05/22] clean up some debugging spew. take dimensions into account when scaling points used for collision hull creation --- .../src/RenderableModelEntityItem.cpp | 47 +++++++++++++++++-- .../src/RenderableModelEntityItem.h | 2 + libraries/entities/src/EntityItem.h | 11 ++++- libraries/physics/src/ShapeInfoUtil.cpp | 15 ++---- libraries/shared/src/ShapeInfo.cpp | 7 +++ 5 files changed, 64 insertions(+), 18 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 86332c8c07..bb3f00d154 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -266,6 +266,14 @@ bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& ori return _model->findRayIntersectionAgainstSubMeshes(origin, direction, distance, face, extraInfo, precisionPicking); } +void RenderableModelEntityItem::updateDimensions(const glm::vec3& value) { + if (glm::distance(_dimensions, value) > MIN_DIMENSIONS_DELTA) { + _dimensions = value; + _dirtyFlags |= (EntityItem::DIRTY_SHAPE | EntityItem::DIRTY_MASS); + } + _model->setScaleToFit(true, _dimensions); +} + bool RenderableModelEntityItem::isReadyToComputeShape() { if (!_model) { @@ -294,6 +302,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { const QSharedPointer collisionNetworkGeometry = _model->getCollisionGeometry(); const FBXGeometry& fbxGeometry = collisionNetworkGeometry->getFBXGeometry(); + AABox aaBox; _points.clear(); unsigned int i = 0; foreach (const FBXMesh& mesh, fbxGeometry.meshes) { @@ -301,15 +310,29 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { foreach (const FBXMeshPart &meshPart, mesh.parts) { QVector pointsInPart; unsigned int triangleCount = meshPart.triangleIndices.size() / 3; - for (unsigned int i = 0; i < triangleCount; i++) { - unsigned int p0Index = meshPart.triangleIndices[i*3]; - unsigned int p1Index = meshPart.triangleIndices[i*3+1]; - unsigned int p2Index = meshPart.triangleIndices[i*3+2]; + assert((unsigned int)meshPart.triangleIndices.size() == triangleCount*3); + for (unsigned int j = 0; j < triangleCount; j++) { + unsigned int p0Index = meshPart.triangleIndices[j*3]; + unsigned int p1Index = meshPart.triangleIndices[j*3+1]; + unsigned int p2Index = meshPart.triangleIndices[j*3+2]; + + assert(p0Index < (unsigned int)mesh.vertices.size()); + assert(p1Index < (unsigned int)mesh.vertices.size()); + assert(p2Index < (unsigned int)mesh.vertices.size()); + + // glm::vec3 p0 = mesh.vertices[p0Index] * scale[0]; + // glm::vec3 p1 = mesh.vertices[p1Index] * scale[1]; + // glm::vec3 p2 = mesh.vertices[p2Index] * scale[2]; + glm::vec3 p0 = mesh.vertices[p0Index]; glm::vec3 p1 = mesh.vertices[p1Index]; glm::vec3 p2 = mesh.vertices[p2Index]; + aaBox += p0; + aaBox += p1; + aaBox += p2; + if (!pointsInPart.contains(p0)) { pointsInPart << p0; } @@ -327,7 +350,21 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { } } - info.setParams(getShapeType(), 0.5f * getDimensions(), _collisionModelURL); + // make sure we aren't about to divide by zero + glm::vec3 aaBoxDim = aaBox.getDimensions(); + aaBoxDim = glm::clamp(aaBoxDim, glm::vec3(FLT_EPSILON), aaBoxDim); + + // scale = dimensions / aabox + glm::vec3 scale = _dimensions / aaBoxDim; + + // multiply each point by scale before handing the point-set off to the physics engine + for (int i = 0; i < _points.size(); i++) { + for (int j = 0; j < _points[i].size(); j++) { + _points[i][j] *= scale; + } + } + + info.setParams(getShapeType(), _dimensions, _collisionModelURL); info.setConvexHulls(_points); } } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 63249f136c..8742fb50eb 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -52,6 +52,8 @@ public: bool needsToCallUpdate() const; + virtual void updateDimensions(const glm::vec3& value); + bool isReadyToComputeShape(); void computeShapeInfo(ShapeInfo& info); ShapeType getShapeType() const; diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 88287f8965..49e450c45e 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -40,6 +40,15 @@ class EntityTreeElementExtraEncodeData; #define debugTreeVector(V) V << "[" << V << " in meters ]" +extern const float MIN_POSITION_DELTA; +extern const float MIN_DIMENSIONS_DELTA; +extern const float MIN_ALIGNMENT_DOT; +extern const float MIN_VELOCITY_DELTA; +extern const float MIN_DAMPING_DELTA; +extern const float MIN_GRAVITY_DELTA; +extern const float MIN_SPIN_DELTA; + + /// 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. @@ -270,7 +279,7 @@ public: void updatePositionInDomainUnits(const glm::vec3& value); void updatePosition(const glm::vec3& value); void updateDimensionsInDomainUnits(const glm::vec3& value); - void updateDimensions(const glm::vec3& value); + virtual void updateDimensions(const glm::vec3& value); void updateRotation(const glm::quat& rotation); void updateDensity(float value); void updateMass(float value); diff --git a/libraries/physics/src/ShapeInfoUtil.cpp b/libraries/physics/src/ShapeInfoUtil.cpp index 07fedb35ad..1073fbae3f 100644 --- a/libraries/physics/src/ShapeInfoUtil.cpp +++ b/libraries/physics/src/ShapeInfoUtil.cpp @@ -77,10 +77,12 @@ void ShapeInfoUtil::collectInfoFromShape(const btCollisionShape* shape, ShapeInf const int numPoints = convexHullShape->getNumPoints(); const btVector3* btPoints = convexHullShape->getUnscaledPoints(); QVector> points; + QVector childPoints; for (int i = 0; i < numPoints; i++) { glm::vec3 point(btPoints->getX(), btPoints->getY(), btPoints->getZ()); - points[0] << point; + childPoints << point; } + points << childPoints; info.setConvexHulls(points); } break; @@ -116,9 +118,6 @@ void ShapeInfoUtil::collectInfoFromShape(const btCollisionShape* shape, ShapeInf btCollisionShape* ShapeInfoUtil::createShapeFromInfo(const ShapeInfo& info) { btCollisionShape* shape = NULL; - - qDebug() << "\n\nHERE" << info.getType(); - switch(info.getType()) { case SHAPE_TYPE_BOX: { shape = new btBoxShape(glmToBullet(info.getHalfExtents())); @@ -149,13 +148,8 @@ btCollisionShape* ShapeInfoUtil::createShapeFromInfo(const ShapeInfo& info) { shape = new btCompoundShape(); const QVector>& points = info.getPoints(); - qDebug() << "\n\nSHAPE_TYPE_COMPOUND" << info.getPoints().size() << "hulls."; - foreach (QVector hullPoints, info.getPoints()) { auto hull = new btConvexHullShape(); - - qDebug() << " SHAPE_TYPE_COMPOUND" << hullPoints.size() << "points in hull."; - foreach (glm::vec3 point, hullPoints) { btVector3 btPoint(point[0], point[1], point[2]); hull->addPoint(btPoint); @@ -165,9 +159,6 @@ btCollisionShape* ShapeInfoUtil::createShapeFromInfo(const ShapeInfo& info) { static_cast(shape)->addChildShape (trans, hull); } } - - qDebug() << "DONE, getNumChildShapes =" << static_cast(shape)->getNumChildShapes(); - break; } return shape; diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index 09677cf36c..73dd945f73 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -38,6 +38,8 @@ void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString } case SHAPE_TYPE_CONVEX_HULL: _url = QUrl(url); + // halfExtents aren't used by convex-hull or compound convex-hull except as part of + // the generation of the key for the ShapeManager. _halfExtents = halfExtents; break; case SHAPE_TYPE_COMPOUND: @@ -51,18 +53,21 @@ void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString } void ShapeInfo::setBox(const glm::vec3& halfExtents) { + _url = ""; _type = SHAPE_TYPE_BOX; _halfExtents = halfExtents; _doubleHashKey.clear(); } void ShapeInfo::setSphere(float radius) { + _url = ""; _type = SHAPE_TYPE_SPHERE; _halfExtents = glm::vec3(radius, radius, radius); _doubleHashKey.clear(); } void ShapeInfo::setEllipsoid(const glm::vec3& halfExtents) { + _url = ""; _type = SHAPE_TYPE_ELLIPSOID; _halfExtents = halfExtents; _doubleHashKey.clear(); @@ -75,9 +80,11 @@ void ShapeInfo::setConvexHulls(const QVector>& points) { _type = SHAPE_TYPE_COMPOUND; } _points = points; + _doubleHashKey.clear(); } void ShapeInfo::setCapsuleY(float radius, float halfHeight) { + _url = ""; _type = SHAPE_TYPE_CAPSULE_Y; _halfExtents = glm::vec3(radius, halfHeight, radius); _doubleHashKey.clear(); From 6e3be260137bbd129d8ed3a19b4d0de5ad3d5344 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 24 Mar 2015 15:28:21 -0700 Subject: [PATCH 06/22] attempting to figure out why physics motion object doesn't get updated when collision model url changes --- .../src/RenderableModelEntityItem.cpp | 49 ++++++++++ .../src/RenderableModelEntityItem.h | 6 ++ libraries/entities/src/EntitySimulation.cpp | 10 +-- libraries/entities/src/EntitySimulation.h | 6 +- libraries/entities/src/EntityTree.cpp | 6 ++ libraries/entities/src/EntityTree.h | 4 +- libraries/entities/src/EntityTreeElement.h | 1 + libraries/entities/src/ModelEntityItem.cpp | 14 ++- libraries/entities/src/ModelEntityItem.h | 6 +- .../entities/src/SimpleEntitySimulation.cpp | 3 +- .../entities/src/SimpleEntitySimulation.h | 2 +- libraries/physics/src/EntityMotionState.cpp | 8 +- libraries/physics/src/EntityMotionState.h | 2 +- libraries/physics/src/ObjectMotionState.h | 2 +- libraries/physics/src/PhysicsEngine.cpp | 89 ++++++++++++++----- libraries/physics/src/PhysicsEngine.h | 4 +- 16 files changed, 172 insertions(+), 40 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index bb3f00d154..0a7d672189 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -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 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 collisionNetworkGeometry = _model->getCollisionGeometry(); const FBXGeometry& fbxGeometry = collisionNetworkGeometry->getFBXGeometry(); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 8742fb50eb..3586bd9941 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -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(); diff --git a/libraries/entities/src/EntitySimulation.cpp b/libraries/entities/src/EntitySimulation.cpp index b093dbe4f4..555f2061e8 100644 --- a/libraries/entities/src/EntitySimulation.cpp +++ b/libraries/entities/src/EntitySimulation.cpp @@ -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) { diff --git a/libraries/entities/src/EntitySimulation.h b/libraries/entities/src/EntitySimulation.h index 1eb4fdc951..9dd86011fa 100644 --- a/libraries/entities/src/EntitySimulation.h +++ b/libraries/entities/src/EntitySimulation.h @@ -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; diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 3ccff46a04..da7194e4bc 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -315,6 +315,12 @@ void EntityTree::deleteEntities(QSet 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) { diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 8536e74e9a..25cc0b0bf4 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -95,7 +95,8 @@ public: void deleteEntity(const EntityItemID& entityID, bool force = false, bool ignoreWarnings = false); void deleteEntities(QSet 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; } diff --git a/libraries/entities/src/EntityTreeElement.h b/libraries/entities/src/EntityTreeElement.h index 0b28dd30d0..e93e00cc1c 100644 --- a/libraries/entities/src/EntityTreeElement.h +++ b/libraries/entities/src/EntityTreeElement.h @@ -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); diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 181f537daa..13eaf0449f 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -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; diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index 081cb429ed..9e34de445b 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -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); diff --git a/libraries/entities/src/SimpleEntitySimulation.cpp b/libraries/entities/src/SimpleEntitySimulation.cpp index 6d45768c26..ee62c00246 100644 --- a/libraries/entities/src/SimpleEntitySimulation.cpp +++ b/libraries/entities/src/SimpleEntitySimulation.cpp @@ -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) { diff --git a/libraries/entities/src/SimpleEntitySimulation.h b/libraries/entities/src/SimpleEntitySimulation.h index 92b6a28215..6a748c3e1f 100644 --- a/libraries/entities/src/SimpleEntitySimulation.h +++ b/libraries/entities/src/SimpleEntitySimulation.h @@ -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(); diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index cd0769255b..3ca016c5d8 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -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 { diff --git a/libraries/physics/src/EntityMotionState.h b/libraries/physics/src/EntityMotionState.h index 7214626fc4..1910e92150 100644 --- a/libraries/physics/src/EntityMotionState.h +++ b/libraries/physics/src/EntityMotionState.h @@ -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); diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index fb402a178d..12d1d14c2d 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -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); diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index a46ba9f819..7dd989c9ab 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -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(motionState)); - _entityMotionStates.insert(motionState); - addObject(shapeInfo, shape, motionState); - } else if (entity->isMoving()) { - EntityMotionState* motionState = new EntityMotionState(entity); - entity->setPhysicsInfo(static_cast(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(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(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(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); diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index cb637c60b9..68161f5c12 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -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); From 1eeb2e89f803008a892ec93382aefbfc68e0303a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 24 Mar 2015 16:23:51 -0700 Subject: [PATCH 07/22] remove some debug spam --- .../src/RenderableModelEntityItem.cpp | 45 ++++-------------- libraries/entities/src/ModelEntityItem.cpp | 6 +-- libraries/physics/src/EntityMotionState.cpp | 4 +- libraries/physics/src/EntityMotionState.h | 2 +- libraries/physics/src/ObjectMotionState.h | 2 +- libraries/physics/src/PhysicsEngine.cpp | 47 +------------------ 6 files changed, 15 insertions(+), 91 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 0a7d672189..88827d066c 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -267,50 +267,26 @@ 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)); + if (_model) { + _model->setCollisionModelURL(QUrl(url)); + } } - bool RenderableModelEntityItem::hasCollisionModel() const { - // return !_collisionModelURL.isEmpty(); - return ! _model->getCollisionURL().isEmpty(); + if (_model) { + return ! _model->getCollisionURL().isEmpty(); + } else { + return !_collisionModelURL.isEmpty(); + } } - const QString& RenderableModelEntityItem::getCollisionModelURL() const { - // return _collisionModelURL; - _collisionModelURL = _model->getCollisionURL().toString(); + assert (!_model || _collisionModelURL == _model->getCollisionURL().toString()); return _collisionModelURL; } - - - void RenderableModelEntityItem::updateDimensions(const glm::vec3& value) { if (glm::distance(_dimensions, value) > MIN_DIMENSIONS_DELTA) { _dimensions = value; @@ -342,12 +318,9 @@ 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 collisionNetworkGeometry = _model->getCollisionGeometry(); const FBXGeometry& fbxGeometry = collisionNetworkGeometry->getFBXGeometry(); diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 13eaf0449f..f135f617f4 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -74,7 +74,7 @@ bool ModelEntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(shapeType, updateShapeType); if (somethingChanged) { - bool wantDebug = true; + bool wantDebug = false; if (wantDebug) { uint64_t now = usecTimestampNow(); int elapsed = now - getLastEdited(); @@ -284,10 +284,6 @@ 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; } diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 3ca016c5d8..35eb006655 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -168,12 +168,10 @@ void EntityMotionState::updateObjectVelocities() { } } -bool EntityMotionState::computeShapeInfo(ShapeInfo& shapeInfo) { +void EntityMotionState::computeShapeInfo(ShapeInfo& shapeInfo) { if (_entity->isReadyToComputeShape()) { _entity->computeShapeInfo(shapeInfo); - return true; } - return false; } float EntityMotionState::computeMass(const ShapeInfo& shapeInfo) const { diff --git a/libraries/physics/src/EntityMotionState.h b/libraries/physics/src/EntityMotionState.h index 1910e92150..7214626fc4 100644 --- a/libraries/physics/src/EntityMotionState.h +++ b/libraries/physics/src/EntityMotionState.h @@ -53,7 +53,7 @@ public: virtual void updateObjectEasy(uint32_t flags, uint32_t frame); virtual void updateObjectVelocities(); - virtual bool computeShapeInfo(ShapeInfo& shapeInfo); + virtual void computeShapeInfo(ShapeInfo& shapeInfo); virtual float computeMass(const ShapeInfo& shapeInfo) const; virtual void sendUpdate(OctreeEditPacketSender* packetSender, uint32_t frame); diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index 12d1d14c2d..fb402a178d 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -67,7 +67,7 @@ public: MotionStateType getType() const { return _type; } virtual MotionType getMotionType() const { return _motionType; } - virtual bool computeShapeInfo(ShapeInfo& info) = 0; + virtual void computeShapeInfo(ShapeInfo& info) = 0; virtual float computeMass(const ShapeInfo& shapeInfo) const = 0; void setFriction(float friction); diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 7dd989c9ab..5f668b4f37 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -59,33 +59,21 @@ void PhysicsEngine::updateEntitiesInternal(const quint64& now) { } bool PhysicsEngine::addEntityInternal(EntityItem* entity) { - - qDebug() << "PhysicsEngine::addEntityInternal"; - assert(entity); void* physicsInfo = entity->getPhysicsInfo(); if (!physicsInfo) { - 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(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(motionState)); _entityMotionStates.insert(motionState); @@ -94,11 +82,7 @@ bool PhysicsEngine::addEntityInternal(EntityItem* entity) { _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; } @@ -123,28 +107,18 @@ 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(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 @@ -537,20 +511,8 @@ bool PhysicsEngine::updateObjectHard(btRigidBody* body, ObjectMotionState* motio // get new shape btCollisionShape* oldShape = body->getCollisionShape(); ShapeInfo shapeInfo; - - - bool computeShapeInfoResult = motionState->computeShapeInfo(shapeInfo); - qDebug() << "\n\n---"; - qDebug() << "PhysicsEngine::updateObjectHard #1 computeShapeInfoResult =" << computeShapeInfoResult; - - + motionState->computeShapeInfo(shapeInfo); 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); @@ -603,12 +565,7 @@ 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; - bool computeShapeInfoResult = motionState->computeShapeInfo(shapeInfo); - - qDebug() << "\n\n---"; - qDebug() << "PhysicsEngine::updateObjectHard #2 computeShapeInfoResult =" << computeShapeInfoResult; - - + motionState->computeShapeInfo(shapeInfo); float mass = motionState->computeMass(shapeInfo); btVector3 inertia(0.0f, 0.0f, 0.0f); body->getCollisionShape()->calculateLocalInertia(mass, inertia); From 8d2c9425096a9d09768d2fed747738557ad087de Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 24 Mar 2015 16:38:11 -0700 Subject: [PATCH 08/22] diff minimization --- .../src/RenderableModelEntityItem.cpp | 7 ------- .../entities-renderer/src/RenderableModelEntityItem.h | 2 -- libraries/entities/src/EntitySimulation.cpp | 10 +++++----- libraries/entities/src/EntitySimulation.h | 2 +- libraries/entities/src/SimpleEntitySimulation.cpp | 3 +-- libraries/entities/src/SimpleEntitySimulation.h | 2 +- libraries/physics/src/PhysicsEngine.cpp | 6 +++--- libraries/physics/src/PhysicsEngine.h | 2 +- 8 files changed, 12 insertions(+), 22 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 88827d066c..025da1d285 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -22,7 +22,6 @@ #include "EntityTreeRenderer.h" #include "RenderableModelEntityItem.h" - EntityItem* RenderableModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { return new RenderableModelEntityItem(entityID, properties); } @@ -309,7 +308,6 @@ bool RenderableModelEntityItem::isReadyToComputeShape() { const QSharedPointer 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; } @@ -342,11 +340,6 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { assert(p1Index < (unsigned int)mesh.vertices.size()); assert(p2Index < (unsigned int)mesh.vertices.size()); - // glm::vec3 p0 = mesh.vertices[p0Index] * scale[0]; - // glm::vec3 p1 = mesh.vertices[p1Index] * scale[1]; - // glm::vec3 p2 = mesh.vertices[p2Index] * scale[2]; - - glm::vec3 p0 = mesh.vertices[p0Index]; glm::vec3 p1 = mesh.vertices[p1Index]; glm::vec3 p2 = mesh.vertices[p2Index]; diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 3586bd9941..90535954b4 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -49,7 +49,6 @@ public: void** intersectedObject, bool precisionPicking) const; Model* getModel(EntityTreeRenderer* renderer); - // virtual void setCollisionModelURL(const QString& url); bool needsToCallUpdate() const; @@ -57,7 +56,6 @@ public: virtual bool hasCollisionModel() const; virtual const QString& getCollisionModelURL() const; - virtual void updateDimensions(const glm::vec3& value); bool isReadyToComputeShape(); diff --git a/libraries/entities/src/EntitySimulation.cpp b/libraries/entities/src/EntitySimulation.cpp index 555f2061e8..b093dbe4f4 100644 --- a/libraries/entities/src/EntitySimulation.cpp +++ b/libraries/entities/src/EntitySimulation.cpp @@ -126,11 +126,11 @@ void EntitySimulation::addEntity(EntityItem* entity) { if (entity->needsToCallUpdate()) { _updateableEntities.insert(entity); } - 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(); - } + 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) { diff --git a/libraries/entities/src/EntitySimulation.h b/libraries/entities/src/EntitySimulation.h index 9dd86011fa..68b42e5ac9 100644 --- a/libraries/entities/src/EntitySimulation.h +++ b/libraries/entities/src/EntitySimulation.h @@ -78,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 bool addEntityInternal(EntityItem* entity) = 0; + virtual void addEntityInternal(EntityItem* entity) = 0; virtual void removeEntityInternal(EntityItem* entity) = 0; diff --git a/libraries/entities/src/SimpleEntitySimulation.cpp b/libraries/entities/src/SimpleEntitySimulation.cpp index ee62c00246..6d45768c26 100644 --- a/libraries/entities/src/SimpleEntitySimulation.cpp +++ b/libraries/entities/src/SimpleEntitySimulation.cpp @@ -29,13 +29,12 @@ void SimpleEntitySimulation::updateEntitiesInternal(const quint64& now) { } } -bool SimpleEntitySimulation::addEntityInternal(EntityItem* entity) { +void SimpleEntitySimulation::addEntityInternal(EntityItem* entity) { if (entity->isMoving()) { _movingEntities.insert(entity); } else if (entity->getCollisionsWillMove()) { _movableButStoppedEntities.insert(entity); } - return true; } void SimpleEntitySimulation::removeEntityInternal(EntityItem* entity) { diff --git a/libraries/entities/src/SimpleEntitySimulation.h b/libraries/entities/src/SimpleEntitySimulation.h index 6a748c3e1f..92b6a28215 100644 --- a/libraries/entities/src/SimpleEntitySimulation.h +++ b/libraries/entities/src/SimpleEntitySimulation.h @@ -23,7 +23,7 @@ public: protected: virtual void updateEntitiesInternal(const quint64& now); - virtual bool addEntityInternal(EntityItem* entity); + virtual void addEntityInternal(EntityItem* entity); virtual void removeEntityInternal(EntityItem* entity); virtual void entityChangedInternal(EntityItem* entity); virtual void clearEntitiesInternal(); diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 5f668b4f37..37b7035101 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -58,12 +58,12 @@ void PhysicsEngine::updateEntitiesInternal(const quint64& now) { } } -bool PhysicsEngine::addEntityInternal(EntityItem* entity) { +void PhysicsEngine::addEntityInternal(EntityItem* entity) { assert(entity); void* physicsInfo = entity->getPhysicsInfo(); if (!physicsInfo) { if (! entity->isReadyToComputeShape()) { - return false; + return; } ShapeInfo shapeInfo; entity->computeShapeInfo(shapeInfo); @@ -84,7 +84,7 @@ bool PhysicsEngine::addEntityInternal(EntityItem* entity) { //qDebug() << "failed to add entity " << entity->getEntityItemID() << " to physics engine"; } } - return true; + return; } void PhysicsEngine::removeEntityInternal(EntityItem* entity) { diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index 68161f5c12..a8c9edf2f8 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -60,7 +60,7 @@ public: // overrides for EntitySimulation void updateEntitiesInternal(const quint64& now); - bool addEntityInternal(EntityItem* entity); + void addEntityInternal(EntityItem* entity); void removeEntityInternal(EntityItem* entity); void entityChangedInternal(EntityItem* entity); void sortEntitiesThatMovedInternal(); From 2f47f7c7bad1361fd5a7884827ba20b31105f9cd Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 24 Mar 2015 16:51:42 -0700 Subject: [PATCH 09/22] diff minimization --- .../src/RenderableModelEntityItem.cpp | 1 - libraries/entities/src/EntitySimulation.h | 4 -- libraries/entities/src/EntityTree.cpp | 6 --- libraries/entities/src/EntityTree.h | 3 -- libraries/entities/src/EntityTreeElement.h | 1 - libraries/physics/src/PhysicsEngine.cpp | 38 +++++++++---------- libraries/physics/src/PhysicsEngine.h | 2 - 7 files changed, 18 insertions(+), 37 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 025da1d285..aab9786762 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -369,7 +369,6 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { glm::vec3 aaBoxDim = aaBox.getDimensions(); aaBoxDim = glm::clamp(aaBoxDim, glm::vec3(FLT_EPSILON), aaBoxDim); - // scale = dimensions / aabox glm::vec3 scale = _dimensions / aaBoxDim; // multiply each point by scale before handing the point-set off to the physics engine diff --git a/libraries/entities/src/EntitySimulation.h b/libraries/entities/src/EntitySimulation.h index 68b42e5ac9..1eb4fdc951 100644 --- a/libraries/entities/src/EntitySimulation.h +++ b/libraries/entities/src/EntitySimulation.h @@ -63,10 +63,6 @@ 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); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index da7194e4bc..3ccff46a04 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -315,12 +315,6 @@ void EntityTree::deleteEntities(QSet 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) { diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 25cc0b0bf4..29fecc88b4 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -95,8 +95,6 @@ public: void deleteEntity(const EntityItemID& entityID, bool force = false, bool ignoreWarnings = false); void deleteEntities(QSet entityIDs, bool force = false, bool ignoreWarnings = false); - // void removeEntityFromSimulation(EntityItem* entity); - void reconfigureEntity(EntityItem* entity); /// \param position point of query in world-frame (meters) /// \param targetRadius radius of query (meters) @@ -162,7 +160,6 @@ 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; } diff --git a/libraries/entities/src/EntityTreeElement.h b/libraries/entities/src/EntityTreeElement.h index e93e00cc1c..0b28dd30d0 100644 --- a/libraries/entities/src/EntityTreeElement.h +++ b/libraries/entities/src/EntityTreeElement.h @@ -147,7 +147,6 @@ 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); diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 37b7035101..a46ba9f819 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -62,29 +62,27 @@ void PhysicsEngine::addEntityInternal(EntityItem* entity) { assert(entity); void* physicsInfo = entity->getPhysicsInfo(); if (!physicsInfo) { - if (! entity->isReadyToComputeShape()) { - return; - } - ShapeInfo shapeInfo; - entity->computeShapeInfo(shapeInfo); - btCollisionShape* shape = _shapeManager.getShape(shapeInfo); - if (shape) { - EntityMotionState* motionState = new EntityMotionState(entity); - entity->setPhysicsInfo(static_cast(motionState)); - _entityMotionStates.insert(motionState); - addObject(shapeInfo, shape, motionState); - } else if (entity->isMoving()) { - EntityMotionState* motionState = new EntityMotionState(entity); - entity->setPhysicsInfo(static_cast(motionState)); - _entityMotionStates.insert(motionState); + if (entity->isReadyToComputeShape()) { + ShapeInfo shapeInfo; + entity->computeShapeInfo(shapeInfo); + btCollisionShape* shape = _shapeManager.getShape(shapeInfo); + if (shape) { + EntityMotionState* motionState = new EntityMotionState(entity); + entity->setPhysicsInfo(static_cast(motionState)); + _entityMotionStates.insert(motionState); + addObject(shapeInfo, shape, motionState); + } else if (entity->isMoving()) { + EntityMotionState* motionState = new EntityMotionState(entity); + entity->setPhysicsInfo(static_cast(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"; + 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"; + } } } - return; } void PhysicsEngine::removeEntityInternal(EntityItem* entity) { diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index a8c9edf2f8..cb637c60b9 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -88,8 +88,6 @@ public: void setAvatarData(AvatarData *avatarData); - // virtual void reconfigureEntity(EntityItem* entity); - private: /// \param motionState pointer to Object's MotionState void removeObjectFromBullet(ObjectMotionState* motionState); From dccedeadff030cd721caae413bca87804141b33e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 24 Mar 2015 16:59:12 -0700 Subject: [PATCH 10/22] diff minimization --- .../src/RenderableModelEntityItem.cpp | 8 -------- .../entities-renderer/src/RenderableModelEntityItem.h | 2 -- libraries/entities/src/EntityItem.h | 11 +---------- 3 files changed, 1 insertion(+), 20 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index aab9786762..43dbb95b6d 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -286,14 +286,6 @@ const QString& RenderableModelEntityItem::getCollisionModelURL() const { return _collisionModelURL; } -void RenderableModelEntityItem::updateDimensions(const glm::vec3& value) { - if (glm::distance(_dimensions, value) > MIN_DIMENSIONS_DELTA) { - _dimensions = value; - _dirtyFlags |= (EntityItem::DIRTY_SHAPE | EntityItem::DIRTY_MASS); - } - _model->setScaleToFit(true, _dimensions); -} - bool RenderableModelEntityItem::isReadyToComputeShape() { if (!_model) { diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 90535954b4..9146a04cf8 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -56,8 +56,6 @@ public: virtual bool hasCollisionModel() const; virtual const QString& getCollisionModelURL() const; - virtual void updateDimensions(const glm::vec3& value); - bool isReadyToComputeShape(); void computeShapeInfo(ShapeInfo& info); ShapeType getShapeType() const; diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 49e450c45e..88287f8965 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -40,15 +40,6 @@ class EntityTreeElementExtraEncodeData; #define debugTreeVector(V) V << "[" << V << " in meters ]" -extern const float MIN_POSITION_DELTA; -extern const float MIN_DIMENSIONS_DELTA; -extern const float MIN_ALIGNMENT_DOT; -extern const float MIN_VELOCITY_DELTA; -extern const float MIN_DAMPING_DELTA; -extern const float MIN_GRAVITY_DELTA; -extern const float MIN_SPIN_DELTA; - - /// 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. @@ -279,7 +270,7 @@ public: void updatePositionInDomainUnits(const glm::vec3& value); void updatePosition(const glm::vec3& value); void updateDimensionsInDomainUnits(const glm::vec3& value); - virtual void updateDimensions(const glm::vec3& value); + void updateDimensions(const glm::vec3& value); void updateRotation(const glm::quat& rotation); void updateDensity(float value); void updateMass(float value); From 719dae61a9a8d015a12f2685439b38bc6951f7e2 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 25 Mar 2015 06:51:00 -0700 Subject: [PATCH 11/22] when a compound shape is deleted, delete the children, as well --- libraries/physics/src/ShapeInfoUtil.h | 2 ++ libraries/physics/src/ShapeManager.cpp | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/libraries/physics/src/ShapeInfoUtil.h b/libraries/physics/src/ShapeInfoUtil.h index fb59f30c69..9585161440 100644 --- a/libraries/physics/src/ShapeInfoUtil.h +++ b/libraries/physics/src/ShapeInfoUtil.h @@ -20,6 +20,8 @@ // translates between ShapeInfo and btShape namespace ShapeInfoUtil { + + // XXX is collectInfoFromShape no longer strictly needed? void collectInfoFromShape(const btCollisionShape* shape, ShapeInfo& info); btCollisionShape* createShapeFromInfo(const ShapeInfo& info); diff --git a/libraries/physics/src/ShapeManager.cpp b/libraries/physics/src/ShapeManager.cpp index 513fbfa7a5..9b3b2f6d35 100644 --- a/libraries/physics/src/ShapeManager.cpp +++ b/libraries/physics/src/ShapeManager.cpp @@ -100,6 +100,18 @@ void ShapeManager::collectGarbage() { DoubleHashKey& key = _pendingGarbage[i]; ShapeReference* shapeRef = _shapeMap.find(key); if (shapeRef && shapeRef->refCount == 0) { + // if the shape we're about to delete is compound, delete the children first. + auto shapeType = ShapeInfoUtil::fromBulletShapeType(shapeRef->shape->getShapeType()); + if (shapeType == SHAPE_TYPE_COMPOUND) { + const btCompoundShape* compoundShape = static_cast(shapeRef->shape); + const int numChildShapes = compoundShape->getNumChildShapes(); + QVector> points; + for (int i = 0; i < numChildShapes; i ++) { + const btCollisionShape* childShape = compoundShape->getChildShape(i); + delete childShape; + } + } + delete shapeRef->shape; _shapeMap.remove(key); } From dd9290bd5900ac5383cba268be3470545ec45a5c Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 25 Mar 2015 15:21:28 -0700 Subject: [PATCH 12/22] clear points for non-hull shapes --- libraries/shared/src/ShapeInfo.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index 73dd945f73..5fe1fc230d 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -23,6 +23,7 @@ void ShapeInfo::clear() { void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString url) { _type = type; + _points.clear(); switch(type) { case SHAPE_TYPE_NONE: _halfExtents = glm::vec3(0.0f); @@ -56,6 +57,7 @@ void ShapeInfo::setBox(const glm::vec3& halfExtents) { _url = ""; _type = SHAPE_TYPE_BOX; _halfExtents = halfExtents; + _points.clear(); _doubleHashKey.clear(); } @@ -63,6 +65,7 @@ void ShapeInfo::setSphere(float radius) { _url = ""; _type = SHAPE_TYPE_SPHERE; _halfExtents = glm::vec3(radius, radius, radius); + _points.clear(); _doubleHashKey.clear(); } @@ -70,6 +73,7 @@ void ShapeInfo::setEllipsoid(const glm::vec3& halfExtents) { _url = ""; _type = SHAPE_TYPE_ELLIPSOID; _halfExtents = halfExtents; + _points.clear(); _doubleHashKey.clear(); } @@ -87,6 +91,7 @@ void ShapeInfo::setCapsuleY(float radius, float halfHeight) { _url = ""; _type = SHAPE_TYPE_CAPSULE_Y; _halfExtents = glm::vec3(radius, halfHeight, radius); + _points.clear(); _doubleHashKey.clear(); } From a3a54e8d7d8fe8059234699efe9202ed7f26361d Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 25 Mar 2015 15:21:36 -0700 Subject: [PATCH 13/22] style --- libraries/entities/src/ModelEntityItem.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index f135f617f4..55d809e70e 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -281,8 +281,7 @@ void ModelEntityItem::updateShapeType(ShapeType type) { } } -void ModelEntityItem::setCollisionModelURL(const QString& url) -{ +void ModelEntityItem::setCollisionModelURL(const QString& url) { if (_collisionModelURL != url) { _collisionModelURL = url; _dirtyFlags |= EntityItem::DIRTY_SHAPE | EntityItem::DIRTY_MASS; From 923951143c062c15edbeec5f31c29e605d20d8da Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 25 Mar 2015 15:21:53 -0700 Subject: [PATCH 14/22] comment out line that's killing cmake for me --- tools/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 5c7c306a62..ba2938aaa6 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -8,5 +8,5 @@ set_target_properties(scribe PROPERTIES FOLDER "Tools") find_package(VHACD) if(VHACD_FOUND) add_subdirectory(vhacd) -set_target_properties(vhacd PROPERTIES FOLDER "Tools") +# set_target_properties(vhacd PROPERTIES FOLDER "Tools") endif() From 43b30c7ffab6f19e29b29d9d9c2771039f8ad104 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 26 Mar 2015 18:35:31 -0700 Subject: [PATCH 15/22] quiet compiler --- assignment-client/src/avatars/AvatarMixer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 176fd51eea..39ae9a85ad 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -149,7 +149,8 @@ void AvatarMixer::broadcastAvatarData() { // about a given otherNode to this node // FIXME does this mean we should sort the othernodes by distance before iterating // over them? - float outputBandwidth = node->getOutboundBandwidth(); + // float outputBandwidth = + node->getOutboundBandwidth(); // this is an AGENT we have received head data from // send back a packet with other active node data to this node From 7da87d6e156bd93802261d8941e9c1ec7126671b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 26 Mar 2015 18:37:55 -0700 Subject: [PATCH 16/22] set up a way to request ResourceCache downloads from a non-networking thread. --- interface/src/Application.cpp | 12 ++++- interface/src/Application.h | 2 + libraries/networking/src/ResourceCache.cpp | 49 ++++++++++++-------- libraries/networking/src/ResourceCache.h | 12 ++++- libraries/render-utils/src/GeometryCache.cpp | 4 +- libraries/render-utils/src/GeometryCache.h | 3 +- libraries/render-utils/src/Model.cpp | 16 ++++++- libraries/render-utils/src/Model.h | 4 +- 8 files changed, 73 insertions(+), 29 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index dc8fa08c4e..a69fc3659d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -344,6 +344,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : // put the NodeList and datagram processing on the node thread nodeList->moveToThread(nodeThread); + // geometry background downloads need to happen on the Datagram Processor Thread. The idle loop will + // emit checkBackgroundDownloads to cause the GeometryCache to check it's queue for requested background + // downloads. + QSharedPointer geometryCacheP = DependencyManager::get(); + ResourceCache *geometryCache = geometryCacheP.data(); + connect(this, &Application::checkBackgroundDownloads, geometryCache, &ResourceCache::checkAsynchronousGets); + // connect the DataProcessor processDatagrams slot to the QUDPSocket readyRead() signal connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, _datagramProcessor, &DatagramProcessor::processDatagrams); @@ -1569,6 +1576,9 @@ void Application::idle() { idleTimer->start(2); } } + + // check for any requested background downloads. + emit checkBackgroundDownloads(); } void Application::setFullscreen(bool fullscreen) { @@ -3140,7 +3150,7 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { int viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); - bool eyeRelativeCamera = false; + // bool eyeRelativeCamera = false; if (billboard) { _mirrorCamera.setFieldOfView(BILLBOARD_FIELD_OF_VIEW); // degees _mirrorCamera.setPosition(_myAvatar->getPosition() + diff --git a/interface/src/Application.h b/interface/src/Application.h index 7764f297d3..54dbf60f3f 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -333,6 +333,8 @@ signals: void svoImportRequested(const QString& url); + void checkBackgroundDownloads(); + public slots: void domainChanged(const QString& domainHostname); void updateWindowTitle(); diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp index b574eb1aeb..f6dfb94903 100644 --- a/libraries/networking/src/ResourceCache.cpp +++ b/libraries/networking/src/ResourceCache.cpp @@ -18,6 +18,7 @@ #include #include +#include #include "NetworkAccessManager.h" #include "ResourceCache.h" @@ -48,32 +49,42 @@ void ResourceCache::refresh(const QUrl& url) { } } +void ResourceCache::getResourceAsynchronously(const QUrl& url) { + qDebug() << "ResourceCache::getResourceAsynchronously" << url.toString(); + _resourcesToBeGottenLock.lockForWrite(); + _resourcesToBeGotten.enqueue(QUrl(url)); + _resourcesToBeGottenLock.unlock(); +} + +void ResourceCache::checkAsynchronousGets() { + assert(QThread::currentThread() == thread()); + _resourcesToBeGottenLock.lockForRead(); + if (_resourcesToBeGotten.isEmpty()) { + _resourcesToBeGottenLock.unlock(); + return; + } + QUrl url = _resourcesToBeGotten.dequeue(); + _resourcesToBeGottenLock.unlock(); + getResource(url); +} + QSharedPointer ResourceCache::getResource(const QUrl& url, const QUrl& fallback, - bool delayLoad, void* extra, bool block) { + bool delayLoad, void* extra) { + QSharedPointer resource = _resources.value(url); + if (!resource.isNull()) { + return resource; + } + if (QThread::currentThread() != thread()) { - // This will re-call this method in the main thread. If block is true and the main thread - // is waiting on a lock, we'll deadlock here. - if (block) { - QSharedPointer result; - QMetaObject::invokeMethod(this, "getResource", Qt::BlockingQueuedConnection, - Q_RETURN_ARG(QSharedPointer, result), Q_ARG(const QUrl&, url), - Q_ARG(const QUrl&, fallback), Q_ARG(bool, delayLoad), Q_ARG(void*, extra)); - return result; - } else { - // Queue the re-invocation of this method, but if the main thread is blocked, don't wait. The - // return value may be NULL -- it's expected that this will be called again later, in order - // to receive the actual Resource. - QMetaObject::invokeMethod(this, "getResource", Qt::QueuedConnection, - Q_ARG(const QUrl&, url), - Q_ARG(const QUrl&, fallback), Q_ARG(bool, delayLoad), Q_ARG(void*, extra)); - return _resources.value(url); - } + assert(delayLoad); + getResourceAsynchronously(url); + return QSharedPointer(); } if (!url.isValid() && !url.isEmpty() && fallback.isValid()) { return getResource(fallback, QUrl(), delayLoad); } - QSharedPointer resource = _resources.value(url); + if (resource.isNull()) { resource = createResource(url, fallback.isValid() ? getResource(fallback, QUrl(), true) : QSharedPointer(), delayLoad, extra); diff --git a/libraries/networking/src/ResourceCache.h b/libraries/networking/src/ResourceCache.h index d4aa9a7fd9..c7aceb2e1a 100644 --- a/libraries/networking/src/ResourceCache.h +++ b/libraries/networking/src/ResourceCache.h @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include @@ -79,6 +81,9 @@ public: void refresh(const QUrl& url); +public slots: + void checkAsynchronousGets(); + protected: qint64 _unusedResourcesMaxSize = DEFAULT_UNUSED_MAX_SIZE; qint64 _unusedResourcesSize = 0; @@ -89,7 +94,7 @@ protected: /// \param delayLoad if true, don't load the resource immediately; wait until load is first requested /// \param extra extra data to pass to the creator, if appropriate Q_INVOKABLE QSharedPointer getResource(const QUrl& url, const QUrl& fallback = QUrl(), - bool delayLoad = false, void* extra = NULL, bool block = true); + bool delayLoad = false, void* extra = NULL); /// Creates a new resource. virtual QSharedPointer createResource(const QUrl& url, @@ -109,6 +114,11 @@ private: int _lastLRUKey = 0; static int _requestLimit; + + void getResourceAsynchronously(const QUrl& url); + QReadWriteLock _resourcesToBeGottenLock; + QQueue _resourcesToBeGotten; + }; /// Base class for resources. diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 29f76291ea..c18dfa4d5f 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -1770,8 +1770,8 @@ void GeometryCache::renderLine(const glm::vec2& p1, const glm::vec2& p2, } -QSharedPointer GeometryCache::getGeometry(const QUrl& url, const QUrl& fallback, bool delayLoad, bool block) { - return getResource(url, fallback, delayLoad, NULL, block).staticCast(); +QSharedPointer GeometryCache::getGeometry(const QUrl& url, const QUrl& fallback, bool delayLoad) { + return getResource(url, fallback, delayLoad, NULL).staticCast(); } QSharedPointer GeometryCache::createResource(const QUrl& url, diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index a64d041fc1..37156a6c71 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -203,8 +203,7 @@ public: /// Loads geometry from the specified URL. /// \param fallback a fallback URL to load if the desired one is unavailable /// \param delayLoad if true, don't load the geometry immediately; wait until load is first requested - QSharedPointer getGeometry(const QUrl& url, const QUrl& fallback = QUrl(), - bool delayLoad = false, bool block = true); + QSharedPointer getGeometry(const QUrl& url, const QUrl& fallback = QUrl(), bool delayLoad = false); protected: diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 873f458ccf..81c9f9448c 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -325,6 +325,8 @@ void Model::init() { _skinTranslucentProgram = gpu::ShaderPointer(gpu::Shader::createProgram(skinModelVertex, modelTranslucentPixel)); makeResult = gpu::Shader::makeProgram(*_skinTranslucentProgram, slotBindings); initSkinProgram(_skinTranslucentProgram, _skinTranslucentLocations); + + (void) makeResult; // quiet compiler } } @@ -1032,12 +1034,22 @@ void Model::setURL(const QUrl& url, const QUrl& fallback, bool retainCurrent, bo } } -void Model::setCollisionModelURL(const QUrl& url, const QUrl& fallback, bool delayLoad) { + +const QSharedPointer Model::getCollisionGeometry(bool delayLoad) +{ + if (_collisionGeometry.isNull() && !_collisionUrl.isEmpty()) { + _collisionGeometry = DependencyManager::get()->getGeometry(_collisionUrl, QUrl(), delayLoad); + } + + return _collisionGeometry; +} + +void Model::setCollisionModelURL(const QUrl& url) { if (_collisionUrl == url) { return; } _collisionUrl = url; - _collisionGeometry = DependencyManager::get()->getGeometry(url, fallback, delayLoad); + _collisionGeometry = DependencyManager::get()->getGeometry(url, QUrl(), true); } bool Model::getJointPositionInWorldFrame(int jointIndex, glm::vec3& position) const { diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 05db20b056..3b4cbdd450 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -109,7 +109,7 @@ public: 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); + Q_INVOKABLE void setCollisionModelURL(const QUrl& url); const QUrl& getCollisionURL() const { return _collisionUrl; } /// Sets the distance parameter used for LOD computations. @@ -134,7 +134,7 @@ public: const QSharedPointer& getGeometry() const { return _geometry; } /// Returns a reference to the shared collision geometry. - const QSharedPointer getCollisionGeometry() {return _collisionGeometry; } + const QSharedPointer getCollisionGeometry(bool delayLoad = true); /// Returns the number of joint states in the model. int getJointStateCount() const { return _jointStates.size(); } From 087248dffca654f6dc2444af5ca86715300672c5 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 27 Mar 2015 13:14:20 -0700 Subject: [PATCH 17/22] fix locking in ResourceCache::checkAsynchronousGets --- libraries/networking/src/ResourceCache.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp index f6dfb94903..739e587f5f 100644 --- a/libraries/networking/src/ResourceCache.cpp +++ b/libraries/networking/src/ResourceCache.cpp @@ -58,14 +58,12 @@ void ResourceCache::getResourceAsynchronously(const QUrl& url) { void ResourceCache::checkAsynchronousGets() { assert(QThread::currentThread() == thread()); - _resourcesToBeGottenLock.lockForRead(); - if (_resourcesToBeGotten.isEmpty()) { + if (!_resourcesToBeGotten.isEmpty()) { + _resourcesToBeGottenLock.lockForWrite(); + QUrl url = _resourcesToBeGotten.dequeue(); _resourcesToBeGottenLock.unlock(); - return; + getResource(url); } - QUrl url = _resourcesToBeGotten.dequeue(); - _resourcesToBeGottenLock.unlock(); - getResource(url); } QSharedPointer ResourceCache::getResource(const QUrl& url, const QUrl& fallback, From cfa30594cc5187889968d79916c06ca6a902dddd Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 27 Mar 2015 14:24:36 -0700 Subject: [PATCH 18/22] make obj reader handle faces with more than 4 vertices --- libraries/fbx/src/OBJReader.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/libraries/fbx/src/OBJReader.cpp b/libraries/fbx/src/OBJReader.cpp index 0aaf8772a2..db2733f27b 100644 --- a/libraries/fbx/src/OBJReader.cpp +++ b/libraries/fbx/src/OBJReader.cpp @@ -249,7 +249,20 @@ bool parseOBJGroup(OBJTokenizer &tokenizer, const QVariantHash& mapping, } else if (indices.count() == 4) { meshPart.quadIndices << indices; } else { - qDebug() << "no support for more than 4 vertices on a face in OBJ files"; + // some obj writers (maya) will write a face with lots of points. + for (int i = 1; i < indices.count() - 1; i++) { + // break the face into triangles + meshPart.triangleIndices.append(indices[0]); + meshPart.triangleIndices.append(indices[i]); + meshPart.triangleIndices.append(indices[i+1]); + } + if (indices.count() == normalIndices.count()) { + for (int i = 1; i < normalIndices.count() - 1; i++) { + faceNormalIndexes.append(normalIndices[0]); + faceNormalIndexes.append(normalIndices[i]); + faceNormalIndexes.append(normalIndices[i+1]); + } + } } } else { // something we don't (yet) care about From 90f51e7d4c5d18f1df7c9c4cc07150f74ec3fc49 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 27 Mar 2015 16:15:54 -0700 Subject: [PATCH 19/22] print a warning when ShapeManager is skipping over a too-large or too-small shape --- libraries/physics/src/ShapeManager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/physics/src/ShapeManager.cpp b/libraries/physics/src/ShapeManager.cpp index 9b3b2f6d35..2a8705561d 100644 --- a/libraries/physics/src/ShapeManager.cpp +++ b/libraries/physics/src/ShapeManager.cpp @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include + #include #include "ShapeInfoUtil.h" @@ -35,6 +37,7 @@ btCollisionShape* ShapeManager::getShape(const ShapeInfo& info) { const float MIN_SHAPE_DIAGONAL_SQUARED = 3.0e-4f; // 1 cm cube const float MAX_SHAPE_DIAGONAL_SQUARED = 3.0e4f; // 100 m cube if (diagonal < MIN_SHAPE_DIAGONAL_SQUARED || diagonal > MAX_SHAPE_DIAGONAL_SQUARED) { + qDebug() << "ShapeManager::getShape -- not making shape due to size" << diagonal; return NULL; } DoubleHashKey key = info.getHash(); From adf076a63077fed8168233629cefc20ebe3c0322 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 30 Mar 2015 09:56:30 -0700 Subject: [PATCH 20/22] optimizations when creating convex hull shapes --- libraries/physics/src/ShapeInfoUtil.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/libraries/physics/src/ShapeInfoUtil.cpp b/libraries/physics/src/ShapeInfoUtil.cpp index 1073fbae3f..8900c5a0dc 100644 --- a/libraries/physics/src/ShapeInfoUtil.cpp +++ b/libraries/physics/src/ShapeInfoUtil.cpp @@ -136,28 +136,32 @@ btCollisionShape* ShapeInfoUtil::createShapeFromInfo(const ShapeInfo& info) { } break; case SHAPE_TYPE_CONVEX_HULL: { - shape = new btConvexHullShape(); + auto hull = new btConvexHullShape(); const QVector>& points = info.getPoints(); foreach (glm::vec3 point, points[0]) { btVector3 btPoint(point[0], point[1], point[2]); - static_cast(shape)->addPoint(btPoint); + hull->addPoint(btPoint, false); } + hull->recalcLocalAabb(); + shape = hull; } break; case SHAPE_TYPE_COMPOUND: { - shape = new btCompoundShape(); + auto compound = new btCompoundShape(); const QVector>& points = info.getPoints(); - foreach (QVector hullPoints, info.getPoints()) { + btTransform trans; + trans.setIdentity(); + foreach (QVector hullPoints, points) { auto hull = new btConvexHullShape(); foreach (glm::vec3 point, hullPoints) { btVector3 btPoint(point[0], point[1], point[2]); - hull->addPoint(btPoint); + hull->addPoint(btPoint, false); } - btTransform trans; - trans.setIdentity(); - static_cast(shape)->addChildShape (trans, hull); + hull->recalcLocalAabb(); + compound->addChildShape (trans, hull); } + shape = compound; } break; } From 8a5192c1d93af5fa65964dc75963a2967dd6265a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 30 Mar 2015 11:22:31 -0700 Subject: [PATCH 21/22] attempt to handle registration point in hull collisions --- libraries/entities-renderer/src/RenderableModelEntityItem.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 43dbb95b6d..eb6706e27f 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -366,6 +366,9 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { // multiply each point by scale before handing the point-set off to the physics engine for (int i = 0; i < _points.size(); i++) { for (int j = 0; j < _points[i].size(); j++) { + // compensate for registraion + _points[i][j] += _model->getOffset(); + // scale so the collision points match the model points _points[i][j] *= scale; } } From e730109c51eea2bd22981cbe7a66be6866ec2b02 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 30 Mar 2015 11:46:48 -0700 Subject: [PATCH 22/22] quiet debuging spew --- libraries/physics/src/ShapeManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/physics/src/ShapeManager.cpp b/libraries/physics/src/ShapeManager.cpp index 2a8705561d..b4d322a4a3 100644 --- a/libraries/physics/src/ShapeManager.cpp +++ b/libraries/physics/src/ShapeManager.cpp @@ -37,7 +37,7 @@ btCollisionShape* ShapeManager::getShape(const ShapeInfo& info) { const float MIN_SHAPE_DIAGONAL_SQUARED = 3.0e-4f; // 1 cm cube const float MAX_SHAPE_DIAGONAL_SQUARED = 3.0e4f; // 100 m cube if (diagonal < MIN_SHAPE_DIAGONAL_SQUARED || diagonal > MAX_SHAPE_DIAGONAL_SQUARED) { - qDebug() << "ShapeManager::getShape -- not making shape due to size" << diagonal; + // qDebug() << "ShapeManager::getShape -- not making shape due to size" << diagonal; return NULL; } DoubleHashKey key = info.getHash();