Beispiel #1
0
 public void BuildData(ref List <Model3D.MeshData> meshes)
 {
     finalMesh = newFinalMesh();
     for (int t = 0; t < TempMeshes.Count; t++)
     {
         uint             indexCount = 0;
         Model3D.MeshData md         = new Model3D.MeshData();
         Bitmap           bmp        = textureImages[t];
         md.texture = ContentPipe.LoadTexture(ref bmp);
         md.texture.TextureParamS = textureInfo[t].wrapS;
         md.texture.TextureParamT = textureInfo[t].wrapT;
         TempMesh temp = TempMeshes[t];
         for (int i = 0; i < temp.vertices.Count; i++)
         {
             int vExists = doesVertexAlreadyExist(t, temp.vertices[i], temp.texCoords[i], temp.colors[i]);
             if (vExists < 0)
             {
                 Vector2 texCoord = temp.texCoords[i];
                 texCoord.X /= (float)bmp.Width * 32.0f;
                 texCoord.Y /= (float)bmp.Height * 32.0f;
                 temp.final.vertices.Add(temp.vertices[i]);
                 temp.final.texCoords.Add(texCoord);
                 temp.final.colors.Add(temp.colors[i]);
                 temp.final.indices.Add(indexCount);
                 indexCount++;
             }
             else
             {
                 temp.final.indices.Add((uint)vExists);
             }
         }
         meshes.Add(md);
     }
 }
Beispiel #2
0
    static private void FillBoundaryFace(TempMesh tempMesh, List <Vector3> added, ref Vector3[] tempTriangle)
    {
        // 1. Reorder added so in order ot their occurence along the perimeter.
        MeshUtils.ReorderList(added);

        // 2. Find actual face vertices
        var face = FindRealPolygon(added);

        // 3. Create triangle fans
        int t_fwd     = 0,
            t_bwd     = face.Count - 1,
            t_new     = 1;
        bool incr_fwd = true;

        while (t_new != t_fwd && t_new != t_bwd)
        {
            MeshTools.AddTriangle(tempMesh, ref tempTriangle, face, t_bwd, t_fwd, t_new);

            if (incr_fwd)
            {
                t_fwd = t_new;
            }
            else
            {
                t_bwd = t_new;
            }

            incr_fwd = !incr_fwd;
            t_new    = incr_fwd ? t_fwd + 1 : t_bwd - 1;
        }
    }
Beispiel #3
0
        /// <summary>
        /// Begins creating a new mesh object with given attributes
        /// </summary>
        /// <param name="name">The name of the Mesh Object</param>
        /// <param name="indices">The vertex indices as triangles</param>
        /// <paramref name="positions"/>
        /// <param name="parentBoneName"></param>
        /// <param name="generateBounding"></param>
        public void StartMeshObject(string name, uint[] indices, SsbhVertexAttribute[] positions, string parentBoneName = "", bool generateBounding = false)
        {
            currentMesh = new TempMesh
            {
                Name       = name,
                ParentBone = parentBoneName
            };
            currentMesh.Indices.AddRange(indices);
            currentMesh.VertexCount = positions.Length;

            meshes.Add(currentMesh);
            AddAttributeToMeshObject(UltimateVertexAttribute.Position0, positions);

            if (generateBounding)
            {
                //TODO: sphere generation
                BoundingBoxGenerator.GenerateAabb(positions, out SsbhVertexAttribute max, out SsbhVertexAttribute min);
                SetAaBoundingBox(min, max);
                SetOrientedBoundingBox(
                    new SsbhVertexAttribute((max.X + min.X / 2), (max.Y + min.Y / 2), (max.Y + min.Y / 2)),
                    new SsbhVertexAttribute((max.X - min.X), (max.Y - min.Y), (max.Z - min.Z)),
                    new float[] {
                    1, 0, 0,
                    0, 1, 0,
                    0, 0, 1
                });
            }
        }
Beispiel #4
0
    void Face(TempMesh mesh, int material, int side, Vector3 q1, Vector3 q2, Vector3 q3, Vector3 q4)
    {
        int a = mesh.vertex.Count;

        mesh.vertex.Add(q1);
        mesh.vertex.Add(q2);
        mesh.vertex.Add(q3);
        mesh.vertex.Add(q4);

        mesh.face.Add(a);
        mesh.face.Add(a + 2);
        mesh.face.Add(a + 1);
        mesh.face.Add(a + 2);
        mesh.face.Add(a + 3);
        mesh.face.Add(a + 1);

        mesh.uv.Add(new Vector2((float)(material - 1) / textureCount + 0.1f, 0));
        mesh.uv.Add(new Vector2((float)(material) / textureCount - 0.1f, 0));
        mesh.uv.Add(new Vector2((float)(material - 1) / textureCount + 0.1f, 1));
        mesh.uv.Add(new Vector2((float)(material) / textureCount - 0.1f, 1));

        /*
         * mesh.uv.Add(Main.main.GetMapTextures(material,0));
         * mesh.uv.Add(Main.main.GetMapTextures(material, 1));
         * mesh.uv.Add(Main.main.GetMapTextures(material, 2));
         * mesh.uv.Add(Main.main.GetMapTextures(material, 3));
         */
    }
Beispiel #5
0
        private TempMesh newTempMesh()
        {
            TempMesh m = new TempMesh();

            m.vertices  = new List <Vector3>();
            m.texCoords = new List <Vector2>();
            m.colors    = new List <Vector4>();
            m.final     = newFinalMesh();
            return(m);
        }
