Ejemplo n.º 1
0
    public void AddGeneratedMesh()
    {
        GeneratedMesh newMesh = new GeneratedMesh();

        newMesh.name = string.Concat("Generated mesh ", generated.Count + 1);
        generated.Add(newMesh);
    }
Ejemplo n.º 2
0
    void MergeGrass(GameObject[] _grassesToMerge)
    {
        GameObject mergedMesh = new GameObject("MergedGrassGroup");
        Vector3    avgPos     = GetAvgPosOfObjs(_grassesToMerge);

        mergedMesh.transform.position = avgPos;
        //Merge objects to one mesh
        int count = _grassesToMerge.Length;

        MeshFilter[] meshFilters = new MeshFilter[count];
        for (int i = 0; i < count; i++)
        {
            meshFilters[i] = _grassesToMerge[i].transform.GetChild(0).GetComponent <MeshFilter>();
            _grassesToMerge[i].transform.position -= avgPos;
        }

        GeneratedMesh.CombineMeshes(mergedMesh.transform, meshFilters);

        /////////////////////////

        //AddLods
        mergedMesh.AddComponent <LODGroup>();
        LOD[]      lods      = new LOD[1];
        Renderer[] renderers = new Renderer[1];
        renderers[0] = mergedMesh.transform.GetChild(0).GetComponent <Renderer>();
        lods[0]      = new LOD(0.07f, renderers);

        mergedMesh.GetComponent <LODGroup>().SetLODs(lods);
        mergedMesh.GetComponent <LODGroup>().RecalculateBounds();
    }
Ejemplo n.º 3
0
    //Generates a mesh along a spline. The mesh is defined in the settings at index i
    private void GenerateMesh(Transform splineParent, SplineSettings settings, int spline, int i)
    {
        GeneratedMesh meshSettings = settings.generated[i];
        string        name         = meshSettings.name;

        if (name.Length == 0)
        {
            name = string.Concat("Generated Mesh ", i.ToString("D2"));
        }
        name = string.Concat(i.ToString("D2"), "-", name);
        Transform newGenerated = splineParent.Find(name);

        //Create a new GameObject if there is none in the current scene
        if (newGenerated == null)
        {
            newGenerated               = new GameObject().transform;
            newGenerated.parent        = splineParent;
            newGenerated.localPosition = Vector3.zero;
            newGenerated.localRotation = Quaternion.identity;
            newGenerated.localScale    = Vector3.one;
            newGenerated.name          = name;
            newGenerated.gameObject.AddComponent <MeshFilter>();
            newGenerated.gameObject.AddComponent <MeshRenderer>();
        }

        //Update mesh and material
        newGenerated.GetComponent <MeshFilter>().mesh       = meshSettings.Generate(splines[spline]);
        newGenerated.GetComponent <MeshRenderer>().material = meshSettings.material;
    }
Ejemplo n.º 4
0
    private static void MakeTriangles(Plane _plane, MeshTriangle _triangle, GeneratedMesh _currentSide, List <Vector3> _addedVertices, MeshTriangle currentMeshTriangle, MeshTriangle oppositeMeshTriangle, bool addVertices)
    {
        float normalizedDistance;
        float distance;

        // Get the distance from the vertex to the intersecting plane, in the direction of a vertex that we know exists on the other side of the intersection
        // From our original triangle
        _plane.Raycast(new Ray(currentMeshTriangle.Vertices[0], (oppositeMeshTriangle.Vertices[0] - currentMeshTriangle.Vertices[0]).normalized), out distance);
        normalizedDistance = distance / (oppositeMeshTriangle.Vertices[0] - currentMeshTriangle.Vertices[0]).magnitude;

        Vector3 vertLeft   = Vector3.Lerp(currentMeshTriangle.Vertices[0], oppositeMeshTriangle.Vertices[0], normalizedDistance);
        Vector3 normalLeft = Vector3.Lerp(currentMeshTriangle.Normals[0], oppositeMeshTriangle.Normals[0], normalizedDistance);
        Vector2 uvLeft     = Vector2.Lerp(currentMeshTriangle.UVs[0], oppositeMeshTriangle.UVs[0], normalizedDistance);

        _plane.Raycast(new Ray(currentMeshTriangle.Vertices[1], (oppositeMeshTriangle.Vertices[1] - currentMeshTriangle.Vertices[1]).normalized), out distance);

        normalizedDistance = distance / (oppositeMeshTriangle.Vertices[1] - currentMeshTriangle.Vertices[1]).magnitude;
        Vector3 vertRight = Vector3.Lerp(currentMeshTriangle.Vertices[1], oppositeMeshTriangle.Vertices[1], normalizedDistance);

        // Since we call this method twice, prevent adding new vertices twice
        if (addVertices)
        {
            _addedVertices.Add(vertLeft);
            _addedVertices.Add(vertRight);
        }
        Vector3 normalRight = Vector3.Lerp(currentMeshTriangle.Normals[1], oppositeMeshTriangle.Normals[1], normalizedDistance);
        Vector3 uvRight     = Vector2.Lerp(currentMeshTriangle.UVs[1], oppositeMeshTriangle.UVs[1], normalizedDistance);

        MeshTriangle currentTriangle;

        Vector3[] updatedVertices = new Vector3[] { currentMeshTriangle.Vertices[0], vertLeft, vertRight };
        Vector3[] updatedNormals  = new Vector3[] { currentMeshTriangle.Normals[0], normalLeft, normalRight };
        Vector2[] updatedUVs      = new Vector2[] { currentMeshTriangle.UVs[0], uvLeft, uvRight };

        currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, _triangle.SubmeshIndex);

        if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0)
            {
                FlipTriangle(currentTriangle);
            }
            _currentSide.AddTriangle(currentTriangle);
        }

        updatedVertices = new Vector3[] { currentMeshTriangle.Vertices[0], currentMeshTriangle.Vertices[1], vertRight };
        updatedNormals  = new Vector3[] { currentMeshTriangle.Normals[0], currentMeshTriangle.Normals[1], normalRight };
        updatedUVs      = new Vector2[] { currentMeshTriangle.UVs[0], currentMeshTriangle.UVs[1], uvRight };

        currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, _triangle.SubmeshIndex);

        if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0)
            {
                FlipTriangle(currentTriangle);
            }
            _currentSide.AddTriangle(currentTriangle);
        }
    }
Ejemplo n.º 5
0
    public static void FillCut(List <Vector3> _addedVertices, Plane _plane, GeneratedMesh _leftMesh, GeneratedMesh _rightMesh, int submeshCount)
    {
        List <Vector3> vertices = new List <Vector3>();
        List <Vector3> polygone = new List <Vector3>();

        // find the needed polygons
        // the cut faces added new vertices by 2 each time to make an edge
        // if two edges contain the same Vector3 point, they are connected

        for (int i = 0; i < _addedVertices.Count; i++)
        {
            // check the edge
            if (!vertices.Contains(_addedVertices[i]))// if it has one, it has this edge
            {
                //new polygon started with this edge
                polygone.Clear();
                polygone.Add(_addedVertices[i]);
                vertices.Add(_addedVertices[i]);
                if (i + 1 < _addedVertices.Count)
                {
                    polygone.Add(_addedVertices[i + 1]);
                    vertices.Add(_addedVertices[i + 1]);
                }

                EvaluatePairs(_addedVertices, vertices, polygone);
                Fill(polygone, _plane, _leftMesh, _rightMesh, submeshCount);
            }
        }
    }
Ejemplo n.º 6
0
 //Copy constructor
 public GeneratedMesh(GeneratedMesh other)
 {
     name        = other.name + " Clone";
     length      = other.length;
     sides       = other.sides;
     smoothEdges = other.smoothEdges;
     rotation    = other.rotation;
     scale       = other.scale;
     offset      = other.offset;
     cap         = other.cap;
     material    = other.material;
 }
 // Draw the editor for a Generated Mesh
 private void DrawGeneratedMeshSettings(GeneratedMesh meshSettings)
 {
     meshSettings.name        = EditorGUILayout.TextField("Name", meshSettings.name);
     meshSettings.length      = EditorGUILayout.Slider("Length", meshSettings.length, 0.05f, 2f);
     meshSettings.sides       = Mathf.FloorToInt(EditorGUILayout.Slider("Sides", meshSettings.sides, 3, 12));
     meshSettings.smoothEdges = EditorGUILayout.Toggle("Smooth Edges", meshSettings.smoothEdges);
     meshSettings.rotation    = EditorGUILayout.Slider("Rotation", meshSettings.rotation, 0f, 360f);
     meshSettings.scale       = EditorGUILayout.Vector2Field("Scale", meshSettings.scale);
     meshSettings.offset      = EditorGUILayout.Vector2Field("Offset", meshSettings.offset);
     meshSettings.cap         = EditorGUILayout.Toggle("Cap", meshSettings.cap);
     meshSettings.material    = (Material)EditorGUILayout.ObjectField("Material", meshSettings.material, typeof(Material), false);
 }
