Example #1
0
        // Token: 0x06000605 RID: 1541 RVA: 0x0003988C File Offset: 0x00037C8C
        public void AddSpan(uint bottom, uint top, int area, int voxelWalkableClimb)
        {
            VoxelSpan voxelSpan = new VoxelSpan(bottom, top, area);

            if (this.firstSpan == null)
            {
                this.firstSpan = voxelSpan;
                return;
            }
            VoxelSpan voxelSpan2 = null;
            VoxelSpan voxelSpan3 = this.firstSpan;

            while (voxelSpan3 != null)
            {
                if (voxelSpan3.bottom > voxelSpan.top)
                {
                    break;
                }
                if (voxelSpan3.top < voxelSpan.bottom)
                {
                    voxelSpan2 = voxelSpan3;
                    voxelSpan3 = voxelSpan3.next;
                }
                else
                {
                    if (voxelSpan3.bottom < bottom)
                    {
                        voxelSpan.bottom = voxelSpan3.bottom;
                    }
                    if (voxelSpan3.top > top)
                    {
                        voxelSpan.top = voxelSpan3.top;
                    }
                    if (AstarMath.Abs((int)(voxelSpan.top - voxelSpan3.top)) <= voxelWalkableClimb)
                    {
                        voxelSpan.area = AstarMath.Max(voxelSpan.area, voxelSpan3.area);
                    }
                    VoxelSpan next = voxelSpan3.next;
                    if (voxelSpan2 != null)
                    {
                        voxelSpan2.next = next;
                    }
                    else
                    {
                        this.firstSpan = next;
                    }
                    voxelSpan3 = next;
                }
            }
            if (voxelSpan2 != null)
            {
                voxelSpan.next  = voxelSpan2.next;
                voxelSpan2.next = voxelSpan;
            }
            else
            {
                voxelSpan.next = this.firstSpan;
                this.firstSpan = voxelSpan;
            }
        }
Example #2
0
        //public System.Object lockObject;
        public void AddSpan(uint bottom, uint top, int area, int voxelWalkableClimb)
        {
            VoxelSpan span = new VoxelSpan (bottom,top,area);

            if (firstSpan == null) {
                firstSpan = span;
                return;
            }

            VoxelSpan prev = null;
            VoxelSpan cSpan = firstSpan;

            while (cSpan != null) {
                if (cSpan.bottom > span.top) {
                    break;

                } else if (cSpan.top < span.bottom) {
                    prev = cSpan;
                    cSpan = cSpan.next;
                } else {
                    if (cSpan.bottom < bottom) {
                        span.bottom = cSpan.bottom;
                    }
                    if (cSpan.top > top) {
                        span.top = cSpan.top;
                    }

                    //1 is flagMergeDistance, when a walkable flag is favored before an unwalkable one
                    if (AstarMath.Abs ((int)span.top - (int)cSpan.top) <= voxelWalkableClimb) {
                        span.area = AstarMath.Max (span.area,cSpan.area);
                    }

                    VoxelSpan next = cSpan.next;
                    if (prev != null) {
                        prev.next = next;
                    } else {
                        firstSpan = next;
                    }
                    cSpan = next;
                }
            }

            if (prev != null) {
                span.next = prev.next;
                prev.next = span;
            } else {
                span.next = firstSpan;
                firstSpan = span;
            }
        }