Beispiel #6
0
    static private void AddTriangle(TempMesh PositiveMesh, ref Vector3[] tempTriangle, List <Vector3> face, int t1, int t2, int t3)
    {
        tempTriangle[0] = face[t1];
        tempTriangle[1] = face[t2];
        tempTriangle[2] = face[t3];
        PositiveMesh.AddTriangle(tempTriangle);

        tempTriangle[1] = face[t3];
        tempTriangle[2] = face[t2];
        // NegativeMesh.AddTriangle(tempTriangle);
    }
Beispiel #7
0
    /// <summary>
    /// Replace the mesh with tempMesh.
    /// </summary>
    public static void ReplaceMesh(Mesh mesh, TempMesh tempMesh)
    {
        mesh.Clear();
        mesh.SetVertices(tempMesh.vertices);
        mesh.SetTriangles(tempMesh.triangles, 0);
        mesh.SetNormals(tempMesh.normals);
        mesh.SetUVs(0, tempMesh.uvs);

        //mesh.RecalculateNormals();
        mesh.RecalculateTangents();
    }
Beispiel #8
0
    void SliceObject(ref Plane slicePlane, GameObject obj)
    {
        var mesh = obj.GetComponent <MeshFilter>().mesh;

        if (!meshCutter.SliceMesh(mesh, ref slicePlane))
        {
            // If we didn't slice the object then no need to separate it into 2 objects
            // Debug.Log("Didn't slice");
            return;
        }

        // TODO: Update center of mass

        bool posBigger = meshCutter.PositiveMesh.surfacearea > meshCutter.NegativeMesh.surfacearea;

        if (posBigger)
        {
            biggerMesh  = meshCutter.PositiveMesh;
            smallerMesh = meshCutter.NegativeMesh;
        }
        else
        {
            biggerMesh  = meshCutter.NegativeMesh;
            smallerMesh = meshCutter.PositiveMesh;
        }

        // Put the bigger mesh in the original object
        // Ignore colliders for now
        ReplaceMesh(mesh, biggerMesh);

        // Create new Sliced object with the other mesh
        GameObject newObject = Instantiate(SlicedPrefab, ObjectContainer);

        newObject.transform.SetPositionAndRotation(obj.transform.position, obj.transform.rotation);
        var newObjMesh = newObject.GetComponent <MeshFilter>().mesh;

        ReplaceMesh(newObjMesh, smallerMesh);

        Transform posTransform, negTransform;

        if (posBigger)
        {
            posTransform = obj.transform;
            negTransform = newObject.transform;
        }
        else
        {
            posTransform = newObject.transform;
            negTransform = obj.transform;
        }

        // Separate meshes
        SeparateMeshes(posTransform, negTransform, slicePlane.normal);
    }
    private bool SliceObject(ref Plane slicePlane, GameObject obj, List <Transform> positiveObjects, List <Transform> negativeObjects, bool isPlayer)
    {
        var mesh = obj.GetComponent <MeshFilter>().mesh;

        if (!_meshCutter.SliceMesh(mesh, ref slicePlane))
        {
            if (slicePlane.GetDistanceToPoint(_meshCutter.GetFirstVertex()) >= 0)
            {
                positiveObjects.Add(obj.transform);
            }
            else
            {
                negativeObjects.Add(obj.transform);
            }

            return(false);
        }

        bool posBigger = _meshCutter.PositiveMesh.surfacearea > _meshCutter.NegativeMesh.surfacearea;

        if (posBigger)
        {
            _biggerMesh  = _meshCutter.PositiveMesh;
            _smallerMesh = _meshCutter.NegativeMesh;
        }
        else
        {
            _biggerMesh  = _meshCutter.NegativeMesh;
            _smallerMesh = _meshCutter.PositiveMesh;
        }

        GameObject newObject = Instantiate(obj, objectContainer);

        newObject.transform.SetPositionAndRotation(obj.transform.position, obj.transform.rotation);
        var newObjMesh = newObject.GetComponent <MeshFilter>().mesh;

        obj.GetComponent <Rigidbody>().useGravity  = true;
        obj.GetComponent <Rigidbody>().isKinematic = false;
        newObject.layer = 18;
        obj.layer       = 18;
        // Destroy(obj.GetComponent<BoxCollider>());
        //
        // obj.AddComponent<SphereCollider>();
        obj.GetComponent <Rigidbody>().AddForce(isPlayer ? 10f : 0f, 10f, 0f);

        ReplaceMesh(mesh, _biggerMesh);
        ReplaceMesh(newObjMesh, _smallerMesh);

        (posBigger ? positiveObjects : negativeObjects).Add(obj.transform);
        (posBigger ? negativeObjects : positiveObjects).Add(newObject.transform);

        return(true);
    }
Beispiel #10
0
    bool SliceObject(ref Plane slicePlane, GameObject obj, List <Transform> positiveObjects, List <Transform> negativeObjects)
    {
        var mesh = obj.GetComponent <MeshFilter>().mesh;

        if (!meshCutter.SliceMesh(mesh, ref slicePlane))
        {
            // Put object in the respective list
            if (slicePlane.GetDistanceToPoint(meshCutter.GetFirstVertex()) >= 0)
            {
                positiveObjects.Add(obj.transform);
            }
            else
            {
                negativeObjects.Add(obj.transform);
            }

            return(false);
        }

        // TODO: Update center of mass

        // Silly condition that labels which mesh is bigger to keep the bigger mesh in the original gameobject
        bool posBigger = meshCutter.PositiveMesh.surfacearea > meshCutter.NegativeMesh.surfacearea;

        if (posBigger)
        {
            biggerMesh  = meshCutter.PositiveMesh;
            smallerMesh = meshCutter.NegativeMesh;
        }
        else
        {
            biggerMesh  = meshCutter.NegativeMesh;
            smallerMesh = meshCutter.PositiveMesh;
        }

        // Create new Sliced object with the other mesh
        GameObject newObject = Instantiate(obj, ObjectContainer);

        newObject.transform.SetPositionAndRotation(obj.transform.position, obj.transform.rotation);
        var newObjMesh = newObject.GetComponent <MeshFilter>().mesh;

        // Put the bigger mesh in the original object
        // TODO: Enable collider generation (either the exact mesh or compute smallest enclosing sphere)
        ReplaceMesh(mesh, biggerMesh);
        ReplaceMesh(newObjMesh, smallerMesh);

        (posBigger ? positiveObjects : negativeObjects).Add(obj.transform);
        (posBigger ? negativeObjects : positiveObjects).Add(newObject.transform);

        return(true);
    }