Ejemplo n.º 8
0
    public static void Cut(GameObject oGO, Vector3 _contactPoint,
                           Vector3 _direction, Material _cutMaterial = null,
                           bool fill = true, bool _addRigidbody = false)
    {
        if (currentCut)
        {
            return;
        }

        currentCut = true;

        Plane plane = new Plane(oGO.transform.InverseTransformDirection(-_direction),
                                oGO.transform.InverseTransformPoint(_contactPoint));

        originalMesh = oGO.GetComponent <MeshFilter>().mesh;
        List <Vector3> addedVertices = new List <Vector3>();

        GeneratedMesh leftMesh  = new GeneratedMesh();
        GeneratedMesh rightMesh = new GeneratedMesh();

        int[] submeshIndices;
        int   triangleIndexA, triangleIndexB, triangleIndexC;


        for (int i = 0; i < originalMesh.subMeshCount; i++)
        {
            submeshIndices = originalMesh.GetTriangles(i);
            for (int j = 0; j < originalMesh.subMeshCount; j += 3)
            {
                triangleIndexA = submeshIndices[j];
                triangleIndexB = submeshIndices[j + 1];
                triangleIndexC = submeshIndices[j + 2];

                MeshTriangle currentTriangle   = GetTriangle(triangleIndexA, triangleIndexB, triangleIndexC, i);
                bool         triangleALeftSide = plane.GetSide(originalMesh.vertices[triangleIndexA]);
                bool         triangleBLeftSide = plane.GetSide(originalMesh.vertices[triangleIndexB]);
                bool         triangleCLeftSide = plane.GetSide(originalMesh.vertices[triangleIndexC]);

                if (triangleALeftSide && triangleBLeftSide && triangleCLeftSide)
                {
                    leftMesh.AddTriangle(currentTriangle);
                }
                else if (!triangleALeftSide && !triangleBLeftSide && !triangleCLeftSide)
                {
                    rightMesh.AddTriangle(currentTriangle);
                }
                else
                {
                }
            }
        }
    }
Ejemplo n.º 9
0
    void MergeGrass()
    {
        //Merge objects to one mesh
        int count = generatedBranches.Length;

        MeshFilter[] meshFilters = new MeshFilter[count];
        for (int i = 0; i < count; i++)
        {
            meshFilters[i] = generatedBranches[i].GetComponent <MeshFilter>();
        }

        mergedMesh = GeneratedMesh.CombineMeshes(transform, meshFilters);
    }
Ejemplo n.º 10
0
    void MergeGrass()
    {
        //Merge objects to one mesh
        //MeshFilter[] meshFilters = new MeshFilter[2];
        //meshFilters[0] = generatedBranch.GetComponent<MeshFilter>();
        //meshFilters[1] = generatedLeaves.GetComponent<MeshFilter>();

        //mergedMesh = GeneratedMesh.CombineMeshes(transform, meshFilters);

        MeshFilter[] meshFilters = new MeshFilter[2];
        meshFilters[0] = generatedBranch.GetComponent <MeshFilter>();
        meshFilters[1] = generatedLeaves.GetComponent <MeshFilter>();

        mergedMesh = GeneratedMesh.CombineMeshesManyMats(transform, meshFilters);
    }
Ejemplo n.º 11
0
    // Generate a GameObject with the mesh
    public static void GenerateGameObject(GeneratedMesh mesh)
    {
        GameObject newGameObject = new GameObject("Generated Slice");

        newGameObject.transform.localScale = originalGameObject.transform.localScale;
        newGameObject.transform.position   = originalGameObject.transform.position;

        newGameObject.AddComponent <MeshFilter>();
        newGameObject.AddComponent <MeshRenderer>();
        newGameObject.AddComponent <MeshCollider>();

        newGameObject.GetComponent <MeshFilter>().mesh.vertices = mesh.Vertices.ToArray();
        newGameObject.GetComponent <MeshFilter>().mesh.normals  = mesh.Normals.ToArray();

        newGameObject.GetComponent <MeshFilter>().mesh.SetUVs(0, mesh.UVs);

        Material[] originalMaterials = originalGameObject.GetComponent <MeshRenderer>().materials;
        Material[] materials         = new Material[mesh.SubmeshIndices.Count];

        for (int i = 0; i < mesh.SubmeshIndices.Count; i++)
        {
            if (i < originalMaterials.Length)
            {
                materials[i] = originalMaterials[i];
            }
            else
            {
                materials[i] = originalMaterials[0];
            }
        }
        newGameObject.GetComponent <MeshRenderer>().materials = materials;

        int submeshCount = mesh.SubmeshIndices.Count;

        newGameObject.GetComponent <MeshFilter>().mesh.subMeshCount = submeshCount;
        for (int i = 0; i < mesh.SubmeshIndices.Count; i++)
        {
            newGameObject.GetComponent <MeshFilter>().mesh.SetTriangles(mesh.SubmeshIndices[i], i);
        }


        newGameObject.AddComponent <Rigidbody>();
        newGameObject.GetComponent <MeshCollider>().sharedMesh = newGameObject.GetComponent <MeshFilter>().mesh;
        newGameObject.GetComponent <MeshCollider>().convex     = true;

        // Small force for a more subtle cutting effect
        newGameObject.GetComponent <Rigidbody>().AddExplosionForce(100.0f, originalGameObject.transform.position, 10f);
    }
Ejemplo n.º 12
0
    private static void Fill(List <Vector3> _vertices, Plane plane, GeneratedMesh leftMesh, GeneratedMesh rightMesh)
    {
        Vector3 centerPosition = Vector3.zero;

        for (int i = 0; i < _vertices.Count; i++)
        {
            centerPosition += _vertices[i];
        }
        centerPosition /= _vertices.Count;

        Vector3 up = plane.normal;

        Vector3 left = Vector3.Cross(plane.normal, plane.normal);

        Vector3 displacement = Vector3.zero;
        Vector2 uv1, uv2;

        for (int i = 0; i < _vertices.Count; i++)
        {
            displacement = _vertices[i] - centerPosition;
            uv1          = new Vector2(0.5f + Vector3.Dot(displacement, left), 0.5f + Vector3.Dot(displacement, up));
            displacement = _vertices[(i + 1) % _vertices.Count] - centerPosition;
            uv2          = new Vector2(0.5f + Vector3.Dot(displacement, left), 0.5f + Vector3.Dot(displacement, up));

            Vector3[] vertices = new Vector3[] { _vertices[i], _vertices[(i + 1) % _vertices.Count], centerPosition };
            Vector3[] normals  = new Vector3[] { -plane.normal, -plane.normal, -plane.normal };
            Vector2[] uvs      = new Vector2[] { uv1, uv2, new Vector2(0.5f, 0.5f) };

            MeshTriangle currenTriangle = new MeshTriangle(vertices, normals, uvs, originalMesh.subMeshCount - 1);

            if (Vector3.Dot(Vector3.Cross(vertices[1] - vertices[0], vertices[2] - vertices[0]), normals[0]) < 0)
            {
                FlipTriangle(currenTriangle);
            }
            leftMesh.AddTriangle(currenTriangle);

            normals        = new Vector3[] { plane.normal, plane.normal, plane.normal };
            currenTriangle = new MeshTriangle(vertices, normals, uvs, originalMesh.subMeshCount - 1);

            if (Vector3.Dot(Vector3.Cross(vertices[1] - vertices[0], vertices[2] - vertices[0]), normals[0]) < 0)
            {
                FlipTriangle(currenTriangle);
            }
            rightMesh.AddTriangle(currenTriangle);
        }
    }
Ejemplo n.º 13
0
    private static void FillCut(List <Vector3> addedVertices, Plane plane, GeneratedMesh leftMesh, GeneratedMesh rightMesh)
    {
        List <Vector3> vertices = new List <Vector3>();
        List <Vector3> polygon  = new List <Vector3>();

        for (int i = 0; i < addedVertices.Count; i++)
        {
            if (!vertices.Contains(addedVertices[i]))
            {
                polygon.Clear();
                polygon.Add(addedVertices[i]);
                polygon.Add(addedVertices[i + 1]);

                vertices.Add(addedVertices[i]);
                vertices.Add(addedVertices[i + 1]);

                EvaluatePairs(addedVertices, vertices, polygon);
                Fill(polygon, plane, leftMesh, rightMesh);
            }
        }
    }
