Пример #1
0
 public static Vector2[] ToVector2(VectorArray2f a)
 {
     Vector2[] v = new Vector2[a.Count];
     for (int i = 0; i < a.Count; ++i) {
         v[i].x = (float)a.array[2 * i];
         v[i].y = (float)a.array[2 * i + 1];
     }
     return v;
 }
Пример #2
0
        VectorArray2f restore_list2f(String valueString)
        {
            string[]      values = valueString.Split(' ');
            int           N      = values.Length / 2;
            VectorArray2f v      = new VectorArray2f(N);

            for (int i = 0; i < N; ++i)
            {
                float x = 0, y = 0;
                float.TryParse(values[2 * i], out x);
                float.TryParse(values[2 * i + 1], out y);
                v.Set(i, x, y);
            }
            return(v);
        }
Пример #3
0
        public override void Generate()
        {
            vertices  = new VectorArray3d((NoSharedVertices) ? (4 * 6) : 8);
            uv        = new VectorArray2f(vertices.Count);
            normals   = new VectorArray3f(vertices.Count);
            triangles = new IndexArray3i(2 * 6);

            if (NoSharedVertices == false)
            {
                for (int i = 0; i < 8; ++i)
                {
                    vertices[i] = Box.Corner(i);
                    normals[i]  = (Vector3F)(vertices[i] - Box.Center[i]).Normalized;
                    uv[i]       = Vector2F.Zero; // what to do for UVs in this case ?!?
                }
                int ti = 0;
                for (int fi = 0; fi < 6; ++fi)
                {
                    triangles.Set(ti++,
                                  gIndices.BoxFaces[fi, 0], gIndices.BoxFaces[fi, 1], gIndices.BoxFaces[fi, 2], Clockwise);
                    triangles.Set(ti++,
                                  gIndices.BoxFaces[fi, 0], gIndices.BoxFaces[fi, 2], gIndices.BoxFaces[fi, 3], Clockwise);
                }
            }
            else
            {
                int        ti        = 0;
                int        vi        = 0;
                Vector2F[] square_uv = new Vector2F[4] {
                    Vector2F.Zero, new Vector2F(1, 0), new Vector2F(1, 1), new Vector2F(0, 1)
                };
                for (int fi = 0; fi < 6; ++fi)
                {
                    int      v0 = vi++; vi += 3;
                    int      ni = gIndices.BoxFaceNormals[fi];
                    Vector3F n  = (Vector3F)(Math.Sign(ni) * Box.Axis(Math.Abs(ni) - 1));
                    for (int j = 0; j < 4; ++j)
                    {
                        vertices[v0 + j] = Box.Corner(gIndices.BoxFaces[fi, j]);
                        normals[v0 + j]  = n;
                        uv[v0 + j]       = square_uv[j];
                    }

                    triangles.Set(ti++, v0, v0 + 1, v0 + 2, Clockwise);
                    triangles.Set(ti++, v0, v0 + 2, v0 + 3, Clockwise);
                }
            }
        }
Пример #4
0
        VectorArray2f restore_list2f_binary(String valueString)
        {
            char[]        str    = valueString.ToCharArray();
            byte[]        buffer = Convert.FromBase64CharArray(str, 0, str.Length);
            int           sz     = sizeof(float);
            int           Nvals  = buffer.Length / sz;
            int           Nvecs  = Nvals / 2;
            VectorArray2f v      = new VectorArray2f(Nvecs);

            for (int i = 0; i < Nvecs; i++)
            {
                float x = BitConverter.ToSingle(buffer, (2 * i) * sz);
                float y = BitConverter.ToSingle(buffer, (2 * i + 1) * sz);
                v.Set(i, x, y);
            }
            return(v);
        }
Пример #5
0
        override public void Generate()
        {
            bool bClosed   = ((EndAngleDeg - StartAngleDeg) > 359.99f);
            int  nRingSize = (NoSharedVertices && bClosed) ? Slices + 1 : Slices;

            vertices  = new VectorArray3d(2 * nRingSize);
            uv        = new VectorArray2f(vertices.Count);
            normals   = new VectorArray3f(vertices.Count);
            triangles = new IndexArray3i(2 * Slices);

            float fTotalRange = (EndAngleDeg - StartAngleDeg) * math.MathUtil.Deg2Radf;
            float fStartRad   = StartAngleDeg * math.MathUtil.Deg2Radf;
            float fDelta      = (bClosed) ? fTotalRange / Slices : fTotalRange / (Slices - 1);

            for (int k = 0; k < nRingSize; ++k)
            {
                float  angle = fStartRad + (float)k * fDelta;
                double cosa = Math.Cos(angle), sina = Math.Sin(angle);
                vertices[k]             = new Vector3D(BaseRadius * cosa, 0, BaseRadius * sina);
                vertices[nRingSize + k] = new Vector3D(TopRadius * cosa, Height, TopRadius * sina);
                float t = (float)k / (float)Slices;
                uv[k]             = new Vector2F(t, 0.0f);
                uv[nRingSize + k] = new Vector2F(t, 1.0f);
                Vector3F n = new Vector3F((float)cosa, 0, (float)sina);
                n.Normalize();
                normals[k] = normals[nRingSize + k] = n;
            }

            int ti = 0;

            for (int k = 0; k < nRingSize - 1; ++k)
            {
                triangles.Set(ti++, k, k + 1, nRingSize + k + 1, Clockwise);
                triangles.Set(ti++, k, nRingSize + k + 1, nRingSize + k, Clockwise);
            }
            if (bClosed && NoSharedVertices == false)        // close disc if we went all the way
            {
                triangles.Set(ti++, nRingSize - 1, 0, nRingSize, Clockwise);
                triangles.Set(ti++, nRingSize - 1, nRingSize, 2 * nRingSize - 1, Clockwise);
            }
        }
Пример #6
0
        override public void Generate()
        {
            vertices  = new VectorArray3d(Slices + 1);
            uv        = new VectorArray2f(Slices + 1);
            normals   = new VectorArray3f(Slices + 1);
            triangles = new IndexArray3i(Slices);

            int vi = 0;

            vertices[vi] = Vector3D.Zero;
            uv[vi]       = new Vector2F(0.5f, 0.5f);
            normals[vi]  = Vector3F.AxisY;
            vi++;

            bool  bFullDisc   = ((EndAngleDeg - StartAngleDeg) > 359.99f);
            float fTotalRange = (EndAngleDeg - StartAngleDeg) * math.MathUtil.Deg2Radf;
            float fStartRad   = StartAngleDeg * math.MathUtil.Deg2Radf;
            float fDelta      = (bFullDisc) ? fTotalRange / Slices : fTotalRange / (Slices - 1);

            for (int k = 0; k < Slices; ++k)
            {
                float  a = fStartRad + (float)k * fDelta;
                double cosa = Math.Cos(a), sina = Math.Sin(a);
                vertices[vi] = new Vector3D(Radius * cosa, 0, Radius * sina);
                uv[vi]       = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina));
                normals[vi]  = Vector3F.AxisY;
                vi++;
            }

            int ti = 0;

            for (int k = 1; k < Slices; ++k)
            {
                triangles.Set(ti++, k, 0, k + 1, Clockwise);
            }
            if (bFullDisc)      // close disc if we went all the way
            {
                triangles.Set(ti++, Slices, 0, 1, Clockwise);
            }
        }
