Make possible to change the size of the collision shapes after their creation

This commit is contained in:
Daniel Chappuis 2020-02-06 07:21:13 +01:00
parent c5873dbc6b
commit 9d776e32dc
29 changed files with 263 additions and 298 deletions

View File

@ -2,6 +2,15 @@
## Develop ## Develop
### Added
- It is now possible to change the size of a BoxShape using the BoxShape::setHalfExtents() method
- It is now possible to change the radius of a SphereShape using the SphereShape::setRadius() method
- It is now possible to change the height and radius of a CapsuleShape using the CapsuleShape::setHeight() and CapsuleShape::setRadius methods
- It is now possible to change the scale of a ConvexMeshShape using the ConvexMeshShape::setScale() method
- It is now possible to change the scale of a ConcaveMeshShape using the ConcaveMeshShape::setScale() method
- It is now possible to change the scale of a HeightFieldShape using the HeightFieldShape::setScale() method
### Changed ### Changed
- The CollisionWorld::testCollision() methods do not have the 'categoryMaskBits' parameter anymore. - The CollisionWorld::testCollision() methods do not have the 'categoryMaskBits' parameter anymore.
@ -16,6 +25,7 @@
- The Logger has to be instanciated using the PhysicsCommon::createLogger() method instead of using its constructor. - The Logger has to be instanciated using the PhysicsCommon::createLogger() method instead of using its constructor.
- The Profiler has to be instanciated using the PhysicsCommon::createProfiler() method instead of using its constructor. - The Profiler has to be instanciated using the PhysicsCommon::createProfiler() method instead of using its constructor.
- There is now a single MemoryManager (with memory allocators) per PhysicsWorld. The memory allocators are no longer shared between worlds. - There is now a single MemoryManager (with memory allocators) per PhysicsWorld. The memory allocators are no longer shared between worlds.
- The Box::getExtent() method has been renamed to Box::getHalfExtents()
- An instance of the BoxShape class cannot be instanciated directly anymore. You need to use the PhysicsCommon::createBoxShape() method. - An instance of the BoxShape class cannot be instanciated directly anymore. You need to use the PhysicsCommon::createBoxShape() method.
- An instance of the SphereShape class cannot be instanciated directly anymore. You need to use the PhysicsCommon::createSphereShape() method. - An instance of the SphereShape class cannot be instanciated directly anymore. You need to use the PhysicsCommon::createSphereShape() method.
- An instance of the CapsuleShape class cannot be instanciated directly anymore. You need to use the PhysicsCommon::createCapsuleShape() method. - An instance of the CapsuleShape class cannot be instanciated directly anymore. You need to use the PhysicsCommon::createCapsuleShape() method.
@ -25,6 +35,7 @@
- An instance of the PolyhedronMesh class cannot be instanciated directly anymore. You need to use the PhysicsCommon::createPolyhedronMesh() method. - An instance of the PolyhedronMesh class cannot be instanciated directly anymore. You need to use the PhysicsCommon::createPolyhedronMesh() method.
- An instance of the TriangleMesh class cannot be instanciated directly anymore. You need to use the PhysicsCommon::createTriangleMesh() method. - An instance of the TriangleMesh class cannot be instanciated directly anymore. You need to use the PhysicsCommon::createTriangleMesh() method.
- The ProxyShape class has been renamed to Collider. The CollisionBody::addCollider(), RigidBody::addCollider() methods have to be used to create and add a collider to a body. Then methods CollisionBody::removeCollider(), RigidBody::removeCollider() need to be used to remove a collider. - The ProxyShape class has been renamed to Collider. The CollisionBody::addCollider(), RigidBody::addCollider() methods have to be used to create and add a collider to a body. Then methods CollisionBody::removeCollider(), RigidBody::removeCollider() need to be used to remove a collider.
- The rendering in the testbed application has been improved
### Removed ### Removed

View File

