コード例 #1
0
        public static BasicMeshData GenerateTorus(int divsMinor, int divsMajor, float rMinor = 1, float rMajor = 1)
        {
            BasicMeshData mesh = new BasicMeshData();

            mesh.normals = new List <Vector3>();
            for (int iMaj = 0; iMaj < divsMajor; iMaj++)
            {
                float   tMaj   = iMaj / (float)divsMajor;
                Vector2 dirMaj = ShapesMath.AngToDir(tMaj * ShapesMath.TAU);
                for (int iMin = 0; iMin < divsMinor; iMin++)
                {
                    float   tMin        = iMin / (float)divsMinor;
                    Vector2 dirMinLocal = ShapesMath.AngToDir(tMin * ShapesMath.TAU);
                    Vector3 dirMin      = (Vector3)dirMaj * dirMinLocal.x + new Vector3(0, 0, dirMinLocal.y);
                    mesh.normals.Add(dirMin);
                    mesh.verts.Add((Vector3)dirMaj * rMajor + dirMin * rMinor);
                    int maj0min0 = iMaj * divsMinor + iMin;
                    int maj1min0 = (iMaj + 1) % divsMajor * divsMinor + iMin;
                    int maj0min1 = iMaj * divsMinor + (iMin + 1) % divsMinor;
                    int maj1min1 = (iMaj + 1) % divsMajor * divsMinor + (iMin + 1) % divsMinor;
                    mesh.tris.Add(maj0min1);
                    mesh.tris.Add(maj0min0);
                    mesh.tris.Add(maj1min1);
                    mesh.tris.Add(maj1min0);
                    mesh.tris.Add(maj1min1);
                    mesh.tris.Add(maj0min0);
                }
            }

            return(mesh);
        }
コード例 #2
0
        public static BasicMeshData GenerateIcosphere(int divs)
        {
            BasicMeshData mesh = new BasicMeshData();

            mesh.normals = new List <Vector3>();

            // foreach face, generate all vertices and triangles
            for (int i = 0; i < 20; i++)
            {
                Vector3 v0 = Icosahedron.verts[Icosahedron.tris[i * 3]];
                Vector3 v1 = Icosahedron.verts[Icosahedron.tris[i * 3 + 1]];
                Vector3 v2 = Icosahedron.verts[Icosahedron.tris[i * 3 + 2]];
                // add this icosa face to the global list
                int       n             = divs + 1; // n is number of verts along one side of the triangle
                int       prevVertCount = mesh.verts.Count;
                Vector3[] verts         = BarycentricVertices(n, v0, v1, v2).ToArray();
                mesh.verts.AddRange(verts);
                mesh.normals.AddRange(verts);
                mesh.tris.AddRange(BarycentricTriangulation(n, globalOffset: prevVertCount));
            }

            // cleanup duplicate verts
            mesh.RemoveDuplicateVertices();

            return(mesh);
        }
コード例 #3
0
        public static BasicMeshData GenerateCone(int divs, bool generateCap)
        {
            BasicMeshData mesh = new BasicMeshData();

            mesh.verts.Add(Vector3.forward);
            for (int i = 1; i < divs + 1; i++)
            {
                float t     = i / (float)divs;
                int   iNext = i == divs ? 1 : i + 1;
                mesh.verts.Add(ShapesMath.AngToDir(t * ShapesMath.TAU));
                mesh.tris.Add(0);                   // vertex 0 is the tip
                mesh.tris.Add(i);
                mesh.tris.Add(iNext);

                if (generateCap && i > 1 && i < divs)
                {
                    mesh.tris.Add(1);                       // vertex 1 is the root edge vert
                    mesh.tris.Add(iNext);
                    mesh.tris.Add(i);
                }
            }

            mesh.normals = mesh.verts.Select(v => v).ToList();               // already normalized

            return(mesh);
        }