Beispiel #11
0
    private bool SliceObject(ref Plane slicePlane, GameObject sliceObject, List <Transform> positiveObjects, List <Transform> negativeObjects)
    {
        var meshFilter = sliceObject.GetComponent <MeshFilter>();
        var mesh       = meshFilter.sharedMesh;

        if (!meshCutter.SliceMesh(mesh, ref slicePlane))
        {
            // Распределяем куски объекта в соответствующие списки
            if (slicePlane.GetDistanceToPoint(meshCutter.GetFirstVertex()) >= 0)
            {
                positiveObjects.Add(sliceObject.transform);
            }
            else
            {
                negativeObjects.Add(sliceObject.transform);
            }

            return(false);
        }

        // Определяем больший меш для исходного объекта
        bool posBigger = meshCutter.PositiveMesh.surfaceArea > meshCutter.NegativeMesh.surfaceArea;

        if (posBigger)
        {
            biggerMesh  = meshCutter.PositiveMesh;
            smallerMesh = meshCutter.NegativeMesh;
        }
        else
        {
            biggerMesh  = meshCutter.NegativeMesh;
            smallerMesh = meshCutter.PositiveMesh;
        }

        //Новый меньший отрезанный объект
        GameObject newObject = Instantiate(sliceObject, ObjectContainer);

        newObject.transform.SetPositionAndRotation(sliceObject.transform.position, sliceObject.transform.rotation);
        var newObjMesh = newObject.GetComponent <MeshFilter>().mesh;

        //Распределение мешей и переопределение MeshCollider'ов
        ReplaceMesh(mesh, biggerMesh, sliceObject.GetComponent <MeshCollider>());
        ReplaceMesh(newObjMesh, smallerMesh, newObject.GetComponent <MeshCollider>());

        (posBigger ? positiveObjects : negativeObjects).Add(sliceObject.transform);
        (posBigger ? negativeObjects : positiveObjects).Add(newObject.transform);

        return(true);
    }
Beispiel #12
0
    public MeshCutter(int initialArraySize)
    {
        PositiveMesh = new TempMesh(initialArraySize);
        NegativeMesh = new TempMesh(initialArraySize);

        addedPairs  = new List <Vector3>(initialArraySize);
        ogVertices  = new List <Vector3>(initialArraySize);
        ogTriangles = new List <int>(initialArraySize * 3);
        ogNormals   = new List <Vector3>(initialArraySize);

        intersectPair = new Vector3[2];
        tempTriangle  = new Vector3[3];

        intersect = new Intersections();
    }
Beispiel #13
0
    /// <summary>
    /// Replace the mesh with tempMesh.
    /// </summary>
    void ReplaceMesh(Mesh mesh, TempMesh tempMesh, MeshCollider collider = null)
    {
        mesh.Clear();
        mesh.SetVertices(tempMesh.vertices);
        mesh.SetTriangles(tempMesh.triangles, 0);
        mesh.SetNormals(tempMesh.normals);

        //mesh.RecalculateNormals();
        mesh.RecalculateTangents();

        if (collider != null && collider.enabled)
        {
            collider.sharedMesh = mesh;
            collider.convex     = true;
        }
    }
Beispiel #14
0
    bool SliceObject(ref Plane slicePlane, GameObject obj, List <Transform> positiveObjects, List <Transform> negativeObjects)
    {
        var mesh = obj.GetComponent <MeshFilter>().mesh;

        if (!meshCutter.SliceMesh(mesh, ref slicePlane))
        {
            if (slicePlane.GetDistanceToPoint(meshCutter.GetFirstVertex()) >= 0)
            {
                positiveObjects.Add(obj.transform);
            }
            else
            {
                negativeObjects.Add(obj.transform);
            }

            return(false);
        }

        bool posBigger = meshCutter.PositiveMesh.surfacearea > meshCutter.NegativeMesh.surfacearea;

        if (posBigger)
        {
            biggerMesh  = meshCutter.PositiveMesh;
            smallerMesh = meshCutter.NegativeMesh;
        }
        else
        {
            biggerMesh  = meshCutter.NegativeMesh;
            smallerMesh = meshCutter.PositiveMesh;
        }

        // Create new Sliced object with the other mesh
        GameObject newObject = Instantiate(obj, ObjectContainer);

        newObject.transform.SetPositionAndRotation(obj.transform.position, obj.transform.rotation);
        var newObjMesh = newObject.GetComponent <MeshFilter>().mesh;


        ReplaceMesh(mesh, biggerMesh);
        ReplaceMesh(newObjMesh, smallerMesh);

        (posBigger ? positiveObjects : negativeObjects).Add(obj.transform);
        (posBigger ? negativeObjects : positiveObjects).Add(newObject.transform);

        return(true);
    }
Beispiel #15
0
        public void AddTexture(TextureFormats.Raw bmp, TextureInfo info, uint segmentAddress, TempMaterial material)
        {
            TempMeshData data;

            data.info           = info;
            data.segmentAddress = segmentAddress;
            if (null != (object)material)
            {
                data.wr_material = material.weakref;
            }
            else
            {
                data.wr_material = null;
            }
            TempMesh.Add(ref TempMeshes, ref data, new TempMeshReferences {
                bmp = bmp,
            });
            currentMaterial = TempMeshes.last;
        }
