Beispiel #1
0
        public static Mesh CreateWireTriangularPrism(Vector3 baseCenter, float baseWidth, float baseDepth, float topWidth, float topDepth, float height, Color color)
        {
            baseWidth = Mathf.Max(Mathf.Abs(baseWidth), 1e-4f);
            baseDepth = Mathf.Max(Mathf.Abs(baseDepth), 1e-4f);
            topWidth  = Mathf.Max(Mathf.Abs(topWidth), 1e-4f);
            topDepth  = Mathf.Max(Mathf.Abs(topDepth), 1e-4f);
            height    = Mathf.Max(Mathf.Abs(height), 1e-4f);

            List <Vector3> cornerPoints  = PrismMath.CalcTriangPrismCornerPoints(baseCenter, baseWidth, baseDepth, topWidth, topDepth, height, Quaternion.identity);
            Vector3        baseLeftPt    = cornerPoints[(int)TriangularPrismCorner.BaseLeft];
            Vector3        baseRightPt   = cornerPoints[(int)TriangularPrismCorner.BaseRight];
            Vector3        baseForwardPt = cornerPoints[(int)TriangularPrismCorner.BaseForward];

            Vector3 topLeftPt    = cornerPoints[(int)TriangularPrismCorner.TopLeft];
            Vector3 topRightPt   = cornerPoints[(int)TriangularPrismCorner.TopRight];
            Vector3 topForwardPt = cornerPoints[(int)TriangularPrismCorner.TopForward];

            Vector3[] positions = new Vector3[]
            {
                baseLeftPt, baseForwardPt, baseRightPt,
                topLeftPt, topForwardPt, topRightPt
            };

            int[] indices = new int[] { 0, 1, 1, 2, 2, 0, 3, 4, 4, 5, 5, 3, 0, 3, 1, 4, 2, 5 };

            Mesh mesh = new Mesh();

            mesh.vertices = positions;
            mesh.colors   = ColorEx.GetFilledColorArray(positions.Length, color);
            mesh.SetIndices(indices, MeshTopology.Lines, 0);
            mesh.UploadMeshData(false);

            return(mesh);
        }
Beispiel #2
0
        public static Mesh CreateWirePyramid(Vector3 baseCenter, float baseWidth, float baseDepth, float height, Color color)
        {
            baseWidth = Mathf.Max(Mathf.Abs(baseWidth), 1e-4f);
            baseDepth = Mathf.Max(Mathf.Abs(baseDepth), 1e-4f);
            height    = Mathf.Max(Mathf.Abs(height), 1e-4f);

            float halfBaseWidth = baseWidth * 0.5f;
            float halfBaseDepth = baseDepth * 0.5f;

            Vector3[] positions = new Vector3[]
            {
                baseCenter - Vector3.right * halfBaseWidth - Vector3.forward * halfBaseDepth,
                baseCenter + Vector3.right * halfBaseWidth - Vector3.forward * halfBaseDepth,
                baseCenter + Vector3.right * halfBaseWidth + Vector3.forward * halfBaseDepth,
                baseCenter - Vector3.right * halfBaseWidth + Vector3.forward * halfBaseDepth,
                baseCenter + Vector3.up * height
            };

            int[] indices = new int[] { 0, 1, 1, 2, 2, 3, 3, 0, 0, 4, 1, 4, 2, 4, 3, 4 };

            Mesh mesh = new Mesh();

            mesh.vertices = positions;
            mesh.colors   = ColorEx.GetFilledColorArray(positions.Length, color);
            mesh.SetIndices(indices, MeshTopology.Lines, 0);
            mesh.UploadMeshData(false);

            return(mesh);
        }
Beispiel #3
0
        public static Mesh CreateWireCircleXY(float circleRadius, int numBorderPoints, Color color)
        {
            if (circleRadius < 1e-4f || numBorderPoints < 4)
            {
                return(null);
            }

            Vector3[] positions = new Vector3[numBorderPoints];
            int[]     indices   = new int[numBorderPoints];

            float angleStep = 360.0f / (numBorderPoints - 1);

            for (int ptIndex = 0; ptIndex < numBorderPoints; ++ptIndex)
            {
                float angle = angleStep * ptIndex * Mathf.Deg2Rad;
                positions[ptIndex] = new Vector3(Mathf.Sin(angle) * circleRadius, Mathf.Cos(angle) * circleRadius, 0.0f);
                indices[ptIndex]   = ptIndex;
            }

            Mesh mesh = new Mesh();

            mesh.vertices = positions;
            mesh.colors   = ColorEx.GetFilledColorArray(numBorderPoints, color);
            mesh.SetIndices(indices, MeshTopology.LineStrip, 0);
            mesh.UploadMeshData(false);

            return(mesh);
        }
Beispiel #4
0
        public static Mesh CreateCoordSystemAxesLines(float axisLength, Color color)
        {
            if (axisLength < 1e-4f)
            {
                return(null);
            }

            Vector3[] positions = new Vector3[]
            {
                Vector3.zero,
                Vector3.right *axisLength,
                Vector3.up *axisLength,
                Vector3.forward *axisLength
            };

            int[] indices = new int[]
            {
                0, 1,
                0, 2,
                0, 3
            };

            Mesh mesh = new Mesh();

            mesh.vertices = positions;
            mesh.colors   = ColorEx.GetFilledColorArray(4, color);
            mesh.SetIndices(indices, MeshTopology.Lines, 0);
            mesh.UploadMeshData(false);

            return(mesh);
        }