Пример #7
0
        override public void Generate()
        {
            vertices  = new VectorArray3d(2 * Slices);
            uv        = new VectorArray2f(2 * Slices);
            normals   = new VectorArray3f(2 * Slices);
            triangles = new IndexArray3i(2 * Slices);

            bool  bFullDisc   = ((EndAngleDeg - StartAngleDeg) > 359.99f);
            float fTotalRange = (EndAngleDeg - StartAngleDeg) * math.MathUtil.Deg2Radf;
            float fStartRad   = StartAngleDeg * math.MathUtil.Deg2Radf;
            float fDelta      = (bFullDisc) ? fTotalRange / Slices : fTotalRange / (Slices - 1);
            float fUVRatio    = InnerRadius / OuterRadius;

            for (int k = 0; k < Slices; ++k)
            {
                float  angle = fStartRad + (float)k * fDelta;
                double cosa = Math.Cos(angle), sina = Math.Sin(angle);
                vertices[k]          = new Vector3D(InnerRadius * cosa, 0, InnerRadius * sina);
                vertices[Slices + k] = new Vector3D(OuterRadius * cosa, 0, OuterRadius * sina);
                uv[k]          = new Vector2F(0.5f * (1.0f + fUVRatio * cosa), 0.5f * (1.0f + fUVRatio * sina));
                uv[Slices + k] = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1.0f + sina));
                normals[k]     = normals[Slices + k] = Vector3F.AxisY;
            }

            int ti = 0;

            for (int k = 0; k < Slices - 1; ++k)
            {
                triangles.Set(ti++, k, k + 1, Slices + k + 1, Clockwise);
                triangles.Set(ti++, k, Slices + k + 1, Slices + k, Clockwise);
            }
            if (bFullDisc)        // close disc if we went all the way
            {
                triangles.Set(ti++, Slices - 1, 0, Slices, Clockwise);
                triangles.Set(ti++, Slices - 1, Slices, 2 * Slices - 1, Clockwise);
            }
        }
Пример #8
0
 public void Initialize(VectorArray3d v, VectorArray3i t,
                        VectorArray3f n = null, VectorArray3f c = null, VectorArray2f uv = null, int[] g = null)
 {
     Vertices   = new DVector <double>(v);
     Triangles  = new DVector <int>(t);
     Normals    = Colors = UVs = null;
     FaceGroups = null;
     if (n != null)
     {
         Normals = new DVector <float>(n);
     }
     if (c != null)
     {
         Colors = new DVector <float>(c);
     }
     if (uv != null)
     {
         UVs = new DVector <float>(uv);
     }
     if (g != null)
     {
         FaceGroups = new DVector <int>(g);
     }
 }
Пример #9
0
        public virtual SimpleMesh RestoreSimpleMesh(TypedAttribSet attributes, bool bSwapRightLeft)
        {
            bool           bBinary  = true;
            TypedAttribSet meshAttr = find_struct(attributes, IOStrings.BinaryMeshStruct);

            if (meshAttr == null)
            {
                meshAttr = find_struct(attributes, IOStrings.AsciiMeshStruct);
                bBinary  = false;
            }
            if (meshAttr == null)
            {
                throw new Exception("SOFactory.RestoreSimpleMesh: Mesh ascii/binary struct not found!");
            }


            VectorArray3d v = null;
            VectorArray3i t = null;
            VectorArray3f n = null, c = null;
            VectorArray2f uv = null;

            if (bBinary)
            {
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshVertices3Binary))
                {
                    v = meshAttr[IOStrings.AMeshVertices3Binary] as VectorArray3d;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshTrianglesBinary))
                {
                    t = meshAttr[IOStrings.AMeshTrianglesBinary] as VectorArray3i;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshNormals3Binary))
                {
                    n = meshAttr[IOStrings.AMeshNormals3Binary] as VectorArray3f;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshColors3Binary))
                {
                    c = meshAttr[IOStrings.AMeshColors3Binary] as VectorArray3f;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshUVs2Binary))
                {
                    uv = meshAttr[IOStrings.AMeshUVs2Binary] as VectorArray2f;
                }
            }
            else
            {
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshVertices3))
                {
                    v = meshAttr[IOStrings.AMeshVertices3] as VectorArray3d;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshTriangles))
                {
                    t = meshAttr[IOStrings.AMeshTriangles] as VectorArray3i;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshNormals3))
                {
                    n = meshAttr[IOStrings.AMeshNormals3] as VectorArray3f;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshColors3))
                {
                    c = meshAttr[IOStrings.AMeshColors3] as VectorArray3f;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshUVs2))
                {
                    uv = meshAttr[IOStrings.AMeshUVs2] as VectorArray2f;
                }
            }

            if (v == null || t == null)
            {
                return(null);
            }

            if (bSwapRightLeft)
            {
                int N = v.Count;
                for (int i = 0; i < N; ++i)
                {
                    Vector3d vv = v[i];
                    v.Set(i, -vv.x, vv.y, -vv.z);
                }
                if (n != null && n.Count == N)
                {
                    for (int i = 0; i < N; ++i)
                    {
                        Vector3f nn = n[i];
                        n.Set(i, -nn.x, nn.y, -nn.z);
                    }
                }
            }

            SimpleMesh m = new SimpleMesh();

            m.Initialize(v, t, n, c, uv);
            return(m);
        }