Beispiel #16
0
        /*
         * public Vector3[] getVertices(int i) {
         * return TempMeshes[i].final.vertices.ToArray();
         * }
         *
         * public Vector2[] getTexCoords(int i)
         * {
         * return TempMeshes[i].final.texCoords.ToArray();
         * }
         *
         * public Vector4[] getColors(int i)
         * {
         *      return TempMeshes[i].final.colors.ToArray();
         * }
         *
         * public Vector3[] getNormals(int i)
         * {
         *      return TempMeshes[i].final.normals.ToArray();
         * }
         *
         * public uint[] getIndices(int i)
         * {
         * return TempMeshes[i].final.indices.ToArray();
         * }
         */
        public bool hasTexture(uint segmentAddress, TempMaterial register)
        {
            TempMesh mesh_iter;
            uint     mesh_iter_pos;

            if (null == (object)register)
            {
                for (mesh_iter = TempMeshes.first,
                     mesh_iter_pos = TempMeshes.count; 0 != mesh_iter_pos;
                     mesh_iter = mesh_iter.next, --mesh_iter_pos)
                {
                    if (mesh_iter.value.segmentAddress == segmentAddress && mesh_iter.value.wr_material == null)
                    {
                        break;
                    }
                }
            }
            else
            {
                for (mesh_iter = TempMeshes.first,
                     mesh_iter_pos = TempMeshes.count; 0 != mesh_iter_pos;
                     mesh_iter = mesh_iter.next, --mesh_iter_pos)
                {
                    if (mesh_iter.value.segmentAddress == segmentAddress && mesh_iter.value.wr_material == register.weakref)
                    {
                        break;
                    }
                }
            }

            if (mesh_iter_pos != 0)
            {
                currentMaterial = mesh_iter;
                return(true);
            }
            else
            {
                return(false);
            }
        }
Beispiel #17
0
        /*
         * private void AddFinalVertex(Vector3 pos, Vector2 uv, Vector4 color)
         * {
         *  finalMesh.vertices.Add(pos);
         *  finalMesh.texCoords.Add(uv);
         *  finalMesh.colors.Add(color);
         * }*/

        private int doesVertexAlreadyExist(int index, Vector3 pos, Vector2 uv, Vector4 col)
        {
            TempMesh tmp = TempMeshes[index];

            for (int i = 0; i < tmp.final.vertices.Count; i++)
            {
                Vector3 v = tmp.final.vertices[i];
                if (pos.X == v.X && pos.Y == v.Y && pos.Z == v.Z)
                {
                    Vector2 t = tmp.final.texCoords[i];
                    if (uv.X == t.X && uv.Y == t.Y)
                    {
                        Vector4 c = tmp.final.colors[i];
                        if (col.X == c.X && col.Y == c.Y && col.Z == c.Z && col.W == c.W)
                        {
                            return(i);
                        }
                    }
                }
            }
            return(-1);
        }
Beispiel #18
0
        public void BuildData(List <Model3D.MeshData> meshes)
        {
            //TextureAtlasBuilder.TextureAtlas atlas = new TextureAtlasBuilder.TextureAtlas(textureImages);
            //atlas.outputToPNG("TestAtlas.png");

            finalMesh = newFinalMesh();
            for (int t = 0; t < TempMeshes.Count; t++)
            {
                uint indexCount = 0;
                meshes.Add(new Model3D.MeshData());
                //if (t != 0) continue;
                //TextureAtlasBuilder.TextureAtlas.AtlasEntry atlasEntry = atlas.getEntryFromID((uint)t);
                Model3D.MeshData md = meshes[t];
                md.texture = ContentPipe.LoadTexture(textureImages[t]);
                md.texture.TextureParamS = textureInfo[t].wrapS;
                md.texture.TextureParamT = textureInfo[t].wrapT;
                //Console.WriteLine("[Building]: " + (OpenTK.Graphics.OpenGL.All)md.texture.TextureParamS + "," +(OpenTK.Graphics.OpenGL.All)md.texture.TextureParamT);
                TempMesh temp = TempMeshes[t];
                for (int i = 0; i < temp.vertices.Count; i++)
                {
                    int vExists = doesVertexAlreadyExist(t, temp.vertices[i], temp.texCoords[i], temp.colors[i]);
                    if (vExists < 0)
                    {
                        Vector2 texCoord = temp.texCoords[i];
                        texCoord.X /= (float)textureImages[t].Width * 32.0f;
                        texCoord.Y /= (float)textureImages[t].Height * 32.0f;
                        temp.final.vertices.Add(temp.vertices[i]);
                        temp.final.texCoords.Add(texCoord);
                        temp.final.colors.Add(temp.colors[i]);
                        temp.final.indices.Add(indexCount);
                        indexCount++;
                    }
                    else
                    {
                        temp.final.indices.Add((uint)vExists);
                    }
                }
            }
        }
Beispiel #19
0
    /// <summary>
    /// Replace the mesh with tempMesh.
    /// </summary>
    void ReplaceMesh(Mesh mesh, TempMesh tempMesh, MeshCollider collider = null)
    {
        //var colors = new Color32[tempMesh.vertices.Count];
        //var color = mesh.colors32[0];
        //for (int i = 0; i < colors.Length; i++) {
        //	colors[i] = color;
        //}
        mesh.Clear();
        mesh.SetVertices(tempMesh.vertices);
        mesh.SetTriangles(tempMesh.triangles, 0);
        mesh.SetNormals(tempMesh.normals);
        mesh.SetUVs(0, tempMesh.uvs);
        //mesh.SetColors();
        //mesh.colors32 = colors;

        //mesh.RecalculateNormals();
        mesh.RecalculateTangents();

        if (collider != null && collider.enabled)
        {
            collider.sharedMesh = mesh;
            collider.convex     = true;
        }
    }
