Пример #1
0
        public MyNavmeshManager(MyRDPathfinding rdPathfinding, Vector3D center, Vector3D forwardDirection, int tileSize, int tileHeight, int tileLineCount, MyRecastOptions recastOptions)
        {
            Vector3 vector = new Vector3(ran.NextFloat(), ran.NextFloat(), ran.NextFloat());

            vector              -= Math.Min(vector.X, Math.Min(vector.Y, vector.Z));
            vector              /= Math.Max(vector.X, Math.Max(vector.Y, vector.Z));
            this.m_debugColor    = new Color(vector);
            this.m_tileSize      = tileSize;
            this.m_tileHeight    = tileHeight;
            this.m_tileLineCount = tileLineCount;
            this.Planet          = this.GetPlanet(center);
            this.m_heightCoordTransformationIncrease = 0.5f;
            float cellSize = 0.2f;

            this.m_recastOptions = recastOptions;
            float num2 = (this.m_tileSize * 0.5f) + (this.m_tileSize * ((float)Math.Floor((double)(this.m_tileLineCount * 0.5f))));
            float num3 = this.m_tileHeight * 0.5f;

            this.m_border = this.m_recastOptions.agentRadius + (3f * cellSize);
            float[] bMin = new float[] { -num2, -num3, -num2 };
            float[] bMax = new float[] { num2, num3, num2 };
            this.m_rdWrapper = new MyRDWrapper();
            this.m_rdWrapper.Init(cellSize, (float)this.m_tileSize, bMin, bMax);
            Vector3D vectord = Vector3D.CalculatePerpendicularVector(-Vector3D.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(center)));

            this.m_navmeshOBBs   = new MyNavmeshOBBs(this.Planet, center, vectord, this.m_tileLineCount, this.m_tileSize, this.m_tileHeight);
            this.m_debugTileSize = new int?[this.m_tileLineCount][];
            for (int i = 0; i < this.m_tileLineCount; i++)
            {
                this.m_debugTileSize[i] = new int?[this.m_tileLineCount];
            }
            this.m_extendedBaseOBB = new MyOrientedBoundingBoxD(this.m_navmeshOBBs.BaseOBB.Center, new Vector3D(this.m_navmeshOBBs.BaseOBB.HalfExtent.X, (double)this.m_tileHeight, this.m_navmeshOBBs.BaseOBB.HalfExtent.Z), this.m_navmeshOBBs.BaseOBB.Orientation);
            this.m_navInputMesh    = new MyNavigationInputMesh(rdPathfinding, this.Planet, center);
        }
Пример #2
0
        public MyNavmeshManager(MyRDPathfinding rdPathfinding, Vector3D center, Vector3D forwardDirection, int tileSize, int tileHeight, int tileLineCount, MyRecastOptions recastOptions)
        {
            m_tileSize      = tileSize;
            m_tileHeight    = tileHeight;
            m_tileLineCount = tileLineCount;
            Planet          = GetPlanet(center);

            m_heightCoordTransformationIncrease = 0.5f;

            float cellSize = RECAST_CELL_SIZE;

            m_recastOptions = recastOptions;

            float horizontalOrigin = (m_tileSize * 0.5f + m_tileSize * (float)Math.Floor(m_tileLineCount * 0.5f));
            var   verticalOrigin   = m_tileHeight * 0.5f;

            m_border = m_recastOptions.agentRadius + 3 * cellSize;

            float[] bmin = new float[3] {
                -horizontalOrigin, -verticalOrigin, -horizontalOrigin
            };
            float[] bmax = new float[3] {
                horizontalOrigin, verticalOrigin, horizontalOrigin
            };

            m_rdWrapper = new MyRDWrapper();
            m_rdWrapper.Init(cellSize, m_tileSize, bmin, bmax);

            Vector3D gravityVector = -Vector3D.Normalize(GameSystems.MyGravityProviderSystem.CalculateTotalGravityInPoint(center));
            var      direction     = Vector3D.CalculatePerpendicularVector(gravityVector);

            m_navmeshOBBs   = new MyNavmeshOBBs(Planet, center, direction, m_tileLineCount, m_tileSize, m_tileHeight);
            m_debugTileSize = new int?[m_tileLineCount][];
            for (int i = 0; i < m_tileLineCount; i++)
            {
                m_debugTileSize[i] = new int?[m_tileLineCount];
            }

            m_extendedBaseOBB = new MyOrientedBoundingBoxD(m_navmeshOBBs.BaseOBB.Center,
                                                           new Vector3D(m_navmeshOBBs.BaseOBB.HalfExtent.X, m_tileHeight, m_navmeshOBBs.BaseOBB.HalfExtent.Z),
                                                           m_navmeshOBBs.BaseOBB.Orientation);

            m_navInputMesh = new MyNavigationInputMesh(rdPathfinding, Planet, center);
        }