Beispiel #5
0
        public static Mesh CreateWireQuadXY(Vector3 center, Vector2 size, Color color)
        {
            Vector2 halfSize = size * 0.5f;

            Vector3[] positions = new Vector3[]
            {
                center - Vector3.right * halfSize.x - Vector3.up * halfSize.y,
                center - Vector3.right * halfSize.x + Vector3.up * halfSize.y,
                center + Vector3.right * halfSize.x + Vector3.up * halfSize.y,
                center + Vector3.right * halfSize.x - Vector3.up * halfSize.y
            };

            int[] indices = new int[]
            {
                0, 1, 1, 2, 2, 3, 3, 0
            };

            Mesh mesh = new Mesh();

            mesh.vertices = positions;
            mesh.colors   = ColorEx.GetFilledColorArray(4, color);
            mesh.SetIndices(indices, MeshTopology.Lines, 0);
            mesh.UploadMeshData(false);

            return(mesh);
        }
Beispiel #6
0
        public static Mesh CreateLine(Vector3 startPoint, Vector3 endPoint, Color color)
        {
            Mesh mesh = new Mesh();

            mesh.vertices = new Vector3[] { startPoint, endPoint };
            mesh.colors   = ColorEx.GetFilledColorArray(2, color);
            mesh.SetIndices(new int[] { 0, 1 }, MeshTopology.Lines, 0);
            mesh.UploadMeshData(false);

            return(mesh);
        }
Beispiel #7
0
        public static Mesh CreateCircleXY(float circleRadius, int numBorderPoints, Color color)
        {
            if (circleRadius < 1e-4f || numBorderPoints < 4)
            {
                return(null);
            }

            int numVerts     = numBorderPoints + 1;
            int numTriangles = numBorderPoints - 1;

            Vector3[] positions = new Vector3[numBorderPoints + 1];
            Vector3[] normals   = new Vector3[positions.Length];
            int[]     indices   = new int[numTriangles * 3];

            int indexPtr = 0;

            positions[0] = Vector3.zero;
            float angleStep = 360.0f / (numBorderPoints - 1);

            for (int ptIndex = 0; ptIndex < numBorderPoints; ++ptIndex)
            {
                float angle = angleStep * ptIndex * Mathf.Deg2Rad;

                int vertIndex = ptIndex + 1;
                positions[vertIndex] = new Vector3(Mathf.Sin(angle) * circleRadius, Mathf.Cos(angle) * circleRadius, 0.0f);
                normals[vertIndex]   = Vector3.forward;
            }

            for (int vertIndex = 1; vertIndex < numVerts - 1; ++vertIndex)
            {
                indices[indexPtr++] = 0;
                indices[indexPtr++] = vertIndex;
                indices[indexPtr++] = vertIndex + 1;
            }

            Mesh mesh = new Mesh();

            mesh.vertices = positions;
            mesh.colors   = ColorEx.GetFilledColorArray(positions.Length, color);
            mesh.normals  = normals;
            mesh.SetIndices(indices, MeshTopology.Triangles, 0);
            mesh.UploadMeshData(false);

            return(mesh);
        }
Beispiel #8
0
        public static Mesh CreateQuadXZ(float width, float depth, Color color)
        {
            if (width < 1e-4f)
            {
                return(null);
            }
            if (depth < 1e-4f)
            {
                return(null);
            }

            float halfWidth = width * 0.5f;
            float halfDepth = depth * 0.5f;

            Vector3[] positions = new Vector3[]
            {
                -Vector3.right * halfWidth - Vector3.forward * halfDepth,
                -Vector3.right * halfWidth + Vector3.forward * halfDepth,
                Vector3.right *halfWidth + Vector3.forward * halfDepth,
                Vector3.right *halfWidth - Vector3.forward * halfDepth
            };

            Vector3[] normals = new Vector3[]
            {
                Vector3.up, Vector3.up, Vector3.up, Vector3.up
            };

            Vector2[] uvs = new Vector2[]
            {
                Vector2.zero, new Vector2(0.0f, 1.0f), new Vector2(1.0f, 1.0f), new Vector2(1.0f, 0.0f)
            };

            Mesh mesh = new Mesh();

            mesh.vertices = positions;
            mesh.normals  = normals;
            mesh.uv       = uvs;
            mesh.colors   = ColorEx.GetFilledColorArray(4, color);
            mesh.SetIndices(new int[] { 0, 1, 2, 2, 3, 0 }, MeshTopology.Triangles, 0);
            mesh.UploadMeshData(false);

            return(mesh);
        }
