public void Init(NavMeshTemplateCreation template)
        {
            this.template = template;

            int length = flattenSize;

            //!!!!!!!!!!!!!!!!//
            freeIndexStack = GenericPoolArray <int> .Take(INITIAL_FREE_INDEX_POOL_SIZE);

            arrayData = GenericPoolArray <Data> .Take(length *ARRAY_DATA_SIZE);

            for (int i = 0; i < length; i++)
            {
                arrayData[i].next = -2;
            }

            for (int i = length; i < arrayData.Length; i++)
            {
                arrayData[i].next = -1;
            }

            filledIndexes          = length;
            freeIndexStackLength   = 0;
            voxelDistanceThreshold = template.voxelSize;


            freeStackHS.Clear();
        }
        private static Vector2[] MakeElipse(float radiusInner, float radiusOuter, int elipseQuadLength)
        {
            Vector2[] array = GenericPoolArray <Vector2> .Take((elipseQuadLength * 4) + 1);

            float radiusDifference = radiusOuter - radiusInner;
            float elipseQuadStep   = Mathf.PI / elipseQuadLength * 0.5f;

            for (int i = 0; i < elipseQuadLength; i++)
            {
                float xValue = Mathf.Cos(i * elipseQuadStep);
                float yValue = Mathf.Sin(i * elipseQuadStep);

                float xInner = xValue * radiusInner;
                float yInner = yValue * radiusInner;

                float xOuter = xValue * radiusOuter;
                float yOuter = yValue * radiusOuter;

                float lerp1 = xOuter / radiusOuter;
                float lerp2 = yOuter / radiusOuter;

                array[i] = new Vector2(xInner + (radiusDifference * lerp1), yInner);
                array[elipseQuadLength + i]       = new Vector2(-yInner - (radiusDifference * lerp2), xInner);
                array[(elipseQuadLength * 2) + i] = new Vector2(-xInner - (radiusDifference * lerp1), -yInner);
                array[(elipseQuadLength * 3) + i] = new Vector2(yInner + (radiusDifference * lerp2), -xInner);
            }

            array[array.Length - 1] = array[0];
            return(array);
        }
