public Mesh GetMesh(string id, Table.Table table, Origin origin) { var height = table.GetSurfaceHeight(_data.Surface, _data.Center.X, _data.Center.Y); switch (id) { case Base: { var mesh = BaseMesh.Clone().MakeScale(_data.Radius, _data.Radius, _data.HeightScale); return(TranslateMesh(mesh, z => z + height, origin)); } case Cap: { var mesh = CapMesh.Clone().MakeScale(_data.Radius * 2, _data.Radius * 2, _data.HeightScale); return(TranslateMesh(mesh, z => z + _data.HeightScale + height, origin)); } case Ring: { var mesh = RingMesh.Clone().MakeScale(_data.Radius, _data.Radius, _data.HeightScale); return(TranslateMesh(mesh, z => z + height, origin)); } case Skirt: { var mesh = SocketMesh.Clone().MakeScale(_data.Radius, _data.Radius, _data.HeightScale); return(TranslateMesh(mesh, z => z + (height + 5.0f), origin)); } } throw new ArgumentException("Unknown bumper mesh \"" + id + "\"."); }
public void Init(Table.Table table) { var stroke = _data.Stroke; _beginY = _data.Center.Y; _endY = _data.Center.Y - stroke; NumFrames = (int)(stroke * (float)(PlungerFrameCount / 80.0)) + 1; // 25 frames per 80 units travel _invScale = NumFrames > 1 ? 1.0f / (NumFrames - 1) : 0.0f; _dyPerFrame = (_endY - _beginY) * _invScale; _circlePoints = _data.Type == PlungerType.PlungerTypeFlat ? 0 : 24; _springLoops = 0.0f; _springEndLoops = 0.0f; _springGauge = 0.0f; _springRadius = 0.0f; _springMinSpacing = 2.2f; _rodY = _beginY + _data.Height; // note the number of cells in the source image _srcCells = _data.AnimFrames; if (_srcCells < 1) { _srcCells = 1; } // figure the width in relative units (0..1) of each cell _cellWid = 1.0f / _srcCells; if (table != null) { _zHeight = table.GetSurfaceHeight(_data.Surface, _data.Center.X, _data.Center.Y) + _data.ZAdjust; _zScale = table.GetScaleZ(); } _desc = GetPlungerDesc(); }
private Mesh GetMesh(string id, Table.Table table, Origin origin) { if (_data.Center == null) { throw new InvalidOperationException($"Cannot export bumper {_data.Name} without center."); } var height = table.GetSurfaceHeight(_data.Surface, _data.Center.X, _data.Center.Y) * table.GetScaleZ(); switch (id) { case Base: { var mesh = BaseMesh.Clone().MakeScale(_data.Radius, _data.Radius, _data.HeightScale); return(TranslateMesh(mesh, z => z * table.GetScaleZ() + height, origin)); } case Cap: { var mesh = CapMesh.Clone().MakeScale(_data.Radius * 2, _data.Radius * 2, _data.HeightScale); return(TranslateMesh(mesh, z => (z + _data.HeightScale) * table.GetScaleZ() + height, origin)); } case Ring: { var mesh = RingMesh.Clone().MakeScale(_data.Radius, _data.Radius, _data.HeightScale); return(TranslateMesh(mesh, z => z * table.GetScaleZ() + height, origin)); } case Skirt: { var mesh = SocketMesh.Clone().MakeScale(_data.Radius, _data.Radius, _data.HeightScale); return(TranslateMesh(mesh, z => z * table.GetScaleZ() + (height + 5.0f), origin)); } } throw new ArgumentException("Unknown bumper mesh \"" + id + "\"."); }
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()); }
public void Init(Table.Table table) { var height = table.GetSurfaceHeight(Data.Surface, Data.Center.X, Data.Center.Y); _hitSpinner = new SpinnerHit(Data, height, this); _hitCircles = _hitGenerator.GetHitCircles(height, this); }
private Dictionary <string, Mesh> GetMeshes(Table.Table table, Origin origin) { var lightMesh = Bulb.Clone(); var height = table.GetSurfaceHeight(_data.Surface, _data.Center.X, _data.Center.Y) * table.GetScaleZ(); var transX = origin == Origin.Global ? _data.Center.X : 0f; var transY = origin == Origin.Global ? _data.Center.Y : 0f; var transZ = origin == Origin.Global ? height : 0f; foreach (var vertex in lightMesh.Vertices) { vertex.X = vertex.X * _data.MeshRadius + transX; vertex.Y = vertex.Y * _data.MeshRadius + transY; vertex.Z = vertex.Z * _data.MeshRadius * table.GetScaleZ() + transZ; } var socketMesh = Socket.Clone(); foreach (var vertex in socketMesh.Vertices) { vertex.X = vertex.X * _data.MeshRadius + transX; vertex.Y = vertex.Y * _data.MeshRadius + transY; vertex.Z = vertex.Z * _data.MeshRadius * table.GetScaleZ() + transZ; } return(new Dictionary <string, Mesh> { { "Bulb", lightMesh }, { "Socket", socketMesh }, }); }
public void Init(Table.Table table) { var zHeight = table.GetSurfaceHeight(Data.Surface, Data.Center.X, Data.Center.Y); PlungerHit = new PlungerHit(Data, zHeight, this); _hitObjects = new HitObject[] { PlungerHit }; }
public Mesh GetMesh(string id, int frame, Table.Table table, Origin origin, bool asRightHanded = true) { var height = table.GetSurfaceHeight(_data.Surface, _data.Center.X, _data.Center.Y); Init(height); if (id == Flat) { var flatMesh = BuildFlatMesh(); return(asRightHanded ? flatMesh.Transform(Matrix3D.RightHanded) : flatMesh); } CalculateArraySizes(); switch (id) { case Rod: var rodMesh = BuildRodMesh(); return(asRightHanded ? rodMesh.Transform(Matrix3D.RightHanded) : rodMesh); case Spring: var springMesh = BuildSpringMesh(); return(asRightHanded ? springMesh.Transform(Matrix3D.RightHanded) : springMesh); } throw new ArgumentException($"Unknown mesh ID \"{id}\"."); }
private bool _solState; // m_solState public FlipperMover(FlipperData data, FlipperState state, EventProxy events, Table.Table table) { _data = data; _state = state; _events = events; _tableData = table.Data; if (data.FlipperRadiusMin > 0 && data.FlipperRadiusMax > data.FlipperRadiusMin) { data.FlipperRadius = data.FlipperRadiusMax - (data.FlipperRadiusMax - data.FlipperRadiusMin) /* m_ptable->m_globalDifficulty*/; data.FlipperRadius = MathF.Max(data.FlipperRadius, data.BaseRadius - data.EndRadius + 0.05f); } else { data.FlipperRadius = data.FlipperRadiusMax; } EndRadius = MathF.Max(data.EndRadius, 0.01f); // radius of flipper end FlipperRadius = MathF.Max(data.FlipperRadius, 0.01f); // radius of flipper arc, center-to-center radius AngleStart = MathF.DegToRad(data.StartAngle); AngleEnd = MathF.DegToRad(data.EndAngle); if (AngleEnd == AngleStart) { // otherwise hangs forever in collisions/updates AngleEnd += 0.0001f; } var height = table.GetSurfaceHeight(data.Surface, data.Center.X, data.Center.Y); var baseRadius = MathF.Max(data.BaseRadius, 0.01f); HitCircleBase = new HitCircle(data.Center, baseRadius, height, height + data.Height, ItemType.Flipper); IsInContact = false; EnableRotateEvent = 0; AngleSpeed = 0; _direction = AngleEnd >= AngleStart; _solState = false; _curTorque = 0.0f; _state.Angle = AngleStart; _angularMomentum = 0; _angularAcceleration = 0; var ratio = (baseRadius - EndRadius) / FlipperRadius; // model inertia of flipper as that of rod of length flipr around its end var mass = _data.GetFlipperMass(_tableData); Inertia = (float)(1.0 / 3.0) * mass * (FlipperRadius * FlipperRadius); LastHitFace = false; // used to optimize hit face search order // F2 Norm, used in Green's transform, in FPM time search // = sinf(faceNormOffset) ZeroAngNorm.X = MathF.Sqrt(1.0f - ratio * ratio); // F1 norm, change sign of x component, i.E -zeroAngNorm.X // = -cosf(faceNormOffset) ZeroAngNorm.Y = -ratio; }
public void Init(Table.Table table) { var height = table.GetSurfaceHeight(Data.Surface, Data.Center.X, Data.Center.Y) * table.GetScaleZ(); // reduce the hit circle radius because only the inner circle of the kicker should start a hit event var radius = Data.Radius * (Data.LegacyMode ? Data.FallThrough ? 0.75f : 0.6f : 1f); _hit = new KickerHit(Data, radius, height, table, this); // height of kicker hit cylinder }
public void Init(Table.Table table) { var height = table.GetSurfaceHeight(Data.Surface, Data.Center.X, Data.Center.Y); var radAngle = MathF.DegToRad(Data.Rotation); var tangent = new Vertex2D(MathF.Cos(radAngle), MathF.Sin(radAngle)); _hitGate = _hitGenerator.GenerateGateHit(height, this); _hitLines = _hitGenerator.GenerateLineSegs(height, tangent, this); _hitCircles = _hitGenerator.GenerateBracketHits(height, tangent, this); }
private HitObject[] GenerateRoundHitObjects(Table.Table table, IItem item) { var height = table.GetSurfaceHeight(_data.Surface, _data.Center.X, _data.Center.Y); return(new HitObject[] { new TriggerHitCircle(_data.Center, _data.Radius, height, height + _data.HitHeight, item) { IsEnabled = _data.IsEnabled, } }); }
private Mesh GetSocketMesh(Table.Table table, Origin origin) { var socketMesh = SocketMesh.Clone(); var height = table.GetSurfaceHeight(_data.Surface, _data.Center.X, _data.Center.Y) * table.GetScaleZ(); var transX = origin == Origin.Global ? _data.Center.X : 0f; var transY = origin == Origin.Global ? _data.Center.Y : 0f; var transZ = origin == Origin.Global ? height : 0f; foreach (var vertex in socketMesh.Vertices) { vertex.X = vertex.X * _data.MeshRadius + transX; vertex.Y = vertex.Y * _data.MeshRadius + transY; vertex.Z = vertex.Z * _data.MeshRadius * table.GetScaleZ() + transZ; } return socketMesh; }
private Dictionary <string, Mesh> GetMeshes(Table.Table table, Origin origin) { if (_data.Center == null) { throw new InvalidOperationException($"Cannot export bumper {_data.Name} without center."); } var matrix = new Matrix3D().RotateZMatrix(MathF.DegToRad(_data.Orientation)); var height = table.GetSurfaceHeight(_data.Surface, _data.Center.X, _data.Center.Y) * table.GetScaleZ(); return(new Dictionary <string, Mesh> { { "Base", GenerateMesh(_scaledBaseMesh, matrix, z => z * table.GetScaleZ() + height, origin) }, { "Ring", GenerateMesh(_scaledRingMesh, matrix, z => z * table.GetScaleZ() + height, origin) }, { "Skirt", GenerateMesh(_scaledSocketMesh, matrix, z => z * table.GetScaleZ() + (height + 5.0f), origin) }, { "Cap", GenerateMesh(_scaledCapMesh, matrix, z => (z + _data.HeightScale) * table.GetScaleZ() + height, origin) } }); }
private bool _solState; // m_solState public FlipperMover(FlipperData data, Table.Table table, IItem item) { var tableData = table.Data; if (data.FlipperRadiusMin > 0 && data.FlipperRadiusMax > data.FlipperRadiusMin) { data.FlipperRadius = data.FlipperRadiusMax - (data.FlipperRadiusMax - data.FlipperRadiusMin) /* m_ptable->m_globalDifficulty*/; data.FlipperRadius = MathF.Max(data.FlipperRadius, data.BaseRadius - data.EndRadius + 0.05f); } else { data.FlipperRadius = data.FlipperRadiusMax; } EndRadius = MathF.Max(data.EndRadius, 0.01f); // radius of flipper end FlipperRadius = MathF.Max(data.FlipperRadius, 0.01f); // radius of flipper arc, center-to-center radius AngleStart = MathF.DegToRad(data.StartAngle); AngleEnd = MathF.DegToRad(data.EndAngle); if (AngleEnd == AngleStart) { // otherwise hangs forever in collisions/updates AngleEnd += 0.0001f; } var height = table.GetSurfaceHeight(data.Surface, data.Center.X, data.Center.Y); var baseRadius = MathF.Max(data.BaseRadius, 0.01f); HitCircleBase = new HitCircle(data.Center, baseRadius, height, height + data.Height, ItemType.Flipper, item); EnableRotateEvent = 0; AngleSpeed = 0; _solState = false; var ratio = (baseRadius - EndRadius) / FlipperRadius; // model inertia of flipper as that of rod of length flipr around its end var mass = data.GetFlipperMass(tableData); Inertia = (float)(1.0 / 3.0) * mass * (FlipperRadius * FlipperRadius); // F2 Norm, used in Green's transform, in FPM time search // = sinf(faceNormOffset) ZeroAngNorm.X = MathF.Sqrt(1.0f - ratio * ratio); // F1 norm, change sign of x component, i.E -zeroAngNorm.X // = -cosf(faceNormOffset) ZeroAngNorm.Y = -ratio; }
private Mesh GetBulbMesh(Table.Table table, Origin origin) { var bulbMesh = BulbMesh.Clone(); var height = table.GetSurfaceHeight(_data.Surface, _data.Center.X, _data.Center.Y); var transX = origin == Origin.Global ? _data.Center.X : 0f; var transY = origin == Origin.Global ? _data.Center.Y : 0f; var transZ = origin == Origin.Global ? height : 0f; for (var i = 0; i < bulbMesh.Vertices.Length; i++) { bulbMesh.Vertices[i].X = bulbMesh.Vertices[i].X * _data.MeshRadius + transX; bulbMesh.Vertices[i].Y = bulbMesh.Vertices[i].Y * _data.MeshRadius + transY; bulbMesh.Vertices[i].Z = bulbMesh.Vertices[i].Z * _data.MeshRadius + transZ; } return(bulbMesh); }
public Matrix3D GetPostMatrix(Table.Table table, Origin origin) { switch (origin) { case Origin.Original: return new Matrix3D().SetTranslation( _data.Center.X, _data.Center.Y, table.GetSurfaceHeight(_data.Surface, _data.Center.X, _data.Center.Y) * table.GetScaleZ() ); case Origin.Global: return Matrix3D.Identity; default: throw new ArgumentOutOfRangeException(nameof(origin), origin, "Unknown origin " + origin); } }
private Mesh GetSocketMesh(Table.Table table, Origin origin) { var socketMesh = SocketMesh.Clone(); var height = table.GetSurfaceHeight(_data.Surface, _data.Center.X, _data.Center.Y) * table.GetScaleZ(); var transX = origin == Origin.Global ? _data.Center.X : 0f; var transY = origin == Origin.Global ? _data.Center.Y : 0f; var transZ = origin == Origin.Global ? height : 0f; for (var i = 0; i < socketMesh.Vertices.Length; i++) { socketMesh.Vertices[i].X = socketMesh.Vertices[i].X * _data.MeshRadius + transX; socketMesh.Vertices[i].Y = socketMesh.Vertices[i].Y * _data.MeshRadius + transY; socketMesh.Vertices[i].Z = socketMesh.Vertices[i].Z * _data.MeshRadius * table.GetScaleZ() + transZ; } return(socketMesh); }
private Dictionary <string, Mesh> GetMeshes(Table.Table table, Origin origin) { if (_data.Center == null) { throw new InvalidOperationException($"Cannot export bumper {_data.Name} without center."); } var matrix = Matrix3D.Identity; var height = table.GetSurfaceHeight(_data.Surface, _data.Center.X, _data.Center.Y) * table.GetScaleZ(); if (_generatedScale != _data.Radius) { _scaledBaseMesh = BaseMesh.Clone().MakeScale(_data.Radius, _data.Radius, _data.HeightScale); _scaledCapMesh = CapMesh.Clone().MakeScale(_data.Radius * 2, _data.Radius * 2, _data.HeightScale); _scaledRingMesh = RingMesh.Clone().MakeScale(_data.Radius, _data.Radius, _data.HeightScale); _scaledSocketMesh = SocketMesh.Clone().MakeScale(_data.Radius, _data.Radius, _data.HeightScale); } return(new Dictionary <string, Mesh> { { "Base", GenerateMesh(_scaledBaseMesh, matrix, z => z * table.GetScaleZ() + height, origin) }, { "Ring", GenerateMesh(_scaledRingMesh, matrix, z => z * table.GetScaleZ() + height, origin) }, { "Skirt", GenerateMesh(_scaledSocketMesh, matrix, z => z * table.GetScaleZ() + (height + 5.0f), origin) }, { "Cap", GenerateMesh(_scaledCapMesh, matrix, z => (z + _data.HeightScale) * table.GetScaleZ() + height, origin) } }); }
public Vertex3D GetBallCreationPosition(Table.Table table) { var height = table.GetSurfaceHeight(Data.Surface, Data.Center.X, Data.Center.Y); return(new Vertex3D(Data.Center.X, Data.Center.Y, height)); // TODO get position from hit object }
protected override float BaseHeight(Table.Table table) { return(table.GetSurfaceHeight(_data.Surface, _data.Center.X, _data.Center.Y)); }
public void Init(Table.Table table) { var height = table.GetSurfaceHeight(Data.Surface, Data.Center.X, Data.Center.Y); _hits = new HitObject[] { new BumperHit(Data, height, this) }; }
private Dictionary <string, Mesh> GenerateMeshes(Table.Table table) { var meshes = new Dictionary <string, Mesh>(); var fullMatrix = new Matrix3D(); fullMatrix.RotateZMatrix(MathF.DegToRad(180.0f)); var height = table.GetSurfaceHeight(_data.Surface, _data.Center.X, _data.Center.Y); const float baseScale = 10.0f; const float tipScale = 10.0f; var baseRadius = _data.BaseRadius - _data.RubberThickness; var endRadius = _data.EndRadius - _data.RubberThickness; // base and tip var baseMesh = FlipperBaseMesh.Clone("Base"); for (var t = 0; t < 13; t++) { foreach (var v in baseMesh.Vertices) { if (v.X == VertsBaseBottom[t].X && v.Y == VertsBaseBottom[t].Y && v.Z == VertsBaseBottom[t].Z) { v.X *= baseRadius * baseScale; v.Y *= baseRadius * baseScale; } if (v.X == VertsTipBottom[t].X && v.Y == VertsTipBottom[t].Y && v.Z == VertsTipBottom[t].Z) { v.X *= endRadius * tipScale; v.Y *= endRadius * tipScale; v.Y += _data.FlipperRadius - endRadius * 7.9f; } if (v.X == VertsBaseTop[t].X && v.Y == VertsBaseTop[t].Y && v.Z == VertsBaseTop[t].Z) { v.X *= baseRadius * baseScale; v.Y *= baseRadius * baseScale; } if (v.X == VertsTipTop[t].X && v.Y == VertsTipTop[t].Y && v.Z == VertsTipTop[t].Z) { v.X *= endRadius * tipScale; v.Y *= endRadius * tipScale; v.Y += _data.FlipperRadius - endRadius * 7.9f; } } } baseMesh.Transform(fullMatrix, null, z => z * _data.Height * table.GetScaleZ() + height); meshes["Base"] = baseMesh; // rubber if (_data.RubberThickness > 0.0) { const float rubberBaseScale = 10.0f; const float rubberTipScale = 10.0f; var rubberMesh = FlipperBaseMesh.Clone("Rubber"); for (var t = 0; t < 13; t++) { foreach (var v in rubberMesh.Vertices) { if (v.X == VertsBaseBottom[t].X && v.Y == VertsBaseBottom[t].Y && v.Z == VertsBaseBottom[t].Z) { v.X = v.X * _data.BaseRadius * rubberBaseScale; v.Y = v.Y * _data.BaseRadius * rubberBaseScale; } if (v.X == VertsTipBottom[t].X && v.Y == VertsTipBottom[t].Y && v.Z == VertsTipBottom[t].Z) { v.X = v.X * _data.EndRadius * rubberTipScale; v.Y = v.Y * _data.EndRadius * rubberTipScale; v.Y = v.Y + _data.FlipperRadius - _data.EndRadius * 7.9f; } if (v.X == VertsBaseTop[t].X && v.Y == VertsBaseTop[t].Y && v.Z == VertsBaseTop[t].Z) { v.X = v.X * _data.BaseRadius * rubberBaseScale; v.Y = v.Y * _data.BaseRadius * rubberBaseScale; } if (v.X == VertsTipTop[t].X && v.Y == VertsTipTop[t].Y && v.Z == VertsTipTop[t].Z) { v.X = v.X * _data.EndRadius * rubberTipScale; v.Y = v.Y * _data.EndRadius * rubberTipScale; v.Y = v.Y + _data.FlipperRadius - _data.EndRadius * 7.9f; } } } rubberMesh.Transform(fullMatrix, null, z => z * _data.RubberWidth * table.GetScaleZ() + (height + _data.RubberHeight)); meshes["Rubber"] = rubberMesh; } return(meshes); }
public Mesh GetMesh(string id, Table.Table table, Origin origin = Origin.Global, bool asRightHanded = true) { var height = table.GetSurfaceHeight(Data.Surface, Data.PosX, Data.PosY); return(_meshGenerator.GetMesh(id, height, 0f, origin: origin, asRightHanded: asRightHanded)); }
private Dictionary <string, Mesh> GenerateMeshes(Table.Table table) { var meshes = new Dictionary <string, Mesh>(); var fullMatrix = new Matrix3D(); fullMatrix.RotateZMatrix(MathF.DegToRad(180.0f)); var height = table.GetSurfaceHeight(_data.Surface, _data.Center.X, _data.Center.Y); var baseRadius = _data.BaseRadius - _data.RubberThickness; var endRadius = _data.EndRadius - _data.RubberThickness; // calc angle needed to fix P0 location var sinAngle = (baseRadius - endRadius) / _data.FlipperRadius; if (sinAngle > 1.0) { sinAngle = 1.0f; } if (sinAngle < -1.0) { sinAngle = -1.0f; } var fixAngle = MathF.Asin(sinAngle); var fixAngleScale = fixAngle / (float)(System.Math.PI * 0.5); // scale (in relation to 90 deg.) // fixAngleScale = 0.0; // note: if you force fixAngleScale = 0.0 then all will look as old version // lambda used to apply fix void ApplyFix(ref Vertex3DNoTex2 vert, Vertex2D center, float midAngle, float radius, Vertex2D newCenter) { var vAngle = MathF.Atan2(vert.Y - center.Y, vert.X - center.X); var nAngle = MathF.Atan2(vert.Ny, vert.Nx); // we want have angles with same sign as midAngle, fix it: if (midAngle < 0.0) { if (vAngle > 0.0) { vAngle -= (float)(System.Math.PI * 2.0); } if (nAngle > 0.0) { nAngle -= (float)(System.Math.PI * 2.0); } } else { if (vAngle < 0.0) { vAngle += (float)(System.Math.PI * 2.0); } if (nAngle < 0.0) { nAngle += (float)(System.Math.PI * 2.0); } } nAngle -= (vAngle - midAngle) * fixAngleScale * MathF.Sign(midAngle); vAngle -= (vAngle - midAngle) * fixAngleScale * MathF.Sign(midAngle); float nL = new Vertex2D(vert.Nx, vert.Ny).Length(); vert.X = MathF.Cos(vAngle) * radius + newCenter.X; vert.Y = MathF.Sin(vAngle) * radius + newCenter.Y; vert.Nx = MathF.Cos(nAngle) * nL; vert.Ny = MathF.Sin(nAngle) * nL; } // base and tip var baseMesh = FlipperBaseMesh.Clone(Base); for (var t = 0; t < 13; t++) { for (var i = 0; i < baseMesh.Vertices.Length; i++) { var v = baseMesh.Vertices[i]; if (v.X == VertsBaseBottom[t].X && v.Y == VertsBaseBottom[t].Y && v.Z == VertsBaseBottom[t].Z) { ApplyFix(ref baseMesh.Vertices[i], new Vertex2D(VertsBaseBottom[6].X, VertsBaseBottom[0].Y), (float)-(System.Math.PI * 0.5), baseRadius, new Vertex2D(0, 0)); } if (v.X == VertsTipBottom[t].X && v.Y == VertsTipBottom[t].Y && v.Z == VertsTipBottom[t].Z) { ApplyFix(ref baseMesh.Vertices[i], new Vertex2D(VertsTipBottom[6].X, VertsTipBottom[0].Y), (float)(System.Math.PI * 0.5), endRadius, new Vertex2D(0, _data.FlipperRadius)); } if (v.X == VertsBaseTop[t].X && v.Y == VertsBaseTop[t].Y && v.Z == VertsBaseTop[t].Z) { ApplyFix(ref baseMesh.Vertices[i], new Vertex2D(VertsBaseBottom[6].X, VertsBaseBottom[0].Y), (float)(-System.Math.PI * 0.5), baseRadius, new Vertex2D(0, 0)); } if (v.X == VertsTipTop[t].X && v.Y == VertsTipTop[t].Y && v.Z == VertsTipTop[t].Z) { ApplyFix(ref baseMesh.Vertices[i], new Vertex2D(VertsTipBottom[6].X, VertsTipBottom[0].Y), (float)(System.Math.PI * 0.5), endRadius, new Vertex2D(0, _data.FlipperRadius)); } } } baseMesh.Transform(fullMatrix, null, z => z * _data.Height * table.GetScaleZ() + height); meshes[Base] = baseMesh; // rubber if (_data.RubberThickness > 0.0) { var rubberMesh = FlipperBaseMesh.Clone(Rubber); for (var t = 0; t < 13; t++) { for (var i = 0; i < rubberMesh.Vertices.Length; i++) { var v = rubberMesh.Vertices[i]; if (v.X == VertsBaseBottom[t].X && v.Y == VertsBaseBottom[t].Y && v.Z == VertsBaseBottom[t].Z) { ApplyFix(ref rubberMesh.Vertices[i], new Vertex2D(VertsBaseBottom[6].X, VertsBaseBottom[0].Y), (float)(-System.Math.PI * 0.5), baseRadius + _data.RubberThickness, new Vertex2D(0, 0)); } if (v.X == VertsTipBottom[t].X && v.Y == VertsTipBottom[t].Y && v.Z == VertsTipBottom[t].Z) { ApplyFix(ref rubberMesh.Vertices[i], new Vertex2D(VertsTipBottom[6].X, VertsTipBottom[0].Y), (float)(System.Math.PI * 0.5), endRadius + _data.RubberThickness, new Vertex2D(0, _data.FlipperRadius)); } if (v.X == VertsBaseTop[t].X && v.Y == VertsBaseTop[t].Y && v.Z == VertsBaseTop[t].Z) { ApplyFix(ref rubberMesh.Vertices[i], new Vertex2D(VertsBaseBottom[6].X, VertsBaseBottom[0].Y), (float)(-System.Math.PI * 0.5), baseRadius + _data.RubberThickness, new Vertex2D(0, 0)); } if (v.X == VertsTipTop[t].X && v.Y == VertsTipTop[t].Y && v.Z == VertsTipTop[t].Z) { ApplyFix(ref rubberMesh.Vertices[i], new Vertex2D(VertsTipBottom[6].X, VertsTipBottom[0].Y), (float)(System.Math.PI * 0.5), endRadius + _data.RubberThickness, new Vertex2D(0, _data.FlipperRadius)); } } } rubberMesh.Transform(fullMatrix, null, z => z * _data.RubberWidth * table.GetScaleZ() + (height + _data.RubberHeight)); meshes[Rubber] = rubberMesh; } return(meshes); }