Exemple #1
0
        List <IndexTriangle> StitchCircles(List <IndexedVertex> circle1, List <IndexedVertex> circle2)
        {
            // Create triangles that connect circle1 to circle2, forming a band of a surface.
            if (circle1.Count != circle2.Count)
            {
                throw new System.Exception("Circles do not have the same number of vertices.");
            }

            List <IndexTriangle> triangles = new List <IndexTriangle>();

            for (int i = 0; i < circle1.Count; i++)
            {
                // Create the triangles that have 2 points each on circle1.
                // These all have the ordering (c2[i], c1[i+1], c1[i]).
                int           iPlus = (i + 1) % circle1.Count;
                IndexedVertex iv1   = circle2[i];
                IndexedVertex iv2   = circle1[iPlus];
                IndexedVertex iv3   = circle1[i];
                IndexTriangle tri   = new IndexTriangle(iv1, iv2, iv3);
                triangles.Add(tri);

                // Create the triangles that have 2 points each on circle2.
                // These have the ordering (c2[i], c2[i+1], c1[i+1].
                iv1 = circle2[i];
                iv2 = circle2[iPlus];
                iv3 = circle1[iPlus];
                tri = new IndexTriangle(iv1, iv2, iv3);
                triangles.Add(tri);
            }
            return(triangles);
        }
Exemple #2
0
        List <IndexTriangle> CloseCylinderCaps(CylinderMesh cylinder, List <IndexedVertex> verts)
        {
            List <IndexTriangle> triangles = new List <IndexTriangle>();

            List <IndexedVertex> bottomCircle = cylinder.circleCuts[0];
            List <IndexedVertex> topCircle    = cylinder.circleCuts[cylinder.circleCuts.Count - 1];

            // Compute center point of bottom circle.
            Vector3 bottomCenter = Vector3.zero;

            foreach (IndexedVertex v in bottomCircle)
            {
                bottomCenter += v.vertex;
            }
            bottomCenter /= bottomCircle.Count;

            // Compute center point of top circle.
            Vector3 topCenter = Vector3.zero;

            foreach (IndexedVertex v in topCircle)
            {
                topCenter += v.vertex;
            }
            topCenter /= topCircle.Count;

            // Add the two points to the mesh.
            IndexedVertex bottomCenterVert = new IndexedVertex(bottomCenter, currentIndex);

            currentIndex++;
            IndexedVertex topCenterVert = new IndexedVertex(topCenter, currentIndex);

            currentIndex++;

            verts.Add(bottomCenterVert);
            verts.Add(topCenterVert);

            // Add triangle fans.
            for (int i = 0; i < bottomCircle.Count; i++)
            {
                // Bottom circle gets CCW order
                int iPlus = (i + 1) % bottomCircle.Count;

                IndexedVertex i1 = bottomCenterVert;
                IndexedVertex i2 = bottomCircle[i];
                IndexedVertex i3 = bottomCircle[iPlus];

                IndexTriangle tri = new IndexTriangle(i1, i2, i3);
                triangles.Add(tri);
            }

            for (int i = 0; i < topCircle.Count; i++)
            {
                // Top circle gets CW order
                int iPlus = (i + 1) % topCircle.Count;

                IndexedVertex i1 = topCenterVert;
                IndexedVertex i2 = topCircle[iPlus];
                IndexedVertex i3 = topCircle[i];

                IndexTriangle tri = new IndexTriangle(i1, i2, i3);
                triangles.Add(tri);
            }

            return(triangles);
        }