示例#3
0
            public LayerInfoHolder(int Length)
            {
                isValid = true;
                mask    = GenericPoolArray <bool> .Take(Length);

                indexes = GenericPoolArray <IndexPair> .Take(Length);

                indexesCount = 0;

                banned = GenericPoolArray <int> .Take(Length);

                bannedCount = 0;
            }
        public DataCompact[] TakeCompactData()
        {
            int size = flattenSize;

            DataCompact[] result = GenericPoolArray <DataCompact> .Take(size);

            sbyte initialPass = -1;

            for (int i = 0; i < size; i++)
            {
                result[i].pass = initialPass;
            }

            return(result);
        }
        //IS EXAMPLE
        private void ReturnFreeIndex(int index)
        {
            if (freeIndexStack.Length == freeIndexStackLength)
            {
                //Debug.LogFormat("stack doubled from {0} to {1}\n", freeIndexStack.Length, freeIndexStack.Length * 2);
                int[] newFreeIndexStack = GenericPoolArray <int> .Take(freeIndexStack.Length * 2);

                Array.Copy(freeIndexStack, newFreeIndexStack, freeIndexStack.Length);
                GenericPoolArray <int> .ReturnToPool(ref freeIndexStack);

                freeIndexStack = newFreeIndexStack;
            }
            freeIndexStack[freeIndexStackLength++] = index;
            //Debug.LogFormat("ReturnFreeIndex: returned {0}, stack length {1}, Cur stack {2}", index, stackLength, DebugCurFreeStack());
        }
        public void AppendCompactData(DataCompact[] value, byte compactDataArea, int startX, int endX, int startZ, int endZ)
        {
            for (int z = startZ; z < endZ; z++)
            {
                for (int x = startX; x < endX; x++)
                {
                    int curIndex = (z * sizeX) + x;
                    var val      = value[curIndex];

                    if (val.pass != -1)
                    {
                        //SetVoxel(x, z, val.min, val.max, val.pass, compactDataArea);
                        //copy pasted code from set voxel to reduce overhead

                        Data curNode = arrayData[curIndex];

                        byte area = compactDataArea;

                        if (curNode.next == -2)
                        {
                            arrayData[curIndex] = new Data(val.min, val.max, val.pass, -1, area);
                        }
                        else
                        {
                            bool isApplyed = false;
                            int  prevIndex = -1;

                            while (true)
                            {
                                curNode = arrayData[curIndex];

                                if (curNode.min > val.max)
                                {
                                    if (isApplyed)
                                    {
                                        break;
                                    }

                                    int freeIndex = freeIndexStackLength > 0 ? freeIndexStack[--freeIndexStackLength] : filledIndexes++;

                                    if (freeIndex == arrayData.Length)
                                    {
                                        Data[] newArrayData = GenericPoolArray <Data> .Take(arrayData.Length * 2);

                                        Array.Copy(arrayData, newArrayData, arrayData.Length);
                                        GenericPoolArray <Data> .ReturnToPool(ref arrayData);

                                        arrayData = newArrayData;
                                    }

                                    arrayData[freeIndex] = curNode;
                                    arrayData[curIndex]  = new Data(val.min, val.max, val.pass, freeIndex, area);
                                    break;
                                }

                                if (curNode.max < val.min)
                                {
                                    if (curNode.next == -1)
                                    {
                                        int freeIndex = freeIndexStackLength > 0 ? freeIndexStack[--freeIndexStackLength] : filledIndexes++;

                                        if (freeIndex == arrayData.Length)
                                        {
                                            Data[] newArrayData = GenericPoolArray <Data> .Take(arrayData.Length * 2);

                                            Array.Copy(arrayData, newArrayData, arrayData.Length);
                                            GenericPoolArray <Data> .ReturnToPool(ref arrayData);

                                            arrayData = newArrayData;
                                        }

                                        arrayData[curIndex].next = freeIndex;
                                        arrayData[freeIndex]     = new Data(val.min, val.max, val.pass, -1, area);
                                        break;
                                    }
                                    else
                                    {
                                        curIndex = curNode.next;
                                        continue;
                                    }
                                }

                                if (curNode.min < val.min)
                                {
                                    val.min = curNode.min;
                                }
                                if (curNode.max > val.max)
                                {
                                    val.max = curNode.max;
                                }

                                if (Math.Abs(val.max - curNode.max) <= voxelDistanceThreshold)
                                {
                                    val.pass = Math.Max(val.pass, curNode.pass);
                                    area     = curNode.area;
                                }

                                if (prevIndex != -1 && arrayData[prevIndex].Intersect(val.min, val.max))
                                {
                                    if (freeIndexStack.Length == freeIndexStackLength)
                                    {
                                        int[] newFreeIndexStack = GenericPoolArray <int> .Take(freeIndexStack.Length * 2);

                                        Array.Copy(freeIndexStack, newFreeIndexStack, freeIndexStack.Length);
                                        GenericPoolArray <int> .ReturnToPool(ref freeIndexStack);

                                        freeIndexStack = newFreeIndexStack;
                                    }
                                    freeIndexStack[freeIndexStackLength++] = curIndex;
                                    arrayData[prevIndex] = new Data(val.min, val.max, val.pass, curNode.next, area);
                                }
                                else
                                {
                                    arrayData[curIndex] = new Data(val.min, val.max, val.pass, curNode.next, area);
                                    prevIndex           = curIndex;
                                }
                                isApplyed = true;
                                curIndex  = curNode.next;
                                if (curIndex == -1)
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
        //const int targetIndex = 9700;
        //int debugAdditions = 0;
        public void SetVoxel(int x, int z, float min, float max, sbyte pass, byte area)
        {
            //work++;

            int  curIndex = (z * sizeX) + x;
            Data curNode  = arrayData[curIndex];

            //bool doDebug = curIndex == targetIndex;

            //if (doDebug) {
            //    debugAdditions++;
            //    Debug.LogFormat("{3} Set Voxel {0} min {1} max {2}", curIndex, min, max, debugAdditions - 1);

            //    Vector3 vMin = GetPos(x + debugAdditions - 1, z, min);
            //    Vector3 vMax = GetPos(x + debugAdditions - 1, z, max);

            //    Debuger_K.AddDot(vMin, Color.black, 0.005f);
            //    Debuger_K.AddDot(vMax, Color.white, 0.005f);
            //    Debuger_K.AddLine(vMin, vMax, Color.white);
            //    Debuger_K.AddLabel(SomeMath.MidPoint(vMin, vMax), debugAdditions - 1);

            //}

            if (curNode.next == -2)
            {
                //if (doDebug) Debug.LogFormat("{0} next == -2", debugAdditions - 1);
                arrayData[curIndex] = new Data(min, max, pass, -1, area);
            }
            else
            {
                bool isApplyed = false;
                int  prevIndex = -1;

                while (true)
                {
                    curNode = arrayData[curIndex];
                    //if (doDebug) Debug.LogFormat("{0} Iteration", debugAdditions - 1);

                    if (curNode.min > max)
                    {
                        //if (doDebug) Debug.LogFormat("{1} curNode.min > max. isApplyed: {0}", isApplyed, debugAdditions - 1);

                        if (isApplyed)
                        {
                            break;
                        }

                        //int freeIndex = GetFreeIndex();
                        int freeIndex = freeIndexStackLength > 0 ? freeIndexStack[--freeIndexStackLength] : filledIndexes++;

                        if (freeIndex == arrayData.Length)
                        {
                            Data[] newArrayData = GenericPoolArray <Data> .Take(arrayData.Length * 2);

                            Array.Copy(arrayData, newArrayData, arrayData.Length);
                            GenericPoolArray <Data> .ReturnToPool(ref arrayData);

                            arrayData = newArrayData;
                        }

                        arrayData[freeIndex] = curNode;
                        arrayData[curIndex]  = new Data(min, max, pass, freeIndex, area);
                        //if (doDebug) Debug.LogFormat("{1} Setted up at {0}", freeIndex, debugAdditions - 1);
                        break;
                    }

                    if (curNode.max < min)
                    {
                        //if (doDebug) Debug.LogFormat("{0} curNode.max < min", debugAdditions - 1);

                        //current node are below current data
                        if (curNode.next == -1)  //no data next just add node
                                                 //if (doDebug) Debug.LogFormat("{0} no data next just add node", debugAdditions - 1);
                        //int freeIndex = GetFreeIndex();
                        {
                            int freeIndex = freeIndexStackLength > 0 ? freeIndexStack[--freeIndexStackLength] : filledIndexes++;

                            if (freeIndex == arrayData.Length)
                            {
                                Data[] newArrayData = GenericPoolArray <Data> .Take(arrayData.Length * 2);

                                Array.Copy(arrayData, newArrayData, arrayData.Length);
                                GenericPoolArray <Data> .ReturnToPool(ref arrayData);

                                arrayData = newArrayData;
                            }


                            arrayData[curIndex].next = freeIndex;
                            arrayData[freeIndex]     = new Data(min, max, pass, -1, area);
                            break;
                        }
                        else  //there is some data next check it
                              //if (doDebug) Debug.LogFormat("{0} there is some data next check it", debugAdditions - 1);
                        {
                            curIndex = curNode.next;
                            continue;
                        }
                    }



                    if (curNode.min < min)
                    {
                        min = curNode.min;
                    }
                    if (curNode.max > max)
                    {
                        max = curNode.max;
                    }

                    //if (doDebug) Debug.LogFormat("{0} Overlaping. new min {1} max {2}", debugAdditions - 1, min, max);

                    if (Math.Abs(max - curNode.max) <= voxelDistanceThreshold)
                    {
                        pass = Math.Max(pass, curNode.pass);
                        area = curNode.area; //here actualy should be priority
                    }


                    if (prevIndex != -1 && arrayData[prevIndex].Intersect(min, max))
                    {
                        //set data to previous index
                        //if (doDebug) Debug.LogFormat("{0} set data to PREVIOUS ({1}) index", debugAdditions - 1, prevIndex);
                        //ReturnFreeIndex(curIndex);

                        if (freeIndexStack.Length == freeIndexStackLength)
                        {
                            int[] newFreeIndexStack = GenericPoolArray <int> .Take(freeIndexStack.Length * 2);

                            Array.Copy(freeIndexStack, newFreeIndexStack, freeIndexStack.Length);
                            GenericPoolArray <int> .ReturnToPool(ref freeIndexStack);

                            freeIndexStack = newFreeIndexStack;
                        }
                        freeIndexStack[freeIndexStackLength++] = curIndex;


                        arrayData[prevIndex] = new Data(min, max, pass, curNode.next, area);
                    }
                    else
                    {
                        //if (doDebug) Debug.LogFormat("{0} set data to CURRENT ({1}) index", debugAdditions - 1, curIndex);
                        arrayData[curIndex] = new Data(min, max, pass, curNode.next, area);
                        prevIndex           = curIndex;
                    }
                    isApplyed = true;
                    curIndex  = curNode.next;
                    if (curIndex == -1)
                    {
                        break;
                    }
                }
            }
        }
        public void AppendMeshConvexPrivate(DataCompact[] compactData, Vector3[] verts, int[] tris, Matrix4x4 matrix, byte area, bool FLIP_Y)
        {
            float voxelSize    = template.voxelSize;
            int   startX_extra = template.startX_extra;
            int   endX_extra   = template.endX_extra;
            int   startZ_extra = template.startZ_extra;
            int   endZ_extra   = template.endZ_extra;

            ShapeDataHelperTriangleRasterization triangleRasterizator = GenericPool <ShapeDataHelperTriangleRasterization> .Take();

            Vector3[] tempVerts = GenericPoolArray <Vector3> .Take(verts.Length);

            for (int i = 0; i < verts.Length; i++)
            {
                tempVerts[i] = matrix.MultiplyPoint3x4(verts[i]);
            }

            //rasterization
            float maxSlopeCos = Mathf.Cos(template.maxSlope * Mathf.PI / 180f);

            for (int t = 0; t < tris.Length; t += 3)
            {
                Vector3 A = tempVerts[tris[t]];
                Vector3 B = tempVerts[tris[t + 1]];
                Vector3 C = tempVerts[tris[t + 2]];

                sbyte passability = -1;
                if (area == 1)//id of clear Area all time
                {
                    passability = (sbyte)Passability.Unwalkable;
                }
                else if (CalculateWalk(A, B, C, maxSlopeCos, FLIP_Y))
                {
                    passability = (sbyte)Passability.Walkable;
                }
                else
                {
                    passability = (sbyte)Passability.Slope;
                }



                //float crossY = Vector3.Cross(B - A, C - A).normalized.y;
                //if (FLIP_Y)
                //    crossY *= -1;
                //                if (crossY > 0) {
                //                    bool unwalkableBySlope = !(crossY >= maxSlopeCos);
                //                    if (area == 1)//id of clear Area all time
                //                        passability = (sbyte)Passability.Unwalkable;
                //                    else if (unwalkableBySlope)
                //                        passability = (sbyte)Passability.Slope;
                //                    else
                //                        passability = (sbyte)Passability.Walkable;

                //#if UNITY_EDITOR
                //                    if (!unwalkableBySlope && Debuger_K.doDebug && Debuger_K.debugOnlyNavMesh == false)
                //                        Debuger_K.AddWalkablePolygon(template.gridPosX, template.gridPosZ, template.properties, A, B, C);
                //#endif
                //                }

                triangleRasterizator.RasterizeTriangle(
                    A, B, C,
                    voxelSize,
                    startX_extra, endX_extra,
                    startZ_extra, endZ_extra,
                    compactData,
                    passability,
                    sizeX);
            }

            GenericPool <ShapeDataHelperTriangleRasterization> .ReturnToPool(ref triangleRasterizator);

            GenericPoolArray <Vector3> .ReturnToPool(ref tempVerts);
        }