Test collision with the triangles of the height field shape. The idea is to use the AABB of the body when need to test and see against which triangles of the height-field we need to test for collision. We compute the sub-grid points that are inside the other body's AABB and then for each rectangle in the sub-grid we generate two triangles that we use to test collision.
| 137 | // to test for collision. We compute the sub-grid points that are inside the other body's AABB |
| 138 | // and then for each rectangle in the sub-grid we generate two triangles that we use to test collision. |
| 139 | void HeightField::computeOverlappingTriangles(const AABB& aabb, Array<Vector3>& triangleVertices, |
| 140 | Array<Vector3>& triangleVerticesNormals, |
| 141 | Array<uint32>& shapeIds, const Vector3& scale) const { |
| 142 | |
| 143 | RP3D_PROFILE("HeightField::computeOverlappingTriangles()", mProfiler); |
| 144 | |
| 145 | // Compute the integer grid coordinates inside the area we need to test for collision |
| 146 | uint32 minGridCoords[3]; |
| 147 | uint32 maxGridCoords[3]; |
| 148 | computeMinMaxGridCoordinates(minGridCoords, maxGridCoords, aabb); |
| 149 | |
| 150 | // Compute the starting and ending coords of the sub-grid according to the up axis |
| 151 | uint32 iMin = clamp(minGridCoords[0], 0, mNbColumns - 1); |
| 152 | uint32 iMax = clamp(maxGridCoords[0], 0, mNbColumns - 1); |
| 153 | uint32 jMin = clamp(minGridCoords[2], 0, mNbRows - 1); |
| 154 | uint32 jMax = clamp(maxGridCoords[2], 0, mNbRows - 1); |
| 155 | |
| 156 | assert(iMin < mNbColumns); |
| 157 | assert(iMax < mNbColumns); |
| 158 | assert(jMin < mNbRows); |
| 159 | assert(jMax < mNbRows); |
| 160 | |
| 161 | // For each sub-grid points (except the last ones one each dimension) |
| 162 | for (uint32 i = iMin; i < iMax; i++) { |
| 163 | for (uint32 j = jMin; j < jMax; j++) { |
| 164 | |
| 165 | // Compute the four point of the current quad |
| 166 | const Vector3 p1 = getVertexAt(i, j) * scale; |
| 167 | const Vector3 p2 = getVertexAt(i, j + 1) * scale; |
| 168 | const Vector3 p3 = getVertexAt(i + 1, j) * scale; |
| 169 | const Vector3 p4 = getVertexAt(i + 1, j + 1) * scale; |
| 170 | |
| 171 | // Generate the first triangle for the current grid rectangle |
| 172 | triangleVertices.add(p1); |
| 173 | triangleVertices.add(p2); |
| 174 | triangleVertices.add(p3); |
| 175 | |
| 176 | // Compute the triangle normal |
| 177 | Vector3 triangle1Normal = (p2 - p1).cross(p3 - p1).getUnit(); |
| 178 | |
| 179 | // Use the triangle face normal as vertices normals (this is an aproximation. The correct |
| 180 | // solution would be to compute all the normals of the neighbor triangles and use their |
| 181 | // weighted average (with incident angle as weight) at the vertices. However, this solution |
| 182 | // seems too expensive (it requires to compute the normal of all neighbor triangles instead |
| 183 | // and compute the angle of incident edges with asin(). Maybe we could also precompute the |
| 184 | // vertices normal at the HeightFieldShape constructor but it will require extra memory to |
| 185 | // store them. |
| 186 | triangleVerticesNormals.add(triangle1Normal); |
| 187 | triangleVerticesNormals.add(triangle1Normal); |
| 188 | triangleVerticesNormals.add(triangle1Normal); |
| 189 | |
| 190 | // Compute the shape ID |
| 191 | shapeIds.add(computeTriangleShapeId(i, j, 0)); |
| 192 | |
| 193 | // Generate the second triangle for the current grid rectangle |
| 194 | triangleVertices.add(p3); |
| 195 | triangleVertices.add(p2); |
| 196 | triangleVertices.add(p4); |
no test coverage detected