Beispiel #1
0
 public void AppendTriangles(IndexArray3i t, int[] groups = null)
 {
     Triangles.Add(t.array);
     if (HasTriangleGroups)
     {
         if (groups != null)
         {
             FaceGroups.Add(groups);
         }
         else
         {
             FaceGroups.Add(0, t.Count);
         }
     }
 }
Beispiel #2
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);
                }
            }
        }
Beispiel #3
0
        private SimpleMesh ToMesh()
        {
            int vcount            = GetVertexCount();
            MdalVertexIterator vi = Mdal.MDAL_M_vertexIterator(this);
            VectorArray3d      v  = vi.GetVertexes(vcount);
            bool          hasColors;
            VectorArray3f c    = GetColors(vcount, out hasColors);
            SimpleMesh    mesh = new SimpleMesh();

            mesh.AppendVertices(v, null, c);
            int fcount           = GetFaceCount();
            MdalFaceIterator fi  = Mdal.MDAL_M_faceIterator(this);
            IndexArray3i     tri = fi.GetTris(fcount, Mdal.MDAL_M_faceVerticesMaximumCount(this));

            mesh.AppendTriangles(tri);
            return(mesh);
        }
Beispiel #4
0
        void Complete(IntermediateMeshGenerator intermediate)
        {
            vertices  = new VectorArray3d(intermediate.Vertices.Count);
            normals   = new VectorArray3f(intermediate.Normals.Count);
            triangles = new IndexArray3i(intermediate.Triangles.Count);

            for (int idx = 0; idx < intermediate.Vertices.Count; idx++)
            {
                vertices[idx] = intermediate.Vertices[idx];
            }
            for (int idx = 0; idx < intermediate.Normals.Count; idx++)
            {
                normals[idx] = intermediate.Normals[idx];
            }
            for (int idx = 0; idx < intermediate.Triangles.Count; idx++)
            {
                triangles[idx] = intermediate.Triangles[idx];
            }
        }
Beispiel #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);
            }
        }
Beispiel #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);
            }
        }
Beispiel #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);
            }
        }
Beispiel #8
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);
                }
            }
        }
Beispiel #9
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);
                }
            }
        }
Beispiel #10
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);
                }
            }
        }
Beispiel #11
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);
                }
            }
        }
Beispiel #12
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());
        }
Beispiel #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);
            }
        }
Beispiel #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);
            }
        }
Beispiel #15
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);
                }
            }
        }