Example #3
0
        /** Builds a polygon mesh from a contour set.
         * \param nvp Maximum allowed vertices per polygon. \note Currently locked to 3
         */
        public void BuildPolyMesh(VoxelContourSet cset, int nvp, out VoxelMesh mesh)
        {
            AstarProfiler.StartProfile("Build Poly Mesh");

            nvp = 3;

            int maxVertices     = 0;
            int maxTris         = 0;
            int maxVertsPerCont = 0;

            for (int i = 0; i < cset.conts.Count; i++)
            {
                // Skip null contours.
                if (cset.conts[i].nverts < 3)
                {
                    continue;
                }

                maxVertices    += cset.conts[i].nverts;
                maxTris        += cset.conts[i].nverts - 2;
                maxVertsPerCont = AstarMath.Max(maxVertsPerCont, cset.conts[i].nverts);
            }

            if (maxVertices >= 65534)
            {
                Debug.LogWarning("To many vertices for unity to render - Unity might screw up rendering, but hopefully the navmesh will work ok");
                //mesh = new VoxelMesh ();
                //yield break;
                //return;
            }

            //int[] vflags = new int[maxVertices];

            /** \todo Could be cached to avoid allocations */
            Int3[] verts = new Int3[maxVertices];
            /** \todo Could be cached to avoid allocations */
            int[] polys = new int[maxTris * nvp];

            //int[] regs = new int[maxTris];

            //int[] areas = new int[maxTris];

            Pathfinding.Util.Memory.MemSet <int> (polys, 0xff, sizeof(int));
            //for (int i=0;i<polys.Length;i++) {
            //	polys[i] = 0xff;
            //}

            //int[] nexVert = new int[maxVertices];

            //int[] firstVert = new int[VERTEX_BUCKET_COUNT];

            int[] indices = new int[maxVertsPerCont];

            int[] tris = new int[maxVertsPerCont * 3];

            //ushort[] polys

            int vertexIndex = 0;
            int polyIndex   = 0;

            for (int i = 0; i < cset.conts.Count; i++)
            {
                VoxelContour cont = cset.conts[i];

                //Skip null contours
                if (cont.nverts < 3)
                {
                    continue;
                }

                for (int j = 0; j < cont.nverts; j++)
                {
                    indices[j]             = j;
                    cont.verts[j * 4 + 2] /= voxelArea.width;
                }

                //yield return (GameObject.FindObjectOfType (typeof(MonoBehaviour)) as MonoBehaviour).StartCoroutine (
                //Triangulate (cont.nverts, cont.verts, indices, tris);
                int ntris = Triangulate(cont.nverts, cont.verts, ref indices, ref tris);

                /*if (ntris > cont.nverts-2) {
                 *      Debug.LogError (ntris + " "+cont.nverts+" "+cont.verts.Length+" "+(cont.nverts-2));
                 * }
                 *
                 * if (ntris > maxVertsPerCont) {
                 *      Debug.LogError (ntris*3 + " "+maxVertsPerCont);
                 * }
                 *
                 * int tmp = polyIndex;
                 *
                 * Debug.Log (maxTris + " "+polyIndex+" "+polys.Length+" "+ntris+" "+(ntris*3) + " " + cont.nverts);*/
                int startIndex = vertexIndex;
                for (int j = 0; j < ntris * 3; polyIndex++, j++)
                {
                    //@Error sometimes
                    polys[polyIndex] = tris[j] + startIndex;
                }

                /*int tmp2 = polyIndex;
                 * if (tmp+ntris*3 != tmp2) {
                 *      Debug.LogWarning (tmp+" "+(tmp+ntris*3)+" "+tmp2+" "+ntris*3);
                 * }*/

                for (int j = 0; j < cont.nverts; vertexIndex++, j++)
                {
                    verts[vertexIndex] = new Int3(cont.verts[j * 4], cont.verts[j * 4 + 1], cont.verts[j * 4 + 2]);
                }
            }

            mesh = new VoxelMesh();
            //yield break;
            Int3[] trimmedVerts = new Int3[vertexIndex];
            for (int i = 0; i < vertexIndex; i++)
            {
                trimmedVerts[i] = verts[i];
            }

            int[] trimmedTris = new int[polyIndex];

            System.Buffer.BlockCopy(polys, 0, trimmedTris, 0, polyIndex * sizeof(int));
            //for (int i=0;i<polyIndex;i++) {
            //	trimmedTris[i] = polys[i];
            //}


            mesh.verts = trimmedVerts;
            mesh.tris  = trimmedTris;

            /*for (int i=0;i<mesh.tris.Length/3;i++) {
             *
             *      int p = i*3;
             *
             *      int p1 = mesh.tris[p];
             *      int p2 = mesh.tris[p+1];
             *      int p3 = mesh.tris[p+2];
             *
             *      //Debug.DrawLine (ConvertPosCorrZ (mesh.verts[p1].x,mesh.verts[p1].y,mesh.verts[p1].z),ConvertPosCorrZ (mesh.verts[p2].x,mesh.verts[p2].y,mesh.verts[p2].z),Color.yellow);
             *      //Debug.DrawLine (ConvertPosCorrZ (mesh.verts[p1].x,mesh.verts[p1].y,mesh.verts[p1].z),ConvertPosCorrZ (mesh.verts[p3].x,mesh.verts[p3].y,mesh.verts[p3].z),Color.yellow);
             *      //Debug.DrawLine (ConvertPosCorrZ (mesh.verts[p3].x,mesh.verts[p3].y,mesh.verts[p3].z),ConvertPosCorrZ (mesh.verts[p2].x,mesh.verts[p2].y,mesh.verts[p2].z),Color.yellow);
             *
             *      //Debug.DrawLine (ConvertPosCorrZ (verts[p1],0,verts[p1+2]),ConvertPosCorrZ (verts[p2],0,verts[p2+2]),Color.blue);
             *      //Debug.DrawLine (ConvertPosCorrZ (verts[p1],0,verts[p1+2]),ConvertPosCorrZ (verts[p3],0,verts[p3+2]),Color.blue);
             *      //Debug.DrawLine (ConvertPosCorrZ (verts[p2],0,verts[p2+2]),ConvertPosCorrZ (verts[p3],0,verts[p3+2]),Color.blue);
             *
             * }*/

            AstarProfiler.EndProfile("Build Poly Mesh");
        }