@ -112,6 +112,9 @@ class AABB {
/// Return true if the ray intersects the AABB /// Return true if the ray intersects the AABB
bool testRayIntersect(const Ray& ray) const; bool testRayIntersect(const Ray& ray) const;
/// Apply a scale factor to the AABB
void applyScale(const Vector3& scale);
/// Create and return an AABB for a triangle /// Create and return an AABB for a triangle
static AABB createAABBForTriangle(const Vector3* trianglePoints); static AABB createAABBForTriangle(const Vector3* trianglePoints);
@ -199,6 +202,12 @@ inline bool AABB::contains(const Vector3& point) const {
point.z >= mMinCoordinates.z - MACHINE_EPSILON && point.z <= mMaxCoordinates.z + MACHINE_EPSILON); point.z >= mMinCoordinates.z - MACHINE_EPSILON && point.z <= mMaxCoordinates.z + MACHINE_EPSILON);
} }
// Apply a scale factor to the AABB
inline void AABB::applyScale(const Vector3& scale) {
mMinCoordinates = mMinCoordinates * scale;
mMaxCoordinates = mMaxCoordinates * scale;
}
// Assignment operator // Assignment operator
inline AABB& AABB::operator=(const AABB& aabb) { inline AABB& AABB::operator=(const AABB& aabb) {
if (this != &aabb) { if (this != &aabb) {

View File

@ -35,15 +35,15 @@ using namespace reactphysics3d;
// Constructor // Constructor
/** /**
* @param extent The vector with the three extents of the box (in meters) * @param halfExtents The vector with the three half-extents of the box
*/ */
BoxShape::BoxShape(const Vector3& extent, MemoryAllocator& allocator) BoxShape::BoxShape(const Vector3& halfExtents, MemoryAllocator& allocator)
: ConvexPolyhedronShape(CollisionShapeName::BOX), mExtent(extent), : ConvexPolyhedronShape(CollisionShapeName::BOX), mHalfExtents(halfExtents),
mHalfEdgeStructure(allocator, 6, 8, 24) { mHalfEdgeStructure(allocator, 6, 8, 24) {
assert(extent.x > decimal(0.0)); assert(halfExtents.x > decimal(0.0));
assert(extent.y > decimal(0.0)); assert(halfExtents.y > decimal(0.0));
assert(extent.z > decimal(0.0)); assert(halfExtents.z > decimal(0.0));
// Vertices // Vertices
mHalfEdgeStructure.addVertex(0); mHalfEdgeStructure.addVertex(0);
@ -87,9 +87,9 @@ BoxShape::BoxShape(const Vector3& extent, MemoryAllocator& allocator)
*/ */
void BoxShape::computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const { void BoxShape::computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const {
decimal factor = (decimal(1.0) / decimal(3.0)) * mass; decimal factor = (decimal(1.0) / decimal(3.0)) * mass;
decimal xSquare = mExtent.x * mExtent.x; decimal xSquare = mHalfExtents.x * mHalfExtents.x;
decimal ySquare = mExtent.y * mExtent.y; decimal ySquare = mHalfExtents.y * mHalfExtents.y;
decimal zSquare = mExtent.z * mExtent.z; decimal zSquare = mHalfExtents.z * mHalfExtents.z;
tensor.setAllValues(factor * (ySquare + zSquare), 0.0, 0.0, tensor.setAllValues(factor * (ySquare + zSquare), 0.0, 0.0,
0.0, factor * (xSquare + zSquare), 0.0, 0.0, factor * (xSquare + zSquare), 0.0,
0.0, 0.0, factor * (xSquare + ySquare)); 0.0, 0.0, factor * (xSquare + ySquare));
@ -111,17 +111,17 @@ bool BoxShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, Collider* colli
if (std::abs(rayDirection[i]) < MACHINE_EPSILON) { if (std::abs(rayDirection[i]) < MACHINE_EPSILON) {
// If the ray's origin is not inside the slab, there is no hit // If the ray's origin is not inside the slab, there is no hit
if (ray.point1[i] > mExtent[i] || ray.point1[i] < -mExtent[i]) return false; if (ray.point1[i] > mHalfExtents[i] || ray.point1[i] < -mHalfExtents[i]) return false;
} }
else { else {
// Compute the intersection of the ray with the near and far plane of the slab // Compute the intersection of the ray with the near and far plane of the slab
decimal oneOverD = decimal(1.0) / rayDirection[i]; decimal oneOverD = decimal(1.0) / rayDirection[i];
decimal t1 = (-mExtent[i] - ray.point1[i]) * oneOverD; decimal t1 = (-mHalfExtents[i] - ray.point1[i]) * oneOverD;
decimal t2 = (mExtent[i] - ray.point1[i]) * oneOverD; decimal t2 = (mHalfExtents[i] - ray.point1[i]) * oneOverD;
currentNormal[0] = (i == 0) ? -mExtent[i] : decimal(0.0); currentNormal[0] = (i == 0) ? -mHalfExtents[i] : decimal(0.0);
currentNormal[1] = (i == 1) ? -mExtent[i] : decimal(0.0); currentNormal[1] = (i == 1) ? -mHalfExtents[i] : decimal(0.0);
currentNormal[2] = (i == 2) ? -mExtent[i] : decimal(0.0); currentNormal[2] = (i == 2) ? -mHalfExtents[i] : decimal(0.0);
// Swap t1 and t2 if need so that t1 is intersection with near plane and // Swap t1 and t2 if need so that t1 is intersection with near plane and
// t2 with far plane // t2 with far plane

View File

@ -50,8 +50,8 @@ class BoxShape : public ConvexPolyhedronShape {
// -------------------- Attributes -------------------- // // -------------------- Attributes -------------------- //
/// Extent sizes of the box in the x, y and z direction /// Half-extents of the box in the x, y and z direction
Vector3 mExtent; Vector3 mHalfExtents;
/// Half-edge structure of the polyhedron /// Half-edge structure of the polyhedron
HalfEdgeStructure mHalfEdgeStructure; HalfEdgeStructure mHalfEdgeStructure;
@ -59,7 +59,7 @@ class BoxShape : public ConvexPolyhedronShape {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
BoxShape(const Vector3& extent, MemoryAllocator& allocator); BoxShape(const Vector3& halfExtents, MemoryAllocator& allocator);
/// Return a local support point in a given direction without the object margin /// Return a local support point in a given direction without the object margin
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const override; virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const override;
@ -86,8 +86,11 @@ class BoxShape : public ConvexPolyhedronShape {
/// Deleted assignment operator /// Deleted assignment operator
BoxShape& operator=(const BoxShape& shape) = delete; BoxShape& operator=(const BoxShape& shape) = delete;
/// Return the extents of the box /// Return the half-extents of the box
Vector3 getExtent() const; Vector3 getHalfExtents() const;
/// Set the half-extents of the box
void setHalfExtents(const Vector3& halfExtents);
/// Return the local bounds of the shape in x, y and z directions /// Return the local bounds of the shape in x, y and z directions
virtual void getLocalBounds(Vector3& min, Vector3& max) const override; virtual void getLocalBounds(Vector3& min, Vector3& max) const override;
@ -132,10 +135,20 @@ class BoxShape : public ConvexPolyhedronShape {
// Return the extents of the box // Return the extents of the box
/** /**
* @return The vector with the three extents of the box shape (in meters) * @return The vector with the three half-extents of the box shape
*/ */
inline Vector3 BoxShape::getExtent() const { inline Vector3 BoxShape::getHalfExtents() const {
return mExtent; return mHalfExtents;
}
// Set the half-extents of the box
/// Note that you might want to recompute the inertia tensor and center of mass of the body
/// after changing the size of the collision shape
/**
* @param halfExtents The vector with the three half-extents of the box
*/
inline void BoxShape::setHalfExtents(const Vector3& halfExtents) {
mHalfExtents = halfExtents;
} }
// Return the local bounds of the shape in x, y and z directions // Return the local bounds of the shape in x, y and z directions
@ -147,7 +160,7 @@ inline Vector3 BoxShape::getExtent() const {
inline void BoxShape::getLocalBounds(Vector3& min, Vector3& max) const { inline void BoxShape::getLocalBounds(Vector3& min, Vector3& max) const {
// Maximum bounds // Maximum bounds
max = mExtent; max = mHalfExtents;
// Minimum bounds // Minimum bounds
min = -max; min = -max;
@ -161,16 +174,16 @@ inline size_t BoxShape::getSizeInBytes() const {
// Return a local support point in a given direction without the object margin // Return a local support point in a given direction without the object margin
inline Vector3 BoxShape::getLocalSupportPointWithoutMargin(const Vector3& direction) const { inline Vector3 BoxShape::getLocalSupportPointWithoutMargin(const Vector3& direction) const {
return Vector3(direction.x < decimal(0.0) ? -mExtent.x : mExtent.x, return Vector3(direction.x < decimal(0.0) ? -mHalfExtents.x : mHalfExtents.x,
direction.y < decimal(0.0) ? -mExtent.y : mExtent.y, direction.y < decimal(0.0) ? -mHalfExtents.y : mHalfExtents.y,
direction.z < decimal(0.0) ? -mExtent.z : mExtent.z); direction.z < decimal(0.0) ? -mHalfExtents.z : mHalfExtents.z);
} }
// Return true if a point is inside the collision shape // Return true if a point is inside the collision shape
inline bool BoxShape::testPointInside(const Vector3& localPoint, Collider* collider) const { inline bool BoxShape::testPointInside(const Vector3& localPoint, Collider* collider) const {
return (localPoint.x < mExtent[0] && localPoint.x > -mExtent[0] && return (localPoint.x < mHalfExtents[0] && localPoint.x > -mHalfExtents[0] &&
localPoint.y < mExtent[1] && localPoint.y > -mExtent[1] && localPoint.y < mHalfExtents[1] && localPoint.y > -mHalfExtents[1] &&
localPoint.z < mExtent[2] && localPoint.z > -mExtent[2]); localPoint.z < mHalfExtents[2] && localPoint.z > -mHalfExtents[2]);
} }
// Return the number of faces of the polyhedron // Return the number of faces of the polyhedron
@ -199,7 +212,7 @@ inline HalfEdgeStructure::Vertex BoxShape::getVertex(uint vertexIndex) const {
inline Vector3 BoxShape::getVertexPosition(uint vertexIndex) const { inline Vector3 BoxShape::getVertexPosition(uint vertexIndex) const {
assert(vertexIndex < getNbVertices()); assert(vertexIndex < getNbVertices());
Vector3 extent = getExtent(); Vector3 extent = getHalfExtents();
switch(vertexIndex) { switch(vertexIndex) {
case 0: return Vector3(-extent.x, -extent.y, extent.z); case 0: return Vector3(-extent.x, -extent.y, extent.z);
@ -240,7 +253,7 @@ inline Vector3 BoxShape::getCentroid() const {
// Return the string representation of the shape // Return the string representation of the shape
inline std::string BoxShape::to_string() const { inline std::string BoxShape::to_string() const {
return "BoxShape{extents=" + mExtent.to_string() + "}"; return "BoxShape{extents=" + mHalfExtents.to_string() + "}";
} }
// Return the number of half-edges of the polyhedron // Return the number of half-edges of the polyhedron

View File

@ -39,6 +39,7 @@ using namespace reactphysics3d;
*/ */
CapsuleShape::CapsuleShape(decimal radius, decimal height) CapsuleShape::CapsuleShape(decimal radius, decimal height)
: ConvexShape(CollisionShapeName::CAPSULE, CollisionShapeType::CAPSULE, radius), mHalfHeight(height * decimal(0.5)) { : ConvexShape(CollisionShapeName::CAPSULE, CollisionShapeType::CAPSULE, radius), mHalfHeight(height * decimal(0.5)) {
// TODO : Throw a library error here if radius or height is not larger than zero
assert(radius > decimal(0.0)); assert(radius > decimal(0.0));
assert(height > decimal(0.0)); assert(height > decimal(0.0));
} }

View File

@ -93,9 +93,15 @@ class CapsuleShape : public ConvexShape {
/// Return the radius of the capsule /// Return the radius of the capsule
decimal getRadius() const; decimal getRadius() const;
/// Set the radius of the capsule
void setRadius(decimal radius);
/// Return the height of the capsule /// Return the height of the capsule
decimal getHeight() const; decimal getHeight() const;
/// Set the height of the capsule
void setHeight(decimal height);
/// Return the local bounds of the shape in x, y and z directions /// Return the local bounds of the shape in x, y and z directions
virtual void getLocalBounds(Vector3& min, Vector3& max) const override; virtual void getLocalBounds(Vector3& min, Vector3& max) const override;
@ -121,6 +127,18 @@ inline decimal CapsuleShape::getRadius() const {
return mMargin; return mMargin;
} }
// Set the radius of the capsule
/// Note that you might want to recompute the inertia tensor and center of mass of the body
/// after changing the radius of the collision shape
/**
* @param radius The radius of the capsule (in meters)
*/
inline void CapsuleShape::setRadius(decimal radius) {
// TODO : Throw a library error here if radius is not larger than zero
assert(radius > decimal(0.0));
mMargin = radius;
}
// Return the height of the capsule // Return the height of the capsule
/** /**
* @return The height of the capsule shape (in meters) * @return The height of the capsule shape (in meters)
@ -129,6 +147,19 @@ inline decimal CapsuleShape::getHeight() const {
return mHalfHeight + mHalfHeight; return mHalfHeight + mHalfHeight;
} }
// Set the height of the capsule
/// Note that you might want to recompute the inertia tensor and center of mass of the body
/// after changing the height of the collision shape
/**
* @param height The height of the capsule (in meters)
*/
inline void CapsuleShape::setHeight(decimal height) {
// TODO : Throw a library error here if radius is not larger than zero
assert(height > decimal(0.0));
mHalfHeight = height * decimal(0.5);
}
// Return the number of bytes used by the collision shape // Return the number of bytes used by the collision shape
inline size_t CapsuleShape::getSizeInBytes() const { inline size_t CapsuleShape::getSizeInBytes() const {
return sizeof(CapsuleShape); return sizeof(CapsuleShape);

View File

@ -35,8 +35,8 @@ using namespace reactphysics3d;
// Constructor // Constructor
ConcaveMeshShape::ConcaveMeshShape(TriangleMesh* triangleMesh, MemoryAllocator& allocator, const Vector3& scaling) ConcaveMeshShape::ConcaveMeshShape(TriangleMesh* triangleMesh, MemoryAllocator& allocator, const Vector3& scaling)
: ConcaveShape(CollisionShapeName::TRIANGLE_MESH), mDynamicAABBTree(allocator), : ConcaveShape(CollisionShapeName::TRIANGLE_MESH, scaling), mDynamicAABBTree(allocator) {
mScaling(scaling) {
mTriangleMesh = triangleMesh; mTriangleMesh = triangleMesh;
mRaycastTestType = TriangleRaycastSide::FRONT; mRaycastTestType = TriangleRaycastSide::FRONT;
@ -63,17 +63,6 @@ void ConcaveMeshShape::initBVHTree() {
// Get the triangle vertices // Get the triangle vertices
triangleVertexArray->getTriangleVertices(triangleIndex, trianglePoints); triangleVertexArray->getTriangleVertices(triangleIndex, trianglePoints);
// Apply the scaling factor to the vertices
trianglePoints[0].x *= mScaling.x;
trianglePoints[0].y *= mScaling.y;
trianglePoints[0].z *= mScaling.z;
trianglePoints[1].x *= mScaling.x;
trianglePoints[1].y *= mScaling.y;
trianglePoints[1].z *= mScaling.z;
trianglePoints[2].x *= mScaling.x;
trianglePoints[2].y *= mScaling.y;
trianglePoints[2].z *= mScaling.z;
// Create the AABB for the triangle // Create the AABB for the triangle
AABB aabb = AABB::createAABBForTriangle(trianglePoints); AABB aabb = AABB::createAABBForTriangle(trianglePoints);
@ -93,15 +82,15 @@ void ConcaveMeshShape::getTriangleVertices(uint subPart, uint triangleIndex, Vec
triangleVertexArray->getTriangleVertices(triangleIndex, outTriangleVertices); triangleVertexArray->getTriangleVertices(triangleIndex, outTriangleVertices);
// Apply the scaling factor to the vertices // Apply the scaling factor to the vertices
outTriangleVertices[0].x *= mScaling.x; outTriangleVertices[0].x *= mScale.x;
outTriangleVertices[0].y *= mScaling.y; outTriangleVertices[0].y *= mScale.y;
outTriangleVertices[0].z *= mScaling.z; outTriangleVertices[0].z *= mScale.z;
outTriangleVertices[1].x *= mScaling.x; outTriangleVertices[1].x *= mScale.x;
outTriangleVertices[1].y *= mScaling.y; outTriangleVertices[1].y *= mScale.y;
outTriangleVertices[1].z *= mScaling.z; outTriangleVertices[1].z *= mScale.z;
outTriangleVertices[2].x *= mScaling.x; outTriangleVertices[2].x *= mScale.x;
outTriangleVertices[2].y *= mScaling.y; outTriangleVertices[2].y *= mScale.y;
outTriangleVertices[2].z *= mScaling.z; outTriangleVertices[2].z *= mScale.z;
} }
// Return the three vertex normals (in the array outVerticesNormals) of a triangle // Return the three vertex normals (in the array outVerticesNormals) of a triangle
@ -144,9 +133,14 @@ void ConcaveMeshShape::computeOverlappingTriangles(const AABB& localAABB, List<V
RP3D_PROFILE("ConcaveMeshShape::computeOverlappingTriangles()", mProfiler); RP3D_PROFILE("ConcaveMeshShape::computeOverlappingTriangles()", mProfiler);
// Scale the input AABB with the inverse scale of the concave mesh (because
// we store the vertices without scale inside the dynamic AABB tree
AABB aabb(localAABB);
aabb.applyScale(Vector3(decimal(1.0) / mScale.x, decimal(1.0) / mScale.y, decimal(1.0) / mScale.z));
// Compute the nodes of the internal AABB tree that are overlapping with the AABB // Compute the nodes of the internal AABB tree that are overlapping with the AABB
List<int> overlappingNodes(allocator); List<int> overlappingNodes(allocator);
mDynamicAABBTree.reportAllShapesOverlappingWithAABB(localAABB, overlappingNodes); mDynamicAABBTree.reportAllShapesOverlappingWithAABB(aabb, overlappingNodes);
const uint nbOverlappingNodes = overlappingNodes.size(); const uint nbOverlappingNodes = overlappingNodes.size();
@ -180,8 +174,13 @@ bool ConcaveMeshShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, Collide
RP3D_PROFILE("ConcaveMeshShape::raycast()", mProfiler); RP3D_PROFILE("ConcaveMeshShape::raycast()", mProfiler);
// Apply the concave mesh inverse scale factor because the mesh is stored without scaling
// inside the dynamic AABB tree
const Vector3 inverseScale(decimal(1.0) / mScale.x, decimal(1.0) / mScale.y, decimal(1.0) / mScale.z);
Ray scaledRay(ray.point1 * inverseScale, ray.point2 * inverseScale, ray.maxFraction);
// Create the callback object that will compute ray casting against triangles // Create the callback object that will compute ray casting against triangles
ConcaveMeshRaycastCallback raycastCallback(mDynamicAABBTree, *this, collider, raycastInfo, ray, allocator); ConcaveMeshRaycastCallback raycastCallback(mDynamicAABBTree, *this, collider, raycastInfo, scaledRay, mScale, allocator);
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE
@ -193,7 +192,7 @@ bool ConcaveMeshShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, Collide
// Ask the Dynamic AABB Tree to report all AABB nodes that are hit by the ray. // Ask the Dynamic AABB Tree to report all AABB nodes that are hit by the ray.
// The raycastCallback object will then compute ray casting against the triangles // The raycastCallback object will then compute ray casting against the triangles
// in the hit AABBs. // in the hit AABBs.
mDynamicAABBTree.raycast(ray, raycastCallback); mDynamicAABBTree.raycast(scaledRay, raycastCallback);
raycastCallback.raycastTriangles(); raycastCallback.raycastTriangles();
@ -269,7 +268,7 @@ void ConcaveMeshRaycastCallback::raycastTriangles() {
mRaycastInfo.body = raycastInfo.body; mRaycastInfo.body = raycastInfo.body;
mRaycastInfo.collider = raycastInfo.collider; mRaycastInfo.collider = raycastInfo.collider;
mRaycastInfo.hitFraction = raycastInfo.hitFraction; mRaycastInfo.hitFraction = raycastInfo.hitFraction;
mRaycastInfo.worldPoint = raycastInfo.worldPoint; mRaycastInfo.worldPoint = raycastInfo.worldPoint * mMeshScale;
mRaycastInfo.worldNormal = raycastInfo.worldNormal; mRaycastInfo.worldNormal = raycastInfo.worldNormal;
mRaycastInfo.meshSubpart = data[0]; mRaycastInfo.meshSubpart = data[0];
mRaycastInfo.triangleIndex = data[1]; mRaycastInfo.triangleIndex = data[1];
@ -277,7 +276,6 @@ void ConcaveMeshRaycastCallback::raycastTriangles() {
smallestHitFraction = raycastInfo.hitFraction; smallestHitFraction = raycastInfo.hitFraction;
mIsHit = true; mIsHit = true;
} }
} }
} }

View File

@ -80,6 +80,7 @@ class ConcaveMeshRaycastCallback : public DynamicAABBTreeRaycastCallback {
const Ray& mRay; const Ray& mRay;
bool mIsHit; bool mIsHit;
MemoryAllocator& mAllocator; MemoryAllocator& mAllocator;
const Vector3& mMeshScale;
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE
@ -92,9 +93,9 @@ class ConcaveMeshRaycastCallback : public DynamicAABBTreeRaycastCallback {
// Constructor // Constructor
ConcaveMeshRaycastCallback(const DynamicAABBTree& dynamicAABBTree, const ConcaveMeshShape& concaveMeshShape, ConcaveMeshRaycastCallback(const DynamicAABBTree& dynamicAABBTree, const ConcaveMeshShape& concaveMeshShape,
Collider* collider, RaycastInfo& raycastInfo, const Ray& ray, MemoryAllocator& allocator) Collider* collider, RaycastInfo& raycastInfo, const Ray& ray, const Vector3& meshScale, MemoryAllocator& allocator)
: mHitAABBNodes(allocator), mDynamicAABBTree(dynamicAABBTree), mConcaveMeshShape(concaveMeshShape), mCollider(collider), : mHitAABBNodes(allocator), mDynamicAABBTree(dynamicAABBTree), mConcaveMeshShape(concaveMeshShape), mCollider(collider),
mRaycastInfo(raycastInfo), mRay(ray), mIsHit(false), mAllocator(allocator) { mRaycastInfo(raycastInfo), mRay(ray), mIsHit(false), mAllocator(allocator), mMeshScale(meshScale) {
} }
@ -131,7 +132,7 @@ class ConcaveMeshShape : public ConcaveShape {
// -------------------- Attributes -------------------- // // -------------------- Attributes -------------------- //
/// Triangle mesh /// Pointer to the triangle mesh
TriangleMesh* mTriangleMesh; TriangleMesh* mTriangleMesh;
/// Dynamic AABB tree to accelerate collision with the triangles /// Dynamic AABB tree to accelerate collision with the triangles
@ -141,9 +142,6 @@ class ConcaveMeshShape : public ConcaveShape {
/// if the user did not provide its own vertices normals) /// if the user did not provide its own vertices normals)
Vector3** mComputedVerticesNormals; Vector3** mComputedVerticesNormals;
/// Scaling
const Vector3 mScaling;
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
@ -168,7 +166,7 @@ class ConcaveMeshShape : public ConcaveShape {
uint computeTriangleShapeId(uint subPart, uint triangleIndex) const; uint computeTriangleShapeId(uint subPart, uint triangleIndex) const;
/// Compute all the triangles of the mesh that are overlapping with the AABB in parameter /// Compute all the triangles of the mesh that are overlapping with the AABB in parameter
virtual void computeOverlappingTriangles(const AABB& localAABB, List<Vector3> &triangleVertices, virtual void computeOverlappingTriangles(const AABB& localAABB, List<Vector3>& triangleVertices,
List<Vector3> &triangleVerticesNormals, List<uint>& shapeIds, List<Vector3> &triangleVerticesNormals, List<uint>& shapeIds,
MemoryAllocator& allocator) const override; MemoryAllocator& allocator) const override;
@ -183,9 +181,6 @@ class ConcaveMeshShape : public ConcaveShape {
/// Deleted assignment operator /// Deleted assignment operator
ConcaveMeshShape& operator=(const ConcaveMeshShape& shape) = delete; ConcaveMeshShape& operator=(const ConcaveMeshShape& shape) = delete;
/// Return the scaling vector
const Vector3& getScaling() const;
/// Return the number of sub parts contained in this mesh /// Return the number of sub parts contained in this mesh
uint getNbSubparts() const; uint getNbSubparts() const;
@ -223,11 +218,6 @@ inline size_t ConcaveMeshShape::getSizeInBytes() const {
return sizeof(ConcaveMeshShape); return sizeof(ConcaveMeshShape);
} }
// Return the scaling vector
inline const Vector3& ConcaveMeshShape::getScaling() const {
return mScaling;
}
// Return the local bounds of the shape in x, y and z directions. // Return the local bounds of the shape in x, y and z directions.
// This method is used to compute the AABB of the box // This method is used to compute the AABB of the box
/** /**

View File

@ -31,7 +31,8 @@
using namespace reactphysics3d; using namespace reactphysics3d;
// Constructor // Constructor
ConcaveShape::ConcaveShape(CollisionShapeName name) ConcaveShape::ConcaveShape(CollisionShapeName name, const Vector3& scaling)
: CollisionShape(name, CollisionShapeType::CONCAVE_SHAPE), mRaycastTestType(TriangleRaycastSide::FRONT) { : CollisionShape(name, CollisionShapeType::CONCAVE_SHAPE), mRaycastTestType(TriangleRaycastSide::FRONT),
mScale(scaling) {
} }

View File

@ -65,6 +65,9 @@ class ConcaveShape : public CollisionShape {
/// Raycast test type for the triangle (front, back, front-back) /// Raycast test type for the triangle (front, back, front-back)
TriangleRaycastSide mRaycastTestType; TriangleRaycastSide mRaycastTestType;
/// Scale of the shape
Vector3 mScale;
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Return true if a point is inside the collision shape /// Return true if a point is inside the collision shape
@ -75,7 +78,7 @@ class ConcaveShape : public CollisionShape {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
ConcaveShape(CollisionShapeName name); ConcaveShape(CollisionShapeName name, const Vector3& scaling);
/// Destructor /// Destructor
virtual ~ConcaveShape() override = default; virtual ~ConcaveShape() override = default;
@ -92,6 +95,12 @@ class ConcaveShape : public CollisionShape {
// Set the raycast test type (front, back, front-back) // Set the raycast test type (front, back, front-back)
void setRaycastTestType(TriangleRaycastSide testType); void setRaycastTestType(TriangleRaycastSide testType);
/// Return the scale of the shape
const Vector3& getScale() const;
/// Set the scale of the shape
void setScale(const Vector3& scale);
/// Return true if the collision shape is convex, false if it is concave /// Return true if the collision shape is convex, false if it is concave
virtual bool isConvex() const override; virtual bool isConvex() const override;
@ -132,6 +141,18 @@ inline void ConcaveShape::setRaycastTestType(TriangleRaycastSide testType) {
mRaycastTestType = testType; mRaycastTestType = testType;
} }
// Return the scale of the shape
inline const Vector3& ConcaveShape::getScale() const {
return mScale;
}
// Set the scale of the shape
/// Note that you might want to recompute the inertia tensor and center of mass of the body
/// after changing the scale of a collision shape
inline void ConcaveShape::setScale(const Vector3& scale) {
mScale = scale;
}
} }
#endif #endif

View File

@ -39,9 +39,9 @@ using namespace reactphysics3d;
* @param stride Stride between the beginning of two elements in the vertices array * @param stride Stride between the beginning of two elements in the vertices array
* @param margin Collision margin (in meters) around the collision shape * @param margin Collision margin (in meters) around the collision shape
*/ */
ConvexMeshShape::ConvexMeshShape(PolyhedronMesh* polyhedronMesh, const Vector3& scaling) ConvexMeshShape::ConvexMeshShape(PolyhedronMesh* polyhedronMesh, const Vector3& scale)
: ConvexPolyhedronShape(CollisionShapeName::CONVEX_MESH), mPolyhedronMesh(polyhedronMesh), : ConvexPolyhedronShape(CollisionShapeName::CONVEX_MESH), mPolyhedronMesh(polyhedronMesh),
mMinBounds(0, 0, 0), mMaxBounds(0, 0, 0), mScaling(scaling) { mMinBounds(0, 0, 0), mMaxBounds(0, 0, 0), mScale(scale) {
// Recalculate the bounds of the mesh // Recalculate the bounds of the mesh
recalculateBounds(); recalculateBounds();
@ -76,7 +76,7 @@ Vector3 ConvexMeshShape::getLocalSupportPointWithoutMargin(const Vector3& direct
assert(maxDotProduct >= decimal(0.0)); assert(maxDotProduct >= decimal(0.0));
// Return the vertex with the largest dot product in the support direction // Return the vertex with the largest dot product in the support direction
return mPolyhedronMesh->getVertex(indexMaxDotProduct) * mScaling; return mPolyhedronMesh->getVertex(indexMaxDotProduct) * mScale;
} }
// Recompute the bounds of the mesh // Recompute the bounds of the mesh
@ -99,8 +99,8 @@ void ConvexMeshShape::recalculateBounds() {
} }
// Apply the local scaling factor // Apply the local scaling factor
mMaxBounds = mMaxBounds * mScaling; mMaxBounds = mMaxBounds * mScale;
mMinBounds = mMinBounds * mScaling; mMinBounds = mMinBounds * mScale;
} }
// Raycast method with feedback information // Raycast method with feedback information

View File

@ -60,13 +60,13 @@ class ConvexMeshShape : public ConvexPolyhedronShape {
/// Mesh maximum bounds in the three local x, y and z directions /// Mesh maximum bounds in the three local x, y and z directions
Vector3 mMaxBounds; Vector3 mMaxBounds;
/// Local scaling /// Scale of the mesh
const Vector3 mScaling; Vector3 mScale;
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
ConvexMeshShape(PolyhedronMesh* polyhedronMesh, const Vector3& scaling = Vector3(1,1,1)); ConvexMeshShape(PolyhedronMesh* polyhedronMesh, const Vector3& scale = Vector3(1,1,1));
/// Recompute the bounds of the mesh /// Recompute the bounds of the mesh
void recalculateBounds(); void recalculateBounds();
@ -96,8 +96,11 @@ class ConvexMeshShape : public ConvexPolyhedronShape {
/// Deleted assignment operator /// Deleted assignment operator
ConvexMeshShape& operator=(const ConvexMeshShape& shape) = delete; ConvexMeshShape& operator=(const ConvexMeshShape& shape) = delete;
/// Return the scaling vector /// Return the scale
const Vector3& getScaling() const; const Vector3& getScale() const;
/// Set the scale
void setScale(const Vector3& scale);
/// Return the local bounds of the shape in x, y and z directions /// Return the local bounds of the shape in x, y and z directions
virtual void getLocalBounds(Vector3& min, Vector3& max) const override; virtual void getLocalBounds(Vector3& min, Vector3& max) const override;
@ -146,8 +149,16 @@ inline size_t ConvexMeshShape::getSizeInBytes() const {
} }
// Return the scaling vector // Return the scaling vector
inline const Vector3& ConvexMeshShape::getScaling() const { inline const Vector3& ConvexMeshShape::getScale() const {
return mScaling; return mScale;
}
// Set the scale
/// Note that you might want to recompute the inertia tensor and center of mass of the body
/// after changing the scale of a collision shape
inline void ConvexMeshShape::setScale(const Vector3& scale) {
mScale = scale;
recalculateBounds();
} }
// Return the local bounds of the shape in x, y and z directions // Return the local bounds of the shape in x, y and z directions
@ -216,7 +227,7 @@ inline const HalfEdgeStructure::Edge& ConvexMeshShape::getHalfEdge(uint edgeInde
// Return the position of a given vertex // Return the position of a given vertex
inline Vector3 ConvexMeshShape::getVertexPosition(uint vertexIndex) const { inline Vector3 ConvexMeshShape::getVertexPosition(uint vertexIndex) const {
assert(vertexIndex < getNbVertices()); assert(vertexIndex < getNbVertices());
return mPolyhedronMesh->getVertex(vertexIndex) * mScaling; return mPolyhedronMesh->getVertex(vertexIndex) * mScale;
} }
// Return the normal vector of a given face of the polyhedron // Return the normal vector of a given face of the polyhedron
@ -227,7 +238,7 @@ inline Vector3 ConvexMeshShape::getFaceNormal(uint faceIndex) const {
// Return the centroid of the polyhedron // Return the centroid of the polyhedron
inline Vector3 ConvexMeshShape::getCentroid() const { inline Vector3 ConvexMeshShape::getCentroid() const {
return mPolyhedronMesh->getCentroid() * mScaling; return mPolyhedronMesh->getCentroid() * mScale;
} }
} }

View File

@ -44,10 +44,10 @@ using namespace reactphysics3d;
HeightFieldShape::HeightFieldShape(int nbGridColumns, int nbGridRows, decimal minHeight, decimal maxHeight, HeightFieldShape::HeightFieldShape(int nbGridColumns, int nbGridRows, decimal minHeight, decimal maxHeight,
const void* heightFieldData, HeightDataType dataType, int upAxis, const void* heightFieldData, HeightDataType dataType, int upAxis,
decimal integerHeightScale, const Vector3& scaling) decimal integerHeightScale, const Vector3& scaling)
: ConcaveShape(CollisionShapeName::HEIGHTFIELD), mNbColumns(nbGridColumns), mNbRows(nbGridRows), : ConcaveShape(CollisionShapeName::HEIGHTFIELD, scaling), mNbColumns(nbGridColumns), mNbRows(nbGridRows),
mWidth(nbGridColumns - 1), mLength(nbGridRows - 1), mMinHeight(minHeight), mWidth(nbGridColumns - 1), mLength(nbGridRows - 1), mMinHeight(minHeight),
mMaxHeight(maxHeight), mUpAxis(upAxis), mIntegerHeightScale(integerHeightScale), mMaxHeight(maxHeight), mUpAxis(upAxis), mIntegerHeightScale(integerHeightScale),
mHeightDataType(dataType), mScaling(scaling) { mHeightDataType(dataType) {
assert(nbGridColumns >= 2); assert(nbGridColumns >= 2);
assert(nbGridRows >= 2); assert(nbGridRows >= 2);
@ -83,8 +83,8 @@ HeightFieldShape::HeightFieldShape(int nbGridColumns, int nbGridRows, decimal mi
* @param max The maximum bounds of the shape in local-space coordinates * @param max The maximum bounds of the shape in local-space coordinates
*/ */
void HeightFieldShape::getLocalBounds(Vector3& min, Vector3& max) const { void HeightFieldShape::getLocalBounds(Vector3& min, Vector3& max) const {
min = mAABB.getMin() * mScaling; min = mAABB.getMin() * mScale;
max = mAABB.getMax() * mScaling; max = mAABB.getMax() * mScale;
} }
// Test collision with the triangles of the height field shape. The idea is to use the AABB // Test collision with the triangles of the height field shape. The idea is to use the AABB
@ -98,8 +98,8 @@ void HeightFieldShape::computeOverlappingTriangles(const AABB& localAABB, List<V
RP3D_PROFILE("HeightFieldShape::computeOverlappingTriangles()", mProfiler); RP3D_PROFILE("HeightFieldShape::computeOverlappingTriangles()", mProfiler);
// Compute the non-scaled AABB // Compute the non-scaled AABB
Vector3 inverseScaling(decimal(1.0) / mScaling.x, decimal(1.0) / mScaling.y, decimal(1.0) / mScaling.z); Vector3 inverseScale(decimal(1.0) / mScale.x, decimal(1.0) / mScale.y, decimal(1.0) / mScale.z);
AABB aabb(localAABB.getMin() * inverseScaling, localAABB.getMax() * inverseScaling); AABB aabb(localAABB.getMin() * inverseScale, localAABB.getMax() * inverseScale);
// Compute the integer grid coordinates inside the area we need to test for collision // Compute the integer grid coordinates inside the area we need to test for collision
int minGridCoords[3]; int minGridCoords[3];
@ -310,7 +310,7 @@ Vector3 HeightFieldShape::getVertexAt(int x, int y) const {
assert(mAABB.contains(vertex)); assert(mAABB.contains(vertex));
return vertex * mScaling; return vertex * mScale;
} }
// Return the string representation of the shape // Return the string representation of the shape

View File

@ -91,9 +91,6 @@ class HeightFieldShape : public ConcaveShape {
/// Local AABB of the height field (without scaling) /// Local AABB of the height field (without scaling)
AABB mAABB; AABB mAABB;
/// Scaling vector
const Vector3 mScaling;
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
@ -136,9 +133,6 @@ class HeightFieldShape : public ConcaveShape {
/// Deleted assignment operator /// Deleted assignment operator
HeightFieldShape& operator=(const HeightFieldShape& shape) = delete; HeightFieldShape& operator=(const HeightFieldShape& shape) = delete;
/// Return the scaling factor
const Vector3& getScaling() const;
/// Return the number of rows in the height field /// Return the number of rows in the height field
int getNbRows() const; int getNbRows() const;
@ -175,11 +169,6 @@ class HeightFieldShape : public ConcaveShape {
friend class PhysicsCommon; friend class PhysicsCommon;
}; };
// Return the scaling factor
inline const Vector3& HeightFieldShape::getScaling() const {
return mScaling;
}
// Return the number of rows in the height field // Return the number of rows in the height field
inline int HeightFieldShape::getNbRows() const { inline int HeightFieldShape::getNbRows() const {
return mNbRows; return mNbRows;

View File

@ -34,7 +34,7 @@ using namespace reactphysics3d;
// Constructor // Constructor
/** /**
* @param radius Radius of the sphere (in meters) * @param radius Radius of the sphere
*/ */
SphereShape::SphereShape(decimal radius) SphereShape::SphereShape(decimal radius)
: ConvexShape(CollisionShapeName::SPHERE, CollisionShapeType::SPHERE, radius) { : ConvexShape(CollisionShapeName::SPHERE, CollisionShapeType::SPHERE, radius) {

View File

@ -81,6 +81,9 @@ class SphereShape : public ConvexShape {
/// Return the radius of the sphere /// Return the radius of the sphere
decimal getRadius() const; decimal getRadius() const;
/// Set the radius of the sphere
void setRadius(decimal radius);
/// Return true if the collision shape is a polyhedron /// Return true if the collision shape is a polyhedron
virtual bool isPolyhedron() const override; virtual bool isPolyhedron() const override;
@ -103,12 +106,23 @@ class SphereShape : public ConvexShape {
// Get the radius of the sphere // Get the radius of the sphere
/** /**
* @return Radius of the sphere (in meters) * @return Radius of the sphere
*/ */
inline decimal SphereShape::getRadius() const { inline decimal SphereShape::getRadius() const {
return mMargin; return mMargin;
} }
// Set the radius of the sphere
/// Note that you might want to recompute the inertia tensor and center of mass of the body
/// after changing the radius of the collision shape
/**
* @param radius Radius of the sphere
*/
inline void SphereShape::setRadius(decimal radius) {
assert(radius > decimal(0.0));
mMargin = radius;
}
// Return true if the collision shape is a polyhedron // Return true if the collision shape is a polyhedron
/** /**
* @return False because the sphere shape is not a polyhedron * @return False because the sphere shape is not a polyhedron

View File

@ -177,6 +177,18 @@ class TestAABB : public Test {
rp3d_test(approxEqual(mAABB1.getVolume(), 8000)); rp3d_test(approxEqual(mAABB1.getVolume(), 8000));
rp3d_test(approxEqual(mAABB2.getVolume(), 2880)); rp3d_test(approxEqual(mAABB2.getVolume(), 2880));
// -------- Test applyScale() -------- //
AABB aabb7(Vector3(1,2,3), Vector3(5, 6, 7));
aabb7.applyScale(Vector3(1, 2, 3));
rp3d_test(approxEqual(aabb7.getMin().x, 1));
rp3d_test(approxEqual(aabb7.getMin().y, 4));
rp3d_test(approxEqual(aabb7.getMin().z, 9));
rp3d_test(approxEqual(aabb7.getMax().x, 5));
rp3d_test(approxEqual(aabb7.getMax().y, 12));
rp3d_test(approxEqual(aabb7.getMax().z, 21));
} }
void testMergeMethods() { void testMergeMethods() {

View File

@ -27,52 +27,7 @@
#include "ConcaveMesh.h" #include "ConcaveMesh.h"
// Constructor // Constructor
ConcaveMesh::ConcaveMesh(rp3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* world, const std::string& meshPath) ConcaveMesh::ConcaveMesh(bool createRigidBody, float mass, reactphysics3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld, const std::string& meshPath)
: PhysicsObject(physicsCommon, meshPath), mVBOVertices(GL_ARRAY_BUFFER),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) {
mPhysicsTriangleMesh = mPhysicsCommon.createTriangleMesh();
// Compute the scaling matrix
mScalingMatrix = openglframework::Matrix4::identity();
mPhysicsTriangleMesh = mPhysicsCommon.createTriangleMesh();
// For each subpart of the mesh
for (unsigned int i=0; i<getNbParts(); i++) {
// Vertex and Indices array for the triangle mesh (data in shared and not copied)
rp3d::TriangleVertexArray* vertexArray =
new rp3d::TriangleVertexArray(getNbVertices(), &(mVertices[0]), sizeof(openglframework::Vector3),
getNbFaces(i), &(mIndices[i][0]), 3 * sizeof(int),
rp3d::TriangleVertexArray::VertexDataType::VERTEX_FLOAT_TYPE,
rp3d::TriangleVertexArray::IndexDataType::INDEX_INTEGER_TYPE);
// Add the triangle vertex array of the subpart to the triangle mesh
mPhysicsTriangleMesh->addSubpart(vertexArray);
}
// Create the collision shape for the rigid body (convex mesh shape) and
// do not forget to delete it at the end
mConcaveShape = mPhysicsCommon.createConcaveMeshShape(mPhysicsTriangleMesh);
mPreviousTransform = rp3d::Transform::identity();
// Create a rigid body corresponding to the sphere in the physics world
mBody = world->createCollisionBody(mPreviousTransform);
// Add a collision shape to the body and specify the mass of the collision shape
mCollider = mBody->addCollider(mConcaveShape, rp3d::Transform::identity());
// Create the VBOs and VAO
createVBOAndVAO();
mTransformMatrix = mTransformMatrix * mScalingMatrix;
}
// Constructor
ConcaveMesh::ConcaveMesh(float mass, reactphysics3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld, const std::string& meshPath)
: PhysicsObject(physicsCommon, meshPath), mVBOVertices(GL_ARRAY_BUFFER), : PhysicsObject(physicsCommon, meshPath), mVBOVertices(GL_ARRAY_BUFFER),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) {
@ -102,13 +57,16 @@ ConcaveMesh::ConcaveMesh(float mass, reactphysics3d::PhysicsCommon& physicsCommo
mPreviousTransform = rp3d::Transform::identity(); mPreviousTransform = rp3d::Transform::identity();
// Create a rigid body corresponding to the sphere in the physics world // Create the body
rp3d::RigidBody* body = physicsWorld->createRigidBody(mPreviousTransform); if (createRigidBody) {
rp3d::RigidBody* body = physicsWorld->createRigidBody(mPreviousTransform);
// Add a collision shape to the body and specify the mass of the collision shape mCollider = body->addCollider(mConcaveShape, rp3d::Transform::identity(), mass);
mCollider = body->addCollider(mConcaveShape, rp3d::Transform::identity(), mass); mBody = body;
}
mBody = body; else {
mBody = physicsWorld->createCollisionBody(mPreviousTransform);
mCollider = mBody->addCollider(mConcaveShape, rp3d::Transform::identity());
}
// Create the VBOs and VAO // Create the VBOs and VAO
createVBOAndVAO(); createVBOAndVAO();

View File

@ -73,10 +73,7 @@ class ConcaveMesh : public PhysicsObject {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
ConcaveMesh(reactphysics3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* world, const std::string& meshPath); ConcaveMesh(bool createRigidBody, float mass, reactphysics3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld, const std::string& meshPath);
/// Constructor
ConcaveMesh(float mass, reactphysics3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld, const std::string& meshPath);
/// Destructor /// Destructor
virtual ~ConcaveMesh() override; virtual ~ConcaveMesh() override;

View File

@ -28,67 +28,7 @@
#include <unordered_set> #include <unordered_set>
// Constructor // Constructor
ConvexMesh::ConvexMesh(rp3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* world, const std::string& meshPath) ConvexMesh::ConvexMesh(bool createRigidBody, float mass, rp3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld, const std::string& meshPath)
: PhysicsObject(physicsCommon, meshPath), mVBOVertices(GL_ARRAY_BUFFER),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) {
// Compute the scaling matrix
mScalingMatrix = openglframework::Matrix4::identity();
// Polygon faces descriptions for the polyhedron
mPolygonFaces = new rp3d::PolygonVertexArray::PolygonFace[getNbFaces(0)];
rp3d::PolygonVertexArray::PolygonFace* face = mPolygonFaces;
for (int f=0; f < getNbFaces(0); f++) {
for (int v = 0; v < 3; v++) {
const openglframework::Vector3 vertex = mVertices[mIndices[0][f*3 + v]];
int vIndex = findVertexIndex(mConvexMeshVertices, vertex);
if (vIndex == -1) {
vIndex = mConvexMeshVertices.size();
mConvexMeshVertices.push_back(vertex);
}
mConvexMeshIndices.push_back(vIndex);
}
face->indexBase = f * 3;
face->nbVertices = 3;
face++;
}
// Create the polygon vertex array
mPolygonVertexArray =
new rp3d::PolygonVertexArray(mConvexMeshVertices.size(), &(mConvexMeshVertices[0]), sizeof(openglframework::Vector3),
&(mConvexMeshIndices[0]), sizeof(int),
getNbFaces(0), mPolygonFaces,
rp3d::PolygonVertexArray::VertexDataType::VERTEX_FLOAT_TYPE,
rp3d::PolygonVertexArray::IndexDataType::INDEX_INTEGER_TYPE);
// Create the polyhedron mesh
mPolyhedronMesh = mPhysicsCommon.createPolyhedronMesh(mPolygonVertexArray);
// Create the collision shape for the rigid body (convex mesh shape) and
// do not forget to delete it at the end
mConvexShape = mPhysicsCommon.createConvexMeshShape(mPolyhedronMesh);
mPreviousTransform = rp3d::Transform::identity();
// Create a rigid body corresponding to the sphere in the physics world
mBody = world->createCollisionBody(mPreviousTransform);
// Add a collision shape to the body and specify the mass of the collision shape
mCollider = mBody->addCollider(mConvexShape, rp3d::Transform::identity());
// Create the VBOs and VAO
createVBOAndVAO();
mTransformMatrix = mTransformMatrix * mScalingMatrix;
}
// Constructor
ConvexMesh::ConvexMesh(float mass, rp3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld, const std::string& meshPath)
: PhysicsObject(physicsCommon, meshPath), mVBOVertices(GL_ARRAY_BUFFER), : PhysicsObject(physicsCommon, meshPath), mVBOVertices(GL_ARRAY_BUFFER),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) {
@ -136,12 +76,16 @@ ConvexMesh::ConvexMesh(float mass, rp3d::PhysicsCommon& physicsCommon, rp3d::Phy
mPreviousTransform = rp3d::Transform::identity(); mPreviousTransform = rp3d::Transform::identity();
// Create a rigid body corresponding to the sphere in the physics world // Create a rigid body corresponding to the sphere in the physics world
rp3d::RigidBody* body = physicsWorld->createRigidBody(mPreviousTransform); if (createRigidBody) {
rp3d::RigidBody* body = physicsWorld->createRigidBody(mPreviousTransform);
mCollider = body->addCollider(mConvexShape, rp3d::Transform::identity(), mass);
mBody = body;
}
else {
// Add a collision shape to the body and specify the mass of the collision shape mBody = physicsWorld->createCollisionBody(mPreviousTransform);
mCollider = body->addCollider(mConvexShape, rp3d::Transform::identity(), mass); mCollider = mBody->addCollider(mConvexShape, rp3d::Transform::identity());
}
mBody = body;
// Create the VBOs and VAO // Create the VBOs and VAO
createVBOAndVAO(); createVBOAndVAO();

View File

@ -86,10 +86,7 @@ class ConvexMesh : public PhysicsObject {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
ConvexMesh(rp3d::PhysicsCommon& physicsCommon, reactphysics3d::PhysicsWorld* world, const std::string& meshPath); ConvexMesh(bool createRigidBody, float mass, rp3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld, const std::string& meshPath);
/// Constructor
ConvexMesh(float mass, rp3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld, const std::string& meshPath);
/// Destructor /// Destructor
virtual ~ConvexMesh() override; virtual ~ConvexMesh() override;

View File

@ -28,47 +28,14 @@
#include "PerlinNoise.h" #include "PerlinNoise.h"
// Constructor // Constructor
HeightField::HeightField(rp3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* world) HeightField::HeightField(bool createRigidBody, float mass, reactphysics3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld)
: PhysicsObject(physicsCommon), mVBOVertices(GL_ARRAY_BUFFER), : PhysicsObject(physicsCommon), mVBOVertices(GL_ARRAY_BUFFER),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) {
// Compute the scaling matrix // Compute the scaling matrix
mScalingMatrix = openglframework::Matrix4::identity(); //mScalingMatrix = openglframework::Matrix4::identity();
mScalingMatrix = openglframework::Matrix4(2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1);
// Generate the height field
generateHeightField();
// Generate the graphics mesh
generateGraphicsMesh();
// Create the collision shape for the rigid body (convex mesh shape) and
// do not forget to delete it at the end
mHeightFieldShape = mPhysicsCommon.createHeightFieldShape(NB_POINTS_WIDTH, NB_POINTS_LENGTH, mMinHeight, mMaxHeight,
mHeightData, rp3d::HeightFieldShape::HeightDataType::HEIGHT_FLOAT_TYPE);
mPreviousTransform = rp3d::Transform::identity();
// Create a rigid body corresponding to the sphere in the physics world
mBody = world->createCollisionBody(mPreviousTransform);
// Add a collision shape to the body and specify the mass of the collision shape
mCollider = mBody->addCollider(mHeightFieldShape, rp3d::Transform::identity());
// Create the VBOs and VAO
createVBOAndVAO();
mTransformMatrix = mTransformMatrix * mScalingMatrix;
}
// Constructor
HeightField::HeightField(float mass, reactphysics3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld)
: PhysicsObject(physicsCommon), mVBOVertices(GL_ARRAY_BUFFER),
mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER),
mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) {
// Compute the scaling matrix
mScalingMatrix = openglframework::Matrix4::identity();
// Generate the height field // Generate the height field
generateHeightField(); generateHeightField();
@ -80,16 +47,20 @@ HeightField::HeightField(float mass, reactphysics3d::PhysicsCommon& physicsCommo
// do not forget to delete it at the end // do not forget to delete it at the end
mHeightFieldShape = mPhysicsCommon.createHeightFieldShape(NB_POINTS_WIDTH, NB_POINTS_LENGTH, mMinHeight, mMaxHeight, mHeightFieldShape = mPhysicsCommon.createHeightFieldShape(NB_POINTS_WIDTH, NB_POINTS_LENGTH, mMinHeight, mMaxHeight,
mHeightData, rp3d::HeightFieldShape::HeightDataType::HEIGHT_FLOAT_TYPE); mHeightData, rp3d::HeightFieldShape::HeightDataType::HEIGHT_FLOAT_TYPE);
mHeightFieldShape->setScale(rp3d::Vector3(2, 2, 2));
mPreviousTransform = rp3d::Transform::identity(); mPreviousTransform = rp3d::Transform::identity();
// Create a rigid body corresponding to the sphere in the physics world // Create a body
rp3d::RigidBody* body = physicsWorld->createRigidBody(mPreviousTransform); if (createRigidBody) {
rp3d::RigidBody* body = physicsWorld->createRigidBody(mPreviousTransform);
// Add a collision shape to the body and specify the mass of the collision shape mCollider = body->addCollider(mHeightFieldShape, rp3d::Transform::identity(), mass);
mCollider = body->addCollider(mHeightFieldShape, rp3d::Transform::identity(), mass); mBody = body;
}
mBody = body; else {
mBody = physicsWorld->createCollisionBody(mPreviousTransform);
mCollider = mBody->addCollider(mHeightFieldShape, rp3d::Transform::identity());
}
// Create the VBOs and VAO // Create the VBOs and VAO
createVBOAndVAO(); createVBOAndVAO();

View File

@ -86,10 +86,7 @@ class HeightField : public PhysicsObject {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
HeightField(reactphysics3d::PhysicsCommon& physicsCommon, reactphysics3d::PhysicsWorld* world); HeightField(bool createRigidBody, float mass, rp3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld);
/// Constructor
HeightField(float mass, rp3d::PhysicsCommon& physicsCommon, rp3d::PhysicsWorld* physicsWorld);
/// Destructor /// Destructor
virtual ~HeightField() override; virtual ~HeightField() override;

View File

@ -103,7 +103,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
// ---------- Concave Mesh ---------- // // ---------- Concave Mesh ---------- //
// Create a convex mesh and a corresponding collision body in the physics world // Create a convex mesh and a corresponding collision body in the physics world
mConcaveMesh = new ConcaveMesh(mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "city.obj"); mConcaveMesh = new ConcaveMesh(false, 1.0f, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "city.obj");
mAllShapes.push_back(mConcaveMesh); mAllShapes.push_back(mConcaveMesh);
// Set the color // Set the color
@ -136,7 +136,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
// ---------- Convex Mesh ---------- // // ---------- Convex Mesh ---------- //
// Create a convex mesh and a corresponding collision body in the physics world // Create a convex mesh and a corresponding collision body in the physics world
mConvexMesh = new ConvexMesh(mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "convexmesh.obj"); mConvexMesh = new ConvexMesh(false, 1.0f, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "convexmesh.obj");
mAllShapes.push_back(mConvexMesh); mAllShapes.push_back(mConvexMesh);
// Set the color // Set the color
@ -147,7 +147,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
// ---------- Heightfield ---------- // // ---------- Heightfield ---------- //
// Create a convex mesh and a corresponding collision body in the physics world // Create a convex mesh and a corresponding collision body in the physics world
mHeightField = new HeightField(mPhysicsCommon, mPhysicsWorld); mHeightField = new HeightField(false, 1.0f, mPhysicsCommon, mPhysicsWorld);
// Set the color // Set the color
mHeightField->setColor(mObjectColorDemo); mHeightField->setColor(mObjectColorDemo);

View File

@ -142,7 +142,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
for (int i=0; i<NB_MESHES; i++) { for (int i=0; i<NB_MESHES; i++) {
// Create a convex mesh and a corresponding rigid in the physics world // Create a convex mesh and a corresponding rigid in the physics world
ConvexMesh* mesh = new ConvexMesh(MESH_MASS, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "convexmesh.obj"); ConvexMesh* mesh = new ConvexMesh(true, MESH_MASS, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "convexmesh.obj");
// Set the box color // Set the box color
mesh->setColor(mObjectColorDemo); mesh->setColor(mObjectColorDemo);

View File

@ -143,7 +143,7 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
for (int i = 0; i<NB_MESHES; i++) { for (int i = 0; i<NB_MESHES; i++) {
// Create a convex mesh and a corresponding rigid in the physics world // Create a convex mesh and a corresponding rigid in the physics world
ConvexMesh* mesh = new ConvexMesh(MESH_MASS, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "convexmesh.obj"); ConvexMesh* mesh = new ConvexMesh(true, MESH_MASS, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "convexmesh.obj");
// Set the box color // Set the box color
mesh->setColor(mObjectColorDemo); mesh->setColor(mObjectColorDemo);
@ -164,7 +164,7 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
rp3d::decimal mass = 1.0; rp3d::decimal mass = 1.0;
// Create a convex mesh and a corresponding rigid in the physics world // Create a convex mesh and a corresponding rigid in the physics world
mConcaveMesh = new ConcaveMesh(mass, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "city.obj"); mConcaveMesh = new ConcaveMesh(true, mass, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "city.obj");
// Set the mesh as beeing static // Set the mesh as beeing static
mConcaveMesh->getRigidBody()->setType(rp3d::BodyType::STATIC); mConcaveMesh->getRigidBody()->setType(rp3d::BodyType::STATIC);

View File

@ -142,7 +142,7 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
for (int i = 0; i<NB_MESHES; i++) { for (int i = 0; i<NB_MESHES; i++) {
// Create a convex mesh and a corresponding rigid in the physics world // Create a convex mesh and a corresponding rigid in the physics world
ConvexMesh* mesh = new ConvexMesh(MESH_MASS, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "convexmesh.obj"); ConvexMesh* mesh = new ConvexMesh(true, MESH_MASS, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "convexmesh.obj");
// Set the box color // Set the box color
mesh->setColor(mObjectColorDemo); mesh->setColor(mObjectColorDemo);
@ -163,7 +163,7 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
rp3d::decimal mass = 1.0; rp3d::decimal mass = 1.0;
// Create a convex mesh and a corresponding rigid in the physics world // Create a convex mesh and a corresponding rigid in the physics world
mHeightField = new HeightField(mass, mPhysicsCommon, mPhysicsWorld); mHeightField = new HeightField(true, mass, mPhysicsCommon, mPhysicsWorld);
// Set the mesh as beeing static // Set the mesh as beeing static
mHeightField->getRigidBody()->setType(rp3d::BodyType::STATIC); mHeightField->getRigidBody()->setType(rp3d::BodyType::STATIC);

View File

@ -140,7 +140,7 @@ PileScene::PileScene(const std::string& name, EngineSettings& settings)
for (int i=0; i<NB_MESHES; i++) { for (int i=0; i<NB_MESHES; i++) {
// Create a convex mesh and a corresponding rigid in the physics world // Create a convex mesh and a corresponding rigid in the physics world
ConvexMesh* mesh = new ConvexMesh(MESH_MASS, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "convexmesh.obj"); ConvexMesh* mesh = new ConvexMesh(true, MESH_MASS, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "convexmesh.obj");
// Set the box color // Set the box color
mesh->setColor(mObjectColorDemo); mesh->setColor(mObjectColorDemo);
@ -161,7 +161,7 @@ PileScene::PileScene(const std::string& name, EngineSettings& settings)
rp3d::decimal mass = 1.0; rp3d::decimal mass = 1.0;
// Create a convex mesh and a corresponding rigid in the physics world // Create a convex mesh and a corresponding rigid in the physics world
mSandbox = new ConcaveMesh(mass, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "sandbox.obj"); mSandbox = new ConcaveMesh(true, mass, mPhysicsCommon, mPhysicsWorld, meshFolderPath + "sandbox.obj");
// Set the mesh as beeing static // Set the mesh as beeing static
mSandbox->getRigidBody()->setType(rp3d::BodyType::STATIC); mSandbox->getRigidBody()->setType(rp3d::BodyType::STATIC);

View File

@ -95,7 +95,7 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
// ---------- Convex Mesh ---------- // // ---------- Convex Mesh ---------- //
// Create a convex mesh and a corresponding collision body in the physics world // Create a convex mesh and a corresponding collision body in the physics world
mConvexMesh = new ConvexMesh(mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "convexmesh.obj"); mConvexMesh = new ConvexMesh(false, 1.0f, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "convexmesh.obj");
// Set the color // Set the color
mConvexMesh->setColor(mObjectColorDemo); mConvexMesh->setColor(mObjectColorDemo);
@ -105,7 +105,7 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
// ---------- Concave Mesh ---------- // // ---------- Concave Mesh ---------- //
// Create a convex mesh and a corresponding collision body in the physics world // Create a convex mesh and a corresponding collision body in the physics world
mConcaveMesh = new ConcaveMesh(mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "city.obj"); mConcaveMesh = new ConcaveMesh(false, 1.0f, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "city.obj");
// Set the color // Set the color
mConcaveMesh->setColor(mObjectColorDemo); mConcaveMesh->setColor(mObjectColorDemo);
@ -115,7 +115,7 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
// ---------- Heightfield ---------- // // ---------- Heightfield ---------- //
// Create a convex mesh and a corresponding collision body in the physics world // Create a convex mesh and a corresponding collision body in the physics world
mHeightField = new HeightField(mPhysicsCommon, mPhysicsWorld); mHeightField = new HeightField(false, 1.0f, mPhysicsCommon, mPhysicsWorld);
// Set the color // Set the color
mHeightField->setColor(mObjectColorDemo); mHeightField->setColor(mObjectColorDemo);