Beispiel #9
0
        public static Mesh CreatePyramid(Vector3 baseCenter, float baseWidth, float baseDepth, float height, Color color)
        {
            baseWidth = Mathf.Max(Mathf.Abs(baseWidth), 1e-4f);
            baseDepth = Mathf.Max(Mathf.Abs(baseDepth), 1e-4f);
            height    = Mathf.Max(Mathf.Abs(height), 1e-4f);

            float halfBaseWidth = baseWidth * 0.5f;
            float halfBaseDepth = baseDepth * 0.5f;

            Vector3 tipPosition = baseCenter + Vector3.up * height;

            Vector3[] positions = new Vector3[]
            {
                // Front face
                tipPosition,
                baseCenter + Vector3.right * halfBaseWidth - Vector3.forward * halfBaseDepth,
                baseCenter - Vector3.right * halfBaseWidth - Vector3.forward * halfBaseDepth,

                // Right face
                tipPosition,
                baseCenter + Vector3.right * halfBaseWidth + Vector3.forward * halfBaseDepth,
                baseCenter + Vector3.right * halfBaseWidth - Vector3.forward * halfBaseDepth,

                // Back face
                tipPosition,
                baseCenter - Vector3.right * halfBaseWidth + Vector3.forward * halfBaseDepth,
                baseCenter + Vector3.right * halfBaseWidth + Vector3.forward * halfBaseDepth,

                // Left face
                tipPosition,
                baseCenter - Vector3.right * halfBaseWidth - Vector3.forward * halfBaseDepth,
                baseCenter - Vector3.right * halfBaseWidth + Vector3.forward * halfBaseDepth,

                // Bottom face
                baseCenter - Vector3.right * halfBaseWidth - Vector3.forward * halfBaseDepth,
                baseCenter + Vector3.right * halfBaseWidth - Vector3.forward * halfBaseDepth,
                baseCenter + Vector3.right * halfBaseWidth + Vector3.forward * halfBaseDepth,
                baseCenter - Vector3.right * halfBaseWidth + Vector3.forward * halfBaseDepth
            };

            int[] indices = new int[]
            {
                0, 1, 2,
                3, 4, 5,
                6, 7, 8,
                9, 10, 11,

                12, 13, 14,
                12, 14, 15
            };

            Vector3[] normals = new Vector3[positions.Length];
            for (int triangleIndex = 0; triangleIndex < 4; ++triangleIndex)
            {
                int index0 = indices[triangleIndex * 3];
                int index1 = indices[triangleIndex * 3 + 1];
                int index2 = indices[triangleIndex * 3 + 2];

                Vector3 edge0  = positions[index1] - positions[index0];
                Vector3 edge1  = positions[index2] - positions[index0];
                Vector3 normal = Vector3.Cross(edge0, edge1).normalized;

                normals[index0] = normal;
                normals[index1] = normal;
                normals[index2] = normal;
            }

            normals[normals.Length - 4] = -Vector3.up;
            normals[normals.Length - 3] = -Vector3.up;
            normals[normals.Length - 2] = -Vector3.up;
            normals[normals.Length - 1] = -Vector3.up;

            Mesh mesh = new Mesh();

            mesh.vertices = positions;
            mesh.colors   = ColorEx.GetFilledColorArray(positions.Length, color);
            mesh.normals  = normals;
            mesh.SetIndices(indices, MeshTopology.Triangles, 0);
            mesh.UploadMeshData(false);

            return(mesh);
        }
