private static List <HitObject> CheckJoint(HitTriangle ph3d1, HitTriangle ph3d2, IItem item) { var hitObjects = new List <HitObject>(); if (ph3d1 != null) // may be null in case of degenerate triangles { var jointNormal = Vertex3D.CrossProduct(ph3d1.Normal, ph3d2.Normal); if (jointNormal.LengthSq() < 1e-8) // coplanar triangles need no joints { return(hitObjects); } } // By convention of the calling function, points 1 [0] and 2 [1] of the second polygon will // be the common-edge points hitObjects.Add(GenerateJoint(ph3d2.Rgv[0], ph3d2.Rgv[1], item)); return(hitObjects); }
public static void Create(BlobBuilder builder, HitTriangle src, ref BlobPtr <Collider> dest) { ref var trianglePtr = ref UnsafeUtility.As <BlobPtr <Collider>, BlobPtr <TriangleCollider> >(ref dest);
public HitObject[] GenerateHitObjects(Table.Table table, IItem item) { var hitObjects = new List <HitObject>(); var rv = _meshGenerator.GetRampVertex(table, PhysicsConstants.HitShapeDetailLevel, true); var rgvLocal = rv.RgvLocal; var rgHeight1 = rv.PointHeights; var vertexCount = rv.VertexCount; var(wallHeightRight, wallHeightLeft) = GetWallHeights(); Vertex2D pv1, pv2, pv3 = new Vertex2D(), pv4 = new Vertex2D(); // Add line segments for right ramp wall. if (wallHeightRight > 0.0f) { for (var i = 0; i < vertexCount - 1; i++) { pv2 = rgvLocal[i]; pv3 = rgvLocal[i + 1]; hitObjects.AddRange(GenerateWallLineSeg(pv2, pv3, i > 0, rgHeight1[i], rgHeight1[i + 1], wallHeightRight, item)); hitObjects.AddRange(GenerateWallLineSeg(pv3, pv2, i < vertexCount - 2, rgHeight1[i], rgHeight1[i + 1], wallHeightRight, item)); // add joints at start and end of right wall if (i == 0) { hitObjects.Add(GenerateJoint2D(pv2, rgHeight1[0], rgHeight1[0] + wallHeightRight, item)); } if (i == vertexCount - 2) { hitObjects.Add(GenerateJoint2D(pv3, rgHeight1[vertexCount - 1], rgHeight1[vertexCount - 1] + wallHeightRight, item)); } } } // Add line segments for left ramp wall. if (wallHeightLeft > 0.0f) { for (var i = 0; i < vertexCount - 1; i++) { pv2 = rgvLocal[vertexCount + i]; pv3 = rgvLocal[vertexCount + i + 1]; hitObjects.AddRange(GenerateWallLineSeg(pv2, pv3, i > 0, rgHeight1[vertexCount - i - 2], rgHeight1[vertexCount - i - 1], wallHeightLeft, item)); hitObjects.AddRange(GenerateWallLineSeg(pv3, pv2, i < vertexCount - 2, rgHeight1[vertexCount - i - 2], rgHeight1[vertexCount - i - 1], wallHeightLeft, item)); // add joints at start and end of left wall if (i == 0) { hitObjects.Add(GenerateJoint2D(pv2, rgHeight1[vertexCount - 1], rgHeight1[vertexCount - 1] + wallHeightLeft, item)); } if (i == vertexCount - 2) { hitObjects.Add(GenerateJoint2D(pv3, rgHeight1[0], rgHeight1[0] + wallHeightLeft, item)); } } } // Add hit triangles for the ramp floor. HitTriangle ph3dpoly, ph3dpolyOld = null; Vertex3D[] rgv3D; for (var i = 0; i < vertexCount - 1; i++) { /* * Layout of one ramp quad seen from above, ramp direction is bottom to top: * * 3 - - 4 * | \ | * | \ | * 2 - - 1 */ pv1 = rgvLocal[i]; // i-th right pv2 = rgvLocal[vertexCount * 2 - i - 1]; // i-th left pv3 = rgvLocal[vertexCount * 2 - i - 2]; // (i+1)-th left pv4 = rgvLocal[i + 1]; // (i+1)-th right // left ramp floor triangle, CCW order rgv3D = new [] { new Vertex3D(pv2.X, pv2.Y, rgHeight1[i]), new Vertex3D(pv1.X, pv1.Y, rgHeight1[i]), new Vertex3D(pv3.X, pv3.Y, rgHeight1[i + 1]) }; // add joint for starting edge of ramp if (i == 0) { hitObjects.Add(GenerateJoint(rgv3D[0], rgv3D[1], item)); } // add joint for left edge hitObjects.Add(GenerateJoint(rgv3D[0], rgv3D[2], item)); //!! this is not efficient at all, use native triangle-soup directly somehow ph3dpoly = new HitTriangle(rgv3D, ItemType.Ramp, item); if (!ph3dpoly.IsDegenerate) // degenerate triangles happen if width is 0 at some point { hitObjects.Add(ph3dpoly); hitObjects.AddRange(CheckJoint(ph3dpolyOld, ph3dpoly, item)); ph3dpolyOld = ph3dpoly; } // right ramp floor triangle, CCW order rgv3D = new [] { new Vertex3D(pv3.X, pv3.Y, rgHeight1[i + 1]), new Vertex3D(pv1.X, pv1.Y, rgHeight1[i]), new Vertex3D(pv4.X, pv4.Y, rgHeight1[i + 1]) }; // add joint for right edge hitObjects.Add(GenerateJoint(rgv3D[1], rgv3D[2], item)); ph3dpoly = new HitTriangle(rgv3D, ItemType.Ramp, item); if (!ph3dpoly.IsDegenerate) { hitObjects.Add(ph3dpoly); } hitObjects.AddRange(CheckJoint(ph3dpolyOld, ph3dpoly, item)); ph3dpolyOld = ph3dpoly; } if (vertexCount >= 2) { // add joint for final edge of ramp var v1 = new Vertex3D(pv4.X, pv4.Y, rgHeight1[vertexCount - 1]); var v2 = new Vertex3D(pv3.X, pv3.Y, rgHeight1[vertexCount - 1]); hitObjects.Add(GenerateJoint(v1, v2, item)); } // add outside bottom, // joints at the intersections are not needed since the inner surface has them // this surface is identical... except for the direction of the normal face. // hence the joints protect both surface edges from having a fall through for (var i = 0; i < vertexCount - 1; i++) { // see sketch above pv1 = rgvLocal[i]; pv2 = rgvLocal[vertexCount * 2 - i - 1]; pv3 = rgvLocal[vertexCount * 2 - i - 2]; pv4 = rgvLocal[i + 1]; // left ramp triangle, order CW rgv3D = new[] { new Vertex3D(pv1.X, pv1.Y, rgHeight1[i]), new Vertex3D(pv2.X, pv2.Y, rgHeight1[i]), new Vertex3D(pv3.X, pv3.Y, rgHeight1[i + 1]) }; ph3dpoly = new HitTriangle(rgv3D, ItemType.Ramp, item); if (!ph3dpoly.IsDegenerate) { hitObjects.Add(ph3dpoly); } // right ramp triangle, order CW rgv3D = new[] { new Vertex3D(pv3.X, pv3.Y, rgHeight1[i + 1]), new Vertex3D(pv4.X, pv4.Y, rgHeight1[i + 1]), new Vertex3D(pv1.X, pv1.Y, rgHeight1[i]) }; ph3dpoly = new HitTriangle(rgv3D, ItemType.Ramp, item); if (!ph3dpoly.IsDegenerate) { hitObjects.Add(ph3dpoly); } } return(hitObjects .Select(obj => SetupHitObject(obj, table)) .ToArray()); }