Example #1
0
        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 + "\".");
        }
Example #2
0
        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();
        }
Example #3
0
        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());
        }
Example #5
0
        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);
        }
Example #6
0
        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 },
            });
        }
Example #7
0
        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 };
        }
Example #8
0
        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}\".");
        }
Example #9
0
        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;
        }
Example #10
0
        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
        }
Example #11
0
        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) }
            });
        }
Example #15
0
        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;
        }
Example #16
0
        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);
			}
		}
Example #18
0
        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);
        }
Example #19
0
        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) }
            });
        }
Example #20
0
        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
        }
Example #21
0
 protected override float BaseHeight(Table.Table table)
 {
     return(table.GetSurfaceHeight(_data.Surface, _data.Center.X, _data.Center.Y));
 }
Example #22
0
        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) };
        }
Example #23
0
        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);
        }
Example #24
0
        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);
        }