private HitObject[] GenerateCurvedHitObjects(Table.Table table, IItem item) { var hitObjects = new List <HitObject>(); var height = table.GetSurfaceHeight(_data.Surface, _data.Center.X, _data.Center.Y); var vVertex = DragPoint.GetRgVertex <RenderVertex2D, CatmullCurve2DCatmullCurveFactory>(_data.DragPoints); var count = vVertex.Length; var rgv = new RenderVertex2D[count]; var rgv3D = new Vertex3D[count]; for (var i = 0; i < count; i++) { rgv[i] = vVertex[i]; rgv3D[i] = new Vertex3D(rgv[i].X, rgv[i].Y, height + (float)(PhysicsConstants.PhysSkin * 2.0)); } for (var i = 0; i < count; i++) { var pv2 = rgv[i < count - 1 ? i + 1 : 0]; var pv3 = rgv[i < count - 2 ? i + 2 : i + 2 - count]; hitObjects.Add(GetLineSeg(pv2, pv3, height, item)); } hitObjects.AddRange(new Hit3DPoly(rgv3D, ItemType.Trigger, item).ConvertToTriangles()); return(hitObjects.ToArray()); }
/// <summary> /// Returns the hit line polygons for the surface. /// </summary> private void GenerateLinePolys(RenderVertex2D pv1, Vertex2D pv2, float playfieldHeight, ICollection <ICollider> colliders) { var bottom = _component.HeightBottom + playfieldHeight; var top = _component.HeightTop + playfieldHeight; if (!pv1.IsSlingshot) { colliders.Add(new LineCollider(pv1.ToUnityFloat2(), pv2.ToUnityFloat2(), bottom, top, _api.GetColliderInfo())); } else { colliders.Add(new LineSlingshotCollider(_colliderComponent.SlingshotForce, pv1.ToUnityFloat2(), pv2.ToUnityFloat2(), bottom, top, _api.GetColliderInfo())); } if (_component.HeightBottom != 0) { // add lower edge as a line colliders.Add(new Line3DCollider(new float3(pv1.X, pv1.Y, bottom), new float3(pv2.X, pv2.Y, bottom), _api.GetColliderInfo())); } // add upper edge as a line colliders.Add(new Line3DCollider(new float3(pv1.X, pv1.Y, top), new float3(pv2.X, pv2.Y, top), _api.GetColliderInfo())); // create vertical joint between the two line segments colliders.Add(new LineZCollider(pv1.ToUnityFloat2(), bottom, top, _api.GetColliderInfo())); // add upper and lower end points of line if (_component.HeightBottom != 0) { colliders.Add(new PointCollider(new float3(pv1.X, pv1.Y, bottom), _api.GetColliderInfo())); } colliders.Add(new PointCollider(new float3(pv1.X, pv1.Y, top), _api.GetColliderInfo())); }
/// <summary> /// Returns the hit line polygons for the surface. /// </summary> private IEnumerable <HitObject> GenerateLinePolys(RenderVertex2D pv1, Vertex2D pv2, EventProxy events, Table.Table table) { var linePolys = new List <HitObject>(); var bottom = _data.HeightBottom + table.TableHeight; var top = _data.HeightTop + table.TableHeight; if (!pv1.IsSlingshot) { linePolys.Add(new LineSeg(pv1, pv2, bottom, top, ItemType.Surface)); } else { var slingLine = new LineSegSlingshot(_data, pv1, pv2, bottom, top, ItemType.Surface) { Force = _data.SlingshotForce, Obj = events, FireEvents = true, Threshold = _data.Threshold }; // slingshots always have hit events linePolys.Add(slingLine); LineSling.Add(slingLine); } if (_data.HeightBottom != 0) { // add lower edge as a line linePolys.Add(new HitLine3D(new Vertex3D(pv1.X, pv1.Y, bottom), new Vertex3D(pv2.X, pv2.Y, bottom), ItemType.Surface)); } // add upper edge as a line linePolys.Add(new HitLine3D(new Vertex3D(pv1.X, pv1.Y, top), new Vertex3D(pv2.X, pv2.Y, top), ItemType.Surface)); // create vertical joint between the two line segments linePolys.Add(new HitLineZ(pv1, bottom, top, ItemType.Surface)); // add upper and lower end points of line if (_data.HeightBottom != 0) { linePolys.Add(new HitPoint(new Vertex3D(pv1.X, pv1.Y, bottom), ItemType.Surface)); } linePolys.Add(new HitPoint(new Vertex3D(pv1.X, pv1.Y, top), ItemType.Surface)); return(linePolys.ToArray()); }
private void GenerateCurvedHitObjects(ICollection <ICollider> colliders) { var height = _component.PositionZ; var vVertex = DragPoint.GetRgVertex <RenderVertex2D, CatmullCurve2DCatmullCurveFactory>(_component.DragPoints); var count = vVertex.Length; var rgv = new RenderVertex2D[count]; var rgv3D = new float3[count]; for (var i = 0; i < count; i++) { rgv[i] = vVertex[i]; rgv3D[i] = new float3(rgv[i].X, rgv[i].Y, height + (float)(PhysicsConstants.PhysSkin * 2.0)); } ColliderUtils.Generate3DPolyColliders(rgv3D, _api.GetColliderInfo(), colliders); for (var i = 0; i < count; i++) { var pv2 = rgv[i < count - 1 ? i + 1 : 0]; var pv3 = rgv[i < count - 2 ? i + 2 : i + 2 - count]; AddLineSeg(pv2.ToUnityFloat2(), pv3.ToUnityFloat2(), height, colliders); } }
public SplineVertex(DragPointData[] dragPoints, int thickness, int tableDetailLevel, float accuracy, bool staticRendering = true, float margin = 0f, bool loop = true) { var vertices = GetCentralCurve(dragPoints, tableDetailLevel, accuracy, staticRendering, loop: loop); var numVertices = vertices.Length; Cross = new bool[numVertices + 1]; MiddlePoints = new Vertex2D[numVertices + 1]; RgvLocal = new Vertex2D[(numVertices + 1) * 2]; for (var i = 0; i < numVertices; i++) { // prev and next wrap around in loops var prev = vertices[i > 0 ? i - 1 : numVertices - 1]; var next = vertices[i < numVertices - 1 ? i + 1 : 0]; // .. but have to be corrected at start and end with "virtual vertices" continuing the spline when not looping, so cuts perpendicular to the tangents // maybe fix ramps after that that also hat the same problem. if (!loop && i == 0) { prev = new RenderVertex2D(vertices[0].X * 2 - vertices[1].X, vertices[0].Y * 2 - vertices[1].Y); } if (!loop && i == (numVertices - 1)) { next = new RenderVertex2D(vertices[numVertices - 1].X * 2 - vertices[numVertices - 2].X, vertices[numVertices - 1].Y * 2 - vertices[numVertices - 2].Y); } var middle = vertices[i]; Cross[i] = middle.IsControlPoint; Vertex2D normal; // Get normal at this point // Notice that these values equal the ones in the line // equation and could probably be substituted by them. var normal1 = new Vertex2D(prev.Y - middle.Y, middle.X - prev.X); // vector vmiddle-vprev rotated RIGHT var normal2 = new Vertex2D(middle.Y - next.Y, next.X - middle.X); // vector vnext-vmiddle rotated RIGHT // not needed special start/end handling as rubbers always loop, except for the case where there are only 2 control points // I guess this does not work as intended, but could not figure out what was wrong. i think that somehow the normal of Node 1 is wrong. /cupiii if (numVertices == 2 && i == numVertices - 1) { normal1.Normalize(); normal = normal1; } else if (numVertices == 2 && i == 0) { normal2.Normalize(); normal = normal2; } else { normal1.Normalize(); normal2.Normalize(); if (MathF.Abs(normal1.X - normal2.X) < 0.0001 && MathF.Abs(normal1.Y - normal2.Y) < 0.0001) { // Two parallel segments normal = normal1; } else { // Find intersection of the two edges meeting this points, but // shift those lines outwards along their normals // First line var a = prev.Y - middle.Y; var b = middle.X - prev.X; // Shift line along the normal var c = a * (normal1.X - prev.X) + b * (normal1.Y - prev.Y); // Second line var d = next.Y - middle.Y; var e = middle.X - next.X; // Shift line along the normal var f = d * (normal2.X - next.X) + e * (normal2.Y - next.Y); var det = a * e - b * d; var invDet = det != 0.0f ? 1.0f / det : 0.0f; var intersectX = (b * f - e * c) * invDet; var intersectY = (c * d - a * f) * invDet; normal = new Vertex2D(middle.X - intersectX, middle.Y - intersectY); } } var widthCur = thickness + margin; MiddlePoints[i] = new Vertex2D(middle.X, middle.Y); RgvLocal[i] = new Vertex2D(middle.X, middle.Y) + widthCur * 0.5f * normal; RgvLocal[(numVertices + 1) * 2 - i - 1] = new Vertex2D(middle.X, middle.Y) - widthCur * 0.5f * normal; if (i == 0) { RgvLocal[numVertices] = RgvLocal[0]; RgvLocal[(numVertices + 1) * 2 - numVertices - 1] = RgvLocal[(numVertices + 1) * 2 - 1]; } } if (loop) { VertexCount = numVertices; } else { MiddlePoints[numVertices] = MiddlePoints[0]; Cross[numVertices] = vertices[0].IsControlPoint; VertexCount = numVertices + 1; } }