Beispiel #10
0
        public static Mesh CreateCylinder(float bottomRadius, float topRadius, float height, int numSlices,
                                          int numStacks, int numBottomCapRings, int numTopCapRings, Color color)
        {
            const float minSize = 1e-4f;

            if (bottomRadius < minSize)
            {
                bottomRadius = minSize;
            }
            if (topRadius < minSize)
            {
                topRadius = minSize;
            }
            if (height < minSize)
            {
                height = minSize;
            }

            const int minNumSlices = 3;

            if (numSlices < minNumSlices)
            {
                numSlices = minNumSlices;
            }

            const int minNumStacks = 1;

            if (numStacks < minNumStacks)
            {
                numStacks = minNumStacks;
            }

            int  minNumCapRings    = 1;
            bool generateBottomCap = numBottomCapRings >= minNumCapRings;
            bool generateTopCap    = numTopCapRings >= minNumCapRings;

            int numAxialRows     = numStacks + 1;
            int numVertsPerRow   = numSlices + 1;
            int numAxialVertices = numAxialRows * numVertsPerRow;
            int totalNumVerts    = numAxialVertices;

            Vector3[]      axialPositions = new Vector3[numAxialVertices];
            Vector3[]      axialNormals   = new Vector3[numAxialVertices];
            List <Vector3> allPositions   = new List <Vector3>(numAxialVertices);
            List <Vector3> allNormals     = new List <Vector3>(numAxialVertices);

            // Generate the axial vertices
            int     vertexPtr    = 0;
            Vector3 basePosition = Vector3.zero;
            Vector3 topPosition  = Vector3.up * height;
            Vector3 cylinderUp   = Vector3.up;
            float   yPosStep     = height / numStacks;
            float   angleStep    = 360.0f / numSlices;

            for (int axialRowIndex = 0; axialRowIndex < numAxialRows; ++axialRowIndex)
            {
                float rowYPos = basePosition.y + axialRowIndex * yPosStep;
                float radius  = Mathf.Lerp(bottomRadius, topRadius, rowYPos / topPosition.y);
                for (int vIndex = 0; vIndex < numVertsPerRow; ++vIndex)
                {
                    float   angle  = vIndex * angleStep;
                    Vector3 normal = (new Vector3(Mathf.Cos(angle * Mathf.Deg2Rad), 0.0f, Mathf.Sin(angle * Mathf.Deg2Rad))).normalized;

                    axialNormals[vertexPtr]   = normal;
                    axialPositions[vertexPtr] = basePosition + rowYPos * cylinderUp + normal * radius;
                    ++vertexPtr;
                }
            }
            allPositions.AddRange(axialPositions);
            allNormals.AddRange(axialNormals);

            // Generate the axial vertex indices
            int        indexPtr        = 0;
            List <int> allIndices      = new List <int>(100);
            int        numAxialIndices = numSlices * numStacks * 6;

            int[] axialIndices = new int[numAxialIndices];
            for (int axialRowIndex = 0; axialRowIndex < numAxialRows - 1; ++axialRowIndex)
            {
                for (int vIndex = 0; vIndex < numVertsPerRow - 1; ++vIndex)
                {
                    int indexOffset = axialRowIndex * numVertsPerRow + vIndex;

                    // First triangle
                    axialIndices[indexPtr++] = indexOffset;
                    axialIndices[indexPtr++] = indexOffset + numVertsPerRow;
                    axialIndices[indexPtr++] = indexOffset + 1;

                    // Second triangle
                    axialIndices[indexPtr++] = indexOffset + numVertsPerRow;
                    axialIndices[indexPtr++] = indexOffset + numVertsPerRow + 1;
                    axialIndices[indexPtr++] = indexOffset + 1;
                }
            }
            allIndices.AddRange(axialIndices);

            // Generate bottom cap if necessary
            if (generateBottomCap)
            {
                int numVertRings    = numBottomCapRings + 1;
                int numVertsPerRing = numSlices + 1;
                int numCapVerts     = numVertRings * numVertsPerRing;
                totalNumVerts += numCapVerts;

                vertexPtr = 0;
                Vector3[] capPositions = new Vector3[numCapVerts];
                Vector3[] capNormals   = new Vector3[numCapVerts];

                for (int ringIndex = 0; ringIndex < numVertRings; ++ringIndex)
                {
                    float radius = Mathf.Lerp(bottomRadius, 0.0f, ringIndex / (float)(numVertRings - 1));
                    for (int vIndex = 0; vIndex < numVertsPerRing; ++vIndex)
                    {
                        float   angle       = vIndex * angleStep;
                        Vector3 positionDir = (new Vector3(Mathf.Cos(angle * Mathf.Deg2Rad), 0.0f, Mathf.Sin(angle * Mathf.Deg2Rad))).normalized;
                        capPositions[vertexPtr] = basePosition + positionDir * radius;
                        capNormals[vertexPtr]   = -cylinderUp;
                        ++vertexPtr;
                    }
                }

                int baseVertexIndex = allPositions.Count;
                allPositions.AddRange(capPositions);
                allNormals.AddRange(capNormals);

                indexPtr = 0;
                int   numCapIndices = numSlices * numBottomCapRings * 6;
                int[] capIndices    = new int[numCapIndices];
                for (int vertexRingIndex = 0; vertexRingIndex < numVertRings - 1; ++vertexRingIndex)
                {
                    for (int vIndex = 0; vIndex < numVertsPerRing - 1; ++vIndex)
                    {
                        int indexOffset = baseVertexIndex + vertexRingIndex * numVertsPerRing + vIndex;

                        // First triangle
                        capIndices[indexPtr++] = indexOffset;
                        capIndices[indexPtr++] = indexOffset + 1;
                        capIndices[indexPtr++] = indexOffset + numVertsPerRing;

                        // Second triangle
                        capIndices[indexPtr++] = indexOffset + numVertsPerRing;
                        capIndices[indexPtr++] = indexOffset + 1;
                        capIndices[indexPtr++] = indexOffset + numVertsPerRing + 1;
                    }
                }
                allIndices.AddRange(capIndices);
            }

            // Generate top cap if necessary
            if (generateTopCap)
            {
                int numVertRings    = numTopCapRings + 1;
                int numVertsPerRing = numSlices + 1;
                int numCapVerts     = numVertRings * numVertsPerRing;
                totalNumVerts += numCapVerts;

                vertexPtr = 0;
                Vector3[] capPositions = new Vector3[numCapVerts];
                Vector3[] capNormals   = new Vector3[numCapVerts];

                for (int ringIndex = 0; ringIndex < numVertRings; ++ringIndex)
                {
                    float radius = Mathf.Lerp(topRadius, 0.0f, ringIndex / (float)(numVertRings - 1));
                    for (int vIndex = 0; vIndex < numVertsPerRing; ++vIndex)
                    {
                        float   angle       = vIndex * angleStep;
                        Vector3 positionDir = (new Vector3(Mathf.Cos(angle * Mathf.Deg2Rad), 0.0f, Mathf.Sin(angle * Mathf.Deg2Rad))).normalized;
                        capPositions[vertexPtr] = topPosition + positionDir * radius;
                        capNormals[vertexPtr]   = cylinderUp;
                        ++vertexPtr;
                    }
                }

                int baseVertexIndex = allPositions.Count;
                allPositions.AddRange(capPositions);
                allNormals.AddRange(capNormals);

                indexPtr = 0;
                int   numCapIndices = numSlices * numTopCapRings * 6;
                int[] capIndices    = new int[numCapIndices];
                for (int vertexRingIndex = 0; vertexRingIndex < numVertRings - 1; ++vertexRingIndex)
                {
                    for (int vIndex = 0; vIndex < numVertsPerRing - 1; ++vIndex)
                    {
                        int indexOffset = baseVertexIndex + vertexRingIndex * numVertsPerRing + vIndex;

                        // First triangle
                        capIndices[indexPtr++] = indexOffset;
                        capIndices[indexPtr++] = indexOffset + numVertsPerRing;
                        capIndices[indexPtr++] = indexOffset + 1;

                        // Second triangle
                        capIndices[indexPtr++] = indexOffset + numVertsPerRing;
                        capIndices[indexPtr++] = indexOffset + numVertsPerRing + 1;
                        capIndices[indexPtr++] = indexOffset + 1;
                    }
                }
                allIndices.AddRange(capIndices);
            }

            Mesh mesh = new Mesh();

            mesh.vertices = allPositions.ToArray();
            mesh.normals  = allNormals.ToArray();
            mesh.colors   = ColorEx.GetFilledColorArray(totalNumVerts, color);
            mesh.SetIndices(allIndices.ToArray(), MeshTopology.Triangles, 0);
            mesh.UploadMeshData(false);

            return(mesh);
        }
