Пример #1
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 },
            });
        }
        protected override Tuple <Matrix3D, Matrix3D> GetTransformationMatrix(Table.Table table)
        {
            var fullMatrix = new Matrix3D();
            var tempMat    = new Matrix3D();

            fullMatrix.RotateZMatrix(RotationZ);
            tempMat.RotateYMatrix(MathF.DegToRad(_data.RotY));
            fullMatrix.Multiply(tempMat);
            tempMat.RotateXMatrix(MathF.DegToRad(_data.RotX));
            fullMatrix.Multiply(tempMat);

            var vertMatrix = new Matrix3D();

            tempMat.SetTranslation(-Position.X, -Position.Y, -Position.Z);
            vertMatrix.Multiply(tempMat, fullMatrix);
            tempMat.SetScaling(Scale.X, Scale.Y, Scale.Z * table.GetScaleZ());
            vertMatrix.Multiply(tempMat);
            if (_data.Height == _data.HitHeight)
            {
                // do not z-scale the hit mesh
                tempMat.SetTranslation(Position.X, Position.Y, _data.Height + table.TableHeight);
            }
            else
            {
                tempMat.SetTranslation(Position.X, Position.Y, _data.Height * table.GetScaleZ() + table.TableHeight);
            }

            vertMatrix.Multiply(tempMat);

            return(new Tuple <Matrix3D, Matrix3D>(vertMatrix, fullMatrix));
        }
Пример #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 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) }
            });
        }
Пример #5
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();
        }
Пример #6
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) }
            });
        }
		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;
		}
Пример #8
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) * 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 < 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 * table.GetScaleZ() + 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);
			}
		}
Пример #10
0
 public KickerHit(KickerData data, float radius, float height, Table.Table table) : base(data.Center.Clone(), radius, height, height + data.HitHeight, ItemType.Kicker)
 {
     HitMesh = new Vertex3D[KickerHitMesh.Vertices.Length];
     if (!data.LegacyMode)
     {
         var rad = Radius * 0.8f;
         for (var t = 0; t < KickerHitMesh.Vertices.Length; t++)
         {
             // find the right normal by calculating the distance from current ball position to vertex of the kicker mesh
             var vPos = new Vertex3D(KickerHitMesh.Vertices[t].X, KickerHitMesh.Vertices[t].Y, KickerHitMesh.Vertices[t].Z);
             vPos.X     = vPos.X * rad + data.Center.X;
             vPos.Y     = vPos.Y * rad + data.Center.Y;
             vPos.Z     = vPos.Z * rad * table.GetScaleZ() + height;
             HitMesh[t] = vPos;
         }
     }
     IsEnabled = data.IsEnabled;
 }
Пример #11
0
        protected override Tuple <Matrix3D, Matrix3D> GetTransformationMatrix(Table.Table table)
        {
            // scale matrix
            var scaleMatrix = new Matrix3D();

            scaleMatrix.SetScaling(Scale.X, Scale.Y, Scale.Z);

            // translation matrix
            var transMatrix = new Matrix3D();

            transMatrix.SetTranslation(Position.X, Position.Y, Position.Z + table.TableHeight);

            // translation + rotation matrix
            var rotTransMatrix = new Matrix3D();

            rotTransMatrix.SetTranslation(_data.RotAndTra[3], _data.RotAndTra[4], _data.RotAndTra[5]);

            var tempMatrix = new Matrix3D();

            tempMatrix.RotateZMatrix(MathF.DegToRad(_data.RotAndTra[2]));
            rotTransMatrix.Multiply(tempMatrix);
            tempMatrix.RotateYMatrix(MathF.DegToRad(_data.RotAndTra[1]));
            rotTransMatrix.Multiply(tempMatrix);
            tempMatrix.RotateXMatrix(MathF.DegToRad(_data.RotAndTra[0]));
            rotTransMatrix.Multiply(tempMatrix);

            tempMatrix.RotateZMatrix(MathF.DegToRad(_data.RotAndTra[8]));
            rotTransMatrix.Multiply(tempMatrix);
            tempMatrix.RotateYMatrix(MathF.DegToRad(_data.RotAndTra[7]));
            rotTransMatrix.Multiply(tempMatrix);
            tempMatrix.RotateXMatrix(MathF.DegToRad(_data.RotAndTra[6]));
            rotTransMatrix.Multiply(tempMatrix);

            var fullMatrix = scaleMatrix.Clone();

            fullMatrix.Multiply(rotTransMatrix);
            fullMatrix.Multiply(transMatrix);              // fullMatrix = Smatrix * RTmatrix * Tmatrix
            scaleMatrix.SetScaling(1.0f, 1.0f, table.GetScaleZ());
            fullMatrix.Multiply(scaleMatrix);

            return(new Tuple <Matrix3D, Matrix3D>(fullMatrix, null));
        }