コード例 #4
0
        public static BasicMeshData GenerateCylinder(int divs)
        {
            BasicMeshData mesh = new BasicMeshData();

            mesh.normals = new List <Vector3>();

            for (int z = 0; z < 2; z++)
            {
                for (int i = 0; i < divs; i++)
                {
                    float   t = i / (float)divs;
                    Vector3 v = ShapesMath.AngToDir(t * ShapesMath.TAU);
                    mesh.normals.Add(v);
                    v.z = z;
                    mesh.verts.Add(v);
                }
            }

            // sides
            for (int i = 0; i < divs; i++)
            {
                int low0 = i;
                int top0 = divs + i;
                int low1 = (i + 1) % divs;
                int top1 = divs + (i + 1) % divs;
                mesh.tris.Add(low0);
                mesh.tris.Add(low1);
                mesh.tris.Add(top1);
                mesh.tris.Add(top1);
                mesh.tris.Add(top0);
                mesh.tris.Add(low0);
            }

            // cap bottom
            for (int i = 1; i < divs - 1; i++)
            {
                mesh.tris.Add(0);
                mesh.tris.Add((i + 1) % divs);
                mesh.tris.Add(i);
            }

            // cap top
            for (int i = 1; i < divs - 1; i++)
            {
                mesh.tris.Add(divs + 0);
                mesh.tris.Add(divs + i);
                mesh.tris.Add(divs + (i + 1) % divs);
            }

            return(mesh);
        }
コード例 #5
0
    private BasicMeshData GenerateBasicMesh(Dictionary <Vector3Int, ShipTile> inChunk)
    {
        List <Vector3> vertices   = new List <Vector3>();
        List <int>     triangles  = new List <int>();
        List <Color32> colors     = new List <Color32>();
        Vector3        adjustment = (Vector3.up) / 2;

        foreach (ShipTile tile in inChunk.Values)
        {
            Vector3 pos       = new Vector3(tile.location.x, tile.location.z, tile.location.y);
            int     firstVert = vertices.Count;
            if (tile.wall)
            {
                foreach (Vector3 v in cubeVerts)
                {
                    vertices.Add(v + pos);
                    colors.Add(tile.col);
                }
                foreach (int t in cubeTriangles)
                {
                    triangles.Add(t + firstVert);
                }
            }
            else
            {
                foreach (Vector3 v in quadVerts)
                {
                    vertices.Add(v + pos);
                    colors.Add(tile.col);
                }
                foreach (int t in quadTriangles)
                {
                    triangles.Add(t + firstVert);
                }
            }
        }
        BasicMeshData mData = new BasicMeshData(vertices.ToArray(), triangles.ToArray(), colors.ToArray());

        return(mData);
    }
コード例 #6
0
        static Mesh UpdatePrimitiveMesh(string primitive, int detail, float boundsSize, BasicMeshData meshData, ref Mesh[] meshArray, int detailLevelCount = 5)
        {
            // make sure array is prepared
            if (meshArray == null || meshArray.Length != detailLevelCount)
            {
                // array incorrectly set up
                meshArray = new Mesh[detailLevelCount];
                Debug.Log($"reinitialized {primitive} mesh array to {detailLevelCount}");
            }

            // field is missing a ref
            if (meshArray[detail] == null)
            {
                string meshName = $"{primitive}_{detail}";
                // find existing mesh
                string assetPath    = AssetDatabase.GetAssetPath(ShapesAssets.Instance);
                Mesh[] assetsAtPath = AssetDatabase.LoadAllAssetsAtPath(assetPath).OfType <Mesh>().ToArray();
                Mesh   existingMesh = assetsAtPath.FirstOrDefault(x => x.name == meshName);
                if (existingMesh != null)
                {
                    // assign existing mesh
                    Debug.Log("Assigning missing mesh ref " + meshName);
                    meshArray[detail] = existingMesh;
                }
                else
                {
                    // create it if it's not found
                    Debug.Log("Creating missing mesh " + meshName);
                    meshArray[detail] = new Mesh {
                        name = meshName
                    };
                    AssetDatabase.AddObjectToAsset(meshArray[detail], ShapesAssets.Instance);
                }
            }

            Mesh m = meshArray[detail];

            meshData.ApplyTo(m);
            m.bounds          = new Bounds(Vector3.zero, Vector3.one * boundsSize);
            meshArray[detail] = m;
            return(m);
        }