Beispiel #20
0
    /// <summary> Save the Mesh as a new GameObject</summary>
    public static GameObject Export(TempMesh tempMesh, string name)
    {
        var g = new GameObject(name);

        var meshFilter = g.AddComponent <MeshFilter>();

        meshFilter.mesh.Clear();
        meshFilter.mesh.SetVertices(tempMesh.vertices);
        meshFilter.mesh.SetTriangles(tempMesh.triangles, 0);
        meshFilter.mesh.SetNormals(tempMesh.normals);
        meshFilter.mesh.SetUVs(0, tempMesh.uvs);

        //mesh.RecalculateNormals();
        meshFilter.mesh.RecalculateTangents();

        // var rigidbody = g.AddComponent<Rigidbody>();
        // rigidbody.useGravity = false;

        // var collider = g.AddComponent<MeshCollider>();
        // collider.convex = true;
        // collider.sharedMesh = mesh;

        return(g);
    }
Beispiel #21
0
    public void Render()
    {
        TempMesh terrain = new TempMesh();
        TempMesh water   = new TempMesh();

        for (int y = (int)(Main.main.chunkSize.y * chunkNumber.y); y < (int)(Main.main.chunkSize.y * (chunkNumber.y + 1)); y++)
        {
            TempMesh terrainCover = new TempMesh();
            TempMesh waterCover   = new TempMesh();
            for (int x = (int)(Main.main.chunkSize.x * chunkNumber.x); x < (int)(Main.main.chunkSize.x * (chunkNumber.x + 1)); x++)
            {
                for (int z = (int)(Main.main.chunkSize.z * chunkNumber.z); z < (int)(Main.main.chunkSize.z * (chunkNumber.z + 1)); z++)
                {
                    if (Main.main.GetBlock(x, y, z) > 0)
                    {
                        if (Main.main.GetBlock(x, y, z) != (int)Material.water)
                        {
                            if (Avaible(x, y + 1, z))
                            {
                                Face(terrain, Main.main.GetBlock(x, y, z), 0, new Vector3(x, y + 1, z), new Vector3(x + 1, y + 1, z), new Vector3(x, y + 1, z + 1), new Vector3(x + 1, y + 1, z + 1));
                            }
                            else
                            {
                                Face(terrainCover, Main.main.GetBlock(x, y, z), 0, new Vector3(x, y + 1, z), new Vector3(x + 1, y + 1, z), new Vector3(x, y + 1, z + 1), new Vector3(x + 1, y + 1, z + 1));
                            }
                        }
                        else
                        {
                            if (Avaible(x, y + 1, z))
                            {
                                Face(water, Main.main.GetBlock(x, y, z), 0, new Vector3(x, y + 1, z), new Vector3(x + 1, y + 1, z), new Vector3(x, y + 1, z + 1), new Vector3(x + 1, y + 1, z + 1));
                            }
                            else
                            {
                                Face(waterCover, Main.main.GetBlock(x, y, z), 0, new Vector3(x, y + 1, z), new Vector3(x + 1, y + 1, z), new Vector3(x, y + 1, z + 1), new Vector3(x + 1, y + 1, z + 1));
                            }
                        }
                        if (Main.main.GetBlock(x, y, z) != (int)Material.water)
                        {
                            if (Avaible(x, y - 1, z))
                            {
                                Face(terrain, Main.main.GetBlock(x, y, z), 1, new Vector3(x + 1, y, z + 1), new Vector3(x + 1, y, z), new Vector3(x, y, z + 1), new Vector3(x, y, z));
                            }

                            if (Avaible(x + 1, y, z))
                            {
                                Face(terrain, Main.main.GetBlock(x, y, z), 2, new Vector3(x + 1, y, z), new Vector3(x + 1, y, z + 1), new Vector3(x + 1, y + 1, z), new Vector3(x + 1, y + 1, z + 1));
                            }

                            if (Avaible(x - 1, y, z))
                            {
                                Face(terrain, Main.main.GetBlock(x, y, z), 2, new Vector3(x, y, z + 1), new Vector3(x, y, z), new Vector3(x, y + 1, z + 1), new Vector3(x, y + 1, z));
                            }

                            if (Avaible(x, y, z - 1))
                            {
                                Face(terrain, Main.main.GetBlock(x, y, z), 2, new Vector3(x, y, z), new Vector3(x + 1, y, z), new Vector3(x, y + 1, z), new Vector3(x + 1, y + 1, z));
                            }

                            if (Avaible(x, y, z + 1))
                            {
                                Face(terrain, Main.main.GetBlock(x, y, z), 2, new Vector3(x + 1, y, z + 1), new Vector3(x, y, z + 1), new Vector3(x + 1, y + 1, z + 1), new Vector3(x, y + 1, z + 1));
                            }
                        }
                    }
                }
            }
            Mesh temp = new Mesh();
            temp.vertices  = terrainCover.vertex.ToArray();
            temp.uv        = terrainCover.uv.ToArray();
            temp.triangles = terrainCover.face.ToArray();
            Mesh temp2 = new Mesh();
            temp2.vertices  = waterCover.vertex.ToArray();
            temp2.uv        = waterCover.uv.ToArray();
            temp2.triangles = waterCover.face.ToArray();
            levels[y]       = new Level(terrain.face.Count, water.face.Count, temp, temp2);
        }
        allTerrain           = new Mesh();
        allTerrain.vertices  = terrain.vertex.ToArray();
        allTerrain.uv        = terrain.uv.ToArray();
        allTerrain.triangles = terrain.face.ToArray();
        allTerrain.RecalculateNormals();
        GetComponent <MeshFilter>().mesh         = allTerrain;
        GetComponent <MeshCollider>().sharedMesh = allTerrain;

        allWater           = new Mesh();
        allWater.vertices  = water.vertex.ToArray();
        allWater.uv        = water.uv.ToArray();
        allWater.triangles = water.face.ToArray();
        allWater.RecalculateNormals();
        waterPrefab.GetComponent <MeshFilter>().mesh = allWater;
    }
    public bool TrianglePlaneIntersect(List <Vector3> vertices, List <Vector2> uvs, List <int> triangles, int startIdx, ref Plane plane, TempMesh posMesh, TempMesh negMesh, Vector3[] intersectVectors)
    {
        int i;

        for (i = 0; i < 3; ++i)
        {
            t[i] = triangles[startIdx + i];
            v[i] = vertices[t[i]];
            u[i] = uvs[t[i]];
        }

        // Находится ли вершина на положительной сетке
        posMesh.ContainsKeys(triangles, startIdx, positive);

        // Если они все на одной стороне, не пересечения нет
        if (positive[0] == positive[1] && positive[1] == positive[2])
        {
            // Все точки на одной стороне, пересечения нет
            // Добавляем их в положительный или отрицательный меш
            (positive[0] ? posMesh : negMesh).AddOriginalTriangle(t);
            return(false);
        }

        // Поиск одиноой точки
        int lonelyPoint = 0;

        if (positive[0] != positive[1])
        {
            lonelyPoint = positive[0] != positive[2] ? 0 : 1;
        }
        else
        {
            lonelyPoint = 2;
        }

        // Устанавливаем предыдущую точку относительно порядка передней грани
        int prevPoint = lonelyPoint - 1;

        if (prevPoint == -1)
        {
            prevPoint = 2;
        }
        // Устанавливаем следующую точку
        int nextPoint = lonelyPoint + 1;

        if (nextPoint == 3)
        {
            nextPoint = 0;
        }

        // Получаем 2 точки пересечения
        ValueTuple <Vector3, Vector2> newPointPrev = Intersect(plane, v[lonelyPoint], v[prevPoint], u[lonelyPoint], u[prevPoint]);
        ValueTuple <Vector3, Vector2> newPointNext = Intersect(plane, v[lonelyPoint], v[nextPoint], u[lonelyPoint], u[nextPoint]);

        // Добавляем новые треугольники и сохраните их в соответствующих буферных мешах
        (positive[lonelyPoint] ? posMesh : negMesh).AddSlicedTriangle(t[lonelyPoint], newPointNext.Item1, newPointPrev.Item1, newPointNext.Item2, newPointPrev.Item2);

        (positive[prevPoint] ? posMesh : negMesh).AddSlicedTriangle(t[prevPoint], newPointPrev.Item1, newPointPrev.Item2, t[nextPoint]);

        (positive[prevPoint] ? posMesh : negMesh).AddSlicedTriangle(t[nextPoint], newPointPrev.Item1, newPointNext.Item1, newPointPrev.Item2, newPointNext.Item2);

        // Возвращаем ребро, которое будет в правильной ориентации для положительного меша
        if (positive[lonelyPoint])
        {
            intersectVectors[0] = newPointPrev.Item1;
            intersectVectors[1] = newPointNext.Item1;
        }
        else
        {
            intersectVectors[0] = newPointNext.Item1;
            intersectVectors[1] = newPointPrev.Item1;
        }
        return(true);
    }