Ejemplo n.º 14
0
    /// <summary>
    /// Takes a triangle, splits it into two, and places it in the correct GeneratedMesh
    /// </summary>
    private static void CutTriangle(Plane _plane, MeshTriangle _triangle, bool _triangleALeftSide, bool _triangleBLeftSide, bool _triangleCLeftSide,
                                    GeneratedMesh _leftSide, GeneratedMesh _rightSide, List <Vector3> _addedVertices)
    {
        // Keep a list of where the triangle vertices lie left of the plane or below
        List <bool> leftSide = new List <bool>();

        leftSide.Add(_triangleALeftSide);
        leftSide.Add(_triangleBLeftSide);
        leftSide.Add(_triangleCLeftSide);

        // We generate two fake triangles with vertex data from the intersecting triangle
        MeshTriangle leftMeshTriangle  = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], _triangle.SubmeshIndex);
        MeshTriangle rightMeshTriangle = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], _triangle.SubmeshIndex);

        // Place the vertices in either the left and right mesh, depending on which side the vertex lies in relation to the plane
        SortVerticesFromIntersectedTriangle(_triangle, leftSide, leftMeshTriangle, rightMeshTriangle);

        // Using the fake triangle, we generate either one or two triangles per side
        MakeTriangles(_plane, _triangle, _leftSide, _addedVertices, leftMeshTriangle, rightMeshTriangle, true);
        MakeTriangles(_plane, _triangle, _rightSide, _addedVertices, rightMeshTriangle, leftMeshTriangle, false);
    }
Ejemplo n.º 15
0
    public static void FillCut(List <Vector3> _addedVertices, Plane _plane, GeneratedMesh _leftMesh, GeneratedMesh _rightMesh)
    {
        List <Vector3> vertices = new List <Vector3>();
        List <Vector3> polygone = new List <Vector3>();

        for (int i = 0; i < _addedVertices.Count; i++)
        {
            if (!vertices.Contains(_addedVertices[i]))
            {
                polygone.Clear();
                polygone.Add(_addedVertices[i]);
                polygone.Add(_addedVertices[i + 1]);

                vertices.Add(_addedVertices[i]);
                vertices.Add(_addedVertices[i + 1]);

                EvaluatePairs(_addedVertices, vertices, polygone);
                Fill(polygone, _plane, _leftMesh, _rightMesh);
            }
        }
    }
Ejemplo n.º 16
0
    private static void GenerateCutterGameobject(GameObject originalGameObject, GeneratedMesh mesh, bool addRigidbody, Vector3 direction)
    {
        if (mesh.Vertices.Count > 3)
        {
            GameObject gameObject = new GameObject(originalGameObject.name, typeof(MeshFilter), typeof(MeshRenderer));
            gameObject.transform.localRotation = originalGameObject.transform.localRotation;
            gameObject.transform.localScale    = originalGameObject.transform.localScale;
            gameObject.transform.position      = originalGameObject.transform.position;

            gameObject.GetComponent <MeshFilter>().mesh = mesh.GenerateMesh();

            gameObject.GetComponent <MeshRenderer>().material = originalGameObject.GetComponent <MeshRenderer>().material;

            if (addRigidbody)
            {
                gameObject.AddComponent <Rigidbody>();
                gameObject.GetComponent <Rigidbody>().AddTorque(direction * 200f);
            }

            gameObject.AddComponent <MeshCollider>();
            gameObject.GetComponent <MeshCollider>().convex = true;
        }
    }
Ejemplo n.º 17
0
    private void GenerateFood()
    {
        int count = 5;

        GeneratedLeaves[] food = new GeneratedLeaves[count];
        for (int i = 0; i < count; i++)
        {
            food[i] = Instantiate(VegetationGenerator.instance.generatedBushFoodPrefab, generatedLeaves.transform);
            food[i].transform.localPosition = generatedLeaves.GetComponent <MeshFilter>().mesh.vertices[Random.Range(0, generatedLeaves.GetComponent <MeshFilter>().mesh.vertexCount - 1)];
            food[i].Generate(0);
            food[i].transform.localScale = new Vector3(0.15f, 0.15f, 0.15f);
            food[i].VerySlowlyConvertToFlatShading();
        }

        //Merge food objects to one mesh
        count = food.Length;
        MeshFilter[] meshFilters = new MeshFilter[count];
        for (int i = 0; i < count; i++)
        {
            meshFilters[i] = food[i].GetComponent <MeshFilter>();
        }

        foodObject = GeneratedMesh.CombineMeshes(generatedLeaves.transform, meshFilters);
    }
Ejemplo n.º 18
0
    void GenerateTile(GameObject tileGameObject)
    {
        BackgroundWorker backgroundWorker = new BackgroundWorker();

        MeshRenderer renderer = tileGameObject.GetComponent <MeshRenderer>();
        Mesh         mesh     = tileGameObject.GetComponent <MeshFilter>().mesh;

        mesh.Clear();
        backgroundWorker.DoWork += (o, a) =>
        {
            Arg aa = (Arg)a.Argument;
            a.Result = GenerateTileAsync(aa.t, aa.position);
        };

        backgroundWorker.RunWorkerCompleted += (o, a) =>
        {
            GeneratedMesh gm = (GeneratedMesh)a.Result;

            mesh.vertices  = gm.vertices;
            mesh.uv        = gm.uvs;
            mesh.triangles = gm.triangles;
            mesh.RecalculateNormals();

            //renderer.material.color = RandomTextureGenerator.RandomColor();

            //tileGameObject.GetComponent<MeshCollider>().sharedMesh = null;
            //tileGameObject.GetComponent<MeshCollider>().sharedMesh = mesh;
        };

        Arg args = new Arg();

        args.t        = tileGameObject;
        args.position = tileGameObject.transform.position;
        workers.Add(backgroundWorker);
        backgroundWorker.RunWorkerAsync(args);
    }
Ejemplo n.º 19
0
    GeneratedMesh GenerateTileAsync(GameObject tileGameObject, Vector3 position)
    {
        int verticesPerSegment = 6;

        int vertexCount = verticesPerSegment * ((int)cellsPerTile.x) * ((int)cellsPerTile.y);

        GeneratedMesh gm = new GeneratedMesh();

        gm.vertices  = new Vector3[vertexCount];
        gm.normals   = new Vector3[vertexCount];
        gm.uvs       = new Vector2[vertexCount];
        gm.triangles = new int[vertexCount];

        gm.colours = new Color[vertexCount];

        int vertex = 0;

        // What cell is x and z for the bottom left of this tile in world space
        Vector3 tileBottomLeft = new Vector3();

        tileBottomLeft.x = -(tileSize.x) / 2;
        tileBottomLeft.z = -(tileSize.y) / 2;

        for (int z = 0; z < cellsPerTile.y; z++)
        {
            for (int x = 0; x < cellsPerTile.x; x++)
            {
                int startVertex = vertex;
                // Calculate some stuff
                Vector3 cellBottomLeft = tileBottomLeft + new Vector3(x * cellSize.x, 0, z * cellSize.y);
                Vector3 cellTopLeft    = tileBottomLeft + new Vector3(x * cellSize.x, 0, (z + 1) * cellSize.y);
                Vector3 cellTopRight   = tileBottomLeft + new Vector3((x + 1) * cellSize.x, 0, (z + 1) * cellSize.y);
                Vector3 celBottomRight = tileBottomLeft + new Vector3((x + 1) * cellSize.x, 0, z * cellSize.y);

                // Add all the samplers together to make the height
                Vector3 cellWorldCoords = position + tileBottomLeft + new Vector3(x * cellSize.x, 0, z * cellSize.y);
                foreach (Sampler sampler in samplers)
                {
                    cellBottomLeft.y += sampler.Sample(cellWorldCoords.x, cellWorldCoords.z);
                    cellTopLeft.y    += sampler.Sample(cellWorldCoords.x, cellWorldCoords.z + cellSize.y);
                    cellTopRight.y   += sampler.Sample(cellWorldCoords.x + cellSize.x, cellWorldCoords.z + cellSize.y);
                    celBottomRight.y += sampler.Sample(cellWorldCoords.x + cellSize.x, cellWorldCoords.z);
                }

                // Make the vertices
                gm.vertices[vertex++] = cellBottomLeft;
                gm.vertices[vertex++] = cellTopLeft;
                gm.vertices[vertex++] = cellTopRight;
                gm.vertices[vertex++] = cellTopRight;
                gm.vertices[vertex++] = celBottomRight;
                gm.vertices[vertex++] = cellBottomLeft;

                // Make the normals, UV's and triangles
                for (int i = 0; i < 6; i++)
                {
                    int vertexIndex = startVertex + i;
                    gm.triangles[vertexIndex] = vertexIndex;
                    gm.uvs[vertexIndex]       = new Vector2(x / cellsPerTile.x, z / cellsPerTile.y);
                }
            }
        }
        return(gm);
    }