Пример #10
0
        public override void Generate()
        {
            int nRings       = Curve.Length;
            int nRingSize    = (NoSharedVertices) ? Slices + 1 : Slices;
            int nCapVertices = (NoSharedVertices) ? Slices + 1 : 1;

            if (Capped == false)
            {
                nCapVertices = 0;
            }

            vertices = new VectorArray3d(nRingSize * nRings + 2 * nCapVertices);
            uv       = new VectorArray2f(vertices.Count);
            normals  = new VectorArray3f(vertices.Count);

            int nSpanTris = (nRings - 1) * (2 * Slices);
            int nCapTris  = (Capped) ? 2 * Slices : 0;

            triangles = new IndexArray3i(nSpanTris + nCapTris);

            float fDelta = (float)((Math.PI * 2.0) / Slices);

            Frame3f f = Axis;

            // generate tube
            for (int ri = 0; ri < nRings; ++ri)
            {
                Vector3D v_along  = Curve[ri];
                Vector3F v_frame  = f.ToFrameP((Vector3F)v_along);
                float    uv_along = (float)ri / (float)(nRings - 1);

                // generate vertices
                int nStartR = ri * nRingSize;
                for (int j = 0; j < nRingSize; ++j)
                {
                    float angle = (float)j * fDelta;

                    // [TODO] this is not efficient...use Matrix3f?
                    Vector3F v_rot = Quaternionf.AxisAngleR(Vector3F.AxisY, angle) * v_frame;
                    Vector3D v_new = f.FromFrameP(v_rot);
                    int      k     = nStartR + j;
                    vertices[k] = v_new;

                    float uv_around = (float)j / (float)(nRingSize);
                    uv[k] = new Vector2F(uv_along, uv_around);

                    // [TODO] proper normal
                    Vector3F n = (Vector3F)(v_new - f.Origin).Normalized;
                    normals[k] = n;
                }
            }


            // generate triangles
            int ti = 0;

            for (int ri = 0; ri < nRings - 1; ++ri)
            {
                int r0 = ri * nRingSize;
                int r1 = r0 + nRingSize;
                for (int k = 0; k < nRingSize - 1; ++k)
                {
                    triangles.Set(ti++, r0 + k, r0 + k + 1, r1 + k + 1, Clockwise);
                    triangles.Set(ti++, r0 + k, r1 + k + 1, r1 + k, Clockwise);
                }
                if (NoSharedVertices == false)        // close disc if we went all the way
                {
                    triangles.Set(ti++, r1 - 1, r0, r1, Clockwise);
                    triangles.Set(ti++, r1 - 1, r1, r1 + nRingSize - 1, Clockwise);
                }
            }



            if (Capped)
            {
                // find avg start loop size
                Vector3D vAvgStart = Vector3D.Zero, vAvgEnd = Vector3D.Zero;
                for (int k = 0; k < Slices; ++k)
                {
                    vAvgStart += vertices[k];
                    vAvgEnd   += vertices[(nRings - 1) * nRingSize + k];
                }
                vAvgStart /= (double)Slices;
                vAvgEnd   /= (double)Slices;

                Frame3f fStart = f;
                fStart.Origin = (Vector3F)vAvgStart;
                Frame3f fEnd = f;
                fEnd.Origin = (Vector3F)vAvgEnd;



                // add endcap verts
                int nBottomC = nRings * nRingSize;
                vertices[nBottomC]  = fStart.Origin;
                uv[nBottomC]        = new Vector2F(0.5f, 0.5f);
                normals[nBottomC]   = -fStart.Z;
                startCapCenterIndex = nBottomC;

                int nTopC = nBottomC + 1;
                vertices[nTopC]   = fEnd.Origin;
                uv[nTopC]         = new Vector2F(0.5f, 0.5f);
                normals[nTopC]    = fEnd.Z;
                endCapCenterIndex = nTopC;

                if (NoSharedVertices)
                {
                    // duplicate first loop and make a fan w/ bottom-center
                    int nExistingB = 0;
                    int nStartB    = nTopC + 1;
                    for (int k = 0; k < Slices; ++k)
                    {
                        vertices[nStartB + k] = vertices[nExistingB + k];
                        //uv[nStartB + k] = (Vector2f)Polygon.Vertices[k].Normalized;

                        float  angle = (float)k * fDelta;
                        double cosa = Math.Cos(angle), sina = Math.Sin(angle);
                        uv[nStartB + k] = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina));

                        normals[nStartB + k] = normals[nBottomC];
                    }
                    append_disc(Slices, nBottomC, nStartB, true, Clockwise, ref ti);

                    // duplicate second loop and make fan
                    int nExistingT = nRingSize * (nRings - 1);
                    int nStartT    = nStartB + Slices;
                    for (int k = 0; k < Slices; ++k)
                    {
                        vertices[nStartT + k] = vertices[nExistingT + k];
                        //uv[nStartT + k] = (Vector2f)Polygon.Vertices[k].Normalized;

                        float  angle = (float)k * fDelta;
                        double cosa = Math.Cos(angle), sina = Math.Sin(angle);
                        uv[nStartT + k] = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina));


                        normals[nStartT + k] = normals[nTopC];
                    }
                    append_disc(Slices, nTopC, nStartT, true, !Clockwise, ref ti);
                }
                else
                {
                    append_disc(Slices, nBottomC, 0, true, Clockwise, ref ti);
                    append_disc(Slices, nTopC, nRingSize * (nRings - 1), true, !Clockwise, ref ti);
                }
            }
        }
Пример #11
0
        public virtual DMesh3 RestoreDMesh(TypedAttribSet attributes)
        {
            bool           is_compressed = false;
            TypedAttribSet meshAttr      = find_struct(attributes, IOStrings.BinaryDMeshStruct);

            if (meshAttr == null)
            {
                meshAttr      = find_struct(attributes, IOStrings.CompressedDMeshStruct);
                is_compressed = true;
            }
            if (meshAttr == null)
            {
                throw new Exception("SOFactory.RestoreDMesh: DMesh binary or compressed struct not found!");
            }

            VectorArray3d v = null;
            VectorArray3f n = null, c = null;
            VectorArray2f uv = null;

            VectorArray3i t = null;

            int[] g = null;

            IndexArray4i e = null;

            short[] e_ref = null;

            var storageMode = IOStrings.MeshStorageMode.EdgeRefCounts;

            if (meshAttr.ContainsKey(IOStrings.AMeshStorageMode))
            {
                storageMode = (IOStrings.MeshStorageMode)(int) meshAttr[IOStrings.AMeshStorageMode];
            }

            if (is_compressed)
            {
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshVertices3Compressed))
                {
                    v = meshAttr[IOStrings.AMeshVertices3Compressed] as VectorArray3d;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshNormals3Compressed))
                {
                    n = meshAttr[IOStrings.AMeshNormals3Compressed] as VectorArray3f;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshColors3Compressed))
                {
                    c = meshAttr[IOStrings.AMeshColors3Compressed] as VectorArray3f;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshUVs2Compressed))
                {
                    uv = meshAttr[IOStrings.AMeshUVs2Compressed] as VectorArray2f;
                }

                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshTrianglesCompressed))
                {
                    t = meshAttr[IOStrings.AMeshTrianglesCompressed] as VectorArray3i;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshTriangleGroupsCompressed))
                {
                    g = meshAttr[IOStrings.AMeshTriangleGroupsCompressed] as int[];
                }

                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshEdgesCompressed))
                {
                    e = meshAttr[IOStrings.AMeshEdgesCompressed] as IndexArray4i;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshEdgeRefCountsCompressed))
                {
                    e_ref = meshAttr[IOStrings.AMeshEdgeRefCountsCompressed] as short[];
                }
            }
            else
            {
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshVertices3Binary))
                {
                    v = meshAttr[IOStrings.AMeshVertices3Binary] as VectorArray3d;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshNormals3Binary))
                {
                    n = meshAttr[IOStrings.AMeshNormals3Binary] as VectorArray3f;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshColors3Binary))
                {
                    c = meshAttr[IOStrings.AMeshColors3Binary] as VectorArray3f;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshUVs2Binary))
                {
                    uv = meshAttr[IOStrings.AMeshUVs2Binary] as VectorArray2f;
                }

                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshTrianglesBinary))
                {
                    t = meshAttr[IOStrings.AMeshTrianglesBinary] as VectorArray3i;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshTriangleGroupsBinary))
                {
                    g = meshAttr[IOStrings.AMeshTriangleGroupsBinary] as int[];
                }

                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshEdgesBinary))
                {
                    e = meshAttr[IOStrings.AMeshEdgesBinary] as IndexArray4i;
                }
                if (check_key_or_debug_print(meshAttr, IOStrings.AMeshEdgeRefCountsBinary))
                {
                    e_ref = meshAttr[IOStrings.AMeshEdgeRefCountsBinary] as short[];
                }
            }

            DMesh3 m = new DMesh3();

            if (n != null)
            {
                m.EnableVertexNormals(Vector3f.Zero);
            }
            if (c != null)
            {
                m.EnableVertexColors(Vector3f.Zero);
            }
            if (uv != null)
            {
                m.EnableVertexUVs(Vector2f.Zero);
            }
            if (g != null)
            {
                m.EnableTriangleGroups(0);
            }

            if (storageMode == IOStrings.MeshStorageMode.EdgeRefCounts)
            {
                if (v == null || t == null || e == null || e_ref == null)
                {
                    return(null);
                }

                m.VerticesBuffer = new DVector <double>(v);
                if (n != null)
                {
                    m.NormalsBuffer = new DVector <float>(n);
                }
                if (c != null)
                {
                    m.ColorsBuffer = new DVector <float>(c);
                }
                if (uv != null)
                {
                    m.UVBuffer = new DVector <float>(uv);
                }
                m.TrianglesBuffer = new DVector <int>(t);
                if (g != null)
                {
                    m.GroupsBuffer = new DVector <int>(g);
                }

                m.EdgesBuffer    = new DVector <int>(e);
                m.EdgesRefCounts = new RefCountVector(e_ref);
                m.RebuildFromEdgeRefcounts();
            }
            else if (storageMode == IOStrings.MeshStorageMode.Minimal)
            {
                if (v == null || t == null)
                {
                    return(null);
                }

                int           NV    = v.Count;
                NewVertexInfo vinfo = new NewVertexInfo();
                for (int k = 0; k < NV; ++k)
                {
                    vinfo.v = v[k];
                    if (n != null)
                    {
                        vinfo.n = n[k];
                    }
                    if (c != null)
                    {
                        vinfo.c = c[k];
                    }
                    if (uv != null)
                    {
                        vinfo.uv = uv[k];
                    }
                    m.AppendVertex(ref vinfo);
                }

                int NT = t.Count;
                for (int k = 0; k < NT; ++k)
                {
                    Vector3i tri  = t[k];
                    int      setg = (g == null) ? -1 : g[k];
                    m.AppendTriangle(tri, setg);
                }
            }
            else
            {
                throw new Exception("SOFactory.RestoreDMesh: unsupported mesh storage mode");
            }

            return(m);
        }