Beispiel #11
0
        public static Mesh CreateSphere(float radius, int numSlices, int numStacks, Color color)
        {
            if (radius < 1e-4f || numSlices < 3 || numStacks < 2)
            {
                return(null);
            }

            int numVertRows    = numStacks + 1;
            int numVertsPerRow = numSlices + 1;
            int numVerts       = numVertRows * numVertsPerRow;

            Vector3[] positions = new Vector3[numVerts];
            Vector3[] normals   = new Vector3[numVerts];

            int vertexPtr = 0;

            float angleStep = 360.0f / (numVertsPerRow - 1);

            for (int vertRowIndex = 0; vertRowIndex < numVertRows; ++vertRowIndex)
            {
                float theta    = Mathf.PI * (float)vertRowIndex / (numVertRows - 1);
                float cosTheta = Mathf.Cos(theta);
                float sinTheta = Mathf.Sin(theta);

                for (int vertIndex = 0; vertIndex < numVertsPerRow; ++vertIndex)
                {
                    float   centralAxisRotAngle = angleStep * vertIndex * Mathf.Deg2Rad;
                    Vector3 rotatedAxis         = Vector3.right * Mathf.Sin(centralAxisRotAngle) +
                                                  Vector3.forward * Mathf.Cos(centralAxisRotAngle);
                    positions[vertexPtr] = rotatedAxis * sinTheta * radius + Vector3.up * cosTheta * radius;
                    normals[vertexPtr]   = Vector3.Normalize(positions[vertexPtr]);
                    ++vertexPtr;
                }
            }

            int indexPtr   = 0;
            int numIndices = numSlices * numStacks * 6;

            int[] indices = new int[numIndices];
            for (int vertRowIndex = 0; vertRowIndex < numVertRows - 1; ++vertRowIndex)
            {
                for (int vertIndex = 0; vertIndex < numVertsPerRow - 1; ++vertIndex)
                {
                    // Calculate the index of the first vertex inside the first triangle
                    int baseIndex = vertRowIndex * numVertsPerRow + vertIndex;

                    // First triangle
                    indices[indexPtr++] = baseIndex;
                    indices[indexPtr++] = baseIndex + numVertsPerRow;
                    indices[indexPtr++] = baseIndex + numVertsPerRow + 1;

                    // Second triangle
                    indices[indexPtr++] = baseIndex + numVertsPerRow + 1;
                    indices[indexPtr++] = baseIndex + 1;
                    indices[indexPtr++] = baseIndex;
                }
            }

            Mesh mesh = new Mesh();

            mesh.vertices = positions;
            mesh.normals  = normals;
            mesh.colors   = ColorEx.GetFilledColorArray(numVerts, color);
            mesh.SetIndices(indices, MeshTopology.Triangles, 0);
            mesh.UploadMeshData(false);

            return(mesh);
        }
Beispiel #12
0
        public static Mesh CreateTriangularPrism(Vector3 baseCenter, float baseWidth, float baseDepth, float topWidth, float topDepth, float height, Color color)
        {
            baseWidth = Mathf.Max(Mathf.Abs(baseWidth), 1e-4f);
            baseDepth = Mathf.Max(Mathf.Abs(baseDepth), 1e-4f);
            topWidth  = Mathf.Max(Mathf.Abs(topWidth), 1e-4f);
            topDepth  = Mathf.Max(Mathf.Abs(topDepth), 1e-4f);
            height    = Mathf.Max(Mathf.Abs(height), 1e-4f);

            List <Vector3> cornerPoints  = PrismMath.CalcTriangPrismCornerPoints(baseCenter, baseWidth, baseDepth, topWidth, topDepth, height, Quaternion.identity);
            Vector3        baseLeftPt    = cornerPoints[(int)TriangularPrismCorner.BaseLeft];
            Vector3        baseRightPt   = cornerPoints[(int)TriangularPrismCorner.BaseRight];
            Vector3        baseForwardPt = cornerPoints[(int)TriangularPrismCorner.BaseForward];

            Vector3 topLeftPt    = cornerPoints[(int)TriangularPrismCorner.TopLeft];
            Vector3 topRightPt   = cornerPoints[(int)TriangularPrismCorner.TopRight];
            Vector3 topForwardPt = cornerPoints[(int)TriangularPrismCorner.TopForward];

            Vector3[] positions = new Vector3[]
            {
                // Top face
                topLeftPt, topForwardPt, topRightPt,

                // Bottom face
                baseLeftPt, baseRightPt, baseForwardPt,

                // Back face
                baseLeftPt, topLeftPt, topRightPt, baseRightPt,

                // Left face
                baseLeftPt, baseForwardPt, topForwardPt, topLeftPt,

                // Right face
                baseRightPt, topRightPt, topForwardPt, baseForwardPt
            };

            int[] indices = new int[]
            {
                // Top face
                0, 1, 2,

                // Bottom face
                3, 4, 5,

                // Back face
                6, 7, 8,
                8, 9, 6,

                // Left face
                10, 11, 12,
                12, 13, 10,

                // Right face
                14, 15, 16,
                16, 17, 14
            };

            Vector3 leftFaceNormal  = Vector3.Cross((positions[11] - positions[10]), (positions[13] - positions[10])).normalized;
            Vector3 rightFaceNormal = Vector3.Cross((positions[15] - positions[14]), (positions[17] - positions[14])).normalized;

            Vector3[] normals = new Vector3[]
            {
                // Top face
                Vector3.up, Vector3.up, Vector3.up,

                // Bottom face
                -Vector3.up, -Vector3.up, -Vector3.up,

                // Back face
                -Vector3.forward, -Vector3.forward, -Vector3.forward, -Vector3.forward,

                // Left face
                leftFaceNormal, leftFaceNormal, leftFaceNormal, leftFaceNormal,

                // Right face
                rightFaceNormal, rightFaceNormal, rightFaceNormal, rightFaceNormal
            };

            Mesh mesh = new Mesh();

            mesh.vertices = positions;
            mesh.colors   = ColorEx.GetFilledColorArray(positions.Length, color);
            mesh.normals  = normals;
            mesh.SetIndices(indices, MeshTopology.Triangles, 0);
            mesh.UploadMeshData(false);

            return(mesh);
        }
Beispiel #13
0
        public static Mesh CreateBox(float width, float height, float depth, Color color)
        {
            if (width < 1e-4f)
            {
                return(null);
            }
            if (height < 1e-4f)
            {
                return(null);
            }
            if (depth < 1e-4f)
            {
                return(null);
            }

            float halfWidth  = width * 0.5f;
            float halfHeight = height * 0.5f;
            float halfDepth  = depth * 0.5f;

            Vector3[] positions = new Vector3[]
            {
                // Front face
                new Vector3(-halfWidth, -halfHeight, -halfDepth),
                new Vector3(-halfWidth, halfHeight, -halfDepth),
                new Vector3(halfWidth, halfHeight, -halfDepth),
                new Vector3(halfWidth, -halfHeight, -halfDepth),

                // Back face
                new Vector3(halfWidth, -halfHeight, halfDepth),
                new Vector3(halfWidth, halfHeight, halfDepth),
                new Vector3(-halfWidth, halfHeight, halfDepth),
                new Vector3(-halfWidth, -halfHeight, halfDepth),

                // Top face
                new Vector3(-halfWidth, halfHeight, -halfDepth),
                new Vector3(-halfWidth, halfHeight, halfDepth),
                new Vector3(halfWidth, halfHeight, halfDepth),
                new Vector3(halfWidth, halfHeight, -halfDepth),

                // Bottom face
                new Vector3(halfWidth, -halfHeight, -halfDepth),
                new Vector3(halfWidth, -halfHeight, halfDepth),
                new Vector3(-halfWidth, -halfHeight, halfDepth),
                new Vector3(-halfWidth, -halfHeight, -halfDepth),

                // Left face
                new Vector3(-halfWidth, -halfHeight, halfDepth),
                new Vector3(-halfWidth, halfHeight, halfDepth),
                new Vector3(-halfWidth, halfHeight, -halfDepth),
                new Vector3(-halfWidth, -halfHeight, -halfDepth),

                // Right face
                new Vector3(halfWidth, -halfHeight, -halfDepth),
                new Vector3(halfWidth, halfHeight, -halfDepth),
                new Vector3(halfWidth, halfHeight, halfDepth),
                new Vector3(halfWidth, -halfHeight, halfDepth)
            };

            Vector3[] normals = new Vector3[]
            {
                // Front face
                -Vector3.forward, -Vector3.forward, -Vector3.forward, -Vector3.forward,

                // Back face
                Vector3.forward, Vector3.forward, Vector3.forward, Vector3.forward,

                // Top face
                Vector3.up, Vector3.up, Vector3.up, Vector3.up,

                // Bottom face
                -Vector3.up, -Vector3.up, -Vector3.up, -Vector3.up,

                // Left face
                -Vector3.right, -Vector3.right, -Vector3.right, -Vector3.right,

                // Right face
                Vector3.right, Vector3.right, Vector3.right, Vector3.right
            };

            int[] indices = new int[]
            {
                // Front face
                0, 1, 2, 2, 3, 0,

                // Back face
                4, 5, 6, 6, 7, 4,

                // Top face
                8, 9, 10, 10, 11, 8,

                // Bottom face
                12, 13, 14, 14, 15, 12,

                // Left face
                16, 17, 18, 18, 19, 16,

                // Right face
                20, 21, 22, 22, 23, 20
            };

            Mesh mesh = new Mesh();

            mesh.vertices = positions;
            mesh.normals  = normals;
            mesh.colors   = ColorEx.GetFilledColorArray(24, color);
            mesh.SetIndices(indices, MeshTopology.Triangles, 0);
            mesh.UploadMeshData(false);

            return(mesh);
        }
Beispiel #14
0
        public static Mesh CreateCylindricalTorus(Vector3 center, float coreRadius, float tubeHrzRadius, float tubeVertRadius, int numTubeSlices, Color color)
        {
            if (coreRadius < 1e-4f || tubeHrzRadius < 1e-4f || numTubeSlices < 3)
            {
                return(null);
            }

            int numVertsPerTubeSlice = 8;
            int numVerts             = numVertsPerTubeSlice * (numTubeSlices + 1);

            Vector3[] positions  = new Vector3[numVerts];
            Vector3[] normals    = new Vector3[numVerts];
            Vector2[] radiusDirs = new Vector2[numVerts];

            int   vertexPtr     = 0;
            float tubeAngleStep = 360.0f / (numTubeSlices - 1);

            for (int tubeSliceIndex = 0; tubeSliceIndex <= numTubeSlices; ++tubeSliceIndex)
            {
                float tubeAngle = tubeAngleStep * tubeSliceIndex * Mathf.Deg2Rad;
                float cosTube   = Mathf.Cos(tubeAngle);
                float sinTube   = Mathf.Sin(tubeAngle);

                Vector3 tubeSliceCenterDir = new Vector3(sinTube, 0.0f, cosTube).normalized;
                Vector3 tubeSliceCenter    = center + tubeSliceCenterDir * coreRadius;
                Vector2 radiusDir          = new Vector2(tubeSliceCenterDir.x, tubeSliceCenterDir.z);

                // Top
                radiusDirs[vertexPtr] = radiusDir;
                positions[vertexPtr]  = tubeSliceCenter + Vector3.up * tubeVertRadius - tubeSliceCenterDir * tubeHrzRadius;
                normals[vertexPtr++]  = Vector3.up;

                radiusDirs[vertexPtr] = radiusDir;
                positions[vertexPtr]  = tubeSliceCenter + Vector3.up * tubeVertRadius + tubeSliceCenterDir * tubeHrzRadius;
                normals[vertexPtr++]  = Vector3.up;

                // Back
                radiusDirs[vertexPtr] = radiusDir;
                positions[vertexPtr]  = tubeSliceCenter + Vector3.up * tubeVertRadius + tubeSliceCenterDir * tubeHrzRadius;
                normals[vertexPtr++]  = tubeSliceCenterDir;

                radiusDirs[vertexPtr] = radiusDir;
                positions[vertexPtr]  = tubeSliceCenter - Vector3.up * tubeVertRadius + tubeSliceCenterDir * tubeHrzRadius;
                normals[vertexPtr++]  = tubeSliceCenterDir;

                // Bottom
                radiusDirs[vertexPtr] = radiusDir;
                positions[vertexPtr]  = tubeSliceCenter - Vector3.up * tubeVertRadius + tubeSliceCenterDir * tubeHrzRadius;
                normals[vertexPtr++]  = -Vector3.up;

                radiusDirs[vertexPtr] = radiusDir;
                positions[vertexPtr]  = tubeSliceCenter - Vector3.up * tubeVertRadius - tubeSliceCenterDir * tubeHrzRadius;
                normals[vertexPtr++]  = -Vector3.up;

                // Front
                radiusDirs[vertexPtr] = radiusDir;
                positions[vertexPtr]  = tubeSliceCenter - Vector3.up * tubeVertRadius - tubeSliceCenterDir * tubeHrzRadius;
                normals[vertexPtr++]  = -tubeSliceCenterDir;

                radiusDirs[vertexPtr] = radiusDir;
                positions[vertexPtr]  = tubeSliceCenter + Vector3.up * tubeVertRadius - tubeSliceCenterDir * tubeHrzRadius;
                normals[vertexPtr++]  = -tubeSliceCenterDir;
            }

            int indexPtr   = 0;
            int numIndices = numTubeSlices * 24;

            int[] indices = new int[numIndices];
            for (int tubeSliceIndex = 0; tubeSliceIndex < numTubeSlices - 1; ++tubeSliceIndex)
            {
                int baseIndex = tubeSliceIndex * numVertsPerTubeSlice;

                // Top quad
                indices[indexPtr++] = baseIndex;
                indices[indexPtr++] = baseIndex + 1;
                indices[indexPtr++] = baseIndex + 1 + numVertsPerTubeSlice;

                indices[indexPtr++] = baseIndex;
                indices[indexPtr++] = baseIndex + 1 + numVertsPerTubeSlice;
                indices[indexPtr++] = baseIndex + numVertsPerTubeSlice;

                // Back quad
                baseIndex          += 2;
                indices[indexPtr++] = baseIndex;
                indices[indexPtr++] = baseIndex + 1;
                indices[indexPtr++] = baseIndex + 1 + numVertsPerTubeSlice;

                indices[indexPtr++] = baseIndex;
                indices[indexPtr++] = baseIndex + 1 + numVertsPerTubeSlice;
                indices[indexPtr++] = baseIndex + numVertsPerTubeSlice;

                // Bottom quad
                baseIndex          += 2;
                indices[indexPtr++] = baseIndex;
                indices[indexPtr++] = baseIndex + 1;
                indices[indexPtr++] = baseIndex + 1 + numVertsPerTubeSlice;

                indices[indexPtr++] = baseIndex;
                indices[indexPtr++] = baseIndex + 1 + numVertsPerTubeSlice;
                indices[indexPtr++] = baseIndex + numVertsPerTubeSlice;

                // Front quad
                baseIndex          += 2;
                indices[indexPtr++] = baseIndex;
                indices[indexPtr++] = baseIndex + 1;
                indices[indexPtr++] = baseIndex + 1 + numVertsPerTubeSlice;

                indices[indexPtr++] = baseIndex;
                indices[indexPtr++] = baseIndex + 1 + numVertsPerTubeSlice;
                indices[indexPtr++] = baseIndex + numVertsPerTubeSlice;
            }

            Mesh mesh = new Mesh();

            mesh.vertices = positions;
            mesh.normals  = normals;
            mesh.uv2      = radiusDirs;
            mesh.colors   = ColorEx.GetFilledColorArray(numVerts, color);
            mesh.SetIndices(indices, MeshTopology.Triangles, 0);
            mesh.UploadMeshData(false);

            return(mesh);
        }
Beispiel #15
0
        public static Mesh CreateTorus(Vector3 center, float coreRadius, float tubeRadius, int numTubeSlices, int numSlices, Color color)
        {
            if (coreRadius < 1e-4f || tubeRadius < 1e-4f || numTubeSlices < 3 || numSlices < 3)
            {
                return(null);
            }

            int numVertsPerTubeSlice = (numSlices + 1);
            int numVerts             = numVertsPerTubeSlice * (numTubeSlices + 1);

            Vector3[] positions = new Vector3[numVerts];
            Vector3[] normals   = new Vector3[numVerts];

            int vertexPtr = 0;

            float outerAngleStep = 360.0f / (numSlices - 1);
            float tubeAngleStep  = 360.0f / (numTubeSlices - 1);

            for (int tubeSliceIndex = 0; tubeSliceIndex <= numTubeSlices; ++tubeSliceIndex)
            {
                float tubeAngle = tubeAngleStep * tubeSliceIndex * Mathf.Deg2Rad;
                float cosTube   = Mathf.Cos(tubeAngle);
                float sinTube   = Mathf.Sin(tubeAngle);

                Vector3 tubeSliceCenter = new Vector3(sinTube * coreRadius, 0.0f, cosTube * coreRadius);

                for (int sliceIndex = 0; sliceIndex <= numSlices; ++sliceIndex)
                {
                    float outerAngle = outerAngleStep * sliceIndex * Mathf.Deg2Rad;
                    float cosOuter   = Mathf.Cos(outerAngle);
                    float sinOuter   = Mathf.Sin(outerAngle);

                    Vector3 vPos = tubeSliceCenter;
                    vPos.x += sinTube * sinOuter * tubeRadius;
                    vPos.y += cosOuter * tubeRadius;
                    vPos.z += cosTube * sinOuter * tubeRadius;

                    vPos += center;
                    positions[vertexPtr] = vPos;
                    normals[vertexPtr]   = (vPos - center).normalized;

                    ++vertexPtr;
                }
            }

            int indexPtr   = 0;
            int numIndices = numTubeSlices * numSlices * 6;

            int[] indices = new int[numIndices];
            for (int tubeSliceIndex = 0; tubeSliceIndex < numTubeSlices; ++tubeSliceIndex)
            {
                for (int sliceIndex = 0; sliceIndex < numSlices; ++sliceIndex)
                {
                    int baseIndex = tubeSliceIndex * numVertsPerTubeSlice + sliceIndex;

                    indices[indexPtr++] = baseIndex;
                    indices[indexPtr++] = baseIndex + 1;
                    indices[indexPtr++] = baseIndex + numVertsPerTubeSlice;

                    indices[indexPtr++] = baseIndex + 1;
                    indices[indexPtr++] = baseIndex + 1 + numVertsPerTubeSlice;
                    indices[indexPtr++] = baseIndex + numVertsPerTubeSlice;
                }
            }

            Mesh mesh = new Mesh();

            mesh.vertices = positions;
            mesh.normals  = normals;
            mesh.colors   = ColorEx.GetFilledColorArray(numVerts, color);
            mesh.SetIndices(indices, MeshTopology.Triangles, 0);
            mesh.UploadMeshData(false);

            return(mesh);
        }