Ejemplo n.º 20
0
    private static void Fill(List <Vector3> _vertices, Plane _plane, GeneratedMesh _leftMesh, GeneratedMesh _rightMesh)
    {
        Vector3 centerPosition = Vector3.zero;

        for (int i = 0; i < _vertices.Count; i++)
        {
            centerPosition += _vertices[i];
        }
        centerPosition = centerPosition / _vertices.Count;

        Vector3 up = new Vector3()
        {
            x = _plane.normal.x,
            y = _plane.normal.y,
            z = _plane.normal.z
        };

        Vector3 left         = Vector3.zero;
        Vector3 displacement = Vector3.zero;
        Vector2 uv1          = Vector2.zero;
        Vector2 uv2          = Vector2.zero;

        for (int i = 0; i < _vertices.Count; i++)
        {
            displacement = _vertices[i] - centerPosition;
            uv1          = new Vector2()
            {
                x = .5f + Vector3.Dot(displacement, left),
                y = .5f + Vector3.Dot(displacement, up)
            };

            displacement = _vertices[(i + 1) % _vertices.Count] - centerPosition;
            uv2          = new Vector2()
            {
                x = .5f + Vector3.Dot(displacement, left),
                y = .5f + Vector3.Dot(displacement, up)
            };

            Vector3[] vertices = new Vector3[] { _vertices[i], _vertices[(i + 1) % _vertices.Count], centerPosition };
            Vector3[] normals  = new Vector3[] { -_plane.normal, -_plane.normal, -_plane.normal };
            Vector2[] uvs      = new Vector2[] { uv1, uv2, new Vector2(0.5f, 0.5f) };

            MeshTriangle currentTriangle = new MeshTriangle(vertices, normals, uvs, originalMesh.subMeshCount + 1);

            // Make sure triangle is facing the right way
            if (Vector3.Dot(Vector3.Cross(vertices[1] - vertices[0], vertices[2] - vertices[0]), normals[0]) < 0)
            {
                FlipTriangle(currentTriangle);
            }

            _leftMesh.AddTriangle(currentTriangle);

            normals         = new Vector3[] { _plane.normal, _plane.normal, _plane.normal };
            currentTriangle = new MeshTriangle(vertices, normals, uvs, originalMesh.subMeshCount + 1);

            if (Vector3.Dot(Vector3.Cross(vertices[1] - vertices[0], vertices[2] - vertices[0]), normals[0]) < 0)
            {
                FlipTriangle(currentTriangle);
            }
            _rightMesh.AddTriangle(currentTriangle);
        }
    }
Ejemplo n.º 21
0
    public void CloneGeneratedMesh(int index)
    {
        GeneratedMesh newMesh = new GeneratedMesh(generated[index]);

        generated.Insert(index + 1, newMesh);
    }
Ejemplo n.º 22
0
    public static void CutGameobject(GameObject originalGameObject, Vector3 contactPoint, Vector3 direction, bool addRigidbody = false)
    {
        if (currentlyCutting)
        {
            return;
        }

        currentlyCutting = true;

        originalMesh = originalGameObject.GetComponent <MeshFilter>().mesh;

        var plane = new Plane(originalGameObject.transform.InverseTransformDirection(direction), originalGameObject.transform.InverseTransformPoint(contactPoint));

        var addedVertices = new List <Vector3>();

        var leftMesh  = new GeneratedMesh();
        var rightMesh = new GeneratedMesh();

        int[] submeshIndices;
        int   triangleIndexA, triangleIndexB, triangleIndexC;

        for (int i = 0; i < originalMesh.subMeshCount; i++)
        {
            submeshIndices = originalMesh.GetTriangles(i);

            for (int j = 0; j < submeshIndices.Length; j += 3)
            {
                triangleIndexA = submeshIndices[j];
                triangleIndexB = submeshIndices[j + 1];
                triangleIndexC = submeshIndices[j + 2];

                MeshTriangle currentTriangle = GetTriangle(triangleIndexA, triangleIndexB, triangleIndexC, i);

                bool[] pointsOnLeftSide = new bool [3];

                pointsOnLeftSide[0] = plane.GetSide(originalMesh.vertices[triangleIndexA]);
                pointsOnLeftSide[1] = plane.GetSide(originalMesh.vertices[triangleIndexB]);
                pointsOnLeftSide[2] = plane.GetSide(originalMesh.vertices[triangleIndexC]);

                if (pointsOnLeftSide[0] && pointsOnLeftSide[1] && pointsOnLeftSide[2])
                {
                    leftMesh.AddTriangle(currentTriangle);
                }
                else if (!pointsOnLeftSide[0] && !pointsOnLeftSide[1] && !pointsOnLeftSide[2])
                {
                    rightMesh.AddTriangle(currentTriangle);
                }
                else
                {
                    CutTriangle(plane, currentTriangle, pointsOnLeftSide, leftMesh, rightMesh, addedVertices);
                }
            }

            FillCut(addedVertices, plane, leftMesh, rightMesh);

            GenerateCutterGameobject(originalGameObject, leftMesh, addRigidbody, Vector3.up);
            GenerateCutterGameobject(originalGameObject, rightMesh, addRigidbody, Vector3.left);

            currentlyCutting = false;
        }
    }
Ejemplo n.º 23
0
    protected IEnumerator MergeChildTrees(float LOD0_Distance, float LOD1_Distance)
    {
        yield return(new WaitForEndOfFrame());

        List <Tree> treesToMerge = new List <Tree>();

        if (transform.parent && !transform.parent.GetComponent <Tree>())
        {
            treesToMerge.Add(this);
            for (int i = 0; i < transform.childCount; i++)
            {
                if (transform.GetChild(i).GetComponent <Tree>())
                {
                    treesToMerge.Add(transform.GetChild(i).GetComponent <Tree>());
                }
            }


            //Merge
            int count = treesToMerge.Count;
            if (count > 0)
            {
                List <MeshFilter> meshFiltersBranches = new List <MeshFilter>();
                List <MeshFilter> meshFiltersLeaves   = new List <MeshFilter>();

                List <MeshFilter> meshFiltersBranchesLOD = new List <MeshFilter>();
                List <MeshFilter> meshFiltersLeavesLOD   = new List <MeshFilter>();
                for (int i = 0; i < count; i++)
                {
                    meshFiltersBranches.Add(treesToMerge[i].generatedBranch.GetComponent <MeshFilter>());
                    meshFiltersBranches.AddRange(treesToMerge[i].generatedBranchesParent.GetComponentsInChildren <MeshFilter>());
                    meshFiltersLeaves.Add(treesToMerge[i].generatedLeaves.GetComponent <MeshFilter>());

                    meshFiltersBranchesLOD.Add(treesToMerge[i].generatedBranchLOD.GetComponent <MeshFilter>());
                    meshFiltersLeavesLOD.Add(treesToMerge[i].generatedLeavesLOD.GetComponent <MeshFilter>());
                }
                GameObject mergedBranches = GeneratedMesh.CombineMeshes(transform, meshFiltersBranches.ToArray());
                mergedBranches.AddComponent <GeneratedBranch>();
                mergedBranches.name = "Newly merged branches";
                generatedBranch     = mergedBranches.GetComponent <GeneratedBranch>();

                GameObject mergedLeaves = GeneratedMesh.CombineMeshes(transform, meshFiltersLeaves.ToArray());
                mergedLeaves.AddComponent <GeneratedLeaves>();
                mergedLeaves.name = "Newly merged leaves";
                generatedLeaves   = mergedLeaves.GetComponent <GeneratedLeaves>();

                //LOD
                GameObject mergedBranchesLOD = GeneratedMesh.CombineMeshes(transform, meshFiltersBranchesLOD.ToArray());
                mergedBranchesLOD.AddComponent <GeneratedBranch>();
                mergedBranchesLOD.name = "Newly merged branches LOD";
                generatedBranchLOD     = mergedBranchesLOD.GetComponent <GeneratedBranch>();

                GameObject mergedLeavesLOD = GeneratedMesh.CombineMeshes(transform, meshFiltersLeavesLOD.ToArray());
                mergedLeavesLOD.AddComponent <GeneratedLeaves>();
                mergedLeavesLOD.name = "Newly merged leaves LOD";
                generatedLeavesLOD   = mergedLeavesLOD.GetComponent <GeneratedLeaves>();
            }

            AddLODsNew(LOD0_Distance, LOD1_Distance);
        }
    }