Пример #12
0
        override public void Generate()
        {
            int nRings       = (NoSharedVertices) ? 2 * (Sections.Length - 1) : Sections.Length;
            int nRingSize    = (NoSharedVertices) ? Slices + 1 : Slices;
            int nCapVertices = (NoSharedVertices) ? Slices + 1 : 1;

            if (Capped == false)
            {
                nCapVertices = 0;
            }
            vertices = new VectorArray3d(nRings * nRingSize + 2 * nCapVertices);
            uv       = new VectorArray2f(vertices.Count);
            normals  = new VectorArray3f(vertices.Count);

            int nSpanTris = (Sections.Length - 1) * (2 * Slices);
            int nCapTris  = (Capped) ? 2 * Slices : 0;

            triangles = new IndexArray3i(nSpanTris + nCapTris);

            float fDelta = (float)((Math.PI * 2.0) / Slices);

            float fYSpan = Sections.Last().SectionY - Sections[0].SectionY;

            if (fYSpan == 0)
            {
                fYSpan = 1.0f;
            }

            // generate top and bottom rings for cylinder
            int ri = 0;

            for (int si = 0; si < Sections.Length; ++si)
            {
                int   nStartR = ri * nRingSize;
                float y       = Sections[si].SectionY;
                float yt      = (y - Sections[0].SectionY) / fYSpan;
                for (int j = 0; j < nRingSize; ++j)
                {
                    int    k = nStartR + j;
                    float  angle = (float)j * fDelta;
                    double cosa = Math.Cos(angle), sina = Math.Sin(angle);
                    vertices[k] = new Vector3D(Sections[si].Radius * cosa, y, Sections[si].Radius * sina);
                    float t = (float)j / (float)(Slices - 1);
                    uv[k] = new Vector2F(t, yt);
                    Vector3F n = new Vector3F((float)cosa, 0, (float)sina);
                    n.Normalize();
                    normals[k] = n;
                }
                ri++;
                if (NoSharedVertices && si != 0 && si != Sections.Length - 1)
                {
                    duplicate_vertex_span(nStartR, nRingSize);
                    ri++;
                }
            }

            // generate triangles
            int ti = 0;

            ri = 0;
            for (int si = 0; si < Sections.Length - 1; ++si)
            {
                int r0 = ri * nRingSize;
                int r1 = r0 + nRingSize;
                ri += (NoSharedVertices) ? 2 : 1;
                for (int k = 0; k < nRingSize - 1; ++k)
                {
                    triangles.Set(ti++, r0 + k, r0 + k + 1, r1 + k + 1, Clockwise);
                    triangles.Set(ti++, r0 + k, r1 + k + 1, r1 + k, Clockwise);
                }
                if (NoSharedVertices == false)        // close disc if we went all the way
                {
                    triangles.Set(ti++, r1 - 1, r0, r1, Clockwise);
                    triangles.Set(ti++, r1 - 1, r1, r1 + nRingSize - 1, Clockwise);
                }
            }

            if (Capped)
            {
                // add endcap verts
                var s0       = Sections[0];
                var sN       = Sections.Last();
                int nBottomC = nRings * nRingSize;
                vertices[nBottomC]  = new Vector3D(0, s0.SectionY, 0);
                uv[nBottomC]        = new Vector2F(0.5f, 0.5f);
                normals[nBottomC]   = new Vector3F(0, -1, 0);
                startCapCenterIndex = nBottomC;

                int nTopC = nBottomC + 1;
                vertices[nTopC]   = new Vector3D(0, sN.SectionY, 0);
                uv[nTopC]         = new Vector2F(0.5f, 0.5f);
                normals[nTopC]    = new Vector3F(0, 1, 0);
                endCapCenterIndex = nTopC;

                if (NoSharedVertices)
                {
                    int nStartB = nTopC + 1;
                    for (int k = 0; k < Slices; ++k)
                    {
                        float  a = (float)k * fDelta;
                        double cosa = Math.Cos(a), sina = Math.Sin(a);
                        vertices[nStartB + k] = new Vector3D(s0.Radius * cosa, s0.SectionY, s0.Radius * sina);
                        uv[nStartB + k]       = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina));
                        normals[nStartB + k]  = -Vector3F.AxisY;
                    }
                    append_disc(Slices, nBottomC, nStartB, true, Clockwise, ref ti);

                    int nStartT = nStartB + Slices;
                    for (int k = 0; k < Slices; ++k)
                    {
                        float  a = (float)k * fDelta;
                        double cosa = Math.Cos(a), sina = Math.Sin(a);
                        vertices[nStartT + k] = new Vector3D(sN.Radius * cosa, sN.SectionY, sN.Radius * sina);
                        uv[nStartT + k]       = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina));
                        normals[nStartT + k]  = Vector3F.AxisY;
                    }
                    append_disc(Slices, nTopC, nStartT, true, !Clockwise, ref ti);
                }
                else
                {
                    append_disc(Slices, nBottomC, 0, true, Clockwise, ref ti);
                    append_disc(Slices, nTopC, nRingSize * (Sections.Length - 1), true, !Clockwise, ref ti);
                }
            }
        }