コード例 #7
0
        public static BasicMeshData GenerateUVSphere(int divsLong, int divsLat)
        {
            BasicMeshData mesh = new BasicMeshData();

            mesh.normals = new List <Vector3>();

            int vertCount = divsLong * divsLat;
            int triCount  = divsLong * (divsLat - 1) * 2 - divsLong * 2;              // subtracting is to remove quads at the pole

            Vector3[] verts = new Vector3[vertCount];
            int       iVert = 0;

            // generate verts
            for (int iLo = 0; iLo < divsLong; iLo++)
            {
                float   tLong   = iLo / (float)divsLong;
                float   angLong = tLong * ShapesMath.TAU;
                Vector2 dirXZ   = ShapesMath.AngToDir(angLong);
                Vector3 dirLong = new Vector3(dirXZ.x, 0f, dirXZ.y);
                for (int iLa = 0; iLa < divsLat; iLa++)
                {
                    float   tLat    = iLa / (divsLat - 1f);
                    float   angLat  = Mathf.Lerp(-0.25f, 0.25f, tLat) * ShapesMath.TAU;
                    Vector2 dirProj = ShapesMath.AngToDir(angLat);
                    verts[iVert++] = dirLong * dirProj.x + Vector3.up * dirProj.y;
                }
            }

            // generate tris
            int[] tris = new int[triCount * 3];
            int   iTri = 0;

            for (int iLo = 0; iLo < divsLong; iLo++)
            {
                for (int iLa = 0; iLa < divsLat - 1; iLa++)
                {
                    int iRoot     = iLo * divsLat + iLa;
                    int iRootNext = (iRoot + divsLat) % vertCount;
                    if (iLa < divsLat - 2)                        // skip first and last (triangles at the poles)
                    {
                        tris[iTri++] = iRoot;
                        tris[iTri++] = iRoot + 1;
                        tris[iTri++] = iRootNext + 1;
                    }

                    if (iLa > 0)
                    {
                        tris[iTri++] = iRootNext + 1;
                        tris[iTri++] = iRootNext;
                        tris[iTri++] = iRoot;
                    }
                }
            }

            mesh.verts.AddRange(verts);
            mesh.tris.AddRange(tris);
            mesh.normals.AddRange(verts);
            mesh.RemoveDuplicateVertices();

            return(mesh);
        }
コード例 #8
0
        public static BasicMeshData GenerateCapsule(int divs)
        {
            BasicMeshData mesh = new BasicMeshData();

            mesh.normals = new List <Vector3>();

            int sides = divs * 4;

            for (int z = 0; z < 2; z++)
            {
                for (int i = 0; i < sides; i++)
                {
                    float   t = i / (float)sides;
                    Vector3 v = ShapesMath.AngToDir(t * ShapesMath.TAU);
                    mesh.normals.Add(v);
                    v.z = z;
                    mesh.verts.Add(v);
                }
            }

            // sides
            for (int i = 0; i < sides; i++)
            {
                int low0 = i;
                int top0 = sides + i;
                int low1 = (i + 1) % sides;
                int top1 = sides + (i + 1) % sides;
                mesh.tris.Add(low0);
                mesh.tris.Add(low1);
                mesh.tris.Add(top1);
                mesh.tris.Add(top1);
                mesh.tris.Add(top0);
                mesh.tris.Add(low0);
            }

            // round caps!
            int n = divs + 1;

            Vector3[] octaBaseVerts = { Vector3.right, Vector3.up, Vector3.left, Vector3.down };
            for (int z = 0; z < 2; z++)
            {
                // half-octahedron
                for (int s = 0; s < 4; s++)
                {
                    Vector3 v0 = z == 0 ? Vector3.back : Vector3.forward;                     // reverse depending on z
                    Vector3 v1 = octaBaseVerts[s];
                    Vector3 v2 = octaBaseVerts[(s + 1) % 4];

                    Vector3[] verts = BarycentricVertices(n, v0, v1, v2).ToArray();
                    mesh.normals.AddRange(verts);
                    if (z == 0)
                    {
                        mesh.tris.AddRange(BarycentricTriangulation(n, mesh.verts.Count).Reverse());
                        mesh.verts.AddRange(verts.Select(x => x));
                    }
                    else
                    {
                        mesh.tris.AddRange(BarycentricTriangulation(n, mesh.verts.Count));
                        mesh.verts.AddRange(verts.Select(x => x + Vector3.forward));
                    }
                }
            }

            mesh.RemoveDuplicateVertices();

            return(mesh);
        }