Пример #3
0
        private MyRecastOptions GetRecastOptions(MyCharacter character)
        {
            MyRecastOptions options1 = new MyRecastOptions();

            options1.cellHeight           = 0.2f;
            options1.agentHeight          = 1.5f;
            options1.agentRadius          = 0.5f;
            options1.agentMaxClimb        = 0.6f;
            options1.agentMaxSlope        = 60f;
            options1.regionMinSize        = 1f;
            options1.regionMergeSize      = 10f;
            options1.edgeMaxLen           = 50f;
            options1.edgeMaxError         = 3f;
            options1.vertsPerPoly         = 6f;
            options1.detailSampleDist     = 6f;
            options1.detailSampleMaxError = 1f;
            options1.partitionType        = 1;
            return(options1);
        }
Пример #4
0
        public void InitializeNavmesh(Vector3D center)
        {
            this.m_isNavmeshInitialized = true;
            float cellSize = 0.2f;

            this.m_singleTileSize   = 20;
            this.m_tileLineCount    = 50;
            this.m_singleTileHeight = 70;
            MyRecastOptions options1 = new MyRecastOptions();

            options1.cellHeight           = 0.2f;
            options1.agentHeight          = 1.5f;
            options1.agentRadius          = 0.5f;
            options1.agentMaxClimb        = 0.5f;
            options1.agentMaxSlope        = 50f;
            options1.regionMinSize        = 1f;
            options1.regionMergeSize      = 10f;
            options1.edgeMaxLen           = 50f;
            options1.edgeMaxError         = 3f;
            options1.vertsPerPoly         = 6f;
            options1.detailSampleDist     = 6f;
            options1.detailSampleMaxError = 1f;
            options1.partitionType        = 1;
            this.m_recastOptions          = options1;
            float num2 = (this.m_singleTileSize * 0.5f) + (this.m_singleTileSize * ((float)Math.Floor((double)(this.m_tileLineCount * 0.5f))));
            float num3 = this.m_singleTileHeight * 0.5f;

            this.m_border = this.m_recastOptions.agentRadius + (3f * cellSize);
            float[] bMin = new float[] { -num2, -num3, -num2 };
            float[] bMax = new float[] { num2, num3, num2 };
            this.rdWrapper = new MyRDWrapper();
            this.rdWrapper.Init(cellSize, (float)this.m_singleTileSize, bMin, bMax);
            Vector3D forwardDirection = Vector3D.CalculatePerpendicularVector(-Vector3D.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(center)));

            this.UnloadData();
            this.m_navmeshOBBs = new MyNavmeshOBBs(this.GetPlanet(center), center, forwardDirection, this.m_tileLineCount, this.m_singleTileSize, this.m_singleTileHeight);
            this.m_meshCenter  = center;
            this.m_visualNavmesh.Clear();
        }
        //private NavmeshOBBs m_navmeshOBBs;

        #region NavmeshOBBs class
        /*
        // TODO: class should have a datastructure to encapsulate OBB with their coordinate and gravity vector        
        
        /// <summary>
        /// Class that contains navmesh OBBs
        /// The middle of the matrix has 0,0 (x,y) coordinate, left is -x, bottom is -y
        /// ATTENTION -> the above is not true anymore -> search for the truth
        /// </summary>
        private class NavmeshOBBs
        {
            #region Fields
            private MyOrientedBoundingBox?[][] m_obbs;
            private float m_tileHalfSize, m_tileHalfHeight;
            Vector3D m_centerPoint;
            #endregion

            public int OBBsPerLine { get; private set; }

            #region Contructor
            // TODO: accept a rotation so we define what is front,back,left, right....
            //       or maybe notttttt
            public NavmeshOBBs(Vector3D centerPoint, int obbsPerLine, int tileSize, int tileHeight)
            {
                // There will always be an odd number of obbs in a line
                OBBsPerLine = obbsPerLine;
                if (OBBsPerLine % 2 == 0)
                    OBBsPerLine += 1;

                m_tileHalfSize = tileSize * 0.5f;
                m_tileHalfHeight = tileHeight * 0.5f;
                m_centerPoint = centerPoint;

                m_obbs = new MyOrientedBoundingBox?[OBBsPerLine][];
                for (int i = 0; i < OBBsPerLine; i++)
                    m_obbs[i] = new MyOrientedBoundingBox?[OBBsPerLine];

                Initialize();
            }
            #endregion

            #region public Methods
            /// <summary>
            /// Return the OBB at the specific coordinate or null, if is out of bounds
            /// </summary>
            public MyOrientedBoundingBox? GetOBB(int coordX, int coordY)
            {
                if (coordX < 0 || coordX >= OBBsPerLine ||
                    coordY < 0 || coordY >= OBBsPerLine)
                    return null;

                return m_obbs[coordY][coordX];
            }

            public MyOrientedBoundingBox? GetOBB(Vector3D worldPosition)
            {
                // TODO: silly search needs to get smarter
                foreach (var obbLine in m_obbs)
                    foreach(var obb in obbLine)
                    {
                        Vector3D diff = obb.Value.Center - worldPosition;
                        if (Math.Abs(diff.X) <= obb.Value.HalfExtent.X &&
                            Math.Abs(diff.Y) <= obb.Value.HalfExtent.Y &&
                            Math.Abs(diff.Z) <= obb.Value.HalfExtent.Z)
                            return obb;
                    }

                return null;
            }

            /// <summary>
            /// TEMPORARY - Returns the coords for the OBB - remove this after creating a data structure to encapsulate...
            /// </summary>
            public bool GetCoords(MyOrientedBoundingBoxD obb, out int xCoord, out int yCoord)
            {
                xCoord = yCoord = -1;

                for (int i = 0; i < m_obbs.Length; i++)
                    for (int j = 0; j < m_obbs[0].Length; j++)
                        if (obb == m_obbs[i][j])
                        {
                            xCoord = j;
                            yCoord = i;
                            return true;
                        }

                return false;
            }

            /// <summary>
            /// Returns a list of OBBs intersected by a line
            /// </summary>
            public List<MyOrientedBoundingBoxD> GetIntersectedOBB(Line line)
            {
                //List<MyOrientedBoundingBoxD> intersectedOBBs = new List<MyOrientedBoundingBoxD>();
                Dictionary<MyOrientedBoundingBox, float> intersectedOBBs = new Dictionary<MyOrientedBoundingBox, float>();

                foreach (var obbLine in m_obbs)
                    foreach (var obb in obbLine)
                        if (obb.Value.Contains(ref line.From) || 
                            obb.Value.Contains(ref line.To) || 
                            obb.Value.Intersects(ref line).HasValue)
                            //intersectedOBBs.Add(obb.Value);
                            intersectedOBBs.Add(obb.Value, Vector3D.Distance(line.From, obb.Value.Center));

                //if (intersectedOBBs.Count > 0)
                //    ;

                return intersectedOBBs.OrderBy(d => d.Value).Select(kvp => kvp.Key).ToList();
            }
            
            #endregion

            #region Private Methods
            private void Initialize()
            {
                /* MyOBBs corners
                 * 00 - Upper Front Left <--
                 * 01 - Upper Back Left <--
                 * 02 - Lower Back Left
                 * 03 - Lower Front Left
                 * 04 - Upper Front Right <--
                 * 05 - Upper Back Right <--
                 * 06 - Lower Back Right
                 * 07 - Lower Front Right
                 */
        /*
                // TODO: use GetOBBCorners
                int middleCoord = (OBBsPerLine - 1) / 2;
                MyOrientedBoundingBoxD obb = CreateOBB(m_centerPoint);
                m_obbs[middleCoord][middleCoord] = obb;

                Vector3[] corners = new Vector3[8];
                obb.GetCorners(corners, 0);

                Vector3D offset = corners[4];
                Vector3D newGravity = -Vector3D.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(offset));                

                Vector3D newPoint = Vector3D.Transform(m_centerPoint - offset, Quaternion.CreateFromAxisAngle(newGravity, (float)(-90 * Math.PI / 180f)));
                Vector3D centerHorizontalDiff = newPoint - (m_centerPoint - offset);

                // //

                // For each point, calculate up and down points //

                Vector3D newCenter = m_centerPoint;
                Vector2I index = new Vector2I(middleCoord,middleCoord);
                for (int i = middleCoord; i >= 0; i--)
                {
                    FillOBBLine(newCenter, index);
                    newCenter -= centerHorizontalDiff;
                    index += new Vector2I(-1,0);
                }

                newCenter = m_centerPoint;
                index.X = index.Y = middleCoord;
                for (int i = middleCoord + 1; i < OBBsPerLine; i++)
                {
                    newCenter += centerHorizontalDiff;
                    index += new Vector2I(1, 0);
                    FillOBBLine(newCenter, index);
                }
            }


            private void FillOBBLine(Vector3D center, Vector2I currentIndex)
            {
                Vector3D gravityVector = -Vector3D.Normalize(GameSystems.MyGravityProviderSystem.CalculateTotalGravityInPoint(center));
                Vector3D perpedicularVector = Vector3D.CalculatePerpendicularVector(gravityVector);
                MyOrientedBoundingBoxD obb = new MyOrientedBoundingBox(center, new Vector3(m_tileHalfSize, m_tileHalfHeight, m_tileHalfSize), Quaternion.CreateFromForwardUp(perpedicularVector, gravityVector));
                if (m_obbs[currentIndex.Y][currentIndex.X] == null)
                    m_obbs[currentIndex.Y][currentIndex.X] = obb;

                Vector3[] corners = new Vector3[8];
                obb.GetCorners(corners, 0);
                Vector3D offset = corners[1];
                Vector3D newGravity = -Vector3D.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(offset));

                Vector3D newPoint = Vector3D.Transform(center - offset, Quaternion.CreateFromAxisAngle(newGravity, (float)(90 * Math.PI / 180f)));
                Vector3D centerVerticalDiff = newPoint - (center - offset);

                FillOBBSemiLine(center, centerVerticalDiff, currentIndex, new Vector2I(0, -1));
                FillOBBSemiLine(center, -centerVerticalDiff, currentIndex, new Vector2I(0, 1));
            }

            

            private void FillOBBSemiLine(Vector3D currentCenter, Vector3D diffVector, Vector2I currentIndex, Vector2I indexAddition)
            {
                if (currentIndex.X < 0 || currentIndex.X >= OBBsPerLine ||
                    currentIndex.Y < 0 || currentIndex.Y >= OBBsPerLine)
                    return;

                if(m_obbs[currentIndex.Y][currentIndex.X] == null)
                    m_obbs[currentIndex.Y][currentIndex.X] = CreateOBB(currentCenter);

                FillOBBSemiLine(currentCenter + diffVector, diffVector, currentIndex + indexAddition, indexAddition);
            }

            private MyOrientedBoundingBoxD CreateOBB(Vector3D center)
            {
                Vector3D gravityVector = -Vector3D.Normalize(GameSystems.MyGravityProviderSystem.CalculateTotalGravityInPoint(center));
                Vector3D perpedicularVector = Vector3D.CalculatePerpendicularVector(gravityVector);
                return new MyOrientedBoundingBox(center, new Vector3(m_tileHalfSize, m_tileHalfHeight, m_tileHalfSize), Quaternion.CreateFromForwardUp(perpedicularVector, gravityVector));
            }
            #endregion
        }
         */
        #endregion

        public void InitializeNavmesh(Vector3D center)
        {
            m_isNavmeshInitialized = true;
            float cellSize = 0.2f;
            m_singleTileSize = 20;
            m_tileLineCount = 50;

            m_singleTileHeight = 70;

            //m_semiColumnCount = ((m_singleTileHeight / m_singleTileSize) - 1) / 2;


            m_recastOptions = new MyRecastOptions()
            {
                cellHeight = 0.2f,
                agentHeight = 1.5f,
                agentRadius = 0.5f,
                agentMaxClimb = 0.5f,
                agentMaxSlope = 50,
                regionMinSize = 1,
                regionMergeSize = 10,
                edgeMaxLen = 50,
                edgeMaxError = 3f,
                vertsPerPoly = 6,
                detailSampleDist = 6,
                detailSampleMaxError = 1,
                partitionType = 1
            };

            float horizontalOrigin = (m_singleTileSize * 0.5f + m_singleTileSize * (float)Math.Floor(m_tileLineCount * 0.5f));
            var verticalOrigin = m_singleTileHeight * 0.5f;
            m_border = m_recastOptions.agentRadius + 3 * cellSize;

            float[] bmin = new float[3] { -horizontalOrigin, -verticalOrigin, -horizontalOrigin };
            float[] bmax = new float[3] { horizontalOrigin, verticalOrigin, horizontalOrigin };

            rdWrapper = new MyRDWrapper();
            rdWrapper.Init(cellSize, m_singleTileSize, bmin, bmax);

            //Vector3D direction = MySession.Static.ControlledEntity.ControllerInfo.Controller.Player.Character.WorldMatrix.Forward;
            Vector3D gravityVector = -Vector3D.Normalize(GameSystems.MyGravityProviderSystem.CalculateTotalGravityInPoint(center));
            var direction = Vector3D.CalculatePerpendicularVector(gravityVector);

            UnloadData();
            m_navmeshOBBs = new MyNavmeshOBBs(GetPlanet(center), center, direction, m_tileLineCount, m_singleTileSize, m_singleTileHeight);
            // TODO: m_meshCenter is used for pathfinding position transformation -> probably use the center point of the OBB
            m_meshCenter = center;

            // To get the center point difference
            //var planet = GetPlanet(center);
            //int halfMaxSize = (int)(m_singleTileSize / 2f);

            //MyNavigationInputMesh.RefreshCache();
            m_visualNavmesh.Clear();
        }