Пример #13
0
        override public void Generate()
        {
            vertices  = new VectorArray3d(4);
            uv        = new VectorArray2f(4);
            normals   = new VectorArray3f(4);
            triangles = new IndexArray3i(2);

            vertices[0] = new Vector3D(-Width / 2.0f, 0, -Height / 2.0f);
            vertices[1] = new Vector3D(Width / 2.0f, 0, -Height / 2.0f);
            vertices[2] = new Vector3D(Width / 2.0f, 0, Height / 2.0f);
            vertices[3] = new Vector3D(-Width / 2.0f, 0, Height / 2.0f);

            normals[0] = normals[1] = normals[2] = normals[3] = Vector3F.AxisY;

            float uvleft = 0.0f, uvright = 1.0f, uvbottom = 0.0f, uvtop = 1.0f;

            // if we want the UV subregion, we assume it is
            if (UVMode != UVModes.FullUVSquare)
            {
                if (Width > Height)
                {
                    float a = Height / Width;
                    if (UVMode == UVModes.CenteredUVRectangle)
                    {
                        uvbottom = 0.5f - a / 2.0f; uvtop = 0.5f + a / 2.0f;
                    }
                    else
                    {
                        uvtop = a;
                    }
                }
                else if (Height > Width)
                {
                    float a = Width / Height;
                    if (UVMode == UVModes.CenteredUVRectangle)
                    {
                        uvleft = 0.5f - a / 2.0f; uvright = 0.5f + a / 2.0f;
                    }
                    else
                    {
                        uvright = a;
                    }
                }
            }

            uv[0] = new Vector2F(uvleft, uvbottom);
            uv[1] = new Vector2F(uvright, uvbottom);
            uv[2] = new Vector2F(uvright, uvtop);
            uv[3] = new Vector2F(uvleft, uvtop);

            if (Clockwise == true)
            {
                triangles.Set(0, 0, 1, 2);
                triangles.Set(1, 0, 2, 3);
            }
            else
            {
                triangles.Set(0, 0, 2, 1);
                triangles.Set(1, 0, 3, 2);
            }
        }
Пример #14
0
        override public void Generate()
        {
            int corner_v = 0, corner_t = 0;

            for (int k = 0; k < 4; ++k)
            {
                if (((int)SharpCorners & (1 << k)) != 0)
                {
                    corner_v += 1;
                    corner_t += 2;
                }
                else
                {
                    corner_v += CornerSteps;
                    corner_t += (CornerSteps + 1);
                }
            }

            vertices  = new VectorArray3d(12 + corner_v);
            uv        = new VectorArray2f(vertices.Count);
            normals   = new VectorArray3f(vertices.Count);
            triangles = new IndexArray3i(10 + corner_t);

            float innerW = Width - 2 * Radius;
            float innerH = Height - 2 * Radius;

            // make vertices for inner "cross" (ie 5 squares)
            vertices[0] = new Vector3D(-innerW / 2.0f, 0, -innerH / 2.0f);
            vertices[1] = new Vector3D(innerW / 2.0f, 0, -innerH / 2.0f);
            vertices[2] = new Vector3D(innerW / 2.0f, 0, innerH / 2.0f);
            vertices[3] = new Vector3D(-innerW / 2.0f, 0, innerH / 2.0f);

            vertices[4] = new Vector3D(-innerW / 2, 0, -Height / 2);
            vertices[5] = new Vector3D(innerW / 2, 0, -Height / 2);

            vertices[6] = new Vector3D(Width / 2, 0, -innerH / 2);
            vertices[7] = new Vector3D(Width / 2, 0, innerH / 2);

            vertices[8] = new Vector3D(innerW / 2, 0, Height / 2);
            vertices[9] = new Vector3D(-innerW / 2, 0, Height / 2);

            vertices[10] = new Vector3D(-Width / 2, 0, innerH / 2);
            vertices[11] = new Vector3D(-Width / 2, 0, -innerH / 2);

            // make triangles for inner cross
            bool cycle = (Clockwise == false);
            int  ti    = 0;

            append_rectangle(0, 1, 2, 3, cycle, ref ti);
            append_rectangle(4, 5, 1, 0, cycle, ref ti);
            append_rectangle(1, 6, 7, 2, cycle, ref ti);
            append_rectangle(3, 2, 8, 9, cycle, ref ti);
            append_rectangle(11, 0, 3, 10, cycle, ref ti);

            int vi = 12;

            for (int j = 0; j < 4; ++j)
            {
                bool sharp = ((int)SharpCorners & (1 << j)) > 0;
                if (sharp)
                {
                    append_2d_disc_segment(corner_spans[3 * j], corner_spans[3 * j + 1], corner_spans[3 * j + 2], 1,
                                           cycle, ref vi, ref ti, -1, math.MathUtil.SqrtTwo * Radius);
                }
                else
                {
                    append_2d_disc_segment(corner_spans[3 * j], corner_spans[3 * j + 1], corner_spans[3 * j + 2], CornerSteps,
                                           cycle, ref vi, ref ti);
                }
            }


            for (int k = 0; k < vertices.Count; ++k)
            {
                normals[k] = Vector3F.AxisY;
            }

            float uvleft = 0.0f, uvright = 1.0f, uvbottom = 0.0f, uvtop = 1.0f;

            // if we want the UV subregion, we assume it is
            if (UVMode != UVModes.FullUVSquare)
            {
                if (Width > Height)
                {
                    float a = Height / Width;
                    if (UVMode == UVModes.CenteredUVRectangle)
                    {
                        uvbottom = 0.5f - a / 2.0f; uvtop = 0.5f + a / 2.0f;
                    }
                    else
                    {
                        uvtop = a;
                    }
                }
                else if (Height > Width)
                {
                    float a = Width / Height;
                    if (UVMode == UVModes.CenteredUVRectangle)
                    {
                        uvleft = 0.5f - a / 2.0f; uvright = 0.5f + a / 2.0f;
                    }
                    else
                    {
                        uvright = a;
                    }
                }
            }

            Vector3D c = new Vector3D(-Width / 2, 0, -Height / 2);

            for (int k = 0; k < vertices.Count; ++k)
            {
                Vector3D v  = vertices[k];
                double   tx = (v.x - c.x) / Width;
                double   ty = (v.y - c.y) / Height;
                uv[k] = new Vector2F((1 - tx) * uvleft + (tx) * uvright,
                                     (1 - ty) * uvbottom + (ty) * uvtop);
            }
        }
