Пример #1
0
        public int GetChunksOverlappingRect(float[] bmin, float[] bmax, ref int[] ids, int maxIds)
        {
            int i = 0;
            int n = 0;

            while (i < NNodes)
            {
                ChunkyTriMeshNode node = Nodes[i];
                bool overlap           = CheckOverlapRect(bmin, bmax, node.bmin, node.bmax);
                bool isLeafNode        = node.i >= 0;

                if (isLeafNode && overlap)
                {
                    if (n < maxIds)
                    {
                        ids[n] = i;
                        n++;
                    }
                }

                if (overlap || isLeafNode)
                {
                    i++;
                }
                else
                {
                    int escapeIndex = -node.i;
                    i += escapeIndex;
                }
            }
            return(n);
        }
Пример #2
0
        private void CalcExtends(BoundsItem[] items, int nitems, int imin, int imax, ref ChunkyTriMeshNode node)
        {
            node.bmin[0] = items[imin].bmin[0];
            node.bmin[1] = items[imin].bmin[1];

            node.bmax[0] = items[imin].bmax[0];
            node.bmax[1] = items[imin].bmax[1];

            for (int i = imin + 1; i < imax; i++)
            {
                BoundsItem it = items[i];
                if (it.bmin[0] < node.bmin[0])
                {
                    node.bmin[0] = it.bmin[0];
                }
                if (it.bmin[1] < node.bmin[1])
                {
                    node.bmin[1] = it.bmin[1];
                }

                if (it.bmax[0] > node.bmax[0])
                {
                    node.bmax[0] = it.bmax[0];
                }
                if (it.bmax[1] > node.bmax[1])
                {
                    node.bmax[1] = it.bmax[1];
                }
            }
        }
Пример #3
0
        public ChunkyTriMesh(RecastVertex[] verts, int[] tris, int ntris, int trisPerChunk)
        {
            int nchunks = (ntris + trisPerChunk - 1) / trisPerChunk;

            Nodes = new ChunkyTriMeshNode[nchunks * 4];
            Tris  = new int[ntris * 3];

            NTris = ntris;

            BoundsItem[] items = new BoundsItem[ntris];

            for (int i = 0; i < ntris; i++)
            {
                int t = i * 3;
                items[i] = new BoundsItem();
                BoundsItem it = items[i];
                it.i       = i;
                it.bmin[0] = it.bmax[0] = verts[tris[t]].X;
                it.bmin[1] = it.bmax[1] = verts[tris[t]].Z;
                for (int j = 1; j < 3; j++)
                {
                    int v = tris[t + j];
                    if (verts[v].X < it.bmin[0])
                    {
                        it.bmin[0] = verts[v].X;
                    }
                    if (verts[v].Z < it.bmin[1])
                    {
                        it.bmin[1] = verts[v].Z;
                    }

                    if (verts[v].X > it.bmax[0])
                    {
                        it.bmax[0] = verts[v].X;
                    }
                    if (verts[v].Z > it.bmax[1])
                    {
                        it.bmax[1] = verts[v].Z;
                    }
                }
            }

            int curTri  = 0;
            int curNode = 0;

            Subdivide(ref items, ntris, 0, ntris, trisPerChunk, ref curNode, nchunks * 4, ref curTri, tris);

            NNodes = curNode;

            MaxTrisPerChunk = 0;
            for (int i = 0; i < NNodes; i++)
            {
                bool isLeaf = Nodes[i].i >= 0;
                if (!isLeaf)
                {
                    continue;
                }
                if (Nodes[i].n > MaxTrisPerChunk)
                {
                    MaxTrisPerChunk = Nodes[i].n;
                }
            }
        }
Пример #4
0
        private void Subdivide(ref BoundsItem[] items, int nitems, int imin, int imax, int trisPerChunk, ref int curNode, int maxNodes, ref int curTri, int[] tris)
        {
            int inum = imax - imin;
            int icur = curNode;

            if (curNode > maxNodes)
            {
                return;
            }

            var node = Nodes[curNode];

            if (Nodes[curNode] == null)
            {
                node           = new ChunkyTriMeshNode();
                Nodes[curNode] = node;
            }
            curNode++;

            if (inum <= trisPerChunk)
            {
                CalcExtends(items, nitems, imin, imax, ref node);

                node.i = curTri;
                node.n = inum;

                for (int i = imin; i < imax; i++)
                {
                    int src = items[i].i * 3;
                    int dst = curTri * 3;
                    curTri++;
                    Tris[dst + 0] = tris[src + 0];
                    Tris[dst + 1] = tris[src + 1];
                    Tris[dst + 2] = tris[src + 2];
                }
            }
            else
            {
                CalcExtends(items, nitems, imin, imax, ref node);

                int axis = LongestAxis(node.bmax[0] - node.bmin[0], node.bmax[1] - node.bmin[1]);

                if (axis == 0)
                {
                    // sort along x-axis
                    Array.Sort(items, imin, inum, new CompareItemX());
                }
                else if (axis == 1)
                {
                    // sort along y-axis
                    Array.Sort(items, imin, inum, new CompareItemY());
                }

                int isplit = imin + inum / 2;

                Subdivide(ref items, nitems, imin, isplit, trisPerChunk, ref curNode, maxNodes, ref curTri, tris);
                Subdivide(ref items, nitems, isplit, imax, trisPerChunk, ref curNode, maxNodes, ref curTri, tris);

                int iescape = curNode - icur;
                node.i = -iescape;
            }
        }