Working on HalfEdgeStructure
This commit is contained in:
parent
30e0132e15
commit
7a656aedc9
|
@ -30,13 +30,14 @@
|
|||
using namespace reactphysics3d;
|
||||
|
||||
// Initialize the structure
|
||||
void HalfEdgeStructure::init(std::vector<const Vector3> vertices, std::vector<std::vector<uint>> faces) {
|
||||
void HalfEdgeStructure::init(std::vector<Vector3> vertices, std::vector<std::vector<uint>> faces) {
|
||||
|
||||
using edgeKey = std::pair<uint, uint>;
|
||||
|
||||
std::map<edgeKey, Edge> edges;
|
||||
std::map<edgeKey, edgeKey> nextEdges;
|
||||
std::map<edgeKey, uint> mapEdgeToStartVertex;
|
||||
std::map<edgeKey, uint> mapEdgeToIndex;
|
||||
|
||||
// For each vertices
|
||||
for (uint v=0; v<vertices.size(); v++) {
|
||||
|
@ -58,10 +59,10 @@ void HalfEdgeStructure::init(std::vector<const Vector3> vertices, std::vector<st
|
|||
|
||||
edgeKey firstEdgeKey;
|
||||
|
||||
// For each edge of the face
|
||||
for (uint e=0; e < faceVertices.size(); e++) {
|
||||
uint v1Index = faceVertices[e];
|
||||
uint v2Index = faceVertices[e == (faceVertices.size() - 1) ? 0 : e + 1];
|
||||
// For each vertex of the face
|
||||
for (uint v=0; v < faceVertices.size(); v++) {
|
||||
uint v1Index = faceVertices[v];
|
||||
uint v2Index = faceVertices[v == (faceVertices.size() - 1) ? 0 : v + 1];
|
||||
|
||||
const edgeKey pairV1V2 = std::make_pair(v1Index, v2Index);
|
||||
|
||||
|
@ -69,21 +70,21 @@ void HalfEdgeStructure::init(std::vector<const Vector3> vertices, std::vector<st
|
|||
Edge edge;
|
||||
edge.faceIndex = f;
|
||||
edge.vertexIndex = v1Index;
|
||||
if (e == 0) {
|
||||
if (v == 0) {
|
||||
firstEdgeKey = pairV1V2;
|
||||
}
|
||||
else if (e >= 1) {
|
||||
nextEdges.insert(currentFaceEdges[currentFaceEdges.size() - 1], pairV1V2);
|
||||
else if (v >= 1) {
|
||||
nextEdges.insert(std::make_pair(currentFaceEdges[currentFaceEdges.size() - 1], pairV1V2));
|
||||
}
|
||||
if (e == (faceVertices.size() - 1)) {
|
||||
nextEdges.insert(pairV1V2, firstEdgeKey);
|
||||
if (v == (faceVertices.size() - 1)) {
|
||||
nextEdges.insert(std::make_pair(pairV1V2, firstEdgeKey));
|
||||
}
|
||||
edges.insert(pairV1V2, edge);
|
||||
edges.insert(std::make_pair(pairV1V2, edge));
|
||||
|
||||
const edgeKey pairV2V1 = std::make_pair(v2Index, v1Index);
|
||||
|
||||
mapEdgeToStartVertex.insert(pairV1V2, v1Index);
|
||||
mapEdgeToStartVertex.insert(pairV2V1, v2Index);
|
||||
mapEdgeToStartVertex.insert(std::make_pair(pairV1V2, v1Index));
|
||||
mapEdgeToStartVertex.insert(std::make_pair(pairV2V1, v2Index));
|
||||
|
||||
auto itEdge = edges.find(pairV2V1);
|
||||
if (itEdge != edges.end()) {
|
||||
|
@ -93,24 +94,25 @@ void HalfEdgeStructure::init(std::vector<const Vector3> vertices, std::vector<st
|
|||
mEdges.push_back(edge);
|
||||
|
||||
itEdge->second.twinEdgeIndex = edgeIndex + 1;
|
||||
itEdge->second.nextEdgeIndex = nextEdges[pairV2V1];
|
||||
|
||||
edge.twinEdgeIndex = edgeIndex;
|
||||
edge.nextEdgeIndex = edges[nextEdges[pairV1V2]].;
|
||||
|
||||
mVertices[v1Index].edgeIndex = edgeIndex;
|
||||
mVertices[v2Index].edgeIndex = edgeIndex + 1;
|
||||
|
||||
mapEdgeToIndex.insert(std::make_pair(pairV1V2, edgeIndex + 1));
|
||||
mapEdgeToIndex.insert(std::make_pair(pairV2V1, edgeIndex));
|
||||
|
||||
face.edgeIndex = edgeIndex + 1;
|
||||
}
|
||||
|
||||
currentFaceEdges.push_back(pairV1V2);
|
||||
}
|
||||
}
|
||||
|
||||
// For each edge of the face
|
||||
for (uint e=0; e < currentFaceEdges.size(); e++) {
|
||||
Edge& edge = currentFaceEdges[e];
|
||||
edge.nextEdgeIndex =
|
||||
}
|
||||
// Set next edges
|
||||
std::map<edgeKey, Edge>::iterator it;
|
||||
for (it = edges.begin(); it != edges.end(); ++it) {
|
||||
it->second.nextEdgeIndex = mapEdgeToIndex[nextEdges[it->first]];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,11 +54,11 @@ class HalfEdgeStructure {
|
|||
};
|
||||
|
||||
struct Vertex {
|
||||
const Vector3 point; // Coordinates of the vertex
|
||||
Vector3 point; // Coordinates of the vertex
|
||||
uint edgeIndex; // Index of one edge emanting from this vertex
|
||||
|
||||
/// Constructor
|
||||
Vertex(const Vector3& p) { point = p;}
|
||||
Vertex(Vector3& p) { point = p;}
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -81,7 +81,7 @@ class HalfEdgeStructure {
|
|||
~HalfEdgeStructure() = default;
|
||||
|
||||
/// Initialize the structure
|
||||
void init(std::vector<const Vector3> vertices, std::vector<std::vector<uint>> faces);
|
||||
void init(std::vector<Vector3> vertices, std::vector<std::vector<uint>> faces);
|
||||
|
||||
/// Return the number of faces
|
||||
uint getNbFaces() const;
|
||||
|
|
|
@ -49,7 +49,7 @@ class PolyhedronMesh {
|
|||
bool mIsFinalized;
|
||||
|
||||
/// All the vertices
|
||||
std::vector<const Vector3> mVertices;
|
||||
std::vector<Vector3> mVertices;
|
||||
|
||||
/// All the indexes of the face vertices
|
||||
std::vector<std::vector<uint>> mFaces;
|
||||
|
|
|
@ -33,7 +33,6 @@ using namespace reactphysics3d;
|
|||
// use between two types of collision shapes.
|
||||
NarrowPhaseAlgorithm* DefaultCollisionDispatch::selectAlgorithm(int type1, int type2) {
|
||||
|
||||
|
||||
CollisionShapeType shape1Type = static_cast<CollisionShapeType>(type1);
|
||||
CollisionShapeType shape2Type = static_cast<CollisionShapeType>(type2);
|
||||
|
||||
|
@ -45,9 +44,13 @@ NarrowPhaseAlgorithm* DefaultCollisionDispatch::selectAlgorithm(int type1, int t
|
|||
if (shape1Type == CollisionShapeType::SPHERE && shape2Type == CollisionShapeType::SPHERE) {
|
||||
return &mSphereVsSphereAlgorithm;
|
||||
}
|
||||
// Sphere vs Convex shapes (convex Mesh, BoxShape) algorithm
|
||||
if (shape1Type == CollisionShapeType::SPHERE && CollisionShape::isConvex(shape2Type)) {
|
||||
return &mSphereVsConvexMeshAlgorithm;
|
||||
// Sphere vs Capsule algorithm
|
||||
if (shape1Type == CollisionShapeType::CAPSULE && shape2Type == CollisionShapeType::SPHERE) {
|
||||
return &mSphereVsCapsuleAlgorithm;
|
||||
}
|
||||
// Capsule vs Capsule algorithm
|
||||
if (shape1Type == CollisionShapeType::CAPSULE && shape2Type == CollisionShapeType::CAPSULE) {
|
||||
return &mCapsuleVsCapsuleAlgorithm;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#include "ConcaveVsConvexAlgorithm.h"
|
||||
#include "SphereVsSphereAlgorithm.h"
|
||||
#include "SphereVsConvexMeshAlgorithm.h"
|
||||
#include "SphereVsCapsuleAlgorithm.h"
|
||||
#include "CapsuleVsCapsuleAlgorithm.h"
|
||||
#include "GJK/GJKAlgorithm.h"
|
||||
|
||||
namespace reactphysics3d {
|
||||
|
@ -51,8 +53,11 @@ class DefaultCollisionDispatch : public CollisionDispatch {
|
|||
/// Sphere vs Convex Mesh collision algorithm
|
||||
SphereVsConvexMeshAlgorithm mSphereVsConvexMeshAlgorithm;
|
||||
|
||||
/// GJK Algorithm
|
||||
GJKAlgorithm mGJKAlgorithm;
|
||||
/// Sphere vs Capsule collision algorithm
|
||||
SphereVsCapsuleAlgorithm mSphereVsCapsuleAlgorithm;
|
||||
|
||||
/// Capsule vs Capsule collision algorithm
|
||||
CapsuleVsCapsuleAlgorithm mCapsuleVsCapsuleAlgorithm;
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
// Libraries
|
||||
#include "GJKAlgorithm.h"
|
||||
#include "constraint/ContactPoint.h"
|
||||
#include "engine/OverlappingPair.h"
|
||||
#include "configuration.h"
|
||||
#include "engine/Profiler.h"
|
||||
#include <algorithm>
|
||||
|
|
80
src/collision/narrowphase/SphereVsCapsuleAlgorithm.cpp
Normal file
80
src/collision/narrowphase/SphereVsCapsuleAlgorithm.cpp
Normal file
|
@ -0,0 +1,80 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "SphereVsCapsuleAlgorithm.h"
|
||||
#include "collision/shapes/SphereShape.h"
|
||||
#include "collision/shapes/CapsuleShape.h"
|
||||
|
||||
// We want to use the ReactPhysics3D namespace
|
||||
using namespace reactphysics3d;
|
||||
|
||||
bool SphereVsCapsuleAlgorithm::testCollision(const NarrowPhaseInfo* narrowPhaseInfo, ContactPointInfo& contactPointInfo) {
|
||||
|
||||
// Get the collision shapes
|
||||
const SphereShape* sphereShape = static_cast<const SphereShape*>(narrowPhaseInfo->collisionShape1);
|
||||
const CapsuleShape* capsuleShape = static_cast<const CapsuleShape*>(narrowPhaseInfo->collisionShape2);
|
||||
|
||||
// Get the transform from sphere local-space to capsule local-space
|
||||
const Transform sphereToCapsuleSpaceTransform = narrowPhaseInfo->shape1ToWorldTransform * narrowPhaseInfo->shape2ToWorldTransform.getInverse();
|
||||
|
||||
// Transform the center of the sphere into the local-space of the capsule shape
|
||||
const Vector3 sphereCenter = sphereToCapsuleSpaceTransform.getPosition();
|
||||
|
||||
// Compute the end-points of the inner segment of the capsule
|
||||
const Vector3 capsuleSegA(0, -capsuleShape->getHeight() * decimal(0.5), 0);
|
||||
const Vector3 capsuleSegB(0, capsuleShape->getHeight() * decimal(0.5), 0);
|
||||
|
||||
// Compute the point on the inner capsule segment that is the closes to center of sphere
|
||||
const Vector3 closestPointOnSegment = computeClosestPointOnSegment(capsuleSegA, capsuleSegB, sphereCenter);
|
||||
|
||||
// Compute the distance between the sphere center and the closest point on the segment
|
||||
Vector3 sphereCenterToSegment = (closestPointOnSegment - sphereCenter);
|
||||
const decimal sphereSegmentDistanceSquare = sphereCenterToSegment.lengthSquare();
|
||||
|
||||
// Compute the sum of the radius of the sphere and the capsule (virtual sphere)
|
||||
decimal sumRadius = sphereShape->getRadius() + capsuleShape->getRadius();
|
||||
|
||||
// If the collision shapes overlap
|
||||
if (sphereSegmentDistanceSquare <= sumRadius * sumRadius && sphereSegmentDistanceSquare > MACHINE_EPSILON) {
|
||||
|
||||
decimal sphereSegmentDistance = std::sqrt(sphereSegmentDistanceSquare);
|
||||
sphereCenterToSegment /= sphereSegmentDistance;
|
||||
|
||||
const Vector3 contactPointSphereLocal = sphereToCapsuleSpaceTransform.getInverse() * (sphereCenter + sphereCenterToSegment * sphereShape->getRadius());
|
||||
const Vector3 contactPointCapsuleLocal = closestPointOnSegment - sphereCenterToSegment * capsuleShape->getRadius();
|
||||
|
||||
const Vector3 normalWorld = narrowPhaseInfo->shape2ToWorldTransform.getOrientation() * sphereCenterToSegment;
|
||||
|
||||
decimal penetrationDepth = sumRadius - sphereSegmentDistance;
|
||||
|
||||
// Create the contact info object
|
||||
contactPointInfo.init(normalWorld, penetrationDepth, contactPointSphereLocal, contactPointCapsuleLocal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
71
src/collision/narrowphase/SphereVsCapsuleAlgorithm.h
Normal file
71
src/collision/narrowphase/SphereVsCapsuleAlgorithm.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef REACTPHYSICS3D_SPHERE_VS_CAPSULE_ALGORITHM_H
|
||||
#define REACTPHYSICS3D_SPHERE_VS_CAPSULE_ALGORITHM_H
|
||||
|
||||
// Libraries
|
||||
#include "body/Body.h"
|
||||
#include "constraint/ContactPoint.h"
|
||||
#include "NarrowPhaseAlgorithm.h"
|
||||
|
||||
|
||||
/// Namespace ReactPhysics3D
|
||||
namespace reactphysics3d {
|
||||
|
||||
// Class SphereVsCapsuleAlgorithm
|
||||
/**
|
||||
* This class is used to compute the narrow-phase collision detection
|
||||
* between a sphere collision shape and a capsule collision shape.
|
||||
*/
|
||||
class SphereVsCapsuleAlgorithm : public NarrowPhaseAlgorithm {
|
||||
|
||||
protected :
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
SphereVsCapsuleAlgorithm() = default;
|
||||
|
||||
/// Destructor
|
||||
virtual ~SphereVsCapsuleAlgorithm() override = default;
|
||||
|
||||
/// Deleted copy-constructor
|
||||
SphereVsCapsuleAlgorithm(const SphereVsCapsuleAlgorithm& algorithm) = delete;
|
||||
|
||||
/// Deleted assignment operator
|
||||
SphereVsCapsuleAlgorithm& operator=(const SphereVsCapsuleAlgorithm& algorithm) = delete;
|
||||
|
||||
/// Compute a contact info if the two bounding volume collide
|
||||
virtual bool testCollision(const NarrowPhaseInfo* narrowPhaseInfo,
|
||||
ContactPointInfo& contactPointInfo) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -40,7 +40,7 @@
|
|||
namespace reactphysics3d {
|
||||
|
||||
/// Type of the collision shape
|
||||
enum class CollisionShapeType {TRIANGLE, BOX, SPHERE, CAPSULE, CONVEX_MESH, CONCAVE_MESH, HEIGHTFIELD};
|
||||
enum class CollisionShapeType {TRIANGLE, BOX, CAPSULE, SPHERE, CONVEX_MESH, CONCAVE_MESH, HEIGHTFIELD};
|
||||
const int NB_COLLISION_SHAPE_TYPES = 9;
|
||||
|
||||
// Declarations
|
||||
|
|
|
@ -87,7 +87,7 @@ Vector3 reactphysics3d::computeClosestPointOnSegment(const Vector3& segPointA, c
|
|||
/// Compute the closest points between two segments
|
||||
/// This method uses the technique described in the book Real-Time
|
||||
/// collision detection by Christer Ericson.
|
||||
void computeClosestPointBetweenTwoSegments(const Vector3& seg1PointA, const Vector3& seg1PointB,
|
||||
void reactphysics3d::computeClosestPointBetweenTwoSegments(const Vector3& seg1PointA, const Vector3& seg1PointB,
|
||||
const Vector3& seg2PointA, const Vector3& seg2PointB,
|
||||
Vector3& closestPointSeg1, Vector3& closestPointSeg2) {
|
||||
|
||||
|
@ -169,7 +169,7 @@ void computeClosestPointBetweenTwoSegments(const Vector3& seg1PointA, const Vect
|
|||
// computes the intersection P between the plane and the segment (segA, segB). The method returns the value "t" such
|
||||
// that P = segA + t * (segB - segA). Note that it only returns a value in [0, 1] if there is an intersection. Otherwise,
|
||||
// there is no intersection between the plane and the segment.
|
||||
decimal computePlaneSegmentIntersection(const Vector3& segA, const Vector3& segB, const decimal planeD, const Vector3& planeNormal) {
|
||||
decimal reactphysics3d::computePlaneSegmentIntersection(const Vector3& segA, const Vector3& segB, const decimal planeD, const Vector3& planeNormal) {
|
||||
|
||||
const decimal parallelEpsilon = decimal(0.0001);
|
||||
decimal t = decimal(-1);
|
||||
|
@ -188,7 +188,7 @@ decimal computePlaneSegmentIntersection(const Vector3& segA, const Vector3& segB
|
|||
}
|
||||
|
||||
/// Compute the distance between a point "point" and a line given by the points "linePointA" and "linePointB"
|
||||
decimal computeDistancePointToLineDistance(const Vector3& linePointA, const Vector3& linePointB, const Vector3& point) {
|
||||
decimal reactphysics3d::computeDistancePointToLineDistance(const Vector3& linePointA, const Vector3& linePointB, const Vector3& point) {
|
||||
|
||||
decimal distAB = (linePointB - linePointA).length();
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "collision/shapes/ConvexMeshShape.h"
|
||||
#include "collision/shapes/ConcaveMeshShape.h"
|
||||
#include "collision/shapes/HeightFieldShape.h"
|
||||
#include "collision/PolyhedronMesh.h"
|
||||
#include "collision/shapes/AABB.h"
|
||||
#include "collision/ProxyShape.h"
|
||||
#include "collision/RaycastInfo.h"
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
#include "SceneDemo.h"
|
||||
#include "Sphere.h"
|
||||
#include "Box.h"
|
||||
#include "Cone.h"
|
||||
#include "Cylinder.h"
|
||||
#include "Capsule.h"
|
||||
#include "Line.h"
|
||||
#include "ConvexMesh.h"
|
||||
|
|
Loading…
Reference in New Issue
Block a user