Beispiel #23
0
    bool SliceObject(ref Plane slicePlane, GameObject obj, List <Transform> positiveObjects, List <Transform> negativeObjects)
    {
        var mesh = obj.GetComponent <MeshFilter>().mesh;

        if (!meshCutter.SliceMesh(mesh, ref slicePlane))
        {
            // Put object in the respective list
            if (slicePlane.GetDistanceToPoint(meshCutter.GetFirstVertex()) >= 0)
            {
                positiveObjects.Add(obj.transform);
            }
            else
            {
                negativeObjects.Add(obj.transform);
            }

            return(false);
        }

        // TODO: Update center of mass

        // Silly condition that labels which mesh is bigger to keep the bigger mesh in the original gameobject
        bool posBigger = meshCutter.PositiveMesh.surfacearea > meshCutter.NegativeMesh.surfacearea;

        if (posBigger)
        {
            biggerMesh  = meshCutter.PositiveMesh;
            smallerMesh = meshCutter.NegativeMesh;
        }
        else
        {
            biggerMesh  = meshCutter.NegativeMesh;
            smallerMesh = meshCutter.PositiveMesh;
        }

        // Create new Sliced object with the other mesh
        var newObject = Instantiate(obj, objectContainer);

        spawner.NewFruitCut(newObject);
        newObject.transform.SetPositionAndRotation(obj.transform.position, obj.transform.rotation);
        var newObjMesh = newObject.GetComponent <MeshFilter>().mesh;

        // Put the bigger mesh in the original object
        // TODO: Enable collider generation (either the exact mesh or compute smallest enclosing sphere)
        ReplaceMesh(mesh, biggerMesh);
        ReplaceMesh(newObjMesh, smallerMesh);

        (posBigger ? positiveObjects : negativeObjects).Add(obj.transform);
        (posBigger ? negativeObjects : positiveObjects).Add(newObject.transform);

        if (obj.layer != /*UI*/ 5)
        {
            sController?.AddScore();
        }
        else
        {
            uiSliceCount += 1;
            if (uiSliceCount == 5)
            {
                gameStarter.GoToGameMode();
                for (int i = 0; i < fruitsChild.transform.childCount; i++)
                {
                    fruitsChild.transform.GetChild(i).gameObject.SetActive(false);
                }
            }
        }
        //audio
        sliceSample.Play();
        //slice effect
        if (fruitSliceEffect != null)
        {
            Instantiate(fruitSliceEffect, obj.transform);
        }

        obj.tag       = "nonSlisable";
        newObject.tag = "nonSlisable";
        return(true);
    }
    /*
     * Small diagram for reference :)
     *       |      |  /|
     *       |      | / |P1
     *       |      |/  |
     *       |    I1|   |
     *       |     /|   |
     *      y|    / |   |
     *       | P0/__|___|P2
     *       |      |I2
     *       |      |
     *       |___________________
     */

    public bool TrianglePlaneIntersect(List <Vector3> vertices, List <Vector2> uvs, List <int> triangles, int startIdx, ref Plane plane, TempMesh posMesh, TempMesh negMesh, Vector3[] intersectVectors)
    {
        int i;

        // Store triangle, vertex and uv from indices
        for (i = 0; i < 3; ++i)
        {
            t[i] = triangles[startIdx + i];
            v[i] = vertices[t[i]];
            u[i] = uvs[t[i]];
        }

        // Store wether the vertex is on positive mesh
        posMesh.ContainsKeys(triangles, startIdx, positive);

        // If they're all on the same side, don't do intersection
        if (positive[0] == positive[1] && positive[1] == positive[2])
        {
            // All points are on the same side. No intersection
            // Add them to either positive or negative mesh
            (positive[0] ? posMesh : negMesh).AddOgTriangle(t);
            return(false);
        }

        // Find lonely point
        int lonelyPoint = 0;

        if (positive[0] != positive[1])
        {
            lonelyPoint = positive[0] != positive[2] ? 0 : 1;
        }
        else
        {
            lonelyPoint = 2;
        }

        // Set previous point in relation to front face order
        int prevPoint = lonelyPoint - 1;

        if (prevPoint == -1)
        {
            prevPoint = 2;
        }
        // Set next point in relation to front face order
        int nextPoint = lonelyPoint + 1;

        if (nextPoint == 3)
        {
            nextPoint = 0;
        }

        // Get the 2 intersection points
        ValueTuple <Vector3, Vector2> newPointPrev = Intersect(plane, v[lonelyPoint], v[prevPoint], u[lonelyPoint], u[prevPoint]);
        ValueTuple <Vector3, Vector2> newPointNext = Intersect(plane, v[lonelyPoint], v[nextPoint], u[lonelyPoint], u[nextPoint]);

        //Set the new triangles and store them in respective tempmeshes
        (positive[lonelyPoint] ? posMesh : negMesh).AddSlicedTriangle(t[lonelyPoint], newPointNext.Item1, newPointPrev.Item1, newPointNext.Item2, newPointPrev.Item2);

        (positive[prevPoint] ? posMesh : negMesh).AddSlicedTriangle(t[prevPoint], newPointPrev.Item1, newPointPrev.Item2, t[nextPoint]);

        (positive[prevPoint] ? posMesh : negMesh).AddSlicedTriangle(t[nextPoint], newPointPrev.Item1, newPointNext.Item1, newPointPrev.Item2, newPointNext.Item2);

        // We return the edge that will be in the correct orientation for the positive side mesh
        if (positive[lonelyPoint])
        {
            intersectVectors[0] = newPointPrev.Item1;
            intersectVectors[1] = newPointNext.Item1;
        }
        else
        {
            intersectVectors[0] = newPointNext.Item1;
            intersectVectors[1] = newPointPrev.Item1;
        }
        return(true);
    }
    void Fracture(Vector2 center)
    {
        vec3center = new Vector3(center.x, center.y);
        print("Generating sites around " + center.ToString("F3"));
        var sites = VoronoiHelpers.GenerateSites(canvasSize, 30, center);

        drawSites(sites);

        var points = new List <VoronoiLib.Structures.FortuneSite>();

        foreach (var site in sites)
        {
            // move all input points to Quadrant 1
            var offsetSite = site;
            points.Add(new VoronoiLib.Structures.FortuneSite(offsetSite.x, offsetSite.y));
        }

        //FortunesAlgorithm.Run(points, min x, min y, max x, max y)
        LinkedList <VoronoiLib.Structures.VEdge> cuttingEdges = VoronoiLib.FortunesAlgorithm.Run(points, 0, 0, 800, 800);

        // HERE !@!@$@!%$@!%

        var delaunay = VoronoiHelpers.GenerateDelaunay(points);

        StartCoroutine(DrawVoronoiCoroutine(cuttingEdges));
        // StartCoroutine(DrawDelaunayCoroutine(delaunay));

        // Make a copy of the original mesh
        var workingMesh = MeshTools.Clone(mesh);
        // Disable the orginal mesh
        // mesh.Clear();
        // this.GetComponent<Renderer>().enabled = false;

        int i = 0;

        // Sutherland–Hodgman algorithm for slicing concave shapes
        foreach (var point in points)
        {
            // Duplicate the working mesh
            var piece = MeshTools.Clone(workingMesh);
            print("Cutting piece " + i + ", " + point.Neighbors.Count + " neighbors.");

            foreach (var neighbor in point.Neighbors)
            {
                // Find the perpendicular bisector and slice
                var a        = new Vector2((float)point.X, (float)point.Y);
                var b        = new Vector2((float)neighbor.X, (float)neighbor.Y);
                var bisector = VoronoiHelpers.PerpendicularBisector(a, b);

                // Keep vertices from this side of the bisector line
                try {
                    TempMesh temp = MeshTools.Cut(piece, bisector, center);
                    MeshTools.ReplaceMesh(mesh, temp);
                    print("SUCCESS");
                } catch (UnityException e) {
                    print(e.ToString());
                }
                // Fill the hole
                // MeshTools.FillHoles(piece);

                // Now we have the final chunk, save it to a new GameObject
                // var g = MeshTools.Export(temp, "Piece " + i);
                // MeshTools.ReplaceMesh(mesh, temp);

                // break;
            }

            // Instantiate(g, g.transform.position, Quaternion.identity);
            i++;
            break;
        }

        mesh = workingMesh;

        print("length: " + points.Count);
    }
