///<summary> /// Gets a world space triangle in the terrain at the given indices (as if it were a mesh). ///</summary> ///<param name="indices">Indices of the triangle.</param> ///<param name="transform">Transform to apply to the triangle vertices.</param> ///<param name="a">First vertex of the triangle.</param> ///<param name="b">Second vertex of the triangle.</param> ///<param name="c">Third vertex of the triangle.</param> public void GetTriangle(ref TriangleMeshConvexContactManifold.TriangleIndices indices, ref AffineTransform transform, out Vector3 a, out Vector3 b, out Vector3 c) { //Reverse the encoded index: //index = i + width * j int width = heights.GetLength(0); int columnA = indices.A / width; int rowA = indices.A - columnA * width; int columnB = indices.B / width; int rowB = indices.B - columnB * width; int columnC = indices.C / width; int rowC = indices.C - columnC * width; GetPosition(rowA, columnA, ref transform, out a); GetPosition(rowB, columnB, ref transform, out b); GetPosition(rowC, columnC, ref transform, out c); }
///<summary> /// Gets overlapped triangles with the terrain shape with a bounding box in the local space of the shape. ///</summary> ///<param name="localSpaceBoundingBox">Bounding box in the local space of the terrain shape.</param> ///<param name="overlappedTriangles">Triangles whose bounding boxes overlap the input bounding box.</param> public bool GetOverlaps(BoundingBox localSpaceBoundingBox, RawList <TriangleMeshConvexContactManifold.TriangleIndices> overlappedTriangles) { int width = heights.GetLength(0); int minX = Math.Max((int)localSpaceBoundingBox.Min.X, 0); int minY = Math.Max((int)localSpaceBoundingBox.Min.Z, 0); int maxX = Math.Min((int)localSpaceBoundingBox.Max.X, width - 2); int maxY = Math.Min((int)localSpaceBoundingBox.Max.Z, heights.GetLength(1) - 2); for (int i = minX; i <= maxX; i++) { for (int j = minY; j <= maxY; j++) { //Before adding a triangle to the list, make sure the object isn't too high or low from the quad. float highest, lowest; float y1 = heights[i, j]; float y2 = heights[i + 1, j]; float y3 = heights[i, j + 1]; float y4 = heights[i + 1, j + 1]; highest = y1; lowest = y1; if (y2 > highest) { highest = y2; } else if (y2 < lowest) { lowest = y2; } if (y3 > highest) { highest = y3; } else if (y3 < lowest) { lowest = y3; } if (y4 > highest) { highest = y4; } else if (y4 < lowest) { lowest = y4; } if (localSpaceBoundingBox.Max.Y < lowest || localSpaceBoundingBox.Min.Y > highest) { continue; } //Now the local bounding box is very likely intersecting those of the triangles. //Add the triangles to the list. var indices = new TriangleMeshConvexContactManifold.TriangleIndices(); //v3 v4 //v1 v2 if (quadTriangleOrganization == QuadTriangleOrganization.BottomLeftUpperRight) { //v1 v2 v3 indices.A = i + j * width; indices.B = i + 1 + j * width; indices.C = i + (j + 1) * width; overlappedTriangles.Add(indices); //v2 v4 v3 indices.A = i + 1 + j * width; indices.B = i + 1 + (j + 1) * width; indices.C = i + (j + 1) * width; overlappedTriangles.Add(indices); } else //Bottom right, Upper left { //v1 v2 v4 indices.A = i + j * width; indices.B = i + 1 + j * width; indices.C = i + 1 + (j + 1) * width; overlappedTriangles.Add(indices); //v1 v4 v3 indices.A = i + j * width; indices.B = i + 1 + (j + 1) * width; indices.C = i + (j + 1) * width; overlappedTriangles.Add(indices); } } } return(overlappedTriangles.count > 0); }
///<summary> /// Gets overlapped triangles with the terrain shape with a bounding box in the local space of the shape. ///</summary> ///<param name="localSpaceBoundingBox">Bounding box in the local space of the terrain shape.</param> ///<param name="overlappedTriangles">Triangles whose bounding boxes overlap the input bounding box.</param> public bool GetOverlaps(BoundingBox localSpaceBoundingBox, RawList<TriangleMeshConvexContactManifold.TriangleIndices> overlappedTriangles) { int width = heights.GetLength(0); int minX = Math.Max((int)localSpaceBoundingBox.Min.X, 0); int minY = Math.Max((int)localSpaceBoundingBox.Min.Z, 0); int maxX = Math.Min((int)localSpaceBoundingBox.Max.X, width - 2); int maxY = Math.Min((int)localSpaceBoundingBox.Max.Z, heights.GetLength(1) - 2); for (int i = minX; i <= maxX; i++) { for (int j = minY; j <= maxY; j++) { //Before adding a triangle to the list, make sure the object isn't too high or low from the quad. float highest, lowest; float y1 = heights[i, j]; float y2 = heights[i + 1, j]; float y3 = heights[i, j + 1]; float y4 = heights[i + 1, j + 1]; highest = y1; lowest = y1; if (y2 > highest) highest = y2; else if (y2 < lowest) lowest = y2; if (y3 > highest) highest = y3; else if (y3 < lowest) lowest = y3; if (y4 > highest) highest = y4; else if (y4 < lowest) lowest = y4; if (localSpaceBoundingBox.Max.Y < lowest || localSpaceBoundingBox.Min.Y > highest) continue; //Now the local bounding box is very likely intersecting those of the triangles. //Add the triangles to the list. var indices = new TriangleMeshConvexContactManifold.TriangleIndices(); //v3 v4 //v1 v2 if (quadTriangleOrganization == QuadTriangleOrganization.BottomLeftUpperRight) { //v1 v2 v3 indices.A = i + j * width; indices.B = i + 1 + j * width; indices.C = i + (j + 1) * width; overlappedTriangles.Add(indices); //v2 v4 v3 indices.A = i + 1 + j * width; indices.B = i + 1 + (j + 1) * width; indices.C = i + (j + 1) * width; overlappedTriangles.Add(indices); } else //Bottom right, Upper left { //v1 v2 v4 indices.A = i + j * width; indices.B = i + 1 + j * width; indices.C = i + 1 + (j + 1) * width; overlappedTriangles.Add(indices); //v1 v4 v3 indices.A = i + j * width; indices.B = i + 1 + (j + 1) * width; indices.C = i + (j + 1) * width; overlappedTriangles.Add(indices); } } } return overlappedTriangles.Count > 0; }