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; } }
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()); }