Ejemplo n.º 24
0
    private static void CutTriangle(Plane _plane, MeshTriangle meshTri, bool tALS, bool TBLS, bool TCLS,
                                    GeneratedMesh lSide, GeneratedMesh rSide, List <Vector3> addedVert)
    {
        List <bool> leftSide = new List <bool>();

        leftSide.Add(tALS);
        leftSide.Add(TBLS);
        leftSide.Add(TCLS);

        MeshTriangle leftMeshTriangle  = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], meshTri.SMIndex);
        MeshTriangle rightMeshTriangle = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], meshTri.SMIndex);

        bool left  = false;
        bool right = false;

        for (int i = 0; i < 3; i++)
        {
            if (leftSide[i])
            {
                if (!left)
                {
                    left = true;

                    leftMeshTriangle.Vert[0] = meshTri.Vert[i];
                    leftMeshTriangle.Vert[1] = leftMeshTriangle.Vert[0];

                    leftMeshTriangle.UV[0] = meshTri.UV[i];
                    leftMeshTriangle.UV[1] = leftMeshTriangle.UV[0];

                    leftMeshTriangle.Norm[0] = meshTri.Norm[i];
                    leftMeshTriangle.Norm[1] = leftMeshTriangle.Norm[0];
                }
                else
                {
                    leftMeshTriangle.Vert[1] = meshTri.Vert[i];
                    leftMeshTriangle.Norm[1] = meshTri.Vert[i];
                    leftMeshTriangle.UV[1]   = meshTri.Vert[i];
                }
            }
            else
            {
                if (!right)
                {
                    right = true;

                    rightMeshTriangle.Vert[0] = meshTri.Vert[i];
                    rightMeshTriangle.Vert[1] = rightMeshTriangle.Vert[0];

                    rightMeshTriangle.UV[0] = meshTri.UV[i];
                    rightMeshTriangle.UV[1] = rightMeshTriangle.UV[0];

                    rightMeshTriangle.Norm[0] = meshTri.Norm[i];
                    rightMeshTriangle.Norm[1] = rightMeshTriangle.Norm[0];
                }
                else
                {
                    rightMeshTriangle.Vert[1] = meshTri.Vert[i];
                    rightMeshTriangle.Norm[1] = meshTri.Vert[i];
                    rightMeshTriangle.UV[1]   = meshTri.Vert[i];
                }
            }
        }

        float normalizedDistance;
        float distance;

        _plane.Raycast(new Ray(leftMeshTriangle.Vert[0],
                               (rightMeshTriangle.Vert[0] - leftMeshTriangle.Vert[0]).normalized), out distance);

        normalizedDistance = distance / (rightMeshTriangle.Vert[0] - leftMeshTriangle.Vert[0]).magnitude;
        Vector3 vertLeft = Vector3.Lerp(leftMeshTriangle.Vert[0], rightMeshTriangle.Vert[0], normalizedDistance);

        addedVert.Add(vertLeft);

        Vector3 normalLeft = Vector3.Lerp(leftMeshTriangle.Norm[0], rightMeshTriangle.Norm[0], normalizedDistance);
        Vector2 uvLeft     = Vector2.Lerp(leftMeshTriangle.UV[0], rightMeshTriangle.UV[0], normalizedDistance);

        _plane.Raycast(new Ray(leftMeshTriangle.Vert[1],
                               (rightMeshTriangle.Vert[1] - leftMeshTriangle.Vert[1]).normalized), out distance);

        normalizedDistance = distance / (rightMeshTriangle.Vert[1] - leftMeshTriangle.Vert[1]).magnitude;
        Vector3 vertRight = Vector3.Lerp(leftMeshTriangle.Vert[1], rightMeshTriangle.Vert[1], normalizedDistance);

        addedVert.Add(vertLeft);

        Vector3 normalRight = Vector3.Lerp(leftMeshTriangle.Norm[1], rightMeshTriangle.Norm[1], normalizedDistance);
        Vector2 uvRight     = Vector2.Lerp(leftMeshTriangle.UV[1], rightMeshTriangle.UV[1], normalizedDistance);

        MeshTriangle currentTriangle;

        Vector3[] updatedVert = new Vector3[] { leftMeshTriangle.Vert[0], vertLeft, vertRight };
        Vector3[] updatedNorm = new Vector3[] { leftMeshTriangle.Norm[0], normalLeft, normalRight };
        Vector2[] updatedUV   = new Vector2[] { leftMeshTriangle.UV[0], uvLeft, uvRight };

        currentTriangle = new MeshTriangle(updatedVert, updatedNorm, updatedUV, meshTri.SMIndex);

        if (updatedVert[0] != updatedVert[1] && updatedVert[0] != updatedVert[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVert[1] - updatedVert[0], updatedVert[2] - updatedVert[0]), updatedVert[0]) < 0)
            {
                FlipTriangle(currentTriangle);
            }
            lSide.AddTriangle(currentTriangle);
        }

        updatedVert = new Vector3[] { leftMeshTriangle.Vert[0], leftMeshTriangle.Vert[1], vertRight };
        updatedNorm = new Vector3[] { leftMeshTriangle.Norm[0], leftMeshTriangle.Norm[1], normalRight };
        updatedUV   = new Vector2[] { leftMeshTriangle.UV[0], uvLeft, uvRight };

        currentTriangle = new MeshTriangle(updatedVert, updatedNorm, updatedUV, meshTri.SMIndex);

        if (updatedVert[0] != updatedVert[1] && updatedVert[0] != updatedVert[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVert[1] - updatedVert[0], updatedVert[2] - updatedVert[0]), updatedVert[0]) < 0)
            {
                FlipTriangle(currentTriangle);
            }
            lSide.AddTriangle(currentTriangle);
        }

        updatedVert = new Vector3[] { rightMeshTriangle.Vert[0], vertLeft, vertRight };
        updatedNorm = new Vector3[] { rightMeshTriangle.Norm[0], normalLeft, normalRight };
        updatedUV   = new Vector2[] { rightMeshTriangle.UV[0], uvLeft, uvRight };

        currentTriangle = new MeshTriangle(updatedVert, updatedNorm, updatedUV, meshTri.SMIndex);

        if (updatedVert[0] != updatedVert[1] && updatedVert[0] != updatedVert[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVert[1] - updatedVert[0], updatedVert[2] - updatedVert[0]), updatedVert[0]) < 0)
            {
                FlipTriangle(currentTriangle);
            }
            rSide.AddTriangle(currentTriangle);
        }

        updatedVert = new Vector3[] { rightMeshTriangle.Vert[0], rightMeshTriangle.Vert[1], vertRight };
        updatedNorm = new Vector3[] { rightMeshTriangle.Norm[0], rightMeshTriangle.Norm[1], normalRight };
        updatedUV   = new Vector2[] { rightMeshTriangle.UV[0], uvLeft, uvRight };

        currentTriangle = new MeshTriangle(updatedVert, updatedNorm, updatedUV, meshTri.SMIndex);

        if (updatedVert[0] != updatedVert[1] && updatedVert[0] != updatedVert[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVert[1] - updatedVert[0], updatedVert[2] - updatedVert[0]), updatedVert[0]) < 0)
            {
                FlipTriangle(currentTriangle);
            }
            rSide.AddTriangle(currentTriangle);
        }
    }