Пример #15
0
 public void AppendVertices(VectorArray3d v, VectorArray3f n = null, VectorArray3f c = null, VectorArray2f uv = null)
 {
     Vertices.Add(v.array);
     if (n != null && HasVertexNormals)
     {
         Normals.Add(n.array);
     }
     else if (HasVertexNormals)
     {
         Normals.Add(new float[] { 0, 1, 0 }, v.Count);
     }
     if (c != null && HasVertexColors)
     {
         Colors.Add(c.array);
     }
     else if (HasVertexColors)
     {
         Normals.Add(new float[] { 1, 1, 1 }, v.Count);
     }
     if (uv != null && HasVertexUVs)
     {
         UVs.Add(uv.array);
     }
     else if (HasVertexUVs)
     {
         UVs.Add(new float[] { 0, 0 }, v.Count);
     }
 }
Пример #16
0
        override public void Generate()
        {
            bool bClosed       = ((EndAngleDeg - StartAngleDeg) > 359.99f);
            int  nRingSize     = (NoSharedVertices && bClosed) ? Slices + 1 : Slices;
            int  nTipVertices  = (NoSharedVertices) ? nRingSize : 1;
            int  nCapVertices  = (NoSharedVertices) ? Slices + 1 : 1;
            int  nFaceVertices = (NoSharedVertices && bClosed == false) ? 6 : 0;

            vertices = new VectorArray3d(nRingSize + nTipVertices + nCapVertices + nFaceVertices);
            uv       = new VectorArray2f(vertices.Count);
            normals  = new VectorArray3f(vertices.Count);

            int nConeTris = (NoSharedVertices) ? 2 * Slices : Slices;
            int nCapTris  = Slices;
            int nFaceTris = (bClosed == false) ? 2 : 0;

            triangles = new IndexArray3i(nConeTris + nCapTris + nFaceTris);

            float fTotalRange = (EndAngleDeg - StartAngleDeg) * math.MathUtil.Deg2Radf;
            float fStartRad   = StartAngleDeg * math.MathUtil.Deg2Radf;
            float fDelta      = (bClosed) ? fTotalRange / Slices : fTotalRange / (Slices - 1);

            // generate rings
            for (int k = 0; k < nRingSize; ++k)
            {
                float  angle = fStartRad + (float)k * fDelta;
                double cosa = Math.Cos(angle), sina = Math.Sin(angle);
                vertices[k] = new Vector3D(BaseRadius * cosa, 0, BaseRadius * sina);
                uv[k]       = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina));
                Vector3F n = new Vector3F(cosa * Height, BaseRadius / Height, sina * Height);
                n.Normalize();
                normals[k] = n;

                if (NoSharedVertices)
                {
                    vertices[nRingSize + k] = new Vector3D(0, Height, 0);
                    uv[nRingSize + k]       = new Vector2F(0.5f, 0.5f);
                    normals[nRingSize + k]  = n;
                }
            }
            if (NoSharedVertices == false)
            {
                vertices[nRingSize] = new Vector3D(0, Height, 0);
                normals[nRingSize]  = Vector3F.AxisY;
                uv[nRingSize]       = new Vector2F(0.5f, 0.5f);
            }

            // generate cylinder panels
            int ti = 0;

            if (NoSharedVertices)
            {
                for (int k = 0; k < nRingSize - 1; ++k)
                {
                    triangles.Set(ti++, k, k + 1, nRingSize + k + 1, Clockwise);
                    triangles.Set(ti++, k, nRingSize + k + 1, nRingSize + k, Clockwise);
                }
            }
            else
            {
                append_disc(Slices, nRingSize, 0, bClosed, !Clockwise, ref ti);
            }

            int nBottomC = nRingSize + nTipVertices;

            vertices[nBottomC] = new Vector3D(0, 0, 0);
            uv[nBottomC]       = new Vector2F(0.5f, 0.5f);
            normals[nBottomC]  = new Vector3F(0, -1, 0);

            if (NoSharedVertices)
            {
                int nStartB = nBottomC + 1;
                for (int k = 0; k < Slices; ++k)
                {
                    float  a = fStartRad + (float)k * fDelta;
                    double cosa = Math.Cos(a), sina = Math.Sin(a);
                    vertices[nStartB + k] = new Vector3D(BaseRadius * cosa, 0, BaseRadius * sina);
                    uv[nStartB + k]       = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina));
                    normals[nStartB + k]  = -Vector3F.AxisY;
                }
                append_disc(Slices, nBottomC, nStartB, bClosed, Clockwise, ref ti);

                // ugh this is very ugly but hard to see the pattern...
                if (bClosed == false)
                {
                    int nStartF = nStartB + Slices;
                    vertices[nStartF]     = vertices[nStartF + 4] = vertices[nBottomC];
                    vertices[nStartF + 1] = vertices[nStartF + 3] = new Vector3D(0, Height, 0);;
                    vertices[nStartF + 2] = vertices[0];;
                    vertices[nStartF + 5] = vertices[nRingSize - 1];
                    normals[nStartF]      = normals[nStartF + 1] = normals[nStartF + 2]
                                                                       = estimate_normal(nStartF, nStartF + 1, nStartF + 2);
                    normals[nStartF + 3] = normals[nStartF + 4] = normals[nStartF + 5]
                                                                      = estimate_normal(nStartF + 3, nStartF + 4, nStartF + 5);

                    uv[nStartF]     = uv[nStartF + 4] = new Vector2F(0, 0);
                    uv[nStartF + 1] = uv[nStartF + 3] = new Vector2F(0, 1);
                    uv[nStartF + 2] = uv[nStartF + 5] = new Vector2F(1, 0);

                    triangles.Set(ti++, nStartF + 0, nStartF + 1, nStartF + 2, !Clockwise);
                    triangles.Set(ti++, nStartF + 3, nStartF + 4, nStartF + 5, !Clockwise);
                }
            }
            else
            {
                append_disc(Slices, nBottomC, 0, bClosed, Clockwise, ref ti);
                if (bClosed == false)
                {
                    triangles.Set(ti++, nBottomC, nRingSize, 0, !Clockwise);
                    triangles.Set(ti++, nBottomC, nRingSize, nRingSize - 1, Clockwise);
                }
            }
        }