Exemple #3
0
        List <IndexTriangle> stitchCylinderEnds(CylinderMesh outer, CylinderMesh inner)
        {
            if (outer.circleCuts.Count != inner.circleCuts.Count)
            {
                throw new System.Exception("Cylinders do not have same number of cuts.");
            }
            int numCuts = outer.circleCuts.Count;
            List <IndexTriangle> triangles = new List <IndexTriangle>();

            List <IndexedVertex> topOuter = outer.circleCuts[numCuts - 1];
            List <IndexedVertex> topInner = inner.circleCuts[numCuts - 1];

            topVerts = topOuter.ConvertAll <Vector3>(new Converter <IndexedVertex, Vector3>(IndexedVertex.toVector3));

            if (topOuter.Count != topInner.Count)
            {
                throw new System.Exception("Circles do not have same number of vertices.");
            }

            // Since the cuts are not necessarily aligned (in the case of curvature
            // or torsion changes), we want to stitch using the closest pairs of vertices.
            // Since we start with outer vertex i = 0, find the index of the inner vertex
            // closest to outer 0.
            Vector3 outer0top       = topOuter[0].vertex;
            int     topInnerOffset  = 0;
            float   closestDistance = Vector3.Distance(outer0top, topInner[0].vertex);

            for (int i = 0; i < topInner.Count; i++)
            {
                float dist = Vector3.Distance(topInner[i].vertex, outer0top);
                if (dist < closestDistance)
                {
                    closestDistance = dist;
                    topInnerOffset  = i;
                }
            }

            // To join the top rim, we need to add the triangles with
            // counterclockwise ordering, since the vertices are clockwise
            // when viewed from below (not above).
            for (int outerI = 0; outerI < topOuter.Count; outerI++)
            {
                int outerIPlus = (outerI + 1) % topOuter.Count;
                int innerI     = (outerI + topInnerOffset) % topInner.Count;
                int innerIPlus = (innerI + 1) % topInner.Count;

                // The triangles with two vertices in the outer circle have
                // the order outer[i], inner[i], outer[i+1].
                IndexedVertex iv1 = topOuter[outerI];
                IndexedVertex iv2 = topInner[innerI];
                IndexedVertex iv3 = topOuter[outerIPlus];
                IndexTriangle tri = new IndexTriangle(iv1, iv2, iv3);
                triangles.Add(tri);

                // The triangles with two vertices in the inner circle have
                // the order inner[i], inner[i+1], outer[i+1].
                iv1 = topInner[innerI];
                iv2 = topInner[innerIPlus];
                iv3 = topOuter[outerIPlus];
                tri = new IndexTriangle(iv1, iv2, iv3);
                triangles.Add(tri);
            }

            List <IndexedVertex> bottomOuter = outer.circleCuts[0];
            List <IndexedVertex> bottomInner = inner.circleCuts[0];

            bottomVerts = bottomOuter.ConvertAll <Vector3>(new Converter <IndexedVertex, Vector3>(IndexedVertex.toVector3));

            if (bottomOuter.Count != bottomInner.Count)
            {
                throw new System.Exception("Circles do not have same number of vertices.");
            }

            // Same procedure as top ring: find starting vertex closest to
            // vertex 0 of outer ring.
            Vector3 outer0bottom      = bottomOuter[0].vertex;
            int     bottomInnerOffset = 0;

            closestDistance = Vector3.Distance(outer0bottom, bottomInner[0].vertex);

            for (int i = 0; i < bottomInner.Count; i++)
            {
                float dist = Vector3.Distance(bottomInner[i].vertex, outer0bottom);
                if (dist < closestDistance)
                {
                    closestDistance   = dist;
                    bottomInnerOffset = i;
                }
            }

            // To join the bottom faces, we add triangles with vertices in clockwise order.
            for (int outerI = 0; outerI < bottomOuter.Count; outerI++)
            {
                int outerIPlus = (outerI + 1) % bottomOuter.Count;
                int innerI     = (outerI + bottomInnerOffset) % bottomInner.Count;
                int innerIPlus = (innerI + 1) % bottomInner.Count;

                // The triangles with two vertices in the outer circle have
                // the order outer[i], outer[i+1], inner[i].
                IndexedVertex iv1 = bottomOuter[outerI];
                IndexedVertex iv2 = bottomOuter[outerIPlus];
                IndexedVertex iv3 = bottomInner[innerI];
                IndexTriangle tri = new IndexTriangle(iv1, iv2, iv3);
                triangles.Add(tri);

                // The triangles with two vertices in the inner circle have
                // the order inner[i], outer[i+1], inner[i+1].
                iv1 = bottomInner[innerI];
                iv2 = bottomOuter[outerIPlus];
                iv3 = bottomInner[innerIPlus];
                tri = new IndexTriangle(iv1, iv2, iv3);
                triangles.Add(tri);
            }

            return(triangles);
        }
Exemple #4
0
        /// <summary>
        /// Create a set of vertices arranged evenly spaced in a circle, with the specified radius,
        /// centered at centerPoint, and with the specified normal direction. The number of vertices
        /// is given by verticesPerCircle.
        /// </summary>
        /// <param name="centerPoint"></param>
        /// <param name="direction"></param>
        /// <param name="radius"></param>
        /// <returns></returns>
        List <IndexedVertex> GenerateCircle(int circNum, Vector3 centerPoint, Vector3 direction,
                                            Vector3 normal, float radius, bool addInnerGrooves = false, bool addOuterGroove = false)
        {
            float angleStep  = (2 * Mathf.PI) / Constants.VERTS_PER_CIRCLE;
            float degreeStep = angleStep * Mathf.Rad2Deg;

            int twistCuts = Mathf.CeilToInt(Mathf.Abs(nextTwistAngle) / degreeStep);

            twistCuts *= Mathf.RoundToInt(Mathf.Sign(nextTwistAngle));

            List <IndexedVertex> verts = new List <IndexedVertex>();

            int grooveRange = Constants.GROOVE_CUT_RADIUS;

            // First create points in a circle in the XY plane, facing the forward direction.
            // Then apply the rotation that will rotate the normal onto the desired direction.
            // Finally, offset it in space to the desired location.
            Quaternion circleRotation = Quaternion.FromToRotation(Vector3.forward, direction);
            Vector3    initNormal     = Vector3.up;
            Vector3    rotatedNormal  = circleRotation * initNormal;

            float      angle          = TelescopeUtils.AngleBetween(rotatedNormal, normal, direction);
            Quaternion normalRotation = Quaternion.AngleAxis(angle, direction);

            for (int i = 0; i < Constants.VERTS_PER_CIRCLE; i++)
            {
                float currentAngle = i * angleStep;
                float radiusOffset = 0;
                if (i < grooveRange ||
                    Mathf.Abs(i - Constants.VERTS_PER_CIRCLE / 2) < grooveRange ||
                    Mathf.Abs(i - Constants.VERTS_PER_CIRCLE) < grooveRange)
                {
                    if (addInnerGrooves)
                    {
                        radiusOffset = (thickness - Constants.SHELL_GAP) * Constants.INDENT_RATIO;
                    }
                    else if (addOuterGroove)
                    {
                        radiusOffset = (thickness - Constants.SHELL_GAP / 2) * Constants.INDENT_RATIO;
                    }
                }

                else if (circNum >= Constants.CUTS_PER_CYLINDER - 1 &&
                         circNum < Constants.CUTS_PER_CYLINDER + Constants.FIN_CUTS)
                {
                    if (addInnerGrooves &&
                        (IsInRadius(i, 0, twistCuts, grooveRange) ||
                         IsInRadius(i, Constants.VERTS_PER_CIRCLE,
                                    Constants.VERTS_PER_CIRCLE + twistCuts, grooveRange) ||
                         IsInRadius(i, Constants.VERTS_PER_CIRCLE / 2,
                                    Constants.VERTS_PER_CIRCLE / 2 + twistCuts, grooveRange)))
                    {
                        radiusOffset = (thickness - Constants.SHELL_GAP) * Constants.INDENT_RATIO;
                    }
                }

                // Make the vertices in clockwise order
                Vector3 vert = new Vector3(Mathf.Cos(currentAngle), -Mathf.Sin(currentAngle));
                // Scale by radius.
                vert *= (radius + radiusOffset);
                // Rotate it to orbit the desired direction.
                vert = circleRotation * vert;
                // Rotate it again so that the curvature normal is aligned.
                vert = normalRotation * vert;
                // Offset in space to the center point.
                vert += centerPoint;
                IndexedVertex iv = new IndexedVertex(vert, currentIndex);
                currentIndex++;
                verts.Add(iv);
            }
            return(verts);
        }
Exemple #5
0
 public IndexTriangle(IndexedVertex iv1, IndexedVertex iv2, IndexedVertex iv3)
 {
     i1 = iv1.index;
     i2 = iv2.index;
     i3 = iv3.index;
 }