Ejemplo n.º 25
0
    public static void Cut(GameObject _originalGameObject, Vector3 _contactPoint, Vector3 _direction, Material _cutMaterial = null, bool fill = true, bool _addRigidbody = false)
    {
        if (currentlyCutting)
        {
            return;
        }

        currentlyCutting = true;

        //We are instantiating a plane through our initial object to seperate the left and right side from each other
        Plane plane = new Plane(_originalGameObject.transform.InverseTransformDirection(-_direction), _originalGameObject.transform.InverseTransformPoint(_contactPoint));

        originalMesh = _originalGameObject.GetComponent <MeshFilter>().mesh;
        List <Vector3> addedVertices = new List <Vector3>();

        //We are getting two new generated meshes for our left and right side
        GeneratedMesh leftMesh  = new GeneratedMesh();
        GeneratedMesh rightMesh = new GeneratedMesh();

        //Some meshes use different submeshes to have multiple materials attached to them
        //in an early iteration I had an extra script to turn everything into one mesh to make my life a little easier
        //however the result was not great because I could only slice objects that had one single material
        int[] submeshIndices;
        int   triangleIndexA, triangleIndexB, triangleIndexC;

        for (int i = 0; i < originalMesh.subMeshCount; i++)
        {
            submeshIndices = originalMesh.GetTriangles(i);

            //We are now going through the submesh indices as triangles to determine on what side of the mesh they are.
            for (int j = 0; j < submeshIndices.Length; j += 3)
            {
                triangleIndexA = submeshIndices[j];
                triangleIndexB = submeshIndices[j + 1];
                triangleIndexC = submeshIndices[j + 2];

                MeshTriangle currentTriangle = GetTriangle(triangleIndexA, triangleIndexB, triangleIndexC, i);

                //We are now using the plane.getside function to see on which side of the cut our trianle is situated
                //or if it might be cut through
                bool triangleALeftSide = plane.GetSide(originalMesh.vertices[triangleIndexA]);
                bool triangleBLeftSide = plane.GetSide(originalMesh.vertices[triangleIndexB]);
                bool triangleCLeftSide = plane.GetSide(originalMesh.vertices[triangleIndexC]);

                //All three vertices are on the left side of the plane, so they need to be added to the left
                //mesh
                if (triangleALeftSide && triangleBLeftSide && triangleCLeftSide)
                {
                    leftMesh.AddTriangle(currentTriangle);
                }
                //All three vertices are on the right side of the mesh.
                else if (!triangleALeftSide && !triangleBLeftSide && !triangleCLeftSide)
                {
                    rightMesh.AddTriangle(currentTriangle);
                }
                else
                {
                    CutTriangle(plane, currentTriangle, triangleALeftSide, triangleBLeftSide, triangleCLeftSide, leftMesh, rightMesh, addedVertices);
                }
            }
        }

        //Filling our cut
        if (fill == true)
        {
            FillCut(addedVertices, plane, leftMesh, rightMesh);
        }

        // Generer de to nye meshes
        Mesh finishedLeftMesh  = leftMesh.GetGeneratedMesh();
        Mesh finishedRightMesh = rightMesh.GetGeneratedMesh();

        Debug.Log(finishedLeftMesh);

        Destroy(_originalGameObject.GetComponent <MeshCollider>());
        MeshCollider newCollider = _originalGameObject.AddComponent <MeshCollider>();

        newCollider.sharedMesh = finishedLeftMesh;
        newCollider.convex     = true;

        // Materials
        Material[] mats = new Material[finishedLeftMesh.subMeshCount];


        for (int i = 0; i < finishedLeftMesh.subMeshCount; i++)
        {
            mats[i] = _originalGameObject.GetComponent <MeshRenderer>().material;
        }
        _originalGameObject.GetComponent <MeshRenderer>().materials = mats;

        // Tildel mesh
        _originalGameObject.GetComponent <MeshFilter>().mesh = finishedLeftMesh;

        // Når meshet er tillagt, beregner vi den nye masse.
        _originalGameObject.GetComponent <Rigidbody>().mass = VolumeAndMass.MassOfMesh(finishedLeftMesh, _originalGameObject.GetComponent <Food>().density);
        // Opdater center of mass
        _originalGameObject.GetComponent <Rigidbody>().centerOfMass = _originalGameObject.GetComponent <MeshFilter>().mesh.bounds.center;


        GameObject rightGO = new GameObject();

        rightGO.transform.position   = _originalGameObject.transform.position + (_direction * .007f);
        rightGO.transform.rotation   = _originalGameObject.transform.rotation;
        rightGO.transform.localScale = _originalGameObject.transform.localScale;
        rightGO.AddComponent <MeshRenderer>();

        // Materials
        mats = new Material[finishedRightMesh.subMeshCount];
        for (int i = 0; i < finishedRightMesh.subMeshCount; i++)
        {
            mats[i] = _originalGameObject.GetComponent <MeshRenderer>().material;
        }
        rightGO.GetComponent <MeshRenderer>().materials = mats;

        // Tildel mesh
        rightGO.AddComponent <MeshFilter>().mesh = finishedRightMesh;

        // Tildel rigidbody
        if (rightGO.GetComponent <Rigidbody>() == null)
        {
            rightGO.AddComponent <Rigidbody>();
        }

        // Når meshet er tillagt, beregner vi den nye masse med samme densitet som det originale objekt (selvfølgelig).
        rightGO.GetComponent <Rigidbody>().mass = VolumeAndMass.MassOfMesh(finishedRightMesh, _originalGameObject.GetComponent <Food>().density);
        // Opdater center of mass
        rightGO.GetComponent <Rigidbody>().centerOfMass = rightGO.GetComponent <MeshFilter>().mesh.bounds.center;

        rightGO.AddComponent <MeshCollider>().sharedMesh = finishedRightMesh;
        rightGO.GetComponent <MeshCollider>().convex     = true;
        rightGO.tag = _originalGameObject.tag;

        // Opdater scripts
        Food newFoodScript    = rightGO.AddComponent <Food>();
        Food originFoodScript = _originalGameObject.GetComponent <Food>();

        UpdateFoodScript(newFoodScript, originFoodScript);

        rightGO.AddComponent <Throwable>();

        currentlyCutting = false;
    }
Ejemplo n.º 26
0
    private static void CutTriangle(Plane _plane, MeshTriangle _triangle, bool _triangleALeftSide, bool _triangleBLeftSide, bool _triangleCLeftSide,
                                    GeneratedMesh _leftSide, GeneratedMesh _rightSide, List <Vector3> _addedVertices)
    {
        List <bool> leftSide = new List <bool>();

        leftSide.Add(_triangleALeftSide);
        leftSide.Add(_triangleBLeftSide);
        leftSide.Add(_triangleCLeftSide);

        MeshTriangle leftMeshTriangle  = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], _triangle.SubmeshIndex);
        MeshTriangle rightMeshTriangle = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], _triangle.SubmeshIndex);

        bool left  = false;
        bool right = false;

        for (int i = 0; i < 3; i++)
        {
            if (leftSide[i])
            {
                if (!left)
                {
                    left = true;

                    leftMeshTriangle.Vertices[0] = _triangle.Vertices[i];
                    leftMeshTriangle.Vertices[1] = leftMeshTriangle.Vertices[0];

                    leftMeshTriangle.UVs[0] = _triangle.UVs[i];
                    leftMeshTriangle.UVs[1] = leftMeshTriangle.UVs[0];

                    leftMeshTriangle.Normals[0] = _triangle.Normals[i];
                    leftMeshTriangle.Normals[1] = leftMeshTriangle.Normals[0];
                }
                else
                {
                    leftMeshTriangle.Vertices[1] = _triangle.Vertices[i];
                    leftMeshTriangle.Normals[1]  = _triangle.Normals[i];
                    leftMeshTriangle.UVs[1]      = _triangle.UVs[i];
                }
            }
            else
            {
                if (!right)
                {
                    right = true;

                    rightMeshTriangle.Vertices[0] = _triangle.Vertices[i];
                    rightMeshTriangle.Vertices[1] = rightMeshTriangle.Vertices[0];

                    rightMeshTriangle.UVs[0] = _triangle.UVs[i];
                    rightMeshTriangle.UVs[1] = rightMeshTriangle.UVs[0];

                    rightMeshTriangle.Normals[0] = _triangle.Normals[i];
                    rightMeshTriangle.Normals[1] = rightMeshTriangle.Normals[0];
                }
                else
                {
                    rightMeshTriangle.Vertices[1] = _triangle.Vertices[i];
                    rightMeshTriangle.Normals[1]  = _triangle.Normals[i];
                    rightMeshTriangle.UVs[1]      = _triangle.UVs[i];
                }
            }
        }

        float normalizedDistance;
        float distance;

        _plane.Raycast(new Ray(leftMeshTriangle.Vertices[0], (rightMeshTriangle.Vertices[0] - leftMeshTriangle.Vertices[0]).normalized), out distance);

        normalizedDistance = distance / (rightMeshTriangle.Vertices[0] - leftMeshTriangle.Vertices[0]).magnitude;
        Vector3 vertLeft = Vector3.Lerp(leftMeshTriangle.Vertices[0], rightMeshTriangle.Vertices[0], normalizedDistance);

        _addedVertices.Add(vertLeft);

        Vector3 normalLeft = Vector3.Lerp(leftMeshTriangle.Normals[0], rightMeshTriangle.Normals[0], normalizedDistance);
        Vector2 uvLeft     = Vector2.Lerp(leftMeshTriangle.UVs[0], rightMeshTriangle.UVs[0], normalizedDistance);

        _plane.Raycast(new Ray(leftMeshTriangle.Vertices[1], (rightMeshTriangle.Vertices[1] - leftMeshTriangle.Vertices[1]).normalized), out distance);

        normalizedDistance = distance / (rightMeshTriangle.Vertices[1] - leftMeshTriangle.Vertices[1]).magnitude;
        Vector3 vertRight = Vector3.Lerp(leftMeshTriangle.Vertices[1], rightMeshTriangle.Vertices[1], normalizedDistance);

        _addedVertices.Add(vertRight);

        Vector3 normalRight = Vector3.Lerp(leftMeshTriangle.Normals[1], rightMeshTriangle.Normals[1], normalizedDistance);
        Vector2 uvRight     = Vector2.Lerp(leftMeshTriangle.UVs[1], rightMeshTriangle.UVs[1], normalizedDistance);

        //TESTING OUR FIRST TRIANGLE
        MeshTriangle currentTriangle;

        Vector3[] updatedVertices = new Vector3[] { leftMeshTriangle.Vertices[0], vertLeft, vertRight };
        Vector3[] updatedNormals  = new Vector3[] { leftMeshTriangle.Normals[0], normalLeft, normalRight };
        Vector2[] updatedUVs      = new Vector2[] { leftMeshTriangle.UVs[0], uvLeft, uvRight };

        currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, _triangle.SubmeshIndex);

        //If our vertices arent the same
        if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0)
            {
                FlipTriangel(currentTriangle);
            }
            _leftSide.AddTriangle(currentTriangle);
        }

        //SECOND TRIANGLE
        updatedVertices = new Vector3[] { leftMeshTriangle.Vertices[0], leftMeshTriangle.Vertices[1], vertRight };
        updatedNormals  = new Vector3[] { leftMeshTriangle.Normals[0], leftMeshTriangle.Normals[1], normalRight };
        updatedUVs      = new Vector2[] { leftMeshTriangle.UVs[0], leftMeshTriangle.UVs[1], uvRight };


        currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, _triangle.SubmeshIndex);
        //If our vertices arent the same
        if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0)
            {
                FlipTriangel(currentTriangle);
            }
            _leftSide.AddTriangle(currentTriangle);
        }

        //THIRD TRIANGLE
        updatedVertices = new Vector3[] { rightMeshTriangle.Vertices[0], vertLeft, vertRight };
        updatedNormals  = new Vector3[] { rightMeshTriangle.Normals[0], normalLeft, normalRight };
        updatedUVs      = new Vector2[] { rightMeshTriangle.UVs[0], uvLeft, uvRight };

        currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, _triangle.SubmeshIndex);
        //If our vertices arent the same
        if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0)
            {
                FlipTriangel(currentTriangle);
            }
            _rightSide.AddTriangle(currentTriangle);
        }

        //FOURTH TRIANGLE
        updatedVertices = new Vector3[] { rightMeshTriangle.Vertices[0], rightMeshTriangle.Vertices[1], vertRight };
        updatedNormals  = new Vector3[] { rightMeshTriangle.Normals[0], rightMeshTriangle.Normals[1], normalRight };
        updatedUVs      = new Vector2[] { rightMeshTriangle.UVs[0], rightMeshTriangle.UVs[1], uvRight };

        currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, _triangle.SubmeshIndex);
        //If our vertices arent the same
        if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0)
            {
                FlipTriangel(currentTriangle);
            }
            _rightSide.AddTriangle(currentTriangle);
        }
    }