Пример #17
0
        public DMesh3 CreateMesh(List <Vector3d> path,
                                 List <Polygon2d> polys,
                                 VectorArray3d seam)
        {
            // Ignore first and last path/polys for mesh generation.
            // We just need the extra path positions to calculate a
            // continuous tangent at the seams.
            List <Vector3d> pathXZ = new List <Vector3d>();

            for (int i = 0; i < path.Count; i++)
            {
                pathXZ.Add(new Vector3d(path[i].x, 0, path[i].z));
            }

            int nVerts = path.Count - 2;
            int nPolys = polys.Count - 2;
            // Same VertexCount for all Polygons.
            int nSlices   = polys[0].VertexCount;
            int nPolySize = nSlices + 1;
            int nVecs     = nVerts * nPolySize;

            vertices = new VectorArray3d(nVecs);
            normals  = new VectorArray3f(nVecs);
            uv       = new VectorArray2f(nVecs);

            int quad_strips = nVerts - 1;
            int nSpanTris   = quad_strips * (2 * nSlices);

            triangles = new IndexArray3i(nSpanTris);

            Frame3f fCur         = new Frame3f(frame);
            double  pathLength   = CurveUtils.ArcLength(path.GetRange(1, nVerts));
            double  accum_path_u = 0;

            for (int ri = 0; ri < nPolys; ++ri)
            {
                int      si      = ri + 1; // actual path/polys index for mesh
                Vector3d tangent = CurveUtils.GetTangent(pathXZ, si);
                fCur.Origin = (Vector3f)path[si];
                fCur.AlignAxis(2, (Vector3f)tangent);

                int    nStartR      = ri * nPolySize;
                double accum_ring_v = 0;
                bool   copy         = ri == nPolys - 1;
                bool   paste        = ri == 0;

                for (int j = 0; j < nPolySize; ++j)
                {
                    int      k      = nStartR + j;
                    Vector2d pv     = polys[si].Vertices[j % nSlices];
                    Vector2d pvNext = polys[si].Vertices[(j + 1) % nSlices];
                    Vector3d v      = fCur.FromPlaneUV((Vector2f)pv, 2);
                    vertices[k] = v;
                    Vector3f n = (Vector3f)(v - fCur.Origin).Normalized;
                    normals[k]    = n;
                    uv[k]         = new Vector2f(accum_path_u, accum_ring_v);
                    accum_ring_v += (pv.Distance(pvNext) / polys[si].ArcLength);
                    if (copy)
                    {
                        Seam[j] = vertices[k];
                    }
                    else if (paste)
                    {
                        vertices[k] = seam[j];
                    }
                }
                double d = path[si].Distance(path[si + 1]);
                accum_path_u += d / pathLength;
            }

            int nStop = nVerts - 1;
            int ti    = 0;

            for (int ri = 0; ri < nStop; ++ri)
            {
                int r0 = ri * nPolySize;
                int r1 = r0 + nPolySize;
                for (int k = 0; k < nPolySize - 1; ++k)
                {
                    triangles.Set(ti++, r0 + k, r0 + k + 1, r1 + k + 1, Clockwise);
                    triangles.Set(ti++, r0 + k, r1 + k + 1, r1 + k, Clockwise);
                }
            }
            return(MakeDMesh());
        }
Пример #18
0
        override public void Generate()
        {
            bool bClosed       = ((EndAngleDeg - StartAngleDeg) > 359.99f);
            int  nRingSize     = (NoSharedVertices && bClosed) ? Slices + 1 : Slices;
            int  nCapVertices  = (NoSharedVertices) ? Slices + 1 : 1;
            int  nFaceVertices = (NoSharedVertices && bClosed == false) ? 8 : 0;

            vertices = new VectorArray3d(2 * nRingSize + 2 * nCapVertices + nFaceVertices);
            uv       = new VectorArray2f(vertices.Count);
            normals  = new VectorArray3f(vertices.Count);

            int nCylTris  = 2 * Slices;
            int nCapTris  = 2 * Slices;
            int nFaceTris = (bClosed == false) ? 4 : 0;

            triangles = new IndexArray3i(nCylTris + nCapTris + nFaceTris);
            groups    = new int[triangles.Count];

            float fTotalRange = (EndAngleDeg - StartAngleDeg) * math.MathUtil.Deg2Radf;
            float fStartRad   = StartAngleDeg * math.MathUtil.Deg2Radf;
            float fDelta      = (bClosed) ? fTotalRange / Slices : fTotalRange / (Slices - 1);

            // generate top and bottom rings for cylinder
            for (int k = 0; k < nRingSize; ++k)
            {
                float  angle = fStartRad + (float)k * fDelta;
                double cosa = Math.Cos(angle), sina = Math.Sin(angle);
                vertices[k]             = new Vector3D(BaseRadius * cosa, 0, BaseRadius * sina);
                vertices[nRingSize + k] = new Vector3D(TopRadius * cosa, Height, TopRadius * sina);
                float t = (float)k / (float)Slices;
                uv[k]             = new Vector2F(t, 0.0f);
                uv[nRingSize + k] = new Vector2F(t, 1.0f);
                Vector3F n = new Vector3F((float)cosa, 0, (float)sina);
                n.Normalize();
                normals[k] = normals[nRingSize + k] = n;
            }

            // generate cylinder panels
            int ti = 0;

            for (int k = 0; k < nRingSize - 1; ++k)
            {
                groups[ti] = 1;
                triangles.Set(ti++, k, k + 1, nRingSize + k + 1, Clockwise);
                groups[ti] = 1;
                triangles.Set(ti++, k, nRingSize + k + 1, nRingSize + k, Clockwise);
            }
            if (bClosed && NoSharedVertices == false)        // close disc if we went all the way
            {
                groups[ti] = 1;
                triangles.Set(ti++, nRingSize - 1, 0, nRingSize, Clockwise);
                groups[ti] = 1;
                triangles.Set(ti++, nRingSize - 1, nRingSize, 2 * nRingSize - 1, Clockwise);
            }

            int nBottomC = 2 * nRingSize;

            vertices[nBottomC] = new Vector3D(0, 0, 0);
            uv[nBottomC]       = new Vector2F(0.5f, 0.5f);
            normals[nBottomC]  = new Vector3F(0, -1, 0);

            int nTopC = 2 * nRingSize + 1;

            vertices[nTopC] = new Vector3D(0, Height, 0);
            uv[nTopC]       = new Vector2F(0.5f, 0.5f);
            normals[nTopC]  = new Vector3F(0, 1, 0);

            if (NoSharedVertices)
            {
                int nStartB = 2 * nRingSize + 2;
                for (int k = 0; k < Slices; ++k)
                {
                    float  a = fStartRad + (float)k * fDelta;
                    double cosa = Math.Cos(a), sina = Math.Sin(a);
                    vertices[nStartB + k] = new Vector3D(BaseRadius * cosa, 0, BaseRadius * sina);
                    uv[nStartB + k]       = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina));
                    normals[nStartB + k]  = -Vector3F.AxisY;
                }
                append_disc(Slices, nBottomC, nStartB, bClosed, Clockwise, ref ti, 2);

                int nStartT = 2 * nRingSize + 2 + Slices;
                for (int k = 0; k < Slices; ++k)
                {
                    float  a = fStartRad + (float)k * fDelta;
                    double cosa = Math.Cos(a), sina = Math.Sin(a);
                    vertices[nStartT + k] = new Vector3D(TopRadius * cosa, Height, TopRadius * sina);
                    uv[nStartT + k]       = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina));
                    normals[nStartT + k]  = Vector3F.AxisY;
                }
                append_disc(Slices, nTopC, nStartT, bClosed, !Clockwise, ref ti, 3);

                // ugh this is very ugly but hard to see the pattern...
                if (bClosed == false)
                {
                    int nStartF = 2 * nRingSize + 2 + 2 * Slices;
                    vertices[nStartF]     = vertices[nStartF + 5] = vertices[nBottomC];
                    vertices[nStartF + 1] = vertices[nStartF + 4] = vertices[nTopC];
                    vertices[nStartF + 2] = vertices[nRingSize];
                    vertices[nStartF + 3] = vertices[0];
                    vertices[nStartF + 6] = vertices[nRingSize - 1];
                    vertices[nStartF + 7] = vertices[2 * nRingSize - 1];
                    normals[nStartF]      = normals[nStartF + 1] = normals[nStartF + 2] = normals[nStartF + 3]
                                                                                              = estimate_normal(nStartF, nStartF + 1, nStartF + 2);
                    normals[nStartF + 4] = normals[nStartF + 5] = normals[nStartF + 6] = normals[nStartF + 7]
                                                                                             = estimate_normal(nStartF + 4, nStartF + 5, nStartF + 6);

                    uv[nStartF]     = uv[nStartF + 5] = new Vector2F(0, 0);
                    uv[nStartF + 1] = uv[nStartF + 4] = new Vector2F(0, 1);
                    uv[nStartF + 2] = uv[nStartF + 7] = new Vector2F(1, 1);
                    uv[nStartF + 3] = uv[nStartF + 6] = new Vector2F(1, 0);

                    append_rectangle(nStartF + 0, nStartF + 1, nStartF + 2, nStartF + 3, !Clockwise, ref ti, 4);
                    append_rectangle(nStartF + 4, nStartF + 5, nStartF + 6, nStartF + 7, !Clockwise, ref ti, 5);
                }
            }
            else
            {
                append_disc(Slices, nBottomC, 0, bClosed, Clockwise, ref ti, 2);
                append_disc(Slices, nTopC, nRingSize, bClosed, !Clockwise, ref ti, 3);
                if (bClosed == false)
                {
                    append_rectangle(nBottomC, 0, nRingSize, nTopC, Clockwise, ref ti, 4);
                    append_rectangle(nRingSize - 1, nBottomC, nTopC, 2 * nRingSize - 1, Clockwise, ref ti, 5);
                }
            }
        }
