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();