Ejemplo n.º 27
0
    public static void Cut(GameObject _originalGameObject,
                           Vector3 _contactPoint,
                           Vector3 _direction,
                           Material _cutMaterial = null,
                           bool _fill            = true,
                           bool _addRigidbody    = false)
    {
        if (currentlyCutting)
        {
            return;
        }

        currentlyCutting = true;

        Plane plane = new Plane(_originalGameObject.transform.InverseTransformDirection(-_direction),
                                _originalGameObject.transform.InverseTransformDirection(_contactPoint));

        originalMesh = _originalGameObject.GetComponent <MeshFilter>().mesh;
        List <Vector3> addedVertices = new List <Vector3>();

        GeneratedMesh leftMesh  = new GeneratedMesh();
        GeneratedMesh rightMesh = new GeneratedMesh();

        int[] submeshIndices;
        int   triangleIndexA, triangleIndexB, triangleIndexC;

        for (int i = 0; i < originalMesh.subMeshCount; ++i)
        {
            submeshIndices = originalMesh.GetTriangles(i);

            for (int j = 0; j < submeshIndices.Length; j += 3)
            {
                triangleIndexA = submeshIndices[j];
                triangleIndexB = submeshIndices[j + 1];
                triangleIndexC = submeshIndices[j + 2];

                MeshTriangle currentTriangle = GetTriangle(triangleIndexA, triangleIndexB, triangleIndexC, i);

                bool triangleALeftSide = plane.GetSide(originalMesh.vertices[triangleIndexA]);
                bool triangleBLeftSide = plane.GetSide(originalMesh.vertices[triangleIndexB]);
                bool triangleCLeftSide = plane.GetSide(originalMesh.vertices[triangleIndexC]);

                if (triangleALeftSide && triangleBLeftSide && triangleCLeftSide)
                {
                    leftMesh.AddTriangle(currentTriangle);
                }
                else if (!triangleALeftSide && !triangleBLeftSide && !triangleCLeftSide)
                {
                    rightMesh.AddTriangle(currentTriangle);
                }
                else
                {
                    CutTriangle(plane, currentTriangle, triangleALeftSide, triangleBLeftSide, triangleCLeftSide, leftMesh, rightMesh, addedVertices);
                }
            }
        }

        if (_fill)
        {
            FillCut(addedVertices, plane, leftMesh, rightMesh);
        }

        originalMesh.Clear();

        originalMesh.vertices  = leftMesh.Vertices.ToArray();
        originalMesh.normals   = leftMesh.Normals.ToArray();
        originalMesh.uv        = leftMesh.UVs.ToArray();
        originalMesh.triangles = leftMesh.Indices(0);


        GameObject secondGameObject = GameObject.Instantiate(_originalGameObject);
        Mesh       secondMesh       = secondGameObject.GetComponent <MeshFilter>().mesh;

        secondMesh.vertices  = rightMesh.Vertices.ToArray();
        secondMesh.normals   = rightMesh.Normals.ToArray();
        secondMesh.uv        = rightMesh.UVs.ToArray();
        secondMesh.triangles = rightMesh.Indices(0);

        Component.Destroy(_originalGameObject.GetComponent <SphereCollider>());
        Component.Destroy(secondGameObject.GetComponent <SphereCollider>());

        _originalGameObject.AddComponent <MeshCollider>();
        secondGameObject.AddComponent <MeshCollider>();

        _originalGameObject.GetComponent <MeshCollider>().convex = true;
        secondGameObject.GetComponent <MeshCollider>().convex    = true;


        currentlyCutting = false;
    }
Ejemplo n.º 28
0
    public static void Fill(List <Vector3> _vertices, Plane _plane, GeneratedMesh _leftMesh, GeneratedMesh _rightMesh)
    {
        //Firstly we need the center we do this by adding up all the vertices and then calculating the average
        Vector3 centerPosition = Vector3.zero;

        for (int i = 0; i < _vertices.Count; i++)
        {
            centerPosition += _vertices[i];
        }
        centerPosition = centerPosition / _vertices.Count;

        //We now need an Upward Axis we use the plane we cut the mesh with for that
        Vector3 up = new Vector3()
        {
            x = _plane.normal.x,
            y = _plane.normal.y,
            z = _plane.normal.z
        };

        Vector3 left = Vector3.Cross(_plane.normal, up);

        Vector3 displacement = Vector3.zero;
        Vector2 uv1          = Vector2.zero;
        Vector2 uv2          = Vector2.zero;

        for (int i = 0; i < _vertices.Count; i++)
        {
            displacement = _vertices[i] - centerPosition;
            uv1          = new Vector2()
            {
                x = .5f + Vector3.Dot(displacement, left),
                y = .5f + Vector3.Dot(displacement, up)
            };

            displacement = _vertices[(i + 1) % _vertices.Count] - centerPosition;
            uv2          = new Vector2()
            {
                x = .5f + Vector3.Dot(displacement, left),
                y = .5f + Vector3.Dot(displacement, up)
            };

            Vector3[] vertices = new Vector3[] { _vertices[i], _vertices[(i + 1) % _vertices.Count], centerPosition };
            Vector3[] normals  = new Vector3[] { -_plane.normal, -_plane.normal, -_plane.normal };
            Vector2[] uvs      = new Vector2[] { uv1, uv2, new Vector2(0.5f, 0.5f) };

            MeshTriangle currentTriangle = new MeshTriangle(vertices, normals, uvs, originalMesh.subMeshCount + 1);

            if (Vector3.Dot(Vector3.Cross(vertices[1] - vertices[0], vertices[2] - vertices[0]), normals[0]) < 0)
            {
                FlipTriangel(currentTriangle);
            }
            _leftMesh.AddTriangle(currentTriangle);

            normals         = new Vector3[] { _plane.normal, _plane.normal, _plane.normal };
            currentTriangle = new MeshTriangle(vertices, normals, uvs, originalMesh.subMeshCount + 1);

            if (Vector3.Dot(Vector3.Cross(vertices[1] - vertices[0], vertices[2] - vertices[0]), normals[0]) < 0)
            {
                FlipTriangel(currentTriangle);
            }
            _rightMesh.AddTriangle(currentTriangle);
        }
    }