Пример #19
0
        override public void Generate()
        {
            if (Polygon == null)
            {
                Polygon = Polygon2d.MakeCircle(1.0f, 8);
            }

            int Slices       = Polygon.VertexCount;
            int nRings       = Vertices.Count;
            int nRingSize    = (NoSharedVertices) ? Slices + 1 : Slices;
            int nCapVertices = (NoSharedVertices) ? Slices + 1 : 1;

            if (Capped == false)
            {
                nCapVertices = 0;
            }

            vertices = new VectorArray3d(nRings * nRingSize + 2 * nCapVertices);
            uv       = new VectorArray2f(vertices.Count);
            normals  = new VectorArray3f(vertices.Count);

            int nSpanTris = (Vertices.Count - 1) * (2 * Slices);
            int nCapTris  = (Capped) ? 2 * Slices : 0;

            triangles = new IndexArray3i(nSpanTris + nCapTris);

            Frame3f  fCur = new Frame3f(Frame);
            Vector3D dv   = CurveUtils.GetTangent(Vertices, 0);;

            fCur.Origin = (Vector3F)Vertices[0];
            fCur.AlignAxis(2, (Vector3F)dv);
            Frame3f fStart = new Frame3f(fCur);

            // generate tube
            for (int ri = 0; ri < nRings; ++ri)
            {
                // propagate frame
                if (ri != 0)
                {
                    Vector3D tan = CurveUtils.GetTangent(Vertices, ri);
                    fCur.Origin = (Vector3F)Vertices[ri];
                    if (ri == 11)
                    {
                        dv = tan;
                    }
                    fCur.AlignAxis(2, (Vector3F)tan);
                }

                float uv_along = (float)ri / (float)(nRings - 1);

                // generate vertices
                int nStartR = ri * nRingSize;
                for (int j = 0; j < nRingSize; ++j)
                {
                    float uv_around = (float)j / (float)(nRings);

                    int      k  = nStartR + j;
                    Vector2D pv = Polygon.Vertices[j % Slices];
                    Vector3D v  = fCur.FromFrameP((Vector2F)pv, 2);
                    vertices[k] = v;
                    uv[k]       = new Vector2F(uv_along, uv_around);
                    Vector3F n = (Vector3F)(v - fCur.Origin).Normalized;
                    normals[k] = n;
                }
            }


            // generate triangles
            int ti = 0;

            for (int ri = 0; ri < nRings - 1; ++ri)
            {
                int r0 = ri * nRingSize;
                int r1 = r0 + nRingSize;
                for (int k = 0; k < nRingSize - 1; ++k)
                {
                    triangles.Set(ti++, r0 + k, r0 + k + 1, r1 + k + 1, Clockwise);
                    triangles.Set(ti++, r0 + k, r1 + k + 1, r1 + k, Clockwise);
                }
                if (NoSharedVertices == false)        // close disc if we went all the way
                {
                    triangles.Set(ti++, r1 - 1, r0, r1, Clockwise);
                    triangles.Set(ti++, r1 - 1, r1, r1 + nRingSize - 1, Clockwise);
                }
            }

            if (Capped)
            {
                // add endcap verts
                int nBottomC = nRings * nRingSize;
                vertices[nBottomC]  = fStart.Origin;
                uv[nBottomC]        = new Vector2F(0.5f, 0.5f);
                normals[nBottomC]   = -fStart.Z;
                startCapCenterIndex = nBottomC;

                int nTopC = nBottomC + 1;
                vertices[nTopC]   = fCur.Origin;
                uv[nTopC]         = new Vector2F(0.5f, 0.5f);
                normals[nTopC]    = fCur.Z;
                endCapCenterIndex = nTopC;

                if (NoSharedVertices)
                {
                    // duplicate first loop and make a fan w/ bottom-center
                    int nExistingB = 0;
                    int nStartB    = nTopC + 1;
                    for (int k = 0; k < Slices; ++k)
                    {
                        vertices[nStartB + k] = vertices[nExistingB + k];
                        uv[nStartB + k]       = (Vector2F)Polygon.Vertices[k].Normalized;
                        normals[nStartB + k]  = normals[nBottomC];
                    }
                    append_disc(Slices, nBottomC, nStartB, true, Clockwise, ref ti);

                    // duplicate second loop and make fan
                    int nExistingT = nRingSize * (nRings - 1);
                    int nStartT    = nStartB + Slices;
                    for (int k = 0; k < Slices; ++k)
                    {
                        vertices[nStartT + k] = vertices[nExistingT + k];
                        uv[nStartT + k]       = (Vector2F)Polygon.Vertices[k].Normalized;
                        normals[nStartT + k]  = normals[nTopC];
                    }
                    append_disc(Slices, nTopC, nStartT, true, !Clockwise, ref ti);
                }
                else
                {
                    append_disc(Slices, nBottomC, 0, true, Clockwise, ref ti);
                    append_disc(Slices, nTopC, nRingSize * (nRings - 1), true, !Clockwise, ref ti);
                }
            }
        }