Beispiel #26
0
    /// <summary>Cut mesh along bisector line and keep only the half containing the center point.</summary>
    public static TempMesh Cut(Mesh mesh, Line bisector, Vector2 center)
    {
        var      initialArraySize = 256;
        TempMesh tempMesh         = new TempMesh(initialArraySize);
        TempMesh trashMesh        = new TempMesh(initialArraySize);
        var      intersect        = new Intersections();

        var addedPairs    = new List <Vector3>(initialArraySize);
        var ogVertices    = new List <Vector3>(initialArraySize);
        var ogNormals     = new List <Vector3>(initialArraySize);
        var ogUvs         = new List <Vector2>(initialArraySize);
        var ogTriangles   = new List <int>(initialArraySize * 3);
        var intersectPair = new Vector3[2];

        var tempTriangle = new Vector3[3];

        // Let's always fill the vertices array so that we can access it even if the mesh didn't intersect
        mesh.GetVertices(ogVertices);
        mesh.GetTriangles(ogTriangles, 0);
        mesh.GetNormals(ogNormals);
        mesh.GetUVs(0, ogUvs);

        tempMesh.Clear();
        trashMesh.Clear();

        for (int i = 0; i < ogVertices.Count; ++i)
        {
            var test = bisector.isLeft(ogVertices[i]);
            // Debug.Log(test);
            if (test)
            {
                tempMesh.AddVertex(ogVertices, ogNormals, ogUvs, i);
            }
            else
            {
                trashMesh.AddVertex(ogVertices, ogNormals, ogUvs, i);
            }
        }

        Plane slice = bisector.GetPlane();

        // 3. Separate triangles and cut those that intersect the plane
        for (int i = 0; i < ogTriangles.Count; i += 3)
        {
            if (intersect.TrianglePlaneIntersect(ogVertices, ogUvs, ogTriangles, i, ref slice, tempMesh, trashMesh, intersectPair))
            {
                addedPairs.AddRange(intersectPair);
            }
        }

        if (addedPairs.Count > 0)
        {
            //FillBoundaryGeneral(addedPairs);
            MeshTools.FillBoundaryFace(tempMesh, addedPairs, ref tempTriangle);
            return(tempMesh);
        }
        else
        {
            throw new UnityException("Error: if added pairs is empty, we should have returned false earlier");
        }

        return(tempMesh);
    }
