Exemple #1
0
        public void VoxelCheckRequest(bool useAsteroidAABB = false)
        {
            if (_collisionSystem.AutoPilot.InGravity())
            {
                var  stepList     = _collisionSystem.AutoPilot.GetPlanetPathSteps(StartPosition, DirectionVector, Distance, true);
                var  planet       = _collisionSystem.AutoPilot.GetCurrentPlanet();
                var  planetCenter = planet.PositionComp.WorldAABB.Center;
                int  index        = -1;
                bool underwater   = false;

                for (int i = 0; i < stepList.Count; i++)
                {
                    var step              = stepList[i];
                    var stepToCore        = Vector3D.Distance(planetCenter, step);
                    var stepSurfaceToCore = Vector3D.Distance(planetCenter, WaterHelper.GetClosestSurface(step, planet, _collisionSystem.AutoPilot.CurrentWater));

                    if (stepToCore < stepSurfaceToCore)
                    {
                        //Logger.MsgDebug("Planet Voxel Found: ", DebugTypeEnum.Collision);
                        index = i == 0 ? 0 : i - 1;
                        break;
                    }
                }

                if (index >= 0)
                {
                    CollisionIsWater = WaterHelper.IsPositionUnderwater(stepList[index], _collisionSystem.AutoPilot.CurrentWater);
                    VoxelEntity      = planet;
                    VoxelCoords      = stepList[index];
                    VoxelDistance    = Vector3D.Distance(StartPosition, stepList[index]);
                }
            }
            else
            {
                MyVoxelBase closestVoxel    = null;
                double      closestDistance = -1;

                /*
                 * //Temp Debug Code Start
                 * _voxelScanList.Clear();
                 * var startCorner = StartPosition + new Vector3D(-2000, -2000, -2000);
                 * var endCorner = StartPosition + new Vector3D(2000, 2000, 2000);
                 * var box = new BoundingBoxD(startCorner, endCorner);
                 * MyGamePruningStructure.GetAllVoxelMapsInBox(ref box, _voxelScanList);
                 */

                foreach (var voxel in _voxelScanList)
                {
                    var planet = voxel as MyPlanet;

                    if (planet != null)
                    {
                        continue;
                    }

                    if (!useAsteroidAABB)
                    {
                        double minDist        = 0;
                        double maxDist        = 0;
                        bool   boxCheckResult = voxel.PositionComp.WorldAABB.Intersect(ref Ray, out minDist, out maxDist);

                        Vector3D startBox    = boxCheckResult ? (minDist - 5) * DirectionVector + StartPosition : StartPosition;
                        Vector3D endBox      = boxCheckResult ? (maxDist + 5) * DirectionVector + StartPosition : EndPosition;
                        Vector3D?hitPosition = null;
                        LineD    voxelLine   = new LineD(startBox, endBox);
                        bool     gotHit      = false;

                        try {
                            using (voxel.Pin()) {
                                gotHit = voxel.GetIntersectionWithLine(ref voxelLine, out hitPosition);
                            }
                        } catch (Exception e) {
                            Logger.WriteLog("Supressed Exception While Checking Voxel Collision");
                            Logger.WriteLog(e.ToString());
                        }

                        if (hitPosition.HasValue)
                        {
                            var hitDist = Vector3D.Distance((Vector3D)hitPosition, StartPosition);

                            if (closestVoxel == null || closestVoxel != null && hitDist < closestDistance)
                            {
                                closestVoxel    = voxel;
                                closestDistance = hitDist;
                            }
                        }
                    }
                    else
                    {
                        if (voxel.PositionComp.WorldAABB.Contains(StartPosition) == ContainmentType.Contains)
                        {
                            var hitDist = Vector3D.Distance(StartPosition, StartPosition + DirectionVector);

                            if (closestVoxel == null || closestVoxel != null && hitDist < closestDistance)
                            {
                                closestVoxel    = voxel;
                                closestDistance = hitDist;
                            }
                        }
                        else
                        {
                            double hitDist = 0;
                            voxel.PositionComp.WorldAABB.Intersects(ref Line, out hitDist);

                            if (closestVoxel == null || closestVoxel != null && hitDist < closestDistance)
                            {
                                closestVoxel    = voxel;
                                closestDistance = hitDist;
                            }
                        }
                    }
                }

                if (closestDistance == -1)
                {
                    return;
                }

                VoxelEntity   = closestVoxel;
                VoxelDistance = closestDistance;
                VoxelCoords   = closestDistance * DirectionVector + StartPosition;
            }
        }