Пример #12
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
        }
        private Mesh GenerateTopMesh(Table.Table table)
        {
            var topMesh = new Mesh("Top");
            var vVertex = DragPoint.GetRgVertex <RenderVertex2D, CatmullCurve2DCatmullCurveFactory>(_data.DragPoints);

            var numVertices = vVertex.Length;
            var rgNormal    = new Vertex2D[numVertices];

            for (var i = 0; i < numVertices; i++)
            {
                var pv1 = vVertex[i];
                var pv2 = vVertex[i < numVertices - 1 ? i + 1 : 0];
                var dx  = pv1.X - pv2.X;
                var dy  = pv1.Y - pv2.Y;

                if (dx != 0.0f || dy != 0.0f)
                {
                    var invLen = 1.0f / MathF.Sqrt(dx * dx + dy * dy);
                    rgNormal[i] = new Vertex2D {
                        X = dy * invLen, Y = dx * invLen
                    };
                }
                else
                {
                    rgNormal[i] = new Vertex2D {
                        X = 0.0f, Y = 0.0f
                    };
                }
            }

            // draw top
            var vPoly = new List <int>(new int[numVertices]);

            for (var i = 0; i < numVertices; i++)
            {
                vPoly[i] = i;
            }

            topMesh.Indices = Mesh.PolygonToTriangles(vVertex, vPoly);
            var numPolys = topMesh.Indices.Length / 3;

            if (numPolys == 0)
            {
                // no polys to render leave vertex buffer undefined
                return(null);
            }

            var heightNotDropped = _data.HeightTop * table.GetScaleZ();
            var heightDropped    = _data.HeightBottom * table.GetScaleZ() + 0.1;

            var invTableWidth  = 1.0f / table.Width;
            var invTableHeight = 1.0f / table.Height;

            Vertex3DNoTex2[][] vertsTop = { new Vertex3DNoTex2[numVertices], new Vertex3DNoTex2[numVertices], new Vertex3DNoTex2[numVertices] };
            for (var i = 0; i < numVertices; i++)
            {
                var pv0 = vVertex[i];

                vertsTop[0][i] = new Vertex3DNoTex2 {
                    X  = pv0.X,
                    Y  = pv0.Y,
                    Z  = heightNotDropped + table.TableHeight,
                    Tu = pv0.X * invTableWidth,
                    Tv = pv0.Y * invTableHeight,
                    Nx = 0,
                    Ny = 0,
                    Nz = 1.0f
                };

                vertsTop[1][i] = new Vertex3DNoTex2 {
                    X  = pv0.X,
                    Y  = pv0.Y,
                    Z  = (float)heightDropped,
                    Tu = pv0.X * invTableWidth,
                    Tv = pv0.Y * invTableHeight,
                    Nx = 0,
                    Ny = 0,
                    Nz = 1.0f
                };

                vertsTop[2][i] = new Vertex3DNoTex2 {
                    X  = pv0.X,
                    Y  = pv0.Y,
                    Z  = _data.HeightBottom,
                    Tu = pv0.X * invTableWidth,
                    Tv = pv0.Y * invTableHeight,
                    Nx = 0,
                    Ny = 0,
                    Nz = -1.0f
                };
            }
            topMesh.Vertices = vertsTop[0];

            return(topMesh);
        }
        private Mesh GenerateSideMesh(Table.Table table)
        {
            var sideMesh = new Mesh("Side");

            var vVertex    = DragPoint.GetRgVertex <RenderVertex2D, CatmullCurve2DCatmullCurveFactory>(_data.DragPoints);
            var rgTexCoord = DragPoint.GetTextureCoords(_data.DragPoints, vVertex);

            var numVertices = vVertex.Length;
            var rgNormal    = new Vertex2D[numVertices];

            for (var i = 0; i < numVertices; i++)
            {
                var pv1 = vVertex[i];
                var pv2 = vVertex[i < numVertices - 1 ? i + 1 : 0];
                var dx  = pv1.X - pv2.X;
                var dy  = pv1.Y - pv2.Y;

                if (dx != 0.0f || dy != 0.0f)
                {
                    var invLen = 1.0f / MathF.Sqrt(dx * dx + dy * dy);
                    rgNormal[i] = new Vertex2D {
                        X = dy * invLen, Y = dx * invLen
                    };
                }
                else
                {
                    rgNormal[i] = new Vertex2D {
                        X = 0.0f, Y = 0.0f
                    };
                }
            }

            var bottom = _data.HeightBottom * table.GetScaleZ() + table.TableHeight;
            var top    = _data.HeightTop * table.GetScaleZ() + table.TableHeight;

            var offset = 0;

            // Render side
            sideMesh.Vertices = new Vertex3DNoTex2[numVertices * 4];
            for (var i = 0; i < numVertices; i++)
            {
                var pv1 = vVertex[i];
                var pv2 = vVertex[i < numVertices - 1 ? i + 1 : 0];

                var a = i == 0 ? numVertices - 1 : i - 1;
                var c = i < numVertices - 1 ? i + 1 : 0;

                var vNormal = new [] { new Vertex2D(), new Vertex2D() };
                if (pv1.Smooth)
                {
                    vNormal[0].X = (rgNormal[a].X + rgNormal[i].X) * 0.5f;
                    vNormal[0].Y = (rgNormal[a].Y + rgNormal[i].Y) * 0.5f;
                }
                else
                {
                    vNormal[0].X = rgNormal[i].X;
                    vNormal[0].Y = rgNormal[i].Y;
                }

                if (pv2.Smooth)
                {
                    vNormal[1].X = (rgNormal[i].X + rgNormal[c].X) * 0.5f;
                    vNormal[1].Y = (rgNormal[i].Y + rgNormal[c].Y) * 0.5f;
                }
                else
                {
                    vNormal[1].X = rgNormal[i].X;
                    vNormal[1].Y = rgNormal[i].Y;
                }

                vNormal[0].Normalize();
                vNormal[1].Normalize();

                sideMesh.Vertices[offset]     = new Vertex3DNoTex2();
                sideMesh.Vertices[offset + 1] = new Vertex3DNoTex2();
                sideMesh.Vertices[offset + 2] = new Vertex3DNoTex2();
                sideMesh.Vertices[offset + 3] = new Vertex3DNoTex2();

                sideMesh.Vertices[offset].X     = pv1.X;
                sideMesh.Vertices[offset].Y     = pv1.Y;
                sideMesh.Vertices[offset].Z     = bottom;
                sideMesh.Vertices[offset + 1].X = pv1.X;
                sideMesh.Vertices[offset + 1].Y = pv1.Y;
                sideMesh.Vertices[offset + 1].Z = top;
                sideMesh.Vertices[offset + 2].X = pv2.X;
                sideMesh.Vertices[offset + 2].Y = pv2.Y;
                sideMesh.Vertices[offset + 2].Z = top;
                sideMesh.Vertices[offset + 3].X = pv2.X;
                sideMesh.Vertices[offset + 3].Y = pv2.Y;
                sideMesh.Vertices[offset + 3].Z = bottom;

                if (_data.SideImage != null)
                {
                    sideMesh.Vertices[offset].Tu = rgTexCoord[i];
                    sideMesh.Vertices[offset].Tv = 1.0f;

                    sideMesh.Vertices[offset + 1].Tu = rgTexCoord[i];
                    sideMesh.Vertices[offset + 1].Tv = 0f;

                    sideMesh.Vertices[offset + 2].Tu = rgTexCoord[c];
                    sideMesh.Vertices[offset + 2].Tv = 0f;

                    sideMesh.Vertices[offset + 3].Tu = rgTexCoord[c];
                    sideMesh.Vertices[offset + 3].Tv = 1.0f;
                }

                sideMesh.Vertices[offset].Nx = vNormal[0].X;
                sideMesh.Vertices[offset].Ny = -vNormal[0].Y;
                sideMesh.Vertices[offset].Nz = 0f;

                sideMesh.Vertices[offset + 1].Nx = vNormal[0].X;
                sideMesh.Vertices[offset + 1].Ny = -vNormal[0].Y;
                sideMesh.Vertices[offset + 1].Nz = 0f;

                sideMesh.Vertices[offset + 2].Nx = vNormal[1].X;
                sideMesh.Vertices[offset + 2].Ny = -vNormal[1].Y;
                sideMesh.Vertices[offset + 2].Nz = 0f;

                sideMesh.Vertices[offset + 3].Nx = vNormal[1].X;
                sideMesh.Vertices[offset + 3].Ny = -vNormal[1].Y;
                sideMesh.Vertices[offset + 3].Nz = 0f;

                offset += 4;
            }

            // prepare index buffer for sides
            var offset2 = 0;

            sideMesh.Indices = new int[numVertices * 6];
            for (var i = 0; i < numVertices; i++)
            {
                sideMesh.Indices[i * 6]     = offset2;
                sideMesh.Indices[i * 6 + 1] = offset2 + 1;
                sideMesh.Indices[i * 6 + 2] = offset2 + 2;
                sideMesh.Indices[i * 6 + 3] = offset2;
                sideMesh.Indices[i * 6 + 4] = offset2 + 2;
                sideMesh.Indices[i * 6 + 5] = offset2 + 3;

                offset2 += 4;
            }

            return(sideMesh);
        }
