Ejemplo n.º 1
0
        public static Light GetDefault(string name, float x, float y)
        {
            var lightData = new LightData(name, x, y)
            {
                DragPoints = new[] {
                    new DragPointData(x, y - 50f)
                    {
                        IsSmooth = true
                    },
                    new DragPointData(x - 50f * MathF.Cos(MathF.PI / 4), y - 50f * MathF.Sin(MathF.PI / 4))
                    {
                        IsSmooth = true
                    },
                    new DragPointData(x - 50f, y)
                    {
                        IsSmooth = true
                    },
                    new DragPointData(x - 50f * MathF.Cos(MathF.PI / 4), y + 50f * MathF.Sin(MathF.PI / 4))
                    {
                        IsSmooth = true
                    },
                    new DragPointData(x, y + 50f)
                    {
                        IsSmooth = true
                    },
                    new DragPointData(x + 50f * MathF.Cos(MathF.PI / 4), y + 50f * MathF.Sin(MathF.PI / 4))
                    {
                        IsSmooth = true
                    },
                    new DragPointData(x + 50f, y)
                    {
                        IsSmooth = true
                    },
                    new DragPointData(x + 50f * MathF.Cos(MathF.PI / 4), y - 50f * MathF.Sin(MathF.PI / 4))
                    {
                        IsSmooth = true
                    },
                }
            };

            return(new Light(lightData));
        }
Ejemplo n.º 2
0
        private Mesh CalculateBuiltinOriginal()
        {
            var mesh = new Mesh(_data.Name);

            // this recalculates the Original Vertices -> should be only called, when sides are altered.
            var outerRadius = -0.5f / MathF.Cos(MathF.PI / _data.Sides);
            var addAngle    = 2.0f * MathF.PI / _data.Sides;
            var offsAngle   = MathF.PI / _data.Sides;
            var minX        = Constants.FloatMax;
            var minY        = Constants.FloatMax;
            var maxX        = -Constants.FloatMax;
            var maxY        = -Constants.FloatMax;

            mesh.Vertices = new Vertex3DNoTex2[4 * _data.Sides + 2];

            // middle point top
            mesh.Vertices[0] = new Vertex3DNoTex2 {
                X = 0.0f, Y = 0.0f, Z = 0.5f
            };
            // middle point bottom
            mesh.Vertices[_data.Sides + 1] = new Vertex3DNoTex2 {
                X = 0.0f, Y = 0.0f, Z = -0.5f
            };

            for (var i = 0; i < _data.Sides; ++i)
            {
                var currentAngle = addAngle * i + offsAngle;

                // calculate Top
                var topVert = new Vertex3DNoTex2 {                 // top point at side
                    X = MathF.Sin(currentAngle) * outerRadius,
                    Y = MathF.Cos(currentAngle) * outerRadius,
                    Z = 0.5f
                };
                mesh.Vertices[i + 1] = topVert;

                // calculate bottom
                var bottomVert = new Vertex3DNoTex2 {                 // bottom point at side
                    X = topVert.X,
                    Y = topVert.Y,
                    Z = -0.5f
                };
                mesh.Vertices[i + 1 + _data.Sides + 1] = bottomVert;

                // calculate sides
                mesh.Vertices[_data.Sides * 2 + 2 + i] = topVert;                 // sideTopVert
                mesh.Vertices[_data.Sides * 3 + 2 + i] = bottomVert;              // sideBottomVert

                // calculate bounds for X and Y
                if (topVert.X < minX)
                {
                    minX = topVert.X;
                }

                if (topVert.X > maxX)
                {
                    maxX = topVert.X;
                }

                if (topVert.Y < minY)
                {
                    minY = topVert.Y;
                }

                if (topVert.Y > maxY)
                {
                    maxY = topVert.Y;
                }
            }

            // these have to be replaced for image mapping
            var middle = mesh.Vertices[0];              // middle point top

            middle.Tu = 0.25f;                          // /4
            middle.Tv = 0.25f;                          // /4
            middle    = mesh.Vertices[_data.Sides + 1]; // middle point bottom
            middle.Tu = 0.25f * 3.0f;                   // /4*3
            middle.Tv = 0.25f;                          // /4
            var invX = 0.5f / (maxX - minX);
            var invY = 0.5f / (maxY - minY);
            var invS = 1.0f / _data.Sides;

            for (var i = 0; i < _data.Sides; i++)
            {
                var topVert = mesh.Vertices[i + 1];                 // top point at side
                topVert.Tu = (topVert.X - minX) * invX;
                topVert.Tv = (topVert.Y - minY) * invY;

                var bottomVert = mesh.Vertices[i + 1 + _data.Sides + 1];                 // bottom point at side
                bottomVert.Tu = topVert.Tu + 0.5f;
                bottomVert.Tv = topVert.Tv;

                var sideTopVert    = mesh.Vertices[_data.Sides * 2 + 2 + i];
                var sideBottomVert = mesh.Vertices[_data.Sides * 3 + 2 + i];

                sideTopVert.Tu    = i * invS;
                sideTopVert.Tv    = 0.5f;
                sideBottomVert.Tu = sideTopVert.Tu;
                sideBottomVert.Tv = 1.0f;
            }

            // So how many indices are needed?
            // 3 per Triangle top - we have m_sides triangles -> 0, 1, 2, 0, 2, 3, 0, 3, 4, ...
            // 3 per Triangle bottom - we have m_sides triangles
            // 6 per Side at the side (two triangles form a rectangle) - we have m_sides sides
            // == 12 * m_sides
            // * 2 for both cullings (m_DrawTexturesInside == true)
            // == 24 * m_sides
            // this will also be the initial sorting, when depths, Vertices and Indices are recreated, because calculateRealTimeOriginal is called.

            // 2 restore indices
            //   check if anti culling is enabled:
            if (_data.DrawTexturesInside)
            {
                mesh.Indices = new int[_data.Sides * 24];
                // draw yes everything twice
                // restore indices
                for (var i = 0; i < _data.Sides; i++)
                {
                    var tmp = i == _data.Sides - 1 ? 1 : i + 2;                     // wrapping around
                    // top
                    mesh.Indices[i * 6]     = 0;
                    mesh.Indices[i * 6 + 1] = i + 1;
                    mesh.Indices[i * 6 + 2] = tmp;
                    mesh.Indices[i * 6 + 3] = 0;
                    mesh.Indices[i * 6 + 4] = tmp;
                    mesh.Indices[i * 6 + 5] = i + 1;

                    var tmp2 = tmp + 1;

                    // bottom
                    mesh.Indices[6 * (i + _data.Sides)]     = _data.Sides + 1;
                    mesh.Indices[6 * (i + _data.Sides) + 1] = _data.Sides + tmp2;
                    mesh.Indices[6 * (i + _data.Sides) + 2] = _data.Sides + 2 + i;
                    mesh.Indices[6 * (i + _data.Sides) + 3] = _data.Sides + 1;
                    mesh.Indices[6 * (i + _data.Sides) + 4] = _data.Sides + 2 + i;
                    mesh.Indices[6 * (i + _data.Sides) + 5] = _data.Sides + tmp2;

                    // sides
                    mesh.Indices[12 * (i + _data.Sides)]      = _data.Sides * 2 + tmp2;
                    mesh.Indices[12 * (i + _data.Sides) + 1]  = _data.Sides * 2 + 2 + i;
                    mesh.Indices[12 * (i + _data.Sides) + 2]  = _data.Sides * 3 + 2 + i;
                    mesh.Indices[12 * (i + _data.Sides) + 3]  = _data.Sides * 2 + tmp2;
                    mesh.Indices[12 * (i + _data.Sides) + 4]  = _data.Sides * 3 + 2 + i;
                    mesh.Indices[12 * (i + _data.Sides) + 5]  = _data.Sides * 3 + tmp2;
                    mesh.Indices[12 * (i + _data.Sides) + 6]  = _data.Sides * 2 + tmp2;
                    mesh.Indices[12 * (i + _data.Sides) + 7]  = _data.Sides * 3 + 2 + i;
                    mesh.Indices[12 * (i + _data.Sides) + 8]  = _data.Sides * 2 + 2 + i;
                    mesh.Indices[12 * (i + _data.Sides) + 9]  = _data.Sides * 2 + tmp2;
                    mesh.Indices[12 * (i + _data.Sides) + 10] = _data.Sides * 3 + tmp2;
                    mesh.Indices[12 * (i + _data.Sides) + 11] = _data.Sides * 3 + 2 + i;
                }
            }
            else
            {
                // only no out-facing polygons
                // restore indices
                mesh.Indices = new int[_data.Sides * 12];
                for (var i = 0; i < _data.Sides; i++)
                {
                    var tmp = i == _data.Sides - 1 ? 1 : i + 2;                     // wrapping around
                    // top
                    mesh.Indices[i * 3]     = 0;
                    mesh.Indices[i * 3 + 2] = i + 1;
                    mesh.Indices[i * 3 + 1] = tmp;

                    //SetNormal(mesh.Vertices[0], &mesh.Indices[i+3], 3); // see below

                    var tmp2 = tmp + 1;
                    // bottom
                    mesh.Indices[3 * (i + _data.Sides)]     = _data.Sides + 1;
                    mesh.Indices[3 * (i + _data.Sides) + 1] = _data.Sides + 2 + i;
                    mesh.Indices[3 * (i + _data.Sides) + 2] = _data.Sides + tmp2;

                    //SetNormal(mesh.Vertices[0], &mesh.Indices[3*(i+_data.Sides)], 3); // see below

                    // sides
                    mesh.Indices[6 * (i + _data.Sides)]     = _data.Sides * 2 + tmp2;
                    mesh.Indices[6 * (i + _data.Sides) + 1] = _data.Sides * 3 + 2 + i;
                    mesh.Indices[6 * (i + _data.Sides) + 2] = _data.Sides * 2 + 2 + i;
                    mesh.Indices[6 * (i + _data.Sides) + 3] = _data.Sides * 2 + tmp2;
                    mesh.Indices[6 * (i + _data.Sides) + 4] = _data.Sides * 3 + tmp2;
                    mesh.Indices[6 * (i + _data.Sides) + 5] = _data.Sides * 3 + 2 + i;
                }
            }

            //SetNormal(mesh.Vertices[0], &mesh.Indices[0], m_mesh.NumIndices()); // SetNormal only works for plane polygons
            Mesh.ComputeNormals(mesh.Vertices, mesh.Vertices.Length, mesh.Indices, mesh.Indices.Length);

            return(mesh);
        }
        private Dictionary <string, Mesh> GenerateMeshes(float height, float margin = 0f)
        {
            var meshes     = new Dictionary <string, Mesh>();
            var fullMatrix = new Matrix3D();

            fullMatrix.RotateZMatrix(MathF.DegToRad(180.0f));

            var baseRadius = _data.BaseRadius - _data.RubberThickness + margin;
            var endRadius  = _data.EndRadius - _data.RubberThickness + margin;

            // 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 = new Mesh(Base, Vertices, Indices).Clone();

            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 + height);
            meshes[Base] = baseMesh;

            // rubber
            var rubberMesh = new Mesh(Rubber, Vertices, Indices).Clone();

            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 + margin,
                                 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 + margin,
                                 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 + margin,
                                 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 + margin,
                                 new Vertex2D(0, _data.FlipperRadius));
                    }
                }
            }
            rubberMesh.Transform(fullMatrix, null, z => z * _data.RubberWidth + (height + _data.RubberHeight + margin * 10f));
            meshes[Rubber] = rubberMesh;

            return(meshes);
        }
Ejemplo n.º 4
0
        public Vertex3DNoTex2[] BuildRodVertices(int frame)
        {
            if (_lathePoints == 0)
            {
                CalculateArraySizes();
            }
            var vertices = new Vertex3DNoTex2[_latheVts];
            var yTip     = _beginY + _dyPerFrame * frame;

            var tu    = 0.51f;
            var stepU = 1.0f / _circlePoints;
            var i     = 0;

            for (var l = 0; l < _circlePoints; l++, tu += stepU)
            {
                // Go down the long axis, adding a vertex for each point
                // in the descriptor list at the current lathe angle.
                if (tu > 1.0f)
                {
                    tu -= 1.0f;
                }

                var angle = (float)(MathF.PI * 2.0) / _circlePoints * l;
                var sn    = MathF.Sin(angle);
                var cs    = MathF.Cos(angle);

                for (var m = 0; m < _lathePoints; m++)
                {
                    ref var c = ref _desc.c[m];

                    // get the current point's coordinates
                    var y  = c.y + yTip;
                    var r  = c.r;
                    var tv = c.tv;

                    // the last coordinate is always the bottom of the rod
                    if (m + 1 == _lathePoints)
                    {
                        // set the end point
                        y = _rodY;

                        // Figure the texture mapping for the rod position.  This is
                        // important because we draw the rod with varying length -
                        // the part that's pulled back beyond the 'rodY' point is
                        // hidden.  We want the texture to maintain the same apparent
                        // position and scale in each frame, so we need to figure the
                        // proportional point of the texture at our cut-off point on
                        // the object surface.
                        var ratio = frame * _invScale;
                        tv = vertices[m - 1].Tv + (tv - vertices[m - 1].Tv) * ratio;
                    }

                    vertices[i++] = new Vertex3DNoTex2 {
                        X  = r * (sn * _data.Width) + _data.Center.X,
                        Y  = y,
                        Z  = (r * (cs * _data.Width) + _data.Width + _zHeight) * _zScale,
                        Nx = c.nx * sn,
                        Ny = c.ny,
                        Nz = c.nx * cs,
                        Tu = tu,
                        Tv = tv
                    };
                }
            }