Raycast method with feedback information This method implements the technique in the book "Real-time Collision Detection" by Christer Ericson.
| 105 | /// This method implements the technique in the book "Real-time Collision Detection" by |
| 106 | /// Christer Ericson. |
| 107 | bool ConvexMeshShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, Collider* collider, MemoryAllocator& /*allocator*/) const { |
| 108 | |
| 109 | // Ray direction |
| 110 | Vector3 direction = ray.point2 - ray.point1; |
| 111 | |
| 112 | decimal tMin = decimal(0.0); |
| 113 | decimal tMax = ray.maxFraction; |
| 114 | Vector3 currentFaceNormal; |
| 115 | bool isIntersectionFound = false; |
| 116 | |
| 117 | const HalfEdgeStructure& halfEdgeStructure = mConvexMesh->getHalfEdgeStructure(); |
| 118 | |
| 119 | // For each face of the convex mesh |
| 120 | for (uint32 f=0; f < mConvexMesh->getNbFaces(); f++) { |
| 121 | |
| 122 | const HalfEdgeStructure::Face& face = halfEdgeStructure.getFace(f); |
| 123 | const Vector3& faceNormal = getFaceNormal(f); |
| 124 | const HalfEdgeStructure::Vertex& faceVertex = halfEdgeStructure.getVertex(face.faceVertices[0]); |
| 125 | const Vector3& facePoint = mConvexMesh->getVertex(faceVertex.vertexPointIndex); |
| 126 | decimal denom = faceNormal.dot(direction); |
| 127 | decimal planeD = faceNormal.dot(facePoint); |
| 128 | decimal dist = planeD - faceNormal.dot(ray.point1); |
| 129 | |
| 130 | // If ray is parallel to the face |
| 131 | if (denom == decimal(0.0)) { |
| 132 | |
| 133 | // If ray is outside the clipping face, we return no intersection |
| 134 | if (dist < decimal(0.0)) return false; |
| 135 | } |
| 136 | else { |
| 137 | |
| 138 | // Compute the intersection between the ray and the current face plane |
| 139 | decimal t = dist / denom; |
| 140 | |
| 141 | // Update the current ray intersection by clipping it with the current face plane |
| 142 | // If the place faces the ray |
| 143 | if (denom < decimal(0.0)) { |
| 144 | // Clip the current ray intersection as it enters the convex mesh |
| 145 | if (t > tMin) { |
| 146 | tMin = t; |
| 147 | currentFaceNormal = faceNormal; |
| 148 | isIntersectionFound = true; |
| 149 | } |
| 150 | } |
| 151 | else { |
| 152 | // Clip the current ray intersection as it exits the convex mesh |
| 153 | if (t < tMax) tMax = t; |
| 154 | } |
| 155 | |
| 156 | // If the ray intersection with the convex mesh becomes empty, report no intersection |
| 157 | if (tMin > tMax) return false; |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | if (isIntersectionFound) { |
| 162 | |
| 163 | // The ray intersects with the convex mesh |
| 164 | assert(tMin >= decimal(0.0)); |
nothing calls this directly
no test coverage detected