// Prepare shards. Set bounds, set neibs
        static void SetShardsByRigids(RFCluster cluster, List <RayfireRigid> rigidList, ConnectivityType connectivity)
        {
            for (int i = 0; i < rigidList.Count; i++)
            {
                // Get mesh filter
                MeshFilter mf = rigidList[i].GetComponent <MeshFilter>();

                // Child has no mesh
                if (mf == null)
                {
                    continue;
                }

                // Create new shard
                RFShard shard = new RFShard(rigidList[i].transform, i);
                shard.cluster = cluster;
                shard.rigid   = rigidList[i];
                shard.uny     = rigidList[i].activation.unyielding;
                shard.col     = rigidList[i].physics.meshCollider;

                // Set faces data for connectivity
                if (connectivity == ConnectivityType.ByMesh)
                {
                    RFTriangle.SetTriangles(shard, mf);
                }

                // Collect shard
                cluster.shards.Add(shard);
            }
        }
Beispiel #2
0
        // Prepare shards. Set bounds, set neibs
        public static List <RFShard> GetShards(List <RayfireRigid> rigidList, ConnectivityType connectivity)
        {
            List <RFShard> shardList = new List <RFShard>();

            for (int i = 0; i < rigidList.Count; i++)
            {
                // Get mesh filter
                MeshFilter mf = rigidList[i].GetComponent <MeshFilter>();

                // Child has no mesh
                if (mf == null)
                {
                    continue;
                }

                // Create new shard
                RFShard shard = new RFShard(rigidList[i].transform, i);
                shard.rigid = rigidList[i];

                // Set faces data for connectivity
                if (connectivity == ConnectivityType.ByMesh)
                {
                    shard.tris = RFTriangle.SetTriangles(shard.tm, mf);
                }

                // Collect shard
                shardList.Add(shard);
            }
            return(shardList);
        }
Beispiel #3
0
        // Prepare shards. Set bounds, set neibs
        public static void SetShardsByTransforms(RFCluster cluster, List <Transform> tmList, ConnectivityType connectivity, bool setRigid = false)
        {
            cluster.shards = new List <RFShard>();
            for (int i = 0; i < tmList.Count; i++)
            {
                // Get mesh filter
                MeshFilter mf = tmList[i].GetComponent <MeshFilter>();

                // Child has no mesh
                if (mf == null)
                {
                    continue;
                }

                // Has no mesh
                if (mf.sharedMesh == null)
                {
                    continue;
                }

                // Create new shard
                RFShard shard = new RFShard(tmList[i], i);
                shard.cluster = cluster;

                // Set faces data for connectivity
                if (connectivity == ConnectivityType.ByMesh || connectivity == ConnectivityType.ByBoundingBoxAndMesh)
                {
                    RFTriangle.SetTriangles(shard, mf);
                }

                // Collect shard
                cluster.shards.Add(shard);
            }

            // Set rigid component
            if (setRigid == true)
            {
                for (int i = 0; i < cluster.shards.Count; i++)
                {
                    cluster.shards[i].rigid = cluster.shards[i].tm.GetComponent <RayfireRigid>();
                }
            }
        }
Beispiel #4
0
        // Get all face in mesh by triangles. IMPORTANT turn on triangle neib calculation in RFTriangle
        List <RFFace> GetFaces(List <RFTriangle> Triangles)
        {
            List <int>    checkedTris = new List <int>();
            List <RFFace> localFaces  = new List <RFFace>();

            // Check every triangle
            int faceId = 0;

            foreach (RFTriangle tri in Triangles)
            {
                // Skip triangle if it is already part of face
                if (checkedTris.Contains(tri.id) == false)
                {
                    // Mark tri as checked
                    checkedTris.Add(tri.id);

                    // Create face
                    RFFace face = new RFFace(faceId, tri.area, tri.normal);
                    face.pos = tri.pos;
                    faceId++;
                    face.tris.Add(tri.id);

                    // List of all triangles to check
                    List <RFTriangle> trisToCheck = new List <RFTriangle>();
                    trisToCheck.Add(tri);

                    // Check all neibs
                    while (trisToCheck.Count > 0)
                    {
                        // Check neib tris
                        foreach (int neibId in trisToCheck[0].neibs)
                        {
                            if (checkedTris.Contains(neibId) == false)
                            {
                                // Get neib tri
                                RFTriangle neibTri = Triangles[neibId];

                                // Compare normals
                                if (tri.normal == neibTri.normal)
                                {
                                    face.area += neibTri.area;
                                    face.pos  += neibTri.pos;
                                    face.tris.Add(neibId);
                                    checkedTris.Add(neibId);
                                    trisToCheck.Add(neibTri);
                                }
                            }
                        }
                        trisToCheck.RemoveAt(0);
                    }

                    // Set pos
                    face.pos /= face.tris.Count;

                    // Collect face
                    localFaces.Add(face);
                }
            }

            return(localFaces);
        }