Example #4
0
        //Code almost completely ripped from Recast
        public void FilterLedges(uint voxelWalkableHeight, int voxelWalkableClimb, float cs, float ch, Vector3 min)
        {
            int wd = voxelArea.width * voxelArea.depth;

#if !ASTAR_RECAST_CLASS_BASED_LINKED_LIST
            LinkedVoxelSpan[] spans      = voxelArea.linkedSpans;
            int[]             DirectionX = voxelArea.DirectionX;
            int[]             DirectionZ = voxelArea.DirectionZ;
#endif
            int width = voxelArea.width;

            //Filter all ledges
            for (int z = 0, pz = 0; z < wd; z += width, pz++)
            {
                for (int x = 0; x < width; x++)
                {
#if !ASTAR_RECAST_CLASS_BASED_LINKED_LIST
                    if (spans[x + z].bottom == VoxelArea.InvalidSpanValue)
                    {
                        continue;
                    }

                    for (int s = x + z; s != -1; s = spans[s].next)
                    {
                        //Skip non-walkable spans
                        if (spans[s].area == UnwalkableArea)
                        {
                            continue;
                        }

                        int bottom = (int)spans[s].top;
                        int top    = spans[s].next != -1 ? (int)spans[spans[s].next].bottom : VoxelArea.MaxHeightInt;

                        int minHeight = VoxelArea.MaxHeightInt;

                        int aMinHeight = (int)spans[s].top;
                        int aMaxHeight = aMinHeight;

                        for (int d = 0; d < 4; d++)
                        {
                            int nx = x + DirectionX[d];
                            int nz = z + DirectionZ[d];

                            //Skip out-of-bounds points
                            if (nx < 0 || nz < 0 || nz >= wd || nx >= width)
                            {
                                spans[s].area = UnwalkableArea;
                                break;
                            }

                            int nsx = nx + nz;

                            int nbottom = -voxelWalkableClimb;

                            int ntop = spans[nsx].bottom != VoxelArea.InvalidSpanValue ? (int)spans[nsx].bottom : VoxelArea.MaxHeightInt;

                            if (System.Math.Min(top, ntop) - System.Math.Max(bottom, nbottom) > voxelWalkableHeight)
                            {
                                minHeight = System.Math.Min(minHeight, nbottom - bottom);
                            }

                            //Loop through spans
                            if (spans[nsx].bottom != VoxelArea.InvalidSpanValue)
                            {
                                for (int ns = nsx; ns != -1; ns = spans[ns].next)
                                {
                                    nbottom = (int)spans[ns].top;
                                    ntop    = spans[ns].next != -1 ? (int)spans[spans[ns].next].bottom : VoxelArea.MaxHeightInt;

                                    if (System.Math.Min(top, ntop) - System.Math.Max(bottom, nbottom) > voxelWalkableHeight)
                                    {
                                        minHeight = System.Math.Min(minHeight, nbottom - bottom);

                                        if (System.Math.Abs(nbottom - bottom) <= voxelWalkableClimb)
                                        {
                                            if (nbottom < aMinHeight)
                                            {
                                                aMinHeight = nbottom;
                                            }
                                            if (nbottom > aMaxHeight)
                                            {
                                                aMaxHeight = nbottom;
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        if (minHeight < -voxelWalkableClimb || (aMaxHeight - aMinHeight) > voxelWalkableClimb)
                        {
                            spans[s].area = UnwalkableArea;
                        }
                    }
#else
                    for (VoxelSpan s = voxelArea.cells[z + x].firstSpan; s != null; s = s.next)
                    {
                        //Skip non-walkable spans
                        if (s.area == UnwalkableArea)
                        {
                            continue;
                        }

                        int bottom = (int)s.top;
                        int top    = s.next != null ? (int)s.next.bottom : VoxelArea.MaxHeightInt;

                        int minHeight = VoxelArea.MaxHeightInt;

                        int aMinHeight = (int)s.top;
                        int aMaxHeight = (int)s.top;

                        for (int d = 0; d < 4; d++)
                        {
                            int nx = x + voxelArea.DirectionX[d];
                            int nz = z + voxelArea.DirectionZ[d];

                            //Skip out-of-bounds points
                            if (nx < 0 || nz < 0 || nz >= wd || nx >= voxelArea.width)
                            {
                                s.area = UnwalkableArea;
                                break;
                            }

                            VoxelSpan nsx = voxelArea.cells[nx + nz].firstSpan;

                            int nbottom = -voxelWalkableClimb;

                            int ntop = nsx != null ? (int)nsx.bottom : VoxelArea.MaxHeightInt;

                            if (AstarMath.Min(top, ntop) - AstarMath.Max(bottom, nbottom) > voxelWalkableHeight)
                            {
                                minHeight = AstarMath.Min(minHeight, nbottom - bottom);
                            }

                            //Loop through spans
                            for (VoxelSpan ns = nsx; ns != null; ns = ns.next)
                            {
                                nbottom = (int)ns.top;
                                ntop    = ns.next != null ? (int)ns.next.bottom : VoxelArea.MaxHeightInt;

                                if (AstarMath.Min(top, ntop) - AstarMath.Max(bottom, nbottom) > voxelWalkableHeight)
                                {
                                    minHeight = AstarMath.Min(minHeight, nbottom - bottom);

                                    if (AstarMath.Abs(nbottom - bottom) <= voxelWalkableClimb)
                                    {
                                        if (nbottom < aMinHeight)
                                        {
                                            aMinHeight = nbottom;
                                        }
                                        if (nbottom > aMaxHeight)
                                        {
                                            aMaxHeight = nbottom;
                                        }
                                    }
                                }
                            }
                        }

                        if (minHeight < -voxelWalkableClimb || (aMaxHeight - aMinHeight) > voxelWalkableClimb)
                        {
                            s.area = UnwalkableArea;
                        }
                    }
#endif
                }
            }
        }
Example #5
0
        public int GetCornerHeight(int x, int z, int i, int dir, ref bool isBorderVertex)
        {
            CompactVoxelSpan s = voxelArea.compactSpans[i];

            int ch = (int)s.y;

            //dir + clockwise direction
            int dirp = (dir + 1) & 0x3;

            //int dirp = (dir+3) & 0x3;

            uint[] regs = new uint[4];

            regs[0] = (uint)voxelArea.compactSpans[i].reg | ((uint)voxelArea.areaTypes[i] << 16);

            if (s.GetConnection(dir) != NotConnected)
            {
                int nx = x + voxelArea.DirectionX[dir];
                int nz = z + voxelArea.DirectionZ[dir];
                int ni = (int)voxelArea.compactCells[nx + nz].index + s.GetConnection(dir);

                CompactVoxelSpan ns = voxelArea.compactSpans[ni];

                ch      = AstarMath.Max(ch, (int)ns.y);
                regs[1] = (uint)ns.reg | ((uint)voxelArea.areaTypes[ni] << 16);

                if (ns.GetConnection(dirp) != NotConnected)
                {
                    int nx2 = nx + voxelArea.DirectionX[dirp];
                    int nz2 = nz + voxelArea.DirectionZ[dirp];
                    int ni2 = (int)voxelArea.compactCells[nx2 + nz2].index + ns.GetConnection(dirp);

                    CompactVoxelSpan ns2 = voxelArea.compactSpans[ni2];

                    ch      = AstarMath.Max(ch, (int)ns2.y);
                    regs[2] = (uint)ns2.reg | ((uint)voxelArea.areaTypes[ni2] << 16);
                }
            }

            if (s.GetConnection(dirp) != NotConnected)
            {
                int nx = x + voxelArea.DirectionX[dirp];
                int nz = z + voxelArea.DirectionZ[dirp];
                int ni = (int)voxelArea.compactCells[nx + nz].index + s.GetConnection(dirp);

                CompactVoxelSpan ns = voxelArea.compactSpans[ni];

                ch      = AstarMath.Max(ch, (int)ns.y);
                regs[3] = (uint)ns.reg | ((uint)voxelArea.areaTypes[ni] << 16);

                if (ns.GetConnection(dir) != NotConnected)
                {
                    int nx2 = nx + voxelArea.DirectionX[dir];
                    int nz2 = nz + voxelArea.DirectionZ[dir];
                    int ni2 = (int)voxelArea.compactCells[nx2 + nz2].index + ns.GetConnection(dir);

                    CompactVoxelSpan ns2 = voxelArea.compactSpans[ni2];

                    ch      = AstarMath.Max(ch, (int)ns2.y);
                    regs[2] = (uint)ns2.reg | ((uint)voxelArea.areaTypes[ni2] << 16);
                }
            }

            // Check if the vertex is special edge vertex, these vertices will be removed later.
            for (int j = 0; j < 4; ++j)
            {
                int a = j;
                int b = (j + 1) & 0x3;
                int c = (j + 2) & 0x3;
                int d = (j + 3) & 0x3;

                // The vertex is a border vertex there are two same exterior cells in a row,
                // followed by two interior cells and none of the regions are out of bounds.
                bool twoSameExts  = (regs[a] & regs[b] & BorderReg) != 0 && regs[a] == regs[b];
                bool twoInts      = ((regs[c] | regs[d]) & BorderReg) == 0;
                bool intsSameArea = (regs[c] >> 16) == (regs[d] >> 16);
                bool noZeros      = regs[a] != 0 && regs[b] != 0 && regs[c] != 0 && regs[d] != 0;
                if (twoSameExts && twoInts && intsSameArea && noZeros)
                {
                    isBorderVertex = true;
                    break;
                }
            }

            return(ch);
        }
Example #6
0
        public void AddLinkedSpan(int index, uint bottom, uint top, int area, int voxelWalkableClimb)
        {
#if !ASTAR_RECAST_ARRAY_BASED_LINKED_LIST
            cells[index].AddSpan(bottom, top, area, voxelWalkableClimb);
#else
            /* Check if the span is valid, otherwise we can replace it with a new (valid) span */
            if (linkedSpans[index].bottom == InvalidSpanValue)
            {
                linkedSpans[index] = new LinkedVoxelSpan(bottom, top, area);
                return;
            }


            int prev   = -1;
            int oindex = index;

            while (index != -1)
            {
                if (linkedSpans[index].bottom > top)
                {
                    break;
                }
                else if (linkedSpans[index].top < bottom)
                {
                    prev  = index;
                    index = linkedSpans[index].next;
                }
                else
                {
                    if (linkedSpans[index].bottom < bottom)
                    {
                        bottom = linkedSpans[index].bottom;
                    }
                    if (linkedSpans[index].top > top)
                    {
                        top = linkedSpans[index].top;
                    }

                    //1 is flagMergeDistance, when a walkable flag is favored before an unwalkable one
                    if (AstarMath.Abs((int)top - (int)linkedSpans[index].top) <= voxelWalkableClimb)
                    {
                        area = AstarMath.Max(area, linkedSpans[index].area);
                    }

                    int next = linkedSpans[index].next;
                    if (prev != -1)
                    {
                        linkedSpans[prev].next = next;

                        if (removedStackCount == removedStack.Length)
                        {
                            int[] st2 = new int[removedStackCount * 4];
                            System.Buffer.BlockCopy(removedStack, 0, st2, 0, removedStackCount * sizeof(int));
                            removedStack = st2;
                        }
                        removedStack[removedStackCount] = index;
                        removedStackCount++;

                        index = next;
                    }
                    else if (next != -1)
                    {
                        linkedSpans[oindex] = linkedSpans[next];

                        if (removedStackCount == removedStack.Length)
                        {
                            int[] st2 = new int[removedStackCount * 4];
                            System.Buffer.BlockCopy(removedStack, 0, st2, 0, removedStackCount * sizeof(int));
                            removedStack = st2;
                        }
                        removedStack[removedStackCount] = next;
                        removedStackCount++;

                        index = linkedSpans[oindex].next;
                    }
                    else
                    {
                        linkedSpans[oindex] = new LinkedVoxelSpan(bottom, top, area);
                        return;
                    }
                }
            }

            if (linkedSpanCount >= linkedSpans.Length)
            {
                LinkedVoxelSpan[] tmp = linkedSpans;
                int count             = linkedSpanCount;
                int popped            = removedStackCount;
                linkedSpans = new LinkedVoxelSpan[linkedSpans.Length * 2];
                ResetLinkedVoxelSpans();
                linkedSpanCount   = count;
                removedStackCount = popped;
                for (int i = 0; i < linkedSpanCount; i++)
                {
                    linkedSpans[i] = tmp[i];
                }
                Debug.Log("Layer estimate too low, doubling size of buffer.\nThis message is harmless.");
            }

            int nextIndex;
            if (removedStackCount > 0)
            {
                removedStackCount--;
                nextIndex = removedStack[removedStackCount];
            }
            else
            {
                nextIndex = linkedSpanCount;
                linkedSpanCount++;
            }

            if (prev != -1)
            {
                //span.next = prev.next;
                //prev.next = span;

                linkedSpans[nextIndex] = new LinkedVoxelSpan(bottom, top, area, linkedSpans[prev].next);
                linkedSpans[prev].next = nextIndex;
            }
            else
            {
                //span.next = firstSpan;
                //firstSpan = span;

                linkedSpans[nextIndex] = linkedSpans[oindex];
                linkedSpans[oindex]    = new LinkedVoxelSpan(bottom, top, area, nextIndex);
            }
#endif
        }
Example #7
0
        // Token: 0x060005FE RID: 1534 RVA: 0x00039398 File Offset: 0x00037798
        public void AddLinkedSpan(int index, uint bottom, uint top, int area, int voxelWalkableClimb)
        {
            if (this.linkedSpans[index].bottom == 4294967295u)
            {
                this.linkedSpans[index] = new LinkedVoxelSpan(bottom, top, area);
                return;
            }
            int num  = -1;
            int num2 = index;

            while (index != -1)
            {
                if (this.linkedSpans[index].bottom > top)
                {
                    break;
                }
                if (this.linkedSpans[index].top < bottom)
                {
                    num   = index;
                    index = this.linkedSpans[index].next;
                }
                else
                {
                    if (this.linkedSpans[index].bottom < bottom)
                    {
                        bottom = this.linkedSpans[index].bottom;
                    }
                    if (this.linkedSpans[index].top > top)
                    {
                        top = this.linkedSpans[index].top;
                    }
                    if (AstarMath.Abs((int)(top - this.linkedSpans[index].top)) <= voxelWalkableClimb)
                    {
                        area = AstarMath.Max(area, this.linkedSpans[index].area);
                    }
                    int next = this.linkedSpans[index].next;
                    if (num != -1)
                    {
                        this.linkedSpans[num].next = next;
                        if (this.removedStackCount == this.removedStack.Length)
                        {
                            int[] dst = new int[this.removedStackCount * 4];
                            Buffer.BlockCopy(this.removedStack, 0, dst, 0, this.removedStackCount * 4);
                            this.removedStack = dst;
                        }
                        this.removedStack[this.removedStackCount] = index;
                        this.removedStackCount++;
                        index = next;
                    }
                    else
                    {
                        if (next == -1)
                        {
                            this.linkedSpans[num2] = new LinkedVoxelSpan(bottom, top, area);
                            return;
                        }
                        this.linkedSpans[num2] = this.linkedSpans[next];
                        if (this.removedStackCount == this.removedStack.Length)
                        {
                            int[] dst2 = new int[this.removedStackCount * 4];
                            Buffer.BlockCopy(this.removedStack, 0, dst2, 0, this.removedStackCount * 4);
                            this.removedStack = dst2;
                        }
                        this.removedStack[this.removedStackCount] = next;
                        this.removedStackCount++;
                        index = this.linkedSpans[num2].next;
                    }
                }
            }
            if (this.linkedSpanCount >= this.linkedSpans.Length)
            {
                LinkedVoxelSpan[] array = this.linkedSpans;
                int num3 = this.linkedSpanCount;
                int num4 = this.removedStackCount;
                this.linkedSpans = new LinkedVoxelSpan[this.linkedSpans.Length * 2];
                this.ResetLinkedVoxelSpans();
                this.linkedSpanCount   = num3;
                this.removedStackCount = num4;
                for (int i = 0; i < this.linkedSpanCount; i++)
                {
                    this.linkedSpans[i] = array[i];
                }
                Debug.Log("Layer estimate too low, doubling size of buffer.\nThis message is harmless.");
            }
            int num5;

            if (this.removedStackCount > 0)
            {
                this.removedStackCount--;
                num5 = this.removedStack[this.removedStackCount];
            }
            else
            {
                num5 = this.linkedSpanCount;
                this.linkedSpanCount++;
            }
            if (num != -1)
            {
                this.linkedSpans[num5]     = new LinkedVoxelSpan(bottom, top, area, this.linkedSpans[num].next);
                this.linkedSpans[num].next = num5;
            }
            else
            {
                this.linkedSpans[num5] = this.linkedSpans[num2];
                this.linkedSpans[num2] = new LinkedVoxelSpan(bottom, top, area, num5);
            }
        }
Example #8
0
        /** Builds a polygon mesh from a contour set.
         *
         * \param cset contour set to build a mesh from.
         * \param nvp Maximum allowed vertices per polygon. \warning Currently locked to 3.
         * \param mesh Results will be written to this mesh.
         */
        public void BuildPolyMesh(VoxelContourSet cset, int nvp, out VoxelMesh mesh)
        {
            AstarProfiler.StartProfile("Build Poly Mesh");

            nvp = 3;

            int maxVertices     = 0;
            int maxTris         = 0;
            int maxVertsPerCont = 0;

            for (int i = 0; i < cset.conts.Count; i++)
            {
                // Skip null contours.
                if (cset.conts[i].nverts < 3)
                {
                    continue;
                }

                maxVertices    += cset.conts[i].nverts;
                maxTris        += cset.conts[i].nverts - 2;
                maxVertsPerCont = AstarMath.Max(maxVertsPerCont, cset.conts[i].nverts);
            }

            if (maxVertices >= 65534)
            {
                Debug.LogWarning("To many vertices for unity to render - Unity might screw up rendering, but hopefully the navmesh will work ok");
                //mesh = new VoxelMesh ();
                //yield break;
                //return;
            }

            /** \todo Could be cached to avoid allocations */
            Int3[] verts = new Int3[maxVertices];
            /** \todo Could be cached to avoid allocations */
            int[] polys = new int[maxTris * nvp];

            Pathfinding.Util.Memory.MemSet <int> (polys, 0xff, sizeof(int));

            int[] indices = new int[maxVertsPerCont];

            int[] tris = new int[maxVertsPerCont * 3];

            int vertexIndex = 0;
            int polyIndex   = 0;

            for (int i = 0; i < cset.conts.Count; i++)
            {
                VoxelContour cont = cset.conts[i];

                //Skip null contours
                if (cont.nverts < 3)
                {
                    continue;
                }

                for (int j = 0; j < cont.nverts; j++)
                {
                    indices[j]             = j;
                    cont.verts[j * 4 + 2] /= voxelArea.width;
                }

                int ntris = Triangulate(cont.nverts, cont.verts, ref indices, ref tris);

                int startIndex = vertexIndex;
                for (int j = 0; j < ntris * 3; polyIndex++, j++)
                {
                    //@Error sometimes
                    polys[polyIndex] = tris[j] + startIndex;
                }

                for (int j = 0; j < cont.nverts; vertexIndex++, j++)
                {
                    verts[vertexIndex] = new Int3(cont.verts[j * 4], cont.verts[j * 4 + 1], cont.verts[j * 4 + 2]);
                }
            }

            mesh = new VoxelMesh();
            //yield break;
            Int3[] trimmedVerts = new Int3[vertexIndex];
            for (int i = 0; i < vertexIndex; i++)
            {
                trimmedVerts[i] = verts[i];
            }

            int[] trimmedTris = new int[polyIndex];

            System.Buffer.BlockCopy(polys, 0, trimmedTris, 0, polyIndex * sizeof(int));

            mesh.verts = trimmedVerts;
            mesh.tris  = trimmedTris;

            // Some debugging

            /*for (int i=0;i<mesh.tris.Length/3;i++) {
             *
             *      int p = i*3;
             *
             *      int p1 = mesh.tris[p];
             *      int p2 = mesh.tris[p+1];
             *      int p3 = mesh.tris[p+2];
             *
             *      //Debug.DrawLine (ConvertPosCorrZ (mesh.verts[p1].x,mesh.verts[p1].y,mesh.verts[p1].z),ConvertPosCorrZ (mesh.verts[p2].x,mesh.verts[p2].y,mesh.verts[p2].z),Color.yellow);
             *      //Debug.DrawLine (ConvertPosCorrZ (mesh.verts[p1].x,mesh.verts[p1].y,mesh.verts[p1].z),ConvertPosCorrZ (mesh.verts[p3].x,mesh.verts[p3].y,mesh.verts[p3].z),Color.yellow);
             *      //Debug.DrawLine (ConvertPosCorrZ (mesh.verts[p3].x,mesh.verts[p3].y,mesh.verts[p3].z),ConvertPosCorrZ (mesh.verts[p2].x,mesh.verts[p2].y,mesh.verts[p2].z),Color.yellow);
             *
             *      //Debug.DrawLine (ConvertPosCorrZ (verts[p1],0,verts[p1+2]),ConvertPosCorrZ (verts[p2],0,verts[p2+2]),Color.blue);
             *      //Debug.DrawLine (ConvertPosCorrZ (verts[p1],0,verts[p1+2]),ConvertPosCorrZ (verts[p3],0,verts[p3+2]),Color.blue);
             *      //Debug.DrawLine (ConvertPosCorrZ (verts[p2],0,verts[p2+2]),ConvertPosCorrZ (verts[p3],0,verts[p3+2]),Color.blue);
             *
             * }*/

            AstarProfiler.EndProfile("Build Poly Mesh");
        }
Example #9
0
        public void AddSpan(uint bottom, uint top, int area, int voxelWalkableClimb)
        {
            VoxelSpan span = new VoxelSpan(bottom, top, area);

            if (this.firstSpan == null)
            {
                this.firstSpan = span;
            }
            else
            {
                VoxelSpan span2     = null;
                VoxelSpan firstSpan = this.firstSpan;
                while (firstSpan != null)
                {
                    if (firstSpan.bottom > span.top)
                    {
                        break;
                    }
                    if (firstSpan.top < span.bottom)
                    {
                        span2     = firstSpan;
                        firstSpan = firstSpan.next;
                    }
                    else
                    {
                        if (firstSpan.bottom < bottom)
                        {
                            span.bottom = firstSpan.bottom;
                        }
                        if (firstSpan.top > top)
                        {
                            span.top = firstSpan.top;
                        }
                        if (AstarMath.Abs((int)(span.top - firstSpan.top)) <= voxelWalkableClimb)
                        {
                            span.area = AstarMath.Max(span.area, firstSpan.area);
                        }
                        VoxelSpan next = firstSpan.next;
                        if (span2 != null)
                        {
                            span2.next = next;
                        }
                        else
                        {
                            this.firstSpan = next;
                        }
                        firstSpan = next;
                    }
                }
                if (span2 != null)
                {
                    span.next  = span2.next;
                    span2.next = span;
                }
                else
                {
                    span.next      = this.firstSpan;
                    this.firstSpan = span;
                }
            }
        }