Exemple #2
0
        private void CalculateAreaAndPath()
        {
            //Reset Existing Values
            _closestNodeToStart = null;
            _closestNodeToEnd   = null;
            _endPath            = false;
            _goodNodes.Clear();
            _badNodes.Clear();
            _pathWaypoints.Clear();
            _shorelineNodes.Clear();

            if (!EnablePathGeneration)
            {
                _endPath = true;
                return;
            }

            //Create The Grid Of Nodes
            var    up                 = _behavior.AutoPilot.UpDirectionFromPlanet;
            var    forward            = Vector3D.CalculatePerpendicularVector(up);
            var    myPos              = _behavior.RemoteControl.GetPosition();
            var    myMatrix           = MatrixD.CreateWorld(myPos, forward, up);
            double distanceOffsetHalf = (_worldStepDistance * _steps) / 2;
            var    startOffset        = new Vector3D(-distanceOffsetHalf, 0, -distanceOffsetHalf);
            var    startGridCoords    = Vector3D.Transform(startOffset, myMatrix);

            _targetCoords = _behavior.AutoPilot.GetPendingWaypoint();

            for (int x = 0; x <= _steps; x++)
            {
                for (int y = 0; y <= _steps; y++)
                {
                    var gridWorldCellOffset = startOffset;
                    gridWorldCellOffset.X += (x * _worldStepDistance);
                    gridWorldCellOffset.Z += (y * _worldStepDistance);
                    var    gridWorldCoords = Vector3D.Transform(gridWorldCellOffset, myMatrix);
                    double distAboveWater  = 0;
                    var    surfaceCoords   = WaterHelper.GetClosestSurface(gridWorldCoords, _behavior.AutoPilot.CurrentPlanet, _behavior.AutoPilot.CurrentWater, ref distAboveWater);

                    if (x == 0 & y == 0)
                    {
                        _gridStartCoords = surfaceCoords;
                    }

                    if (x == _steps - 1 & y == _steps - 1)
                    {
                        _gridEndCoords = surfaceCoords;
                    }

                    var node = new PathNode(surfaceCoords, x, y);

                    if (distAboveWater > -_minimumDepth)
                    {
                        _badNodes.Add(node);
                        continue;
                    }

                    _goodNodes.Add(node);
                    node.DistanceFromStart = Vector3D.Distance(myPos, surfaceCoords);
                    node.DistanceFromEnd   = Vector3D.Distance(surfaceCoords, _targetCoords);

                    if (_closestNodeToStart == null || node.DistanceFromStart < _closestNodeToStart.DistanceFromStart)
                    {
                        _closestNodeToStart = node;
                    }

                    if (_closestNodeToEnd == null || node.DistanceFromEnd < _closestNodeToEnd.DistanceFromEnd)
                    {
                        _closestNodeToEnd = node;
                    }
                }
            }

            for (int i = _goodNodes.Count - 1; i >= 0; i--)
            {
                if (GetNeighbours(_goodNodes[i], true).Count > 0)
                {
                    _shorelineNodes.Add(_goodNodes[i]);
                    _goodNodes.RemoveAt(i);
                }
            }

            if (_shorelineNodes.Contains(_closestNodeToStart))
            {
                _closestNodeToStart = null;

                foreach (var node in _goodNodes)
                {
                    if (_closestNodeToStart == null || node.DistanceFromStart < _closestNodeToStart.DistanceFromStart)
                    {
                        _closestNodeToStart = node;
                    }
                }
            }

            if (_shorelineNodes.Contains(_closestNodeToEnd))
            {
                _closestNodeToEnd = null;

                foreach (var node in _goodNodes)
                {
                    if (_closestNodeToEnd == null || node.DistanceFromEnd < _closestNodeToEnd.DistanceFromEnd)
                    {
                        _closestNodeToEnd = node;
                    }
                }
            }

            //Logger.MsgDebug("Total Nodes Calculated: " + _goodNodes.Count, DebugTypeEnum.AutoPilot);

            //Calculate the Path
            _pathWaypoints = new List <Vector3D>(FindPath());
        }