Beispiel #5
0
        // Get all triangles by mesh
        public static List <RFTriangle> GetTriangles(Mesh mesh, Transform tm)
        {
            // List of all triangles
            List <RFTriangle> localTriangles = new List <RFTriangle>();

            for (int i = 0; i < mesh.triangles.Length; i += 3)
            {
                // Vertex indexes
                int i1 = mesh.triangles[i];
                int i2 = mesh.triangles[i + 1];
                int i3 = mesh.triangles[i + 2];

                // Get vertices position and area
                Vector3 v1    = tm.TransformPoint(mesh.vertices[i1]);
                Vector3 v2    = tm.TransformPoint(mesh.vertices[i2]);
                Vector3 v3    = tm.TransformPoint(mesh.vertices[i3]);
                Vector3 cross = Vector3.Cross(v1 - v2, v1 - v3);
                float   area  = cross.magnitude * 0.5f;

                // Set position
                Vector3 pos = (v1 + v2 + v3) / 3f;

                // Create triangle and collect it
                RFTriangle triangle = new RFTriangle(i / 3, area, mesh.normals[i1], pos, new List <int> {
                    i1, i2, i3
                });
                localTriangles.Add(triangle);
            }

            //Set triangle neibs
            //for (int i = 0; i < localTriangles.Count; i++)
            //{
            //    RFTriangle tri1 = localTriangles[i];
            //    for (int t = 0; t < localTriangles.Count; t++)
            //    {
            //        if (i != t && tri1.neibs.Count < 3)
            //        {
            //            Check tri for neib state

            //           RFTriangle tri2 = localTriangles[t];

            //            Tri1 and tri2 is not neibs already
            //            if (tri2.neibs.Contains(tri1.id) == false)
            //            {
            //                Amount of neib verts
            //                int vertsMatch = 0;

            //                Check for same verts
            //                foreach (int vertInd in tri1.verts)
            //                        if (tri2.verts.Contains(vertInd) == true)
            //                            vertsMatch++;

            //                Tri is neib
            //                if (vertsMatch > 1)
            //                {
            //                    tri1.neibs.Add(tri2.id);
            //                    tri2.neibs.Add(tri1.id);
            //                }
            //            }
            //        }
            //    }
            //}

            return(localTriangles);
        }
Beispiel #6
0
        // Set shard neibs
        public static void SetShardNeibs(List <RFShard> shards, ConnectivityType type, float minArea = 0, float minSize = 0, int perc = 0, int seed = 0)
        {
            // Set list
            for (int i = 0; i < shards.Count; i++)
            {
                shards[i].neibShards = new List <RFShard>();
                shards[i].nArea      = new List <float>();
                shards[i].nIds       = new List <int>();
                shards[i].nAm        = 0;
            }

            // Set neib and area info
            for (int i = 0; i < shards.Count; i++)
            {
                // Skip by size
                if (minSize > 0 && shards[i].sz < minSize)
                {
                    continue;
                }

                for (int s = 0; s < shards.Count; s++)
                {
                    // Skip itself
                    if (s != i)
                    {
                        // Skip by size
                        if (minSize > 0 && shards[s].sz < minSize)
                        {
                            continue;
                        }

                        // Set random state for same pair
                        if (perc > 0)
                        {
                            Random.InitState(shards[i].id + shards[s].id + seed);
                            if (Random.Range(0, 100) < perc)
                            {
                                continue;
                            }
                        }

                        // Check if shard was not added as neib before
                        if (shards[s].nIds.Contains(shards[i].id) == false)
                        {
                            // Bounding box intersection check
                            if (shards[i].bnd.Intersects(shards[s].bnd) == true)
                            {
                                // Get areas
                                float area = 0;

                                if (type != ConnectivityType.ByBoundingBox)
                                {
                                    area = shards[i].NeibArea(shards[s]);
                                }

                                if (type != ConnectivityType.ByMesh)
                                {
                                    area = (shards[i].sz + shards[s].sz) / 4f;
                                }

                                // Skip low area neibs TODO filter after all connected, leave one biggest ??
                                if (minArea > 0 && area < minArea)
                                {
                                    continue;
                                }

                                // Collect
                                if (area > 0)
                                {
                                    shards[i].neibShards.Add(shards[s]);
                                    shards[i].nArea.Add(area);
                                    shards[i].nIds.Add(shards[s].id);

                                    shards[s].neibShards.Add(shards[i]);
                                    shards[s].nArea.Add(area);
                                    shards[s].nIds.Add(shards[i].id);
                                }
                            }
                        }
                    }
                }

                // Set original neib amount to know if neibs was removed
                shards[i].nAm = shards[i].nIds.Count;
            }

            // Clear triangles data
            if (type == ConnectivityType.ByMesh)
            {
                for (int i = 0; i < shards.Count; i++)
                {
                    RFTriangle.Clear(shards[i]);
                }
            }
        }