Пример #15
0
        private Dictionary <string, Mesh> GenerateMeshes(Table.Table table)
        {
            var meshes   = new Dictionary <string, Mesh>();
            var topMesh  = new Mesh("Top");
            var sideMesh = new Mesh("Side");

            var vVertex    = DragPoint.GetRgVertex <RenderVertex2D, CatmullCurve2DCatmullCurveFactory>(_data.DragPoints);
            var rgTexCoord = DragPoint.GetTextureCoords(_data.DragPoints, vVertex);

            var numVertices = vVertex.Length;
            var rgNormal    = new Vertex2D[numVertices];

            for (var i = 0; i < numVertices; i++)
            {
                var pv1 = vVertex[i];
                var pv2 = vVertex[i < numVertices - 1 ? i + 1 : 0];
                var dx  = pv1.X - pv2.X;
                var dy  = pv1.Y - pv2.Y;

                var invLen = 1.0f / MathF.Sqrt(dx * dx + dy * dy);

                rgNormal[i] = new Vertex2D {
                    X = dy * invLen, Y = dx * invLen
                };
            }

            var bottom = _data.HeightBottom * table.GetScaleZ() + table.TableHeight;
            var top    = _data.HeightTop * table.GetScaleZ() + table.TableHeight;

            var offset = 0;

            // Render side
            sideMesh.Vertices = new Vertex3DNoTex2[numVertices * 4];
            for (var i = 0; i < numVertices; i++)
            {
                var pv1 = vVertex[i];
                var pv2 = vVertex[i < numVertices - 1 ? i + 1 : 0];

                var a = i == 0 ? numVertices - 1 : i - 1;
                var c = i < numVertices - 1 ? i + 1 : 0;

                var vNormal = new [] { new Vertex2D(), new Vertex2D() };
                if (pv1.Smooth)
                {
                    vNormal[0].X = (rgNormal[a].X + rgNormal[i].X) * 0.5f;
                    vNormal[0].Y = (rgNormal[a].Y + rgNormal[i].Y) * 0.5f;
                }
                else
                {
                    vNormal[0].X = rgNormal[i].X;
                    vNormal[0].Y = rgNormal[i].Y;
                }

                if (pv2.Smooth)
                {
                    vNormal[1].X = (rgNormal[i].X + rgNormal[c].X) * 0.5f;
                    vNormal[1].Y = (rgNormal[i].Y + rgNormal[c].Y) * 0.5f;
                }
                else
                {
                    vNormal[1].X = rgNormal[i].X;
                    vNormal[1].Y = rgNormal[i].Y;
                }

                vNormal[0].Normalize();
                vNormal[1].Normalize();

                sideMesh.Vertices[offset]     = new Vertex3DNoTex2();
                sideMesh.Vertices[offset + 1] = new Vertex3DNoTex2();
                sideMesh.Vertices[offset + 2] = new Vertex3DNoTex2();
                sideMesh.Vertices[offset + 3] = new Vertex3DNoTex2();

                sideMesh.Vertices[offset].X     = pv1.X;
                sideMesh.Vertices[offset].Y     = pv1.Y;
                sideMesh.Vertices[offset].Z     = bottom;
                sideMesh.Vertices[offset + 1].X = pv1.X;
                sideMesh.Vertices[offset + 1].Y = pv1.Y;
                sideMesh.Vertices[offset + 1].Z = top;
                sideMesh.Vertices[offset + 2].X = pv2.X;
                sideMesh.Vertices[offset + 2].Y = pv2.Y;
                sideMesh.Vertices[offset + 2].Z = top;
                sideMesh.Vertices[offset + 3].X = pv2.X;
                sideMesh.Vertices[offset + 3].Y = pv2.Y;
                sideMesh.Vertices[offset + 3].Z = bottom;

                if (_data.SideImage != null)
                {
                    sideMesh.Vertices[offset].Tu = rgTexCoord[i];
                    sideMesh.Vertices[offset].Tv = 1.0f;

                    sideMesh.Vertices[offset + 1].Tu = rgTexCoord[i];
                    sideMesh.Vertices[offset + 1].Tv = 0f;

                    sideMesh.Vertices[offset + 2].Tu = rgTexCoord[c];
                    sideMesh.Vertices[offset + 2].Tv = 0f;

                    sideMesh.Vertices[offset + 3].Tu = rgTexCoord[c];
                    sideMesh.Vertices[offset + 3].Tv = 1.0f;
                }

                sideMesh.Vertices[offset].Nx = vNormal[0].X;
                sideMesh.Vertices[offset].Ny = -vNormal[0].Y;
                sideMesh.Vertices[offset].Nz = 0f;

                sideMesh.Vertices[offset + 1].Nx = vNormal[0].X;
                sideMesh.Vertices[offset + 1].Ny = -vNormal[0].Y;
                sideMesh.Vertices[offset + 1].Nz = 0f;

                sideMesh.Vertices[offset + 2].Nx = vNormal[1].X;
                sideMesh.Vertices[offset + 2].Ny = -vNormal[1].Y;
                sideMesh.Vertices[offset + 2].Nz = 0f;

                sideMesh.Vertices[offset + 3].Nx = vNormal[1].X;
                sideMesh.Vertices[offset + 3].Ny = -vNormal[1].Y;
                sideMesh.Vertices[offset + 3].Nz = 0f;

                offset += 4;
            }

            // prepare index buffer for sides
            var offset2 = 0;

            sideMesh.Indices = new int[numVertices * 6];
            for (var i = 0; i < numVertices; i++)
            {
                sideMesh.Indices[i * 6]     = offset2;
                sideMesh.Indices[i * 6 + 1] = offset2 + 1;
                sideMesh.Indices[i * 6 + 2] = offset2 + 2;
                sideMesh.Indices[i * 6 + 3] = offset2;
                sideMesh.Indices[i * 6 + 4] = offset2 + 2;
                sideMesh.Indices[i * 6 + 5] = offset2 + 3;

                offset2 += 4;
            }

            // draw top
            var vPoly = new List <int>(new int[numVertices]);

            for (var i = 0; i < numVertices; i++)
            {
                vPoly[i] = i;
            }

            topMesh.Indices = Mesh.PolygonToTriangles(vVertex, vPoly);

            var numPolys = topMesh.Indices.Length / 3;

            if (numPolys == 0)
            {
                // no polys to render leave vertex buffer undefined
                return(meshes);
            }

            var heightNotDropped = _data.HeightTop * table.GetScaleZ();
            var heightDropped    = _data.HeightBottom * table.GetScaleZ() + 0.1;

            var invTableWidth  = 1.0f / table.Width;
            var invTableHeight = 1.0f / table.Height;

            Vertex3DNoTex2[][] vertsTop = { new Vertex3DNoTex2[numVertices], new Vertex3DNoTex2[numVertices], new Vertex3DNoTex2[numVertices] };
            for (var i = 0; i < numVertices; i++)
            {
                var pv0 = vVertex[i];

                vertsTop[0][i] = new Vertex3DNoTex2 {
                    X  = pv0.X,
                    Y  = pv0.Y,
                    Z  = heightNotDropped + table.TableHeight,
                    Tu = pv0.X * invTableWidth,
                    Tv = pv0.Y * invTableHeight,
                    Nx = 0,
                    Ny = 0,
                    Nz = 1.0f
                };

                vertsTop[1][i] = new Vertex3DNoTex2 {
                    X  = pv0.X,
                    Y  = pv0.Y,
                    Z  = (float)heightDropped,
                    Tu = pv0.X * invTableWidth,
                    Tv = pv0.Y * invTableHeight,
                    Nx = 0,
                    Ny = 0,
                    Nz = 1.0f
                };

                vertsTop[2][i] = new Vertex3DNoTex2 {
                    X  = pv0.X,
                    Y  = pv0.Y,
                    Z  = _data.HeightBottom,
                    Tu = pv0.X * invTableWidth,
                    Tv = pv0.Y * invTableHeight,
                    Nx = 0,
                    Ny = 0,
                    Nz = -1.0f
                };
            }
            topMesh.Vertices = vertsTop[0];

            if (topMesh.Vertices.Length > 0)
            {
                meshes["Top"] = topMesh;
            }
            if (System.Math.Abs(top - bottom) > 0.00001f)
            {
                meshes["Side"] = sideMesh;
            }
            return(meshes);
        }
        private Mesh GenerateFlatRightWall(Table.Table table, RampVertex rv)
        {
            var invTableWidth  = 1.0f / table.Width;
            var invTableHeight = 1.0f / table.Height;
            var numVertices    = rv.VertexCount * 2;
            var numIndices     = (rv.VertexCount - 1) * 6;

            var mesh = new Mesh("RightWall")
            {
                Vertices = new Vertex3DNoTex2[numVertices],
                Indices  = new int[numIndices]
            };

            for (var i = 0; i < rv.VertexCount; i++)
            {
                var rgv3d1 = new Vertex3DNoTex2();
                var rgv3d2 = new Vertex3DNoTex2();

                rgv3d1.X = rv.RgvLocal[i].X;
                rgv3d1.Y = rv.RgvLocal[i].Y;
                rgv3d1.Z = rv.PointHeights[i] * table.GetScaleZ();

                rgv3d2.X = rv.RgvLocal[i].X;
                rgv3d2.Y = rv.RgvLocal[i].Y;
                rgv3d2.Z = (rv.PointHeights[i] + _data.RightWallHeightVisible) * table.GetScaleZ();

                if (_data.Image != null && _data.ImageWalls)
                {
                    if (_data.ImageAlignment == RampImageAlignment.ImageModeWorld)
                    {
                        rgv3d1.Tu = rgv3d1.X * invTableWidth;
                        rgv3d1.Tv = rgv3d1.Y * invTableHeight;
                    }
                    else
                    {
                        rgv3d1.Tu = 0;
                        rgv3d1.Tv = rv.PointRatios[i];
                    }
                    rgv3d2.Tu = rgv3d1.Tu;
                    rgv3d2.Tv = rgv3d1.Tv;
                }
                else
                {
                    rgv3d1.Tu = 0.0f;
                    rgv3d1.Tv = 0.0f;
                    rgv3d2.Tu = 0.0f;
                    rgv3d2.Tv = 0.0f;
                }

                mesh.Vertices[i * 2]     = rgv3d1;
                mesh.Vertices[i * 2 + 1] = rgv3d2;

                if (i == rv.VertexCount - 1)
                {
                    break;
                }

                mesh.Indices[i * 6]     = i * 2;
                mesh.Indices[i * 6 + 1] = i * 2 + 1;
                mesh.Indices[i * 6 + 2] = i * 2 + 3;
                mesh.Indices[i * 6 + 3] = i * 2;
                mesh.Indices[i * 6 + 4] = i * 2 + 3;
                mesh.Indices[i * 6 + 5] = i * 2 + 2;
            }

            Mesh.ComputeNormals(mesh.Vertices, numVertices, mesh.Indices, (rv.VertexCount - 1) * 6);
            return(mesh);
        }
        private HitObject[] GenerateHitTargetHits(Table.Table table, IItem item)
        {
            var addedEdges = new EdgeSet();
            var hitMesh    = _meshGenerator.GetRenderObjects(table, Origin.Original, false).RenderObjects[0].Mesh;
            var hitObjects = GenerateCollidables(hitMesh, addedEdges, _data.IsLegacy, table, item).ToList();

            var tempMatrix = new Matrix3D().RotateZMatrix(MathF.DegToRad(_data.RotZ));
            var fullMatrix = new Matrix3D().Multiply(tempMatrix);

            if (!_data.IsLegacy)
            {
                var rgv3D          = new Vertex3D[DropTargetHitPlaneVertices.Length];
                var hitShapeOffset = 0.18f;
                if (_data.TargetType == TargetType.DropTargetBeveled)
                {
                    hitShapeOffset = 0.25f;
                }
                if (_data.TargetType == TargetType.DropTargetFlatSimple)
                {
                    hitShapeOffset = 0.13f;
                }

                // now create a special hit shape with hit event enabled to prevent a hit event when hit from behind
                for (var i = 0; i < DropTargetHitPlaneVertices.Length; i++)
                {
                    var dropTargetHitPlaneVertex = DropTargetHitPlaneVertices[i];
                    var vert = new Vertex3D(
                        dropTargetHitPlaneVertex.X,
                        dropTargetHitPlaneVertex.Y + hitShapeOffset,
                        dropTargetHitPlaneVertex.Z
                        );

                    vert.X *= _data.Size.X;
                    vert.Y *= _data.Size.Y;
                    vert.Z *= _data.Size.Z;
                    vert.MultiplyMatrix(fullMatrix);
                    rgv3D[i] = new Vertex3D(
                        vert.X + _data.Position.X,
                        vert.Y + _data.Position.Y,
                        vert.Z * table.GetScaleZ() + _data.Position.Z + table.TableHeight
                        );
                }

                for (var i = 0; i < DropTargetHitPlaneIndices.Length; i += 3)
                {
                    var i0 = DropTargetHitPlaneIndices[i];
                    var i1 = DropTargetHitPlaneIndices[i + 1];
                    var i2 = DropTargetHitPlaneIndices[i + 2];

                    // NB: HitTriangle wants CCW vertices, but for rendering we have them in CW order
                    var rgv3D2 = new[] { rgv3D[i0], rgv3D[i2], rgv3D[i1] };

                    hitObjects.Add(SetupHitObject(new HitTriangle(rgv3D2, ItemType.HitTarget, item), true, table));
                    hitObjects.AddRange(addedEdges.AddHitEdge(i0, i1, rgv3D2[0], rgv3D2[2], ItemType.HitTarget, item).Select(obj => SetupHitObject(obj, true, table)));
                    hitObjects.AddRange(addedEdges.AddHitEdge(i1, i2, rgv3D2[2], rgv3D2[1], ItemType.HitTarget, item).Select(obj => SetupHitObject(obj, true, table)));
                    hitObjects.AddRange(addedEdges.AddHitEdge(i2, i0, rgv3D2[1], rgv3D2[0], ItemType.HitTarget, item).Select(obj => SetupHitObject(obj, true, table)));
                }

                // add collision vertices
                for (var i = 0; i < DropTargetHitPlaneVertices.Length; ++i)
                {
                    hitObjects.Add(SetupHitObject(new HitPoint(rgv3D[i], ItemType.HitTarget, item), true, table));
                }
            }
            return(hitObjects.ToArray());
        }
        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);
        }
Пример #19
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);
        }