Beispiel #27
0
    bool SliceObject(ref Plane slicePlane, GameObject obj, List <Transform> positiveObjects, List <Transform> negativeObjects, bool isPlayer)
    {
        var mesh = obj.GetComponent <MeshFilter>().mesh;

        if (!meshCutter.SliceMesh(mesh, ref slicePlane))
        {
            // Put object in the respective list
            if (slicePlane.GetDistanceToPoint(meshCutter.GetFirstVertex()) >= 0)
            {
                positiveObjects.Add(obj.transform);
            }
            else
            {
                negativeObjects.Add(obj.transform);
            }

            return(false);
        }

        // TODO: Update center of mass

        // Silly condition that labels which mesh is bigger to keep the bigger mesh in the original gameobject
        bool posBigger = meshCutter.PositiveMesh.surfacearea > meshCutter.NegativeMesh.surfacearea;

        if (posBigger)
        {
            biggerMesh  = meshCutter.PositiveMesh;
            smallerMesh = meshCutter.NegativeMesh;
        }
        else
        {
            biggerMesh  = meshCutter.NegativeMesh;
            smallerMesh = meshCutter.PositiveMesh;
        }

        // Create new Sliced object with the other mesh
        GameObject newObject = Instantiate(obj, ObjectContainer);

        newObject.transform.SetPositionAndRotation(obj.transform.position, obj.transform.rotation);
        var newObjMesh = newObject.GetComponent <MeshFilter>().mesh;

        //add gravity and disable kinematic to new game object
        obj.GetComponent <Rigidbody>().useGravity  = true;
        obj.GetComponent <Rigidbody>().isKinematic = false;
        newObject.layer = 13;
        obj.layer       = 13;
        //Recalculate box collider
        Destroy(obj.GetComponent <BoxCollider>());
        // obj.AddComponent<MeshCollider>();
        // obj.GetComponent<MeshCollider>().convex = true;

        obj.AddComponent <SphereCollider>();
        obj.GetComponent <Rigidbody>().AddForce(isPlayer ? 10f : 0f, gm.cutObjGravityCoefficient * 10f, 0f);
        //obj.GetComponent<SphereCollider>().isTrigger = true;
        // obj.GetComponent<SphereCollider>().radius = 0.5f;
        // obj.GetComponent<SphereCollider>().center = new Vector3(0f,1f,0f);

        // Put the bigger mesh in the original object
        // TODO: Enable collider generation (either the exact mesh or compute smallest enclosing sphere)
        ReplaceMesh(mesh, biggerMesh);
        ReplaceMesh(newObjMesh, smallerMesh);

        (posBigger ? positiveObjects : negativeObjects).Add(obj.transform);
        (posBigger ? negativeObjects : positiveObjects).Add(newObject.transform);

        return(true);
    }
Beispiel #28
0
 public void Dispose()
 {
     TempMesh.Free(ref TempMeshes);
 }