Ejemplo n.º 29
0
    Mesh GenerateMesh(Vector3 position)
    {
        int verticesPerSegment = 6;

        int vertexCount = verticesPerSegment * ((int)cellsPerTile) * ((int)cellsPerTile);

        int vertex = 0;
        // What cell is x and z for the bottom left of this tile in world space
        Vector3 tileBottomLeft = new Vector3();

        tileBottomLeft.x = -(cellsPerTile) / 2;
        tileBottomLeft.z = -(cellsPerTile) / 2;

        GeneratedMesh gm = new GeneratedMesh();

        gm.vertices  = new Vector3[vertexCount];
        gm.normals   = new Vector3[vertexCount];
        gm.uv        = new Vector2[vertexCount];
        gm.triangles = new int[vertexCount];
        gm.colors    = new Color[vertexCount];

        Vector2 texOrigin = position / cellSize;

        texOrigin.x = texOrigin.x % textureGenerator.size;
        texOrigin.y = texOrigin.y % textureGenerator.size;

        float tilesPerTexture = textureGenerator.size / cellsPerTile;

        for (int z = 0; z < cellsPerTile; z++)
        {
            for (int x = 0; x < cellsPerTile; x++)
            {
                int startVertex = vertex;

                Vector3 cellBottomLeft  = tileBottomLeft + new Vector3(x * cellSize, 0, z * cellSize);
                Vector3 cellTopLeft     = tileBottomLeft + new Vector3(x * cellSize, 0, ((z + 1) * cellSize));
                Vector3 cellTopRight    = tileBottomLeft + new Vector3((x + 1) * cellSize, 0, (z + 1) * cellSize);
                Vector3 cellBottomRight = tileBottomLeft + new Vector3((x + 1) * cellSize, 0, z * cellSize);

                // Add all the samplers together to make the height
                Vector3 cell = (position / cellSize) + tileBottomLeft + new Vector3(x, 0, z);
                foreach (Sampler sampler in samplers)
                {
                    cellBottomLeft.y  = sampler.Operate(cellBottomLeft.y, cell.x, cell.z);
                    cellTopLeft.y     = sampler.Operate(cellTopLeft.y, cell.x, cell.z + 1);
                    cellTopRight.y    = sampler.Operate(cellTopRight.y, cell.x + 1, cell.z + 1);
                    cellBottomRight.y = sampler.Operate(cellBottomRight.y, cell.x + 1, cell.z);
                }

                // Make the vertices
                gm.vertices[vertex++] = cellBottomLeft;
                gm.vertices[vertex++] = cellTopLeft;
                gm.vertices[vertex++] = cellTopRight;
                gm.vertices[vertex++] = cellTopRight;
                gm.vertices[vertex++] = cellBottomRight;
                gm.vertices[vertex++] = cellBottomLeft;

                vertex          = startVertex;
                gm.uv[vertex++] = MakeUV(position, x, z);
                gm.uv[vertex++] = MakeUV(position, x, z + 1);
                gm.uv[vertex++] = MakeUV(position, x + 1, z + 1);
                gm.uv[vertex++] = MakeUV(position, x + 1, z + 1);
                gm.uv[vertex++] = MakeUV(position, x + 1, z);
                gm.uv[vertex++] = MakeUV(position, x, z);


                // Make the triangles
                for (int i = 0; i < 6; i++)
                {
                    int vertexIndex = startVertex + i;
                    gm.triangles[vertexIndex] = vertexIndex;
                    gm.colors[vertexIndex]    = color;
                }
            }
        }
        Mesh mesh = new Mesh();

        mesh.vertices  = gm.vertices;
        mesh.uv        = gm.uv;
        mesh.triangles = gm.triangles;
        mesh.colors    = gm.colors;
        mesh.RecalculateNormals();

        return(mesh);
    }
Ejemplo n.º 30
0
    GeneratedMesh GenerateTileAsync(GameObject tileGameObject, Vector3 position, bool lod)
    {
        int verticesPerSegment = 6;

        //adjusting these values for LOD if necessary
        Vector2 cellsPerTile;
        Vector2 tileSize;
        Vector2 cellSize;

        if (lod)
        {
            cellsPerTile = new Vector2(this.cellsPerTile.x / lodFactor, this.cellsPerTile.y / lodFactor);
            tileSize = new Vector2(this.tileSize.x * lodFactor, this.tileSize.y * lodFactor);
            cellSize = new Vector2(this.cellSize.x * lodFactor, this.cellSize.y * lodFactor);
        }
        else
        {
            cellsPerTile = this.cellsPerTile;
            tileSize = this.tileSize;
            cellSize = this.cellSize;
        }

        int vertexCount = verticesPerSegment * ((int)cellsPerTile.x) * ((int)cellsPerTile.y);

        GeneratedMesh gm = new GeneratedMesh();

        gm.vertices = new Vector3[vertexCount];
        gm.normals = new Vector3[vertexCount];
        gm.uvs = new Vector2[vertexCount];
        gm.triangles = new int[vertexCount];

        gm.colours = new Color[vertexCount];

        int vertex = 0;

        // What cell is x and z for the bottom left of this tile in world space
        Vector3 tileBottomLeft = new Vector3();
        tileBottomLeft.x = - (tileSize.x) / 2;
        tileBottomLeft.z = - (tileSize.y) / 2;

        for (int z = 0; z < cellsPerTile.y; z++)
        {
            for (int x = 0; x < cellsPerTile.x; x++)
            {
                int startVertex = vertex;
                // Calculate some stuff
                Vector3 cellBottomLeft = tileBottomLeft + new Vector3(x * cellSize.x, 0, z * cellSize.y);
                Vector3 cellTopLeft = tileBottomLeft + new Vector3(x * cellSize.x, 0, (z + 1) * cellSize.y);
                Vector3 cellTopRight = tileBottomLeft + new Vector3((x + 1) * cellSize.x, 0 , (z + 1) * cellSize.y);
                Vector3 celBottomRight = tileBottomLeft + new Vector3((x + 1) * cellSize.x, 0, z * cellSize.y);

                // Add all the samplers together to make the height
                Vector3 cellWorldCoords = position + tileBottomLeft  + new Vector3(x * cellSize.x, 0, z * cellSize.y);
                foreach(Sampler sampler in samplers)
                {
                    cellBottomLeft.y += sampler.Sample(cellWorldCoords.x, cellWorldCoords.z);
                    cellTopLeft.y += sampler.Sample(cellWorldCoords.x, cellWorldCoords.z + cellSize.y);
                    cellTopRight.y += sampler.Sample(cellWorldCoords.x + cellSize.x, cellWorldCoords.z + cellSize.y);
                    celBottomRight.y += sampler.Sample(cellWorldCoords.x + cellSize.x, cellWorldCoords.z);
                }

                // Make the vertices
                gm.vertices[vertex++] = cellBottomLeft;
                gm.vertices[vertex++] = cellTopLeft;
                gm.vertices[vertex++] = cellTopRight;
                gm.vertices[vertex++] = cellTopRight;
                gm.vertices[vertex++] = celBottomRight;
                gm.vertices[vertex++] = cellBottomLeft;

                // Make the normals, UV's and triangles
                for (int i = 0; i < 6; i++)
                {
                    int vertexIndex = startVertex + i;
                    gm.triangles[vertexIndex] = vertexIndex;
                    gm.uvs[vertexIndex] = new Vector2(x / cellsPerTile.x, z / cellsPerTile.y);
                }
            }
        }
        return gm;
    }
Ejemplo n.º 31
0
    public static void Cut(GameObject _originalGameObject, Vector3 _contactPoint, Vector3 _direction, Material _cutMaterial = null,
                           bool fill = true, bool _addRigidBody = false)
    {
        if (currentlyCutting)
        {
            return;
        }

        currentlyCutting = true;

        Plane plane = new Plane(_originalGameObject.transform.InverseTransformDirection(-_direction),
                                _originalGameObject.transform.InverseTransformPoint(_contactPoint));

        originalGameObject = _originalGameObject;
        originalMesh       = _originalGameObject.GetComponent <MeshFilter>().mesh;
        List <Vector3> addedVertices = new List <Vector3>();

        GeneratedMesh leftMesh  = new GeneratedMesh();
        GeneratedMesh rightMesh = new GeneratedMesh();

        int[] submeshIndices;
        int   triangleIndexA, triangleIndexB, triangleIndexC;

        for (int i = 0; i < originalMesh.subMeshCount; i++)
        {
            submeshIndices = originalMesh.GetTriangles(i);

            for (int j = 0; j < submeshIndices.Length; j += 3)
            {
                triangleIndexA = submeshIndices[j];
                triangleIndexB = submeshIndices[j + 1];
                triangleIndexC = submeshIndices[j + 2];

                MeshTriangle currentTriangle = GetTriangle(triangleIndexA, triangleIndexB, triangleIndexC, i);

                bool triangleALeftSide = plane.GetSide(originalMesh.vertices[triangleIndexA]);
                bool triangleBLeftSide = plane.GetSide(originalMesh.vertices[triangleIndexB]);
                bool triangleCLeftSide = plane.GetSide(originalMesh.vertices[triangleIndexC]);

                /*
                 *  Three different cases:
                 *  - The triangle is either above the plane
                 *  - The triangle is below the plane
                 *  - The place intersects the triangle
                 */
                if (triangleALeftSide && triangleBLeftSide && triangleCLeftSide)
                {
                    leftMesh.AddTriangle(currentTriangle);
                }
                else if (!triangleALeftSide && !triangleBLeftSide && !triangleCLeftSide)
                {
                    rightMesh.AddTriangle(currentTriangle);
                }
                else
                {
                    CutTriangle(plane, currentTriangle, triangleALeftSide, triangleBLeftSide, triangleCLeftSide, leftMesh, rightMesh, addedVertices);
                }
            }
        }

        // if either mesh has no vertices, return
        if (leftMesh.Vertices.Count == 0 || rightMesh.Vertices.Count == 0 || addedVertices.Count == 0)
        {
            currentlyCutting = false;
            return;
        }

        FillCut(addedVertices, plane, leftMesh, rightMesh);

        GenerateGameObject(leftMesh);
        GenerateGameObject(rightMesh);
        Object.Destroy(_originalGameObject);
        currentlyCutting = false;
    }