Exemplo n.º 1
0
        private void ParseVertices(PrimitiveData data, byte[] bytes)
        {
            if (data.NumVertices == 0)
            {
                throw new ArgumentOutOfRangeException(nameof(data), "Cannot add vertices when size is unknown.");
            }

            if (bytes.Length < data.NumVertices * Vertex3DNoTex2.Size)
            {
                throw new ArgumentOutOfRangeException($"Tried to read {data.NumVertices} vertices for primitive item \"${data.Name}\" (${data.StorageName}), but only ${bytes.Length} bytes available.");
            }

            if (!(GetValue(data) is Mesh mesh))
            {
                throw new ArgumentException("BiffVertices attribute must sit on a Mesh object.");
            }

            var vertices = new Vertex3DNoTex2[data.NumVertices];

            using (var stream = new MemoryStream(bytes))
                using (var reader = new BinaryReader(stream)) {
                    for (var i = 0; i < data.NumVertices; i++)
                    {
                        vertices[i] = new Vertex3DNoTex2(reader);
                    }
                }
            mesh.Vertices = vertices;
        }
Exemplo n.º 2
0
        private Mesh GenerateFlatRightWall(float tableWidth, float tableHeight, RampVertex rv)
        {
            var invTableWidth  = 1.0f / tableWidth;
            var invTableHeight = 1.0f / tableHeight;
            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];

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

                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;


                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);
        }
Exemplo n.º 3
0
        private static void AssertVerticesEqual(ObjVector4 expected, Vertex3DNoTex2 actual, float threshold, bool switchZ = false)
        {
            var sign = switchZ ? -1 : 1;

            actual.X.Should().BeApproximately(expected.X, threshold);
            actual.Y.Should().BeApproximately(expected.Y, threshold);
            actual.Z.Should().BeApproximately(sign * expected.Z, threshold);
        }
Exemplo n.º 4
0
 private static void AssertVerticesEqual(ObjVector4 expected, Vertex3DNoTex2 actual, double threshold = FloatThresholdComparer.Threshold)
 {
     Assert.Equal(expected.X, actual.X, new FloatThresholdComparer(threshold));
     Assert.Equal(expected.Y, actual.Y, new FloatThresholdComparer(threshold));
     Assert.Equal(expected.Z, actual.Z, new FloatThresholdComparer(threshold));
 }
Exemplo n.º 5
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.Clone();                 // sideTopVert
                mesh.Vertices[_data.Sides * 3 + 2 + i] = bottomVert.Clone();              // 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 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);
        }
Exemplo n.º 7
0
 public static Vector3 ToUnityUvVector2(this Vertex3DNoTex2 vertex)
 {
     return(new Vector2(vertex.Tu, -vertex.Tv));
 }
Exemplo n.º 8
0
 public static Vector3 ToUnityNormalVector3(this Vertex3DNoTex2 vertex)
 {
     return(new Vector3(vertex.Nx, vertex.Ny, vertex.Nz));
 }
Exemplo n.º 9
0
 public static Vector3 ToUnityVector3(this Vertex3DNoTex2 vertex)
 {
     return(new Vector3(vertex.X, vertex.Y, vertex.Z));
 }
Exemplo n.º 10
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
                    };
                }
            }
Exemplo n.º 11
0
        private Vertex3DNoTex2[] CreateWire(int numRings, int numSegments, IReadOnlyList <Vertex2D> midPoints, IReadOnlyList <float> initialHeights)
        {
            var vertices = new Vertex3DNoTex2[numRings * numSegments];
            var prev     = new Vertex3D();
            var index    = 0;

            for (var i = 0; i < numRings; i++)
            {
                var i2     = i == numRings - 1 ? i : i + 1;
                var height = initialHeights[i];

                var tangent = new Vertex3D(
                    midPoints[i2].X - midPoints[i].X,
                    midPoints[i2].Y - midPoints[i].Y,
                    initialHeights[i2] - initialHeights[i]
                    );
                if (i == numRings - 1)
                {
                    // for the last spline point use the previous tangent again, otherwise we won't see the complete wire (it stops one control point too early)
                    tangent.X = midPoints[i].X - midPoints[i - 1].X;
                    tangent.Y = midPoints[i].Y - midPoints[i - 1].Y;
                }

                Vertex3D biNormal;
                Vertex3D normal;
                if (i == 0)
                {
                    var up = new Vertex3D(
                        midPoints[i2].X + midPoints[i].X,
                        midPoints[i2].Y + midPoints[i].Y,
                        initialHeights[i2] - height
                        );
                    normal   = Vertex3D.CrossProduct(tangent, up);                       //normal
                    biNormal = Vertex3D.CrossProduct(tangent, normal);
                }
                else
                {
                    normal   = Vertex3D.CrossProduct(prev, tangent);
                    biNormal = Vertex3D.CrossProduct(tangent, normal);
                }

                biNormal.Normalize();
                normal.Normalize();
                prev = biNormal;

                var invNumRings    = 1.0f / numRings;
                var invNumSegments = 1.0f / numSegments;
                var u = i * invNumRings;
                for (var j = 0; j < numSegments; j++, index++)
                {
                    var v   = (j + u) * invNumSegments;
                    var tmp = Vertex3D.GetRotatedAxis(j * (360.0f * invNumSegments), tangent, normal) * (_data.WireDiameter * 0.5f);

                    vertices[index] = new Vertex3DNoTex2 {
                        X  = midPoints[i].X + tmp.X,
                        Y  = midPoints[i].Y + tmp.Y,
                        Z  = height + tmp.Z,
                        Tu = u,
                        Tv = v
                    };

                    // normals
                    var n = new Vertex3D(
                        vertices[index].X - midPoints[i].X,
                        vertices[index].Y - midPoints[i].Y,
                        vertices[index].Z - height
                        );
                    var len = 1.0f / MathF.Sqrt(n.X * n.X + n.Y * n.Y + n.Z * n.Z);
                    vertices[index].Nx = n.X * len;
                    vertices[index].Ny = n.Y * len;
                    vertices[index].Nz = n.Z * len;
                }
            }

            return(vertices);
        }
        private Mesh GenerateFlatFloorMesh(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("Floor")
            {
                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[rv.VertexCount * 2 - i - 1].X;
                rgv3d2.Y = rv.RgvLocal[rv.VertexCount * 2 - i - 1].Y;
                rgv3d2.Z = rgv3d1.Z;

                if (_data.Image != null)
                {
                    if (_data.ImageAlignment == RampImageAlignment.ImageModeWorld)
                    {
                        rgv3d1.Tu = rgv3d1.X * invTableWidth;
                        rgv3d1.Tv = rgv3d1.Y * invTableHeight;
                        rgv3d2.Tu = rgv3d2.X * invTableWidth;
                        rgv3d2.Tv = rgv3d2.Y * invTableHeight;
                    }
                    else
                    {
                        rgv3d1.Tu = 1.0f;
                        rgv3d1.Tv = rv.PointRatios[i];
                        rgv3d2.Tu = 0.0f;
                        rgv3d2.Tv = rv.PointRatios[i];
                    }
                }
                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);
        }
Exemplo n.º 13
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);
        }
Exemplo n.º 14
0
 private Vertex3DNoTex2[] Find(IEnumerable <Vertex3DNoTex2> vertices, Vertex3DNoTex2 vertex, int precision)
 {
     return(vertices.Where(v => v.Equals(vertex, precision)).ToArray());
 }
 private static void AssertVerticesEqual(ObjVector4 expected, Vertex3DNoTex2 actual, float threshold)
 {
     actual.X.Should().BeApproximately(expected.X, threshold);
     actual.Y.Should().BeApproximately(expected.Y, threshold);
     actual.Z.Should().BeApproximately(expected.Z, threshold);
 }