public void DrawHighlight() { var block = m_tool.GetTargetGrid().GetCubeBlock(m_tool.TargetCube); //Debug.Assert(block != null, "Call programmer"); if (block == null) // This is just a workaround, so that the above assert does not crash the game on release return; Matrix blockWorldMatrixF; block.Orientation.GetMatrix(out blockWorldMatrixF); MatrixD blockWorldMatrix = blockWorldMatrixF; MatrixD gridWorld = m_tool.GetTargetGrid().Physics.GetWorldMatrix(); blockWorldMatrix = blockWorldMatrix * Matrix.CreateTranslation(block.Position) * Matrix.CreateScale(m_tool.GetTargetGrid().GridSize) * gridWorld; /*Vector3 pos = Vector3.Transform(new Vector3(0.0f, 0.0f, 0.0f), blockRotation); MyRenderProxy.DebugDrawAxis(blockRotation, m_targetGrid.GridSize, false); MyRenderProxy.DebugDrawSphere(pos, 0.5f, new Vector3(1.0f, 0.0f, 0.0f), 1.0f, false);*/ float highlightThickness = m_tool.GetTargetGrid().GridSizeEnum == MyCubeSize.Large ? 0.06f : 0.03f; Vector3 centerOffset = new Vector3(0.5f, 0.5f, 0.5f); TimeSpan time = MySession.Static.ElapsedPlayTime; Vector3 inflate = new Vector3(0.05f); BoundingBoxD bb = new BoundingBoxD(-block.BlockDefinition.Center - centerOffset - inflate, block.BlockDefinition.Size - block.BlockDefinition.Center - centerOffset + inflate); Color color = m_tool.HighlightColor; var lineMaterial = m_tool.HighlightMaterial; MySimpleObjectDraw.DrawTransparentBox(ref blockWorldMatrix, ref bb, ref color, MySimpleObjectRasterizer.Wireframe, 1, highlightThickness, null, lineMaterial, false); }
public Area() { ProxyId = -1; ForestBox = BoundingBoxD.CreateInvalid(); ItemIds = new Dictionary<long, HashSet<int>>(); IsFull = false; }
public static bool RemoveEncounter(BoundingBoxD boundingVolume, int seed) { bool wasFound = false; for (int i = 0; i < 2; ++i) { MyEncounterId encounter = new MyEncounterId(boundingVolume, seed,i); if (true == m_savedEncounters.Contains(encounter)) { wasFound = false; continue; } List<IMyEntity> entitiesToRemove = new List<IMyEntity>(); foreach (var entity in m_entityToEncounterConversion) { if (entity.Value.BoundingBox == encounter.BoundingBox && entity.Value.Seed == encounter.Seed && entity.Value.EncounterId == encounter.EncounterId) { entity.Key.Close(); entitiesToRemove.Add(entity.Key); wasFound = true; } } foreach (var entity in entitiesToRemove) { m_entityToEncounterConversion.Remove(entity); } } return wasFound; }
public MyPlanet GetClosestContainingPlanet(Vector3D point) { m_voxels.Clear(); BoundingBoxD b = new BoundingBoxD(point, point); MyGamePruningStructure.GetAllVoxelMapsInBox(ref b, m_voxels); double dist = double.PositiveInfinity; MyPlanet p = null; foreach (var v in m_voxels) { if (v is MyPlanet) { var d = Vector3.Distance(v.WorldMatrix.Translation, point); if (d < dist) { dist = d; p = (MyPlanet)v; } } } return p; }
public MyEncounterId(BoundingBoxD box, int seed, int encounterId) { BoundingBox = box; Seed = seed; EncounterId = encounterId; PlacePosition = Vector3D.Zero; }
public override bool DebugDraw() { // Duplicit. Use MyFakes.DEBUG_DRAW_MODEL_DUMMIES; /*if (m_model != null) { foreach (var d in m_model.Dummies) { VRageRender.MyRenderProxy.DebugDrawOBB(d.Value.Matrix * WorldMatrix, Color.Blue.ToVector3(), 1.0f, false, false); VRageRender.MyRenderProxy.DebugDrawAxis(d.Value.Matrix * WorldMatrix, 1, false); } }*/ if (MyDebugDrawSettings.DEBUG_DRAW_CUBE_BLOCK_AABBS) { Color color = Color.Red; Color green = Color.Green; var centerGrid = m_cubeBlock.BlockDefinition.Center; var min = (m_cubeBlock.Min * m_cubeBlock.CubeGrid.GridSize) - new Vector3(m_cubeBlock.CubeGrid.GridSize / 2.0f); var max = (m_cubeBlock.Max * m_cubeBlock.CubeGrid.GridSize) + new Vector3(m_cubeBlock.CubeGrid.GridSize / 2.0f); BoundingBoxD bbox = new BoundingBoxD(min, max); var worldMat = m_cubeBlock.CubeGrid.WorldMatrix; MySimpleObjectDraw.DrawTransparentBox(ref worldMat, ref bbox, ref color, MySimpleObjectRasterizer.Wireframe, 1, 0.01f); } return true; }
public void PrepareVoxelTriangleTests(BoundingBoxD cellBoundingBox, List<MyCubeGrid> gridsToTestOutput) { ProfilerShort.Begin("PrepareVoxelTriangleTests"); m_tmpEntityList.Clear(); // Each triangle will be tested with grids up to one largest cube further away from them, so we have to reflect this in the bounding box. float largeCubeSize = MyDefinitionManager.Static.GetCubeSize(MyCubeSize.Large); cellBoundingBox.Inflate(largeCubeSize); // Furthermore, a triangle cannot lie in a cube under existing block, so we have to extend the bbox even further if (MyPerGameSettings.NavmeshPresumesDownwardGravity) { var min = cellBoundingBox.Min; min.Y -= largeCubeSize; cellBoundingBox.Min = min; } MyGamePruningStructure.GetAllEntitiesInBox(ref cellBoundingBox, m_tmpEntityList); foreach (var entity in m_tmpEntityList) { var grid = entity as MyCubeGrid; if (grid == null) continue; if (!MyGridPathfinding.GridCanHaveNavmesh(grid)) continue; gridsToTestOutput.Add(grid); } m_tmpEntityList.Clear(); ProfilerShort.End(); }
public static MyEntity Spawn(this MyPhysicalInventoryItem thisItem, MyFixedPoint amount, BoundingBoxD box, MyEntity owner = null) { if(amount < 0) { return null; } MatrixD spawnMatrix = MatrixD.Identity; spawnMatrix.Translation = box.Center; var entity = Spawn(thisItem, amount, spawnMatrix, owner); if (entity == null) return null; var size = entity.PositionComp.LocalVolume.Radius; var halfSize = box.Size / 2 - new Vector3(size); halfSize = Vector3.Max(halfSize, Vector3.Zero); box = new BoundingBoxD(box.Center - halfSize, box.Center + halfSize); var pos = MyUtils.GetRandomPosition(ref box); Vector3 forward = MyUtils.GetRandomVector3Normalized(); Vector3 up = MyUtils.GetRandomVector3Normalized(); while (forward == up) up = MyUtils.GetRandomVector3Normalized(); Vector3 right = Vector3.Cross(forward, up); up = Vector3.Cross(right, forward); entity.WorldMatrix = MatrixD.CreateWorld(pos, forward, up); return entity; }
public void Init(ref Vector3I pos, MyPlanet planet) { m_pos = pos; m_cellHashCode = pos.GetHashCode() + planet.PositionLeftBottomCorner.GetHashCode(); m_planet = planet; SectorBox = new BoundingBoxD(m_planet.PositionLeftBottomCorner + pos * SECTOR_SIZE_METERS, m_planet.PositionLeftBottomCorner + pos * SECTOR_SIZE_METERS + SECTOR_SIZE_METERS); m_sectorCenter = SectorBox.Center; }
public MyElement(uint id) { m_id = id; Flags = MyElementFlag.EF_AABB_DIRTY; m_aabb = new BoundingBoxD(); m_proxyData = PROXY_UNASSIGNED; m_shadowProxyData = PROXY_UNASSIGNED; }
private void InitVoxelMap(Vector3D position, Vector3I size, string materialName, bool defineMemory) { IsValid = true; Size = size; _sizeMinusOne = new Vector3I(Size.X - 1, Size.Y - 1, Size.Z - 1); VoxelMaterial = SpaceEngineersCore.Resources.GetMaterialIndex(materialName); _positionLeftBottomCorner = position; _boundingContent = new BoundingBoxD(new Vector3I(Size.X, Size.Y, Size.Z), new Vector3I(0, 0, 0)); // this is too big for the current SEToolbox code to cope with, and is probably a planet. if (!defineMemory) return; // If you need larged voxel maps, enlarge this constant. Debug.Assert(Size.X <= MyVoxelConstants.MAX_VOXEL_MAP_SIZE_IN_VOXELS); Debug.Assert(Size.Y <= MyVoxelConstants.MAX_VOXEL_MAP_SIZE_IN_VOXELS); Debug.Assert(Size.Z <= MyVoxelConstants.MAX_VOXEL_MAP_SIZE_IN_VOXELS); // Voxel map size must be multiple of a voxel data cell size. Debug.Assert((Size.X & MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_MASK) == 0); Debug.Assert((Size.Y & MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_MASK) == 0); Debug.Assert((Size.Z & MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_MASK) == 0); _dataCellsCount.X = Size.X >> MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS; _dataCellsCount.Y = Size.Y >> MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS; _dataCellsCount.Z = Size.Z >> MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS; // Voxel map size must be multiple of a voxel data cell size. Debug.Assert((Size.X % MyVoxelConstants.VOXEL_RENDER_CELL_SIZE_IN_VOXELS) == 0); Debug.Assert((Size.Y % MyVoxelConstants.VOXEL_RENDER_CELL_SIZE_IN_VOXELS) == 0); Debug.Assert((Size.Z % MyVoxelConstants.VOXEL_RENDER_CELL_SIZE_IN_VOXELS) == 0); // Array of voxel cells in this voxel map. _voxelContentCells = new MyVoxelContentCell[_dataCellsCount.X][][]; for (var x = 0; x < _voxelContentCells.Length; x++) { _voxelContentCells[x] = new MyVoxelContentCell[_dataCellsCount.Y][]; for (var y = 0; y < _voxelContentCells[x].Length; y++) { _voxelContentCells[x][y] = new MyVoxelContentCell[_dataCellsCount.Z]; } } // Set base material. _voxelMaterialCells = new MyVoxelMaterialCell[_dataCellsCount.X][][]; for (var x = 0; x < _dataCellsCount.X; x++) { _voxelMaterialCells[x] = new MyVoxelMaterialCell[_dataCellsCount.Y][]; for (var y = 0; y < _dataCellsCount.Y; y++) { _voxelMaterialCells[x][y] = new MyVoxelMaterialCell[_dataCellsCount.Z]; for (var z = 0; z < _dataCellsCount.Z; z++) { _voxelMaterialCells[x][y][z] = new MyVoxelMaterialCell(VoxelMaterial, 0xFF); } } } }
public override void AccumulateCorrection(ref VRageMath.Vector3 correction, ref float weight) { Vector3D position = Parent.PositionAndOrientation.Translation; BoundingBoxD box = new BoundingBoxD(position - Vector3D.One, position + Vector3D.One); Vector3D currentMovement = Parent.ForwardVector * Parent.Speed; if (Parent.Speed > 0.01f) currentMovement.Normalize(); // Don't do any correction if we're not moving if (currentMovement.LengthSquared() < 0.01) { return; } var entities = MyEntities.GetEntitiesInAABB(ref box); foreach (var entity in entities) { var environmentItems = entity as MyEnvironmentItems; if (environmentItems == null) continue; environmentItems.GetItemsInRadius(ref position, 6.0f, m_trees); foreach (var item in m_trees) { Vector3D dir = item - position; var dist = dir.Normalize(); dir = Vector3D.Reject(currentMovement, dir); dir.Y = 0.0f; if (dir.Z * dir.Z + dir.X * dir.X < 0.1) { Vector3D dirLocal = Vector3D.TransformNormal(dir, Parent.PositionAndOrientationInverted); dir = position - item; dir = Vector3D.Cross(Vector3D.Up, dir); if (dirLocal.X < 0) dir = -dir; } dir.Normalize(); correction += (6f - dist) * Weight * dir; if (!correction.IsValid()) { System.Diagnostics.Debugger.Break(); } } m_trees.Clear(); } weight += Weight; entities.Clear(); }
public AreaData(int id, BoundingBoxD box, Dictionary<long, HashSet<int>> items) { Id = id; ForestBox = box; ItemIds = DictionaryReader<long, HashSetReader<int>>.Empty; var dictionary = new Dictionary<long, HashSetReader<int>>(); foreach (var pair in items) dictionary[pair.Key] = new HashSetReader<int>(pair.Value); ItemIds = new DictionaryReader<long, HashSetReader<int>>(dictionary); }
public static bool GetShapeCenter(HkShape shape, uint shapeKey, MyCubeGrid grid, ref Vector3D shapeCenter) { bool shapeSet = true; switch (shape.ShapeType) { case HkShapeType.List: var listShape = (HkListShape)shape; shape = listShape.GetChildByIndex((int)shapeKey); break; case HkShapeType.Mopp: var moppShape = (HkMoppBvTreeShape)shape; shape = moppShape.ShapeCollection.GetShape(shapeKey, null); break; case HkShapeType.Box: var boxShape = (HkBoxShape)shape; shape = boxShape; break; case HkShapeType.ConvexTranslate: var convexTranslateShape = (HkConvexShape)shape; shape = convexTranslateShape; break; case HkShapeType.ConvexTransform: var convexTransformShape = (HkConvexTransformShape)shape; shape = convexTransformShape; break; /* case HkShapeType.BvTree: var bvTreeShape = (HkBvTreeShape)shape; var iterator = bvTreeShape.Base.GetContainer(); while (iterator.CurrentValue.IsContainer() && iterator.CurrentValue.ShapeType != HkShapeType.ConvexTranslate && iterator.CurrentValue.ShapeType != HkShapeType.ConvexTransform) iterator.Next(); if (iterator.IsValid) shape = iterator.CurrentValue; else shapeSet = false; break;*/ default: shapeSet = false; break; } if (shapeSet) { Vector4 min4, max4; shape.GetLocalAABB(0.05f, out min4, out max4); Vector3 worldMin = Vector3.Transform(new Vector3(min4), grid.PositionComp.WorldMatrix); Vector3 worldMax = Vector3.Transform(new Vector3(max4), grid.PositionComp.WorldMatrix); var worldAABB = new BoundingBoxD(worldMin, worldMax); shapeCenter = worldAABB.Center; } return shapeSet; }
public void Init(IMy2DClipmapManager parent, int x, int y, int lod, ref BoundingBox2D bounds) { m_manager = (MyPlanetEnvironmentComponent)parent; var bounds3D = new BoundingBoxD(new Vector3D(bounds.Min, 0), new Vector3D(bounds.Max, 0)); Lod = lod; Face = m_manager.ActiveFace; var matrix = m_manager.ActiveClipmap.WorldMatrix; bounds3D = bounds3D.Transform(matrix); Coords = new Vector2I(x, y); Id = MyPlanetSectorId.MakeSectorId(x, y, m_manager.ActiveFace, lod); m_manager.RegisterProxy(this); MyEnvironmentSectorParameters sectorParams; matrix.Translation = Vector3D.Zero; sectorParams.SurfaceBasisX = Vector3.Transform(new Vector3(bounds.Width / 2, 0, 0), matrix); sectorParams.SurfaceBasisY = Vector3.Transform(new Vector3(0, bounds.Height / 2, 0), matrix); sectorParams.Center = bounds3D.Center; if (lod > m_manager.MaxLod) return; if (!m_manager.TryGetSector(Id, out EnvironmentSector)) { sectorParams.SectorId = Id; sectorParams.EntityId = MyPlanetSectorId.MakeSectorId(x, y, m_manager.ActiveFace, lod); sectorParams.Bounds = m_manager.GetBoundingShape(ref sectorParams.Center, ref sectorParams.SurfaceBasisX, ref sectorParams.SurfaceBasisY); ; sectorParams.Environment = m_manager.EnvironmentDefinition; sectorParams.DataRange = new BoundingBox2I(Coords << lod, ((Coords + 1) << lod) - 1); sectorParams.Provider = m_manager.Providers[m_manager.ActiveFace]; EnvironmentSector = m_manager.EnvironmentDefinition.CreateSector(); EnvironmentSector.Init(m_manager, ref sectorParams); m_manager.Planet.AddChildEntity((MyEntity)EnvironmentSector); } m_manager.EnqueueOperation(this, lod); LodSet = lod; EnvironmentSector.OnLodCommit += sector_OnMyLodCommit; }
internal void Construct() { m_components.Clear(); m_visible = true; m_renderProxyDirty = true; m_ID = new MyIDTracker<MyActor>(); m_localAabb = null; m_relativeTransform = null; Aabb = BoundingBoxD.CreateInvalid(); }
/// <summary> /// called multiple times for ships, to be kept up to date. /// </summary> public override void UpdateAfterSimulation10() { if (CommandAsteroidEditClear.ActiveVoxelDeleter) { var worldMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.WorldMatrix; var position = worldMatrix.Translation + worldMatrix.Forward * 1.6f + worldMatrix.Up * 1.35f + worldMatrix.Right * 0.1f; var currentAsteroidList = new List<IMyVoxelBase>(); var bb = new BoundingBoxD(position - 0.2f, position + 0.2f); MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.IsBoxIntersectingBoundingBoxOfThisVoxelMap(ref bb)); if (currentAsteroidList.Count > 0) { _isInRange = true; var storage = currentAsteroidList[0].Storage; var point = new Vector3I(position - currentAsteroidList[0].PositionLeftBottomCorner); var cache = new MyStorageDataCache(); var min = (point / 64) * 64; var max = min + 63; var size = max - min; cache.Resize(size); storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, (int)VRageRender.MyLodTypeEnum.LOD0, min, max); Vector3I p = point - min; var content = cache.Content(ref p); if (content > 0) { content = 0x00; cache.Content(ref p, content); storage.WriteRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, min, max); } //storage = null; } else { _isInRange = false; } } if (CommandAsteroidEditSet.ActiveVoxelSetter) { var worldMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.WorldMatrix; CommandAsteroidEditSet.ActiveVoxelSetterPosition = worldMatrix.Translation + worldMatrix.Forward * 1.6f + worldMatrix.Up * 1.35f + worldMatrix.Right * 0.1f; } else { CommandAsteroidEditSet.ActiveVoxelSetterPosition = null; } }
public bool Contains(IMyEntity entity) { switch (Shape) { case ProtectionAreaShape.Cube: var boundingBox = new BoundingBoxD(new Vector3D(Center.X - Size, Center.Y - Size, Center.Z - Size), new Vector3D(Center.X + Size, Center.Y + Size, Center.Z + Size)); return boundingBox.Intersects(entity.WorldAABB); case ProtectionAreaShape.Sphere: var boundingSphere = new BoundingSphereD(Center, Size); return boundingSphere.Intersects(entity.WorldAABB); } return false; }
public MyClipmap(uint id, MyClipmapScaleEnum scaleGroup, MatrixD worldMatrix, Vector3I sizeLod0, IMyClipmapCellHandler cellProvider) { m_scaleGroup = scaleGroup; m_worldMatrix = worldMatrix; MatrixD.Invert(ref m_worldMatrix, out m_invWorldMatrix); m_sizeLod0 = sizeLod0; m_localAABB = new BoundingBoxD(Vector3D.Zero, new Vector3D(sizeLod0 * MyVoxelConstants.RENDER_CELL_SIZE_IN_METRES)); for (int lod = 0; lod < m_lodLevels.Length; ++lod) { m_lodLevels[lod] = new LodLevel(this, lod, ((m_sizeLod0 - 1) >> lod) + 1); } m_updateQueueItem = new UpdateQueueItem(this); m_requestCollector = new RequestCollector(id); m_cellHandler = cellProvider; }
public MyClipmap(uint id, MyClipmapScaleEnum scaleGroup, MatrixD worldMatrix, Vector3I sizeLod0, IMyClipmapCellHandler cellProvider) { m_scaleGroup = scaleGroup; m_worldMatrix = worldMatrix; MatrixD.Invert(ref m_worldMatrix, out m_invWorldMatrix); m_sizeLod0 = sizeLod0; m_localAABB = new BoundingBoxD(Vector3D.Zero, new Vector3D(sizeLod0 * MyVoxelCoordSystems.RenderCellSizeInMeters(0))); for (int lod = 0; lod < m_lodLevels.Length; ++lod) { var sizeShift = lod + MyVoxelCoordSystems.RenderCellSizeInLodVoxelsShiftDelta(lod); m_lodLevels[lod] = new LodLevel(this, lod, ((m_sizeLod0 - 1) >> sizeShift) + 1); } m_updateQueueItem = new UpdateQueueItem(this); m_requestCollector = new RequestCollector(id); m_cellHandler = cellProvider; }
public override void UpdateWorldAABB() { CulledObjects.GetAll(m_list, true); m_localAABB = BoundingBoxD.CreateInvalid(); foreach (var element in m_list) { m_localAABB = m_localAABB.Include(element.WorldAABB); } m_aabb = m_localAABB.Transform(ref m_worldMatrix); base.UpdateWorldAABB(); }
public static void DrawSemiTransparentBox(MyCubeGrid grid, MySlimBlock block, Color color, bool onlyWireframe = false, string lineMaterial = null, Vector4? lineColor = null) { var min = (block.Min * grid.GridSize) - new Vector3(grid.GridSize / 2.0f + 0.02f); var max = (block.Max * grid.GridSize) + new Vector3(grid.GridSize / 2.0f + 0.02f); BoundingBoxD boxr = new BoundingBoxD(min, max); MatrixD gridMatrix = grid.WorldMatrix; var lColor = Color.White; if (lineColor.HasValue) { lColor = lineColor.Value; } MySimpleObjectDraw.DrawTransparentBox(ref gridMatrix, ref boxr, ref lColor, MySimpleObjectRasterizer.Wireframe, 1, 0.04f, null, lineMaterial, false); if (!onlyWireframe) { Color faceColor = new Color(color * 0.2f, 0.3f); MySimpleObjectDraw.DrawTransparentBox(ref gridMatrix, ref boxr, ref faceColor, MySimpleObjectRasterizer.Solid, 0, 0.04f, "Square", null, true); } }
public MyEntity Spawn(MyFixedPoint amount, BoundingBoxD box, MyEntity owner = null) { var entity = Spawn(amount, MatrixD.Identity, owner); var size = entity.PositionComp.LocalVolume.Radius; var halfSize = box.Size / 2 - new Vector3(size); halfSize = Vector3.Max(halfSize, Vector3.Zero); box = new BoundingBoxD(box.Center - halfSize, box.Center + halfSize); var pos = MyUtils.GetRandomPosition(ref box); Vector3 forward = MyUtils.GetRandomVector3Normalized(); Vector3 up = MyUtils.GetRandomVector3Normalized(); while (forward == up) up = MyUtils.GetRandomVector3Normalized(); Vector3 right = Vector3.Cross(forward, up); up = Vector3.Cross(right, forward); entity.WorldMatrix = MatrixD.CreateWorld(pos, forward, up); return entity; }
public static bool GetShapeCenter(HkShape shape, int shapeKey, MyCubeGrid grid, ref Vector3D shapeCenter) { bool shapeSet = true; switch (shape.ShapeType) { case HkShapeType.List: var listShape = (HkListShape)shape; shape = listShape.GetChildByIndex(shapeKey); break; case HkShapeType.Mopp: var moppShape = (HkMoppBvTreeShape)shape; shape = moppShape.ShapeCollection.GetShape((uint)shapeKey, null); break; case HkShapeType.Box: var boxShape = (HkBoxShape)shape; shape = boxShape; break; case HkShapeType.ConvexTranslate: var convexTranslateShape = (HkConvexShape)shape; shape = convexTranslateShape; break; case HkShapeType.ConvexTransform: var convexTransformShape = (HkConvexTransformShape)shape; shape = convexTransformShape; break; default: shapeSet = false; break; } if (shapeSet) { Vector4 min4, max4; shape.GetLocalAABB(0.05f, out min4, out max4); Vector3 worldMin = Vector3.Transform(new Vector3(min4), grid.PositionComp.WorldMatrix); Vector3 worldMax = Vector3.Transform(new Vector3(max4), grid.PositionComp.WorldMatrix); var worldAABB = new BoundingBoxD(worldMin, worldMax); shapeCenter = worldAABB.Center; } return shapeSet; }
public override void AccumulateCorrection(ref Vector3 correction, ref float weight) { if (Parent.Speed < 0.01f) return; var characterBotEntity = Parent.BotEntity as MyCharacter; // remove me pls if (characterBotEntity == null) return; var position = Parent.PositionAndOrientation.Translation; BoundingBoxD box = new BoundingBoxD(position - Vector3D.One * 3, position + Vector3D.One * 3); Vector3D currentMovement = Parent.ForwardVector; var entities = MyEntities.GetEntitiesInAABB(ref box); foreach (var entity in entities) { var character = entity as MyCharacter; if (character == null || character == characterBotEntity) continue; if (character.ModelName == characterBotEntity.ModelName) // remove me pls continue; Vector3D characterPos = character.PositionComp.GetPosition(); Vector3D dir = characterPos - position; double dist = dir.Normalize(); dist = MathHelper.Clamp(dist, 0, 6); var cos = Vector3D.Dot(dir, currentMovement); var opposite = -dir; if (cos > -0.807) correction += (6f - dist) * Weight * opposite; if (!correction.IsValid()) { System.Diagnostics.Debugger.Break(); } } entities.Clear(); weight += Weight; }
public static void DrawSemiTransparentBox(Vector3I minPosition, Vector3I maxPosition, MyCubeGrid grid, Color color, bool onlyWireframe = false, string lineMaterial = null, Vector4? lineColor = null) { var gridSize = grid.GridSize; var min = (minPosition * gridSize) - new Vector3((gridSize / 2.0f) * SEMI_TRANSPARENT_BOX_MODIFIER); var max = (maxPosition * gridSize) + new Vector3((gridSize / 2.0f) * SEMI_TRANSPARENT_BOX_MODIFIER); BoundingBoxD boxr = new BoundingBoxD(min, max); MatrixD gridMatrix = grid.WorldMatrix; var lColor = Color.White; if (lineColor.HasValue) { lColor = lineColor.Value; } MySimpleObjectDraw.DrawTransparentBox(ref gridMatrix, ref boxr, ref lColor, MySimpleObjectRasterizer.Wireframe, 1, 0.04f, null, lineMaterial, false); if (!onlyWireframe) { Color faceColor = new Color(color * 0.2f, 0.3f); MySimpleObjectDraw.DrawTransparentBox(ref gridMatrix, ref boxr, ref faceColor, MySimpleObjectRasterizer.Solid, 0, 0.04f, "Square", null, true); } }
protected override void OnLoad(BitStream stream, Action <MyVoxelBase> loadingDoneHandler) { MyVoxelBase voxelMap; bool isUserCreated = VRage.Serialization.MySerializer.CreateAndRead <bool>(stream); bool isFromPrefab = VRage.Serialization.MySerializer.CreateAndRead <bool>(stream); bool rangeChanged = VRage.Serialization.MySerializer.CreateAndRead <bool>(stream); byte[] data = null; string asteroidName = null; if (rangeChanged) { data = VRage.Serialization.MySerializer.CreateAndRead <byte[]>(stream); } else if (isUserCreated) { asteroidName = VRage.Serialization.MySerializer.CreateAndRead <string>(stream); } if (isFromPrefab) { var builder = VRage.Serialization.MySerializer.CreateAndRead <MyObjectBuilder_EntityBase>(stream, MyObjectBuilderSerializer.Dynamic); if (rangeChanged && data != null) { IMyStorage storage = MyStorageBase.Load(data); if (MyEntities.TryGetEntityById <MyVoxelBase>(builder.EntityId, out voxelMap)) { if (voxelMap is MyVoxelMap) { ((MyVoxelMap)voxelMap).Storage = storage; } else if (voxelMap is MyPlanet) { ((MyPlanet)voxelMap).Storage = storage; } else { Debug.Fail("Unknown voxel kind"); } } else { voxelMap = (MyVoxelBase)MyEntities.CreateFromObjectBuilderNoinit(builder); if (voxelMap is MyVoxelMap) { ((MyVoxelMap)voxelMap).Init(builder, storage); } else if (voxelMap is MyPlanet) { ((MyPlanet)voxelMap).Init(builder, storage); } else { Debug.Fail("Unknown voxel kind"); } if (voxelMap != null) { MyEntities.Add(voxelMap); } } } else if (isUserCreated) { TryRemoveExistingEntity(builder.EntityId); IMyStorage storage = MyGuiScreenDebugSpawnMenu.CreateAsteroidStorage(asteroidName, 0); voxelMap = (MyVoxelBase)MyEntities.CreateFromObjectBuilderNoinit(builder); if (voxelMap is MyVoxelMap) { ((MyVoxelMap)voxelMap).Init(builder, storage); } if (voxelMap != null) { MyEntities.Add(voxelMap); } } else { TryRemoveExistingEntity(builder.EntityId); voxelMap = (MyVoxelBase)MyEntities.CreateFromObjectBuilderNoinit(builder); if (voxelMap != null) { voxelMap.Init(builder); MyEntities.Add(voxelMap); } } } else { long voxelMapId = VRage.Serialization.MySerializer.CreateAndRead <long>(stream); MyEntities.TryGetEntityById <MyVoxelBase>(voxelMapId, out voxelMap); } if (voxelMap != null) { BoundingBoxD voxelBox = new BoundingBoxD(voxelMap.PositionLeftBottomCorner, voxelMap.PositionLeftBottomCorner + voxelMap.SizeInMetres); m_entities = MyEntities.GetEntitiesInAABB(ref voxelBox); foreach (var entity in m_entities) { MyVoxelBase voxel = entity as MyVoxelBase; if (voxel != null) { if (voxel.Save == false && voxel != voxelMap) { voxel.Close(); break; } } } m_entities.Clear(); } loadingDoneHandler(voxelMap); }
internal int GetEntityCompareDist(HitEntity x, HitEntity y, ProInfo info) { var xDist = double.MaxValue; var yDist = double.MaxValue; var beam = x.Intersection; var count = y != null ? 2 : 1; var eWarPulse = info.AmmoDef.Const.Ewar && info.AmmoDef.Const.Pulse; var triggerEvent = eWarPulse && !info.EwarAreaPulse && info.AmmoDef.Const.EwarTriggerRange > 0; for (int i = 0; i < count; i++) { var isX = i == 0; MyEntity ent; HitEntity hitEnt; HitEntity otherHit; if (isX) { hitEnt = x; otherHit = y; ent = hitEnt.Entity; } else { hitEnt = y; otherHit = x; ent = hitEnt.Entity; } var dist = double.MaxValue; var shield = ent as IMyTerminalBlock; var grid = ent as MyCubeGrid; var voxel = ent as MyVoxelBase; if (triggerEvent && (info.Ai.Targets.ContainsKey(ent) || shield != null)) { hitEnt.PulseTrigger = true; } else if (hitEnt.Projectile != null) { dist = hitEnt.HitDist.Value; } else if (shield != null) { hitEnt.Hit = true; dist = hitEnt.HitDist.Value; } else if (grid != null) { /* * var otherGrid = otherHit?.Entity as MyCubeGrid; * if (otherGrid != null && otherGrid.IsInSameLogicalGroupAs(grid)) * hitEnt.SubGrids.Add(otherHit); */ if (hitEnt.Hit) { dist = Vector3D.Distance(hitEnt.Intersection.From, hitEnt.HitPos.Value); hitEnt.HitDist = dist; } else if (hitEnt.HitPos != null) { dist = Vector3D.Distance(hitEnt.Intersection.From, hitEnt.HitPos.Value); hitEnt.HitDist = dist; hitEnt.Hit = true; } else { if (hitEnt.SphereCheck || info.EwarActive && eWarPulse) { var ewarActive = hitEnt.EventType == Field || hitEnt.EventType == Effect; var hitPos = !ewarActive ? hitEnt.PruneSphere.Center + (hitEnt.Intersection.Direction * hitEnt.PruneSphere.Radius) : hitEnt.PruneSphere.Center; if (hitEnt.SelfHit && Vector3D.DistanceSquared(hitPos, hitEnt.Info.Origin) <= grid.GridSize * grid.GridSize) { continue; } if (!ewarActive) { GetAndSortBlocksInSphere(hitEnt.Info.AmmoDef, hitEnt.Info.System, grid, hitEnt.PruneSphere, false, hitEnt.Blocks); } if (hitEnt.Blocks.Count > 0 || ewarActive) { dist = 0; hitEnt.HitDist = dist; hitEnt.Hit = true; hitEnt.HitPos = hitPos; } } else { var closestBlockFound = false; for (int j = 0; j < hitEnt.Vector3ICache.Count; j++) { var firstBlock = grid.GetCubeBlock(hitEnt.Vector3ICache[j]) as IMySlimBlock; MatrixD transform = grid.WorldMatrix; if (firstBlock != null && !firstBlock.IsDestroyed && firstBlock != hitEnt.Info.Target.FiringCube.SlimBlock) { hitEnt.Blocks.Add(firstBlock); if (closestBlockFound) { continue; } MyOrientedBoundingBoxD obb; var fat = firstBlock.FatBlock; if (fat != null) { obb = new MyOrientedBoundingBoxD(fat.Model.BoundingBox, fat.PositionComp.WorldMatrixRef); } else { Vector3 halfExt; firstBlock.ComputeScaledHalfExtents(out halfExt); var blockBox = new BoundingBoxD(-halfExt, halfExt); transform.Translation = grid.GridIntegerToWorld(firstBlock.Position); obb = new MyOrientedBoundingBoxD(blockBox, transform); } var hitDist = obb.Intersects(ref beam) ?? Vector3D.Distance(beam.From, obb.Center); var hitPos = beam.From + (beam.Direction * hitDist); if (hitEnt.SelfHit) { if (Vector3D.DistanceSquared(hitPos, hitEnt.Info.Origin) <= grid.GridSize * 3) { hitEnt.Blocks.Clear(); } else { dist = hitDist; hitEnt.HitDist = dist; hitEnt.Hit = true; hitEnt.HitPos = hitPos; } break; } dist = hitDist; hitEnt.HitDist = dist; hitEnt.Hit = true; hitEnt.HitPos = hitPos; closestBlockFound = true; } } } } } else if (voxel != null) { hitEnt.Hit = true; dist = hitEnt.HitDist.Value; hitEnt.HitDist = dist; } else if (ent is IMyDestroyableObject) { if (hitEnt.Hit) { dist = Vector3D.Distance(hitEnt.Intersection.From, hitEnt.HitPos.Value); } else { if (hitEnt.SphereCheck || info.EwarActive && eWarPulse) { var ewarActive = hitEnt.EventType == Field || hitEnt.EventType == Effect; dist = 0; hitEnt.HitDist = dist; hitEnt.Hit = true; var hitPos = !ewarActive ? hitEnt.PruneSphere.Center + (hitEnt.Intersection.Direction * hitEnt.PruneSphere.Radius) : hitEnt.PruneSphere.Center; hitEnt.HitPos = hitPos; } else { var transform = ent.PositionComp.WorldMatrixRef; var box = ent.PositionComp.LocalAABB; var obb = new MyOrientedBoundingBoxD(box, transform); dist = obb.Intersects(ref beam) ?? double.MaxValue; if (dist < double.MaxValue) { hitEnt.Hit = true; hitEnt.HitPos = beam.From + (beam.Direction * dist); hitEnt.HitDist = dist; } } } } if (isX) { xDist = dist; } else { yDist = dist; } } return(xDist.CompareTo(yDist)); }
private void RecalcAreaBoundigBox() { var border = 0.25d; _AreaBoundingBox = new BoundingBoxD(new Vector3D(-AreaDepthRear + border, -AreaWidthLeft + border, -AreaHeightBottom + border), new Vector3D(AreaDepthFront - border, AreaWidthRight - border, AreaHeightTop - border)); }
//1. Object A reaches borders //2. Make ideal cluster box B around A //3. Detect all cluster intersections C of B //4. Make union of all C and B to D //5. Find best division of D //6. Foreach dominant axis //6A split until only allowed size //6B leave lowest larger size //repeat 6 until dominant axis is allowed size or not splittable public void ReorderClusters(BoundingBoxD aabb, ulong objectId = ulong.MaxValue) { //1+2 aabb.InflateToMinimum(IdealClusterSize); bool isBoxSafe = false; BoundingBoxD unionCluster = aabb; //3 m_clusterTree.OverlapAllBoundingBox(ref unionCluster, m_resultList); HashSet <MyObjectData> objectsInUnion = new HashSet <MyObjectData>(); while (!isBoxSafe) { //4 objectsInUnion.Clear(); if (objectId != ulong.MaxValue) { objectsInUnion.Add(m_objectsData[objectId]); } foreach (MyCluster collidedCluster in m_resultList) { unionCluster.Include(collidedCluster.AABB); foreach (var ob in m_objectsData.Where(x => collidedCluster.Objects.Contains(x.Key)).Select(x => x.Value)) { objectsInUnion.Add(ob); } } int oldClustersCount = m_resultList.Count; //3 m_clusterTree.OverlapAllBoundingBox(ref unionCluster, m_resultList); isBoxSafe = oldClustersCount == m_resultList.Count; //Box is safe only if no new clusters were added m_staticTree.OverlapAllBoundingBox(ref unionCluster, m_objectDataResultList); foreach (var ob in m_objectDataResultList) { if (m_objectsData[ob].Cluster != null) { if (!m_resultList.Contains(m_objectsData[ob].Cluster)) { unionCluster.Include(m_objectsData[ob].Cluster.AABB); isBoxSafe = false; } } } } m_staticTree.OverlapAllBoundingBox(ref unionCluster, m_objectDataResultList); foreach (var ob in m_objectDataResultList) { //var c = m_objectsData[ob].Cluster.AABB.Contains(unionCluster); System.Diagnostics.Debug.Assert(m_objectsData[ob].Cluster == null || m_objectsData[ob].Cluster.AABB.Contains(m_objectsData[ob].AABB) != ContainmentType.Disjoint, "Clusters failure"); System.Diagnostics.Debug.Assert(m_objectsData[ob].Cluster == null || (m_clusters.Contains(m_objectsData[ob].Cluster) && m_resultList.Contains(m_objectsData[ob].Cluster)), "Static object is not inside found clusters"); objectsInUnion.Add(m_objectsData[ob]); } #if DEBUG foreach (var ob in objectsInUnion) { System.Diagnostics.Debug.Assert(ob.Cluster == null || (m_clusters.Contains(ob.Cluster) && m_resultList.Contains(ob.Cluster)), "There is object not belonging to found cluster!"); } #endif //5 Stack <MyClusterDescription> clustersToDivide = new Stack <MyClusterDescription>(); List <MyClusterDescription> finalClusters = new List <MyClusterDescription>(); var unionClusterDesc = new MyClusterDescription() { AABB = unionCluster, DynamicObjects = objectsInUnion.Where(x => x.ActivationHandler == null || !x.ActivationHandler.IsStaticForCluster).ToList(), StaticObjects = objectsInUnion.Where(x => (x.ActivationHandler != null) && x.ActivationHandler.IsStaticForCluster).ToList(), }; clustersToDivide.Push(unionClusterDesc); var staticObjectsToRemove = unionClusterDesc.StaticObjects.Where(x => x.Cluster != null).ToList(); var staticObjectsTotal = unionClusterDesc.StaticObjects.Count; while (clustersToDivide.Count > 0) { MyClusterDescription desc = clustersToDivide.Pop(); if (desc.DynamicObjects.Count == 0) { continue; } //minimal valid aabb usable for this cluster BoundingBoxD minimumCluster = BoundingBoxD.CreateInvalid(); for (int i = 0; i < desc.DynamicObjects.Count; i++) { MyObjectData objectData0 = desc.DynamicObjects[i]; BoundingBoxD aabb0 = objectData0.AABB.GetInflated(IdealClusterSize / 2); minimumCluster.Include(aabb0); } //Divide along longest axis BoundingBoxD dividedCluster = minimumCluster; Vector3D currentMax = minimumCluster.Max; int longestAxis = minimumCluster.Size.AbsMaxComponent(); switch (longestAxis) { case 0: desc.DynamicObjects.Sort(AABBComparerX.Static); break; case 1: desc.DynamicObjects.Sort(AABBComparerY.Static); break; case 2: desc.DynamicObjects.Sort(AABBComparerZ.Static); break; } bool isClusterSplittable = false; if (minimumCluster.Size.AbsMax() >= MaximumForSplit.AbsMax()) { for (int i = 1; i < desc.DynamicObjects.Count; i++) { MyObjectData objectData0 = desc.DynamicObjects[i - 1]; MyObjectData objectData1 = desc.DynamicObjects[i]; BoundingBoxD aabb0 = objectData0.AABB.GetInflated(IdealClusterSize / 2); BoundingBoxD aabb1 = objectData1.AABB.GetInflated(IdealClusterSize / 2); //two neigbour object have distance between them bigger than minimum if ((aabb1.Min.GetDim(longestAxis) - aabb0.Max.GetDim(longestAxis)) > 0) { System.Diagnostics.Debug.Assert(aabb0.Max.GetDim(longestAxis) - minimumCluster.Min.GetDim(longestAxis) > 0, "Invalid minimal cluster"); isClusterSplittable = true; currentMax.SetDim(longestAxis, aabb0.Max.GetDim(longestAxis)); break; } } } dividedCluster.Max = currentMax; dividedCluster.InflateToMinimum(IdealClusterSize); MyClusterDescription dividedClusterDesc = new MyClusterDescription() { AABB = dividedCluster, DynamicObjects = new List <MyObjectData>(), StaticObjects = new List <MyObjectData>(), }; foreach (var dynObj in desc.DynamicObjects.ToList()) { var cont = dividedCluster.Contains(dynObj.AABB); if (cont == ContainmentType.Contains) { dividedClusterDesc.DynamicObjects.Add(dynObj); desc.DynamicObjects.Remove(dynObj); } System.Diagnostics.Debug.Assert(cont != ContainmentType.Intersects, "Cannot split clusters in the middle of objects"); } foreach (var statObj in desc.StaticObjects.ToList()) { var cont = dividedCluster.Contains(statObj.AABB); if ((cont == ContainmentType.Contains) || (cont == ContainmentType.Intersects)) { dividedClusterDesc.StaticObjects.Add(statObj); desc.StaticObjects.Remove(statObj); } } dividedClusterDesc.AABB = dividedCluster; if (desc.DynamicObjects.Count > 0) { BoundingBoxD restCluster = BoundingBoxD.CreateInvalid(); foreach (var restbb in desc.DynamicObjects) { restCluster.Include(restbb.AABB.GetInflated(MinimumDistanceFromBorder)); } restCluster.InflateToMinimum(IdealClusterSize); MyClusterDescription restClusterDesc = new MyClusterDescription() { AABB = restCluster, DynamicObjects = desc.DynamicObjects.ToList(), StaticObjects = desc.StaticObjects.ToList(), }; if (restClusterDesc.AABB.Size.AbsMax() > 2 * IdealClusterSize.AbsMax()) { clustersToDivide.Push(restClusterDesc); } else { finalClusters.Add(restClusterDesc); } } if (dividedClusterDesc.AABB.Size.AbsMax() > 2 * IdealClusterSize.AbsMax() && isClusterSplittable) { clustersToDivide.Push(dividedClusterDesc); } else { finalClusters.Add(dividedClusterDesc); } } #if DEBUG //Check consistency for (int i = 0; i < finalClusters.Count; i++) { for (int j = 0; j < finalClusters.Count; j++) { if (i != j) { var cont = finalClusters[i].AABB.Contains(finalClusters[j].AABB); System.Diagnostics.Debug.Assert(cont == ContainmentType.Disjoint, "Overlapped clusters!"); if (cont != ContainmentType.Disjoint) { } } } } #endif #if DEBUG Dictionary <MyCluster, List <ulong> > objectsPerRemovedCluster = new Dictionary <MyCluster, List <ulong> >(); Dictionary <MyCluster, List <ulong> > dynamicObjectsInCluster = new Dictionary <MyCluster, List <ulong> >(); foreach (var finalCluster in finalClusters) { foreach (var ob in finalCluster.DynamicObjects) { if (ob.Cluster != null) { if (!objectsPerRemovedCluster.ContainsKey(ob.Cluster)) { objectsPerRemovedCluster[ob.Cluster] = new List <ulong>(); } objectsPerRemovedCluster[ob.Cluster].Add(ob.Id); } else { } } } foreach (var removingCluster in objectsPerRemovedCluster) { dynamicObjectsInCluster[removingCluster.Key] = new List <ulong>(); foreach (var ob in removingCluster.Key.Objects) { if (!m_objectsData[ob].ActivationHandler.IsStaticForCluster) { dynamicObjectsInCluster[removingCluster.Key].Add(ob); } } System.Diagnostics.Debug.Assert(removingCluster.Value.Count == dynamicObjectsInCluster[removingCluster.Key].Count, "Not all objects from removing cluster are going to new clusters!"); } Dictionary <MyCluster, List <ulong> > staticObjectsInCluster = new Dictionary <MyCluster, List <ulong> >(); foreach (var staticObj in staticObjectsToRemove) { System.Diagnostics.Debug.Assert(staticObj.Cluster != null, "Where to remove?"); if (!staticObjectsInCluster.ContainsKey(staticObj.Cluster)) { staticObjectsInCluster[staticObj.Cluster] = new List <ulong>(); } staticObjectsInCluster[staticObj.Cluster].Add(staticObj.Id); } #endif HashSet <MyCluster> oldClusters = new HashSet <MyCluster>(); HashSet <MyCluster> newClusters = new HashSet <MyCluster>(); foreach (var staticObj in staticObjectsToRemove) { if (staticObj.Cluster != null) { oldClusters.Add(staticObj.Cluster); RemoveObjectFromCluster(staticObj, true); } else { } } foreach (var staticObj in staticObjectsToRemove) { if (staticObj.Cluster != null) { staticObj.ActivationHandler.FinishRemoveBatch(staticObj.Cluster.UserData); staticObj.Cluster = null; } } int staticObjectsAdded = 0; //Move objects from old clusters to new clusters, use batching foreach (var finalCluster in finalClusters) { BoundingBoxD clusterAABB = finalCluster.AABB; MyCluster newCluster = CreateCluster(ref clusterAABB); #if DEBUG for (int i = 0; i < finalCluster.DynamicObjects.Count; i++) { for (int j = 0; j < finalCluster.DynamicObjects.Count; j++) { if (i != j) { System.Diagnostics.Debug.Assert(finalCluster.DynamicObjects[i].Id != finalCluster.DynamicObjects[j].Id); } } } #endif foreach (var obj in finalCluster.DynamicObjects) { if (obj.Cluster != null) { oldClusters.Add(obj.Cluster); RemoveObjectFromCluster(obj, true); } else { System.Diagnostics.Debug.Assert(objectId == obj.Id || obj.ActivationHandler.IsStaticForCluster, "Dynamic object must have cluster"); } } foreach (var obj in finalCluster.DynamicObjects) { if (obj.Cluster != null) { obj.ActivationHandler.FinishRemoveBatch(obj.Cluster.UserData); obj.Cluster = null; } } //Finish batches on old worlds and remove old worlds foreach (MyCluster oldCluster in oldClusters) { if (OnFinishBatch != null) { OnFinishBatch(oldCluster.UserData); } } foreach (var obj in finalCluster.DynamicObjects) { AddObjectToCluster(newCluster, obj.Id, true); } foreach (var obj in finalCluster.StaticObjects) { if (newCluster.AABB.Contains(obj.AABB) != ContainmentType.Disjoint) { AddObjectToCluster(newCluster, obj.Id, true); staticObjectsAdded++; } } newClusters.Add(newCluster); } System.Diagnostics.Debug.Assert(staticObjectsTotal >= staticObjectsAdded, "Static objects appeared out of union"); foreach (MyCluster oldCluster in oldClusters) { RemoveCluster(oldCluster); } //Finish batches on new world and their objects foreach (MyCluster newCluster in newClusters) { if (OnFinishBatch != null) { OnFinishBatch(newCluster.UserData); } foreach (var ob in newCluster.Objects) { if (m_objectsData[ob].ActivationHandler != null) { m_objectsData[ob].ActivationHandler.FinishAddBatch(); } } } if (OnClustersReordered != null) { OnClustersReordered(); } }
public ulong AddObject(BoundingBoxD bbox, IMyActivationHandler activationHandler, ulong?customId, string tag, long entityId) { if (SingleCluster.HasValue && m_clusters.Count == 0) { BoundingBoxD bb = SingleCluster.Value; bb.Inflate(200); //inflate 200m so objects near world border have AABB inside => physics created CreateCluster(ref bb); } BoundingBoxD inflatedBBox; if (SingleCluster.HasValue || ForcedClusters) { inflatedBBox = bbox; } else { inflatedBBox = bbox.GetInflated(MinimumDistanceFromBorder); } m_clusterTree.OverlapAllBoundingBox(ref inflatedBBox, m_returnedClusters); MyCluster cluster = null; bool needReorder = false; if (m_returnedClusters.Count == 1) { if (m_returnedClusters[0].AABB.Contains(inflatedBBox) == ContainmentType.Contains) { cluster = m_returnedClusters[0]; } else if (m_returnedClusters[0].AABB.Contains(inflatedBBox) == ContainmentType.Intersects && activationHandler.IsStaticForCluster) { if (m_returnedClusters[0].AABB.Contains(bbox) == ContainmentType.Disjoint) { //completely out } else { cluster = m_returnedClusters[0]; } } else { needReorder = true; } } else if (m_returnedClusters.Count > 1) { if (!activationHandler.IsStaticForCluster) { needReorder = true; } } else if (m_returnedClusters.Count == 0) { if (SingleCluster.HasValue) { return(VRageMath.Spatial.MyClusterTree.CLUSTERED_OBJECT_ID_UNITIALIZED); } if (!activationHandler.IsStaticForCluster) { var clusterBB = new BoundingBoxD(bbox.Center - IdealClusterSize / 2, bbox.Center + IdealClusterSize / 2); m_clusterTree.OverlapAllBoundingBox(ref clusterBB, m_returnedClusters); if (m_returnedClusters.Count == 0) { //Space is empty, create new cluster m_staticTree.OverlapAllBoundingBox(ref clusterBB, m_objectDataResultList); cluster = CreateCluster(ref clusterBB); foreach (var ob in m_objectDataResultList) { System.Diagnostics.Debug.Assert(m_objectsData[ob].Cluster == null, "Found object must not be in cluster!"); if (m_objectsData[ob].Cluster == null) { AddObjectToCluster(cluster, ob, false); } } } else //There is still some blocking cluster { needReorder = true; } } } ulong objectId = customId.HasValue ? customId.Value : m_clusterObjectCounter++; int staticObjectId = MyDynamicAABBTreeD.NullNode; m_objectsData[objectId] = new MyObjectData() { Id = objectId, Cluster = cluster, ActivationHandler = activationHandler, AABB = bbox, StaticId = staticObjectId, Tag = tag, EntityId = entityId }; System.Diagnostics.Debug.Assert(!needReorder || (!SingleCluster.HasValue && needReorder), "Object cannot be added outside borders of a single cluster"); System.Diagnostics.Debug.Assert(!needReorder || (!ForcedClusters && needReorder), "Error in cluster data, they dont correspond to provided objects"); if (needReorder && !SingleCluster.HasValue && !ForcedClusters) { System.Diagnostics.Debug.Assert(cluster == null, "Error in cluster logic"); ReorderClusters(bbox, objectId); if (!m_objectsData[objectId].ActivationHandler.IsStaticForCluster) { System.Diagnostics.Debug.Assert(m_objectsData[objectId].Cluster != null, "Object not added"); } #if DEBUG m_clusterTree.OverlapAllBoundingBox(ref bbox, m_returnedClusters); System.Diagnostics.Debug.Assert(m_returnedClusters.Count <= 1, "Clusters overlap!"); if (m_returnedClusters.Count != 0) { System.Diagnostics.Debug.Assert(activationHandler.IsStaticForCluster ? m_returnedClusters[0].AABB.Contains(inflatedBBox) != ContainmentType.Disjoint : m_returnedClusters[0].AABB.Contains(inflatedBBox) == ContainmentType.Contains, "Clusters reorder failure!"); } #endif } if (activationHandler.IsStaticForCluster) { staticObjectId = m_staticTree.AddProxy(ref bbox, objectId, 0); m_objectsData[objectId].StaticId = staticObjectId; } if (cluster != null) { return(AddObjectToCluster(cluster, objectId, false)); } else { return(objectId); } }
protected Vector3I_RangeIterator GetCellsIterator(BoundingSphereD sphere) { return(GetCellsIterator(BoundingBoxD.CreateFromSphere(sphere))); }
internal void UpdateAfterSimulation10() { this.UpdateRigidBodyShape(); if (this.m_voxelMap.Storage != null) { foreach (IMyEntity entity in this.m_nearbyEntities) { if (entity != null) { bool flag = false; MyPhysicsBody physics = entity.Physics as MyPhysicsBody; if (((physics != null) && (physics.RigidBody != null)) && ((physics.RigidBody.Layer == 0x17) || (physics.RigidBody.Layer == 10))) { flag = true; } if ((((entity is MyCubeGrid) || flag) && !entity.MarkedForClose) && (entity.Physics != null)) { BoundingBoxD xd; this.GetPrediction(entity, out xd); if (xd.Intersects(this.m_voxelMap.PositionComp.WorldAABB)) { Vector3I vectori; Vector3I vectori2; HkUniformGridShape shape; int num1; if (flag || !UseLod1VoxelPhysics) { num1 = 0; } else { num1 = 1; } int lod = num1; int num2 = 1 << (lod & 0x1f); BoundingBoxD xd2 = xd.TransformFast(this.m_voxelMap.PositionComp.WorldMatrixInvScaled); xd2.Translate(this.m_voxelMap.SizeInMetresHalf); Vector3 max = (Vector3)xd2.Max; Vector3 min = (Vector3)xd2.Min; this.ClampVoxelCoords(ref min, ref max, out vectori, out vectori2); vectori = vectori >> lod; vectori2 = vectori2 >> lod; int size = ((vectori2 - vectori) + 1).Size; if (size >= m_cellsToGenerateBuffer.Length) { m_cellsToGenerateBuffer = new Vector3I[MathHelper.GetNearestBiggerPowerOfTwo(size)]; } if (this.GetShape(lod, out shape)) { if (shape.Base.IsZero) { MyAnalyticsHelper.ReportBug("Null voxel shape", "SE-7366", true, @"E:\Repo1\Sources\Sandbox.Game\Engine\Voxels\MyVoxelPhysicsBody.cs", 680); } else { int requiredCellsCount = shape.GetMissingCellsInRange(ref vectori, ref vectori2, m_cellsToGenerateBuffer); if (requiredCellsCount != 0) { BoundingBoxI box = new BoundingBoxI((vectori * 8) * num2, (Vector3I)(((vectori2 + 1) * 8) * num2)); box.Translate(this.m_voxelMap.StorageMin); if ((requiredCellsCount > 0) && (this.m_voxelMap.Storage.Intersect(ref box, lod, true) != ContainmentType.Intersects)) { this.SetEmptyShapes(lod, ref shape, requiredCellsCount); } else { for (int i = 0; i < requiredCellsCount; i++) { this.StartPrecalcJobPhysicsIfNeeded(lod, i); } } } } } } } } } this.ScheduleBatchJobs(); if (this.m_bodiesInitialized) { this.CheckAndDiscardShapes(); } } }
private static void DrawMountPointsAxisHelpers(MyCubeBlockDefinition def, ref MatrixD drawMatrix, float cubeSize) { Vector3I centerGrid = def.Center; Vector3 centerOffset = def.Size * 0.5f; MatrixD drawTransf = MatrixD.CreateTranslation(centerGrid - centerOffset) * MatrixD.CreateScale(cubeSize) * drawMatrix; // Draw axis helpers for the six mount point walls for (int i = 0; i < 6; ++i) { Base6Directions.Direction dir = (Base6Directions.Direction)i; Vector3D position = Vector3D.Zero; position.Z = -0.2f; Vector3D normal = Vector3.Forward; Vector3D right = Vector3.Right; Vector3D up = Vector3.Up; position = def.MountPointLocalToBlockLocal(position, dir); position = Vector3D.Transform(position, drawTransf); normal = def.MountPointLocalNormalToBlockLocal(normal, dir); normal = Vector3D.TransformNormal(normal, drawTransf); up = def.MountPointLocalNormalToBlockLocal(up, dir); up = Vector3D.TransformNormal(up, drawTransf); right = def.MountPointLocalNormalToBlockLocal(right, dir); right = Vector3D.TransformNormal(right, drawTransf); MatrixD rightMat = MatrixD.CreateWorld(position + right * 0.25f, normal, right); MatrixD upMat = MatrixD.CreateWorld(position + up * 0.25f, normal, up); Vector4 rc = Color.Red.ToVector4(); Vector4 uc = Color.Green.ToVector4(); MyRenderProxy.DebugDrawSphere(position, 0.03f * cubeSize, Color.Red.ToVector3(), 1.0f, true); MySimpleObjectDraw.DrawTransparentCylinder(ref rightMat, 0.0f, 0.03f * cubeSize, 0.5f * cubeSize, ref rc, false, 16, 0.01f * cubeSize); MySimpleObjectDraw.DrawTransparentCylinder(ref upMat, 0.0f, 0.03f * cubeSize, 0.5f * cubeSize, ref uc, false, 16, 0.01f * cubeSize); MyRenderProxy.DebugDrawLine3D(position, position - normal * 0.2f, Color.Red, Color.Red, true); float textSizeX = 0.5f * cubeSize; float textSizeY = 0.5f * cubeSize; float textSizeDesc = 0.5f * cubeSize; if (MySector.MainCamera != null) { float distX = (float)(position + right * 0.55f - MySector.MainCamera.Position).Length(); float distY = (float)(position + up * 0.55f - MySector.MainCamera.Position).Length(); float distDesc = (float)(position + normal * 0.1f - MySector.MainCamera.Position).Length(); textSizeX = textSizeX * 6 / distX; textSizeY = textSizeY * 6 / distY; textSizeDesc = textSizeDesc * 6 / distDesc; } MyRenderProxy.DebugDrawText3D(position + right * 0.55f, "X", Color.Red, textSizeX, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER); MyRenderProxy.DebugDrawText3D(position + up * 0.55f, "Y", Color.Green, textSizeY, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER); MyRenderProxy.DebugDrawText3D(position + normal * 0.1f, m_mountPointSideNames[i], Color.White, textSizeDesc, true, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER); } // If close enough, draw a black grid spaced by tenths of a mount point unit float dist = (float)(drawTransf.Translation - MySector.MainCamera.Position).Length(); BoundingBoxD bb = new BoundingBoxD(-def.Size * cubeSize * 0.5f, def.Size * cubeSize * 0.5f); dist -= (float)bb.Size.Max() * 0.866f; // sqrt(3) * 0.5 - half of the solid diagonal of a cube Color black = Color.Black; if (dist < cubeSize * 3.0f) { MySimpleObjectDraw.DrawTransparentBox(ref drawMatrix, ref bb, ref black, ref black, MySimpleObjectRasterizer.Wireframe, def.Size * 10, 0.005f / (float)bb.Size.Max() * cubeSize, onlyFrontFaces: true); } }
//internal static void BeginQuadRendering() //{ // var context = MyRender.Context; // context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; // context.Rasterizer.SetViewport(0, 0, MyRender.ViewportResolution.X, MyRender.ViewportResolution.Y); // context.OutputMerger.SetTargets(null as DepthStencilView, MyRender.Backbuffer.RenderTarget); // context.OutputMerger.BlendState = null; //} //internal static void DrawQuad() //{ //} internal static void DrawHierarchyDebug() { var worldToClip = MyEnvironment.ViewProjection; var displayString = new StringBuilder(); var batch = MyLinesRenderer.CreateBatch(); if (MyRender11.Settings.DisplayIDs) { foreach (var actor in MyActorFactory.GetAll()) { var h = actor.GetGroupLeaf(); var r = actor.GetRenderable(); Vector3 position; uint ID; if (r != null) { position = r.m_owner.WorldMatrix.Translation; ID = r.m_owner.ID; } else if (h != null) { position = h.m_owner.WorldMatrix.Translation; ID = h.m_owner.ID; } else { continue; } var clipPosition = Vector3.Transform(position, ref worldToClip); clipPosition.X = clipPosition.X * 0.5f + 0.5f; clipPosition.Y = clipPosition.Y * -0.5f + 0.5f; if (clipPosition.Z > 0 && clipPosition.Z < 1) { displayString.AppendFormat("{0}", ID); MySpritesRenderer.DrawText(new Vector2(clipPosition.X, clipPosition.Y) * MyRender11.ViewportResolution, displayString, Color.DarkCyan, 0.5f); } displayString.Clear(); } } if (MyRender11.Settings.DisplayAabbs) { //foreach (var h in MyComponentFactory<MyHierarchyComponent>.GetAll()) //{ // if (h.IsParent) // { // batch.AddBoundingBox(h.m_owner.Aabb, Color.Red); // } // else // { // batch.AddBoundingBox(h.m_owner.Aabb, Color.Orange); // } //} foreach (var actor in MyActorFactory.GetAll()) { var h = actor.GetGroupRoot(); var r = actor.GetRenderable(); if (h != null) { var bb = BoundingBoxD.CreateInvalid(); foreach (var child in h.m_children) { if (child.m_visible) { bb.Include(child.Aabb); } } batch.AddBoundingBox((BoundingBox)bb, Color.Red); MyPrimitivesRenderer.Draw6FacedConvex(bb.GetCorners().Select(x => (Vector3)x).ToArray(), Color.Red, 0.1f); } else if (r != null && actor.GetGroupLeaf() == null) { batch.AddBoundingBox((BoundingBox)r.m_owner.Aabb, Color.Green); } } } batch.Commit(); }
private new bool TestPlacement() { bool retval = true; m_touchingGrids.Clear(); for (int i = 0; i < PreviewGrids.Count; ++i) { var grid = PreviewGrids[i]; var settings = m_settings.GetGridPlacementSettings(grid.GridSizeEnum); m_touchingGrids.Add(null); if (MySession.Static.SurvivalMode && !MyCubeBuilder.SpectatorIsBuilding && !MySession.Static.IsAdminModeEnabled(Sync.MyId)) { if (i == 0 && MyCubeBuilder.CameraControllerSpectator) { m_visible = false; return(false); } if (i == 0 && !MyCubeBuilder.Static.DynamicMode) { MatrixD invMatrix = grid.PositionComp.WorldMatrixNormalizedInv; if (!MyCubeBuilderGizmo.DefaultGizmoCloseEnough(ref invMatrix, (BoundingBoxD)grid.PositionComp.LocalAABB, grid.GridSize, MyCubeBuilder.IntersectionDistance)) { m_visible = false; return(false); } } /*if (!MySession.Static.SimpleSurvival && MySession.Static.ControlledEntity is MyCharacter) * { * foreach (var block in grid.GetBlocks()) * { * retval &= (MySession.Static.ControlledEntity as MyCharacter).CanStartConstruction(block.BlockDefinition); * if (!retval) * break; * } * } * * if (i == 0 && MySession.Static.SimpleSurvival) * { * retval = retval && MyCubeBuilder.Static.CanBuildBlockSurvivalTime(); * }*/ if (!retval) { return(false); } } if (MyCubeBuilder.Static.DynamicMode) { // if (!m_dynamicBuildAllowed) // { var settingsLocal = grid.GridSizeEnum == MyCubeSize.Large ? m_settings.LargeGrid : m_settings.SmallGrid; bool anyBlockVoxelHit = false; foreach (var block in grid.GetBlocks()) { Vector3 minLocal = block.Min * PreviewGrids[i].GridSize - Vector3.Half * PreviewGrids[i].GridSize; Vector3 maxLocal = block.Max * PreviewGrids[i].GridSize + Vector3.Half * PreviewGrids[i].GridSize; BoundingBoxD aabbLocal = new BoundingBoxD(minLocal, maxLocal); if (!anyBlockVoxelHit) { anyBlockVoxelHit = TestVoxelPlacement(block, ref settings, true); } retval = retval && MyCubeGrid.TestPlacementArea(grid, grid.IsStatic, ref settingsLocal, aabbLocal, true, testVoxel: false); if (!retval) { break; } } retval = retval && anyBlockVoxelHit; // } } else if (i == 0 && m_hitEntity is MyCubeGrid && IsSnapped /* && SnapMode == SnapMode.Base6Directions*/) { var hitGrid = m_hitEntity as MyCubeGrid; var settingsLocal = m_settings.GetGridPlacementSettings(hitGrid.GridSizeEnum, hitGrid.IsStatic); bool smallOnLargeGrid = hitGrid.GridSizeEnum == MyCubeSize.Large && grid.GridSizeEnum == MyCubeSize.Small; if (smallOnLargeGrid) { retval = retval && MyCubeGrid.TestPlacementArea(grid, ref settings, (BoundingBoxD)grid.PositionComp.LocalAABB, false); } else { retval = retval && TestGridPlacementOnGrid(grid, ref settingsLocal, hitGrid); } m_touchingGrids.Clear(); m_touchingGrids.Add(hitGrid); } else if (i == 0 && m_hitEntity is MyVoxelMap) { bool anyBlockVoxelHit = false; foreach (var block in grid.CubeBlocks) { if (block.FatBlock is MyCompoundCubeBlock) { MyCompoundCubeBlock compoundBlock = block.FatBlock as MyCompoundCubeBlock; foreach (var blockInCompound in compoundBlock.GetBlocks()) { if (!anyBlockVoxelHit) { anyBlockVoxelHit = TestVoxelPlacement(blockInCompound, ref settings, false); } retval = retval && TestBlockPlacementArea(blockInCompound, ref settings, false, false); if (!retval) { break; } } } else { if (!anyBlockVoxelHit) { anyBlockVoxelHit = TestVoxelPlacement(block, ref settings, false); } retval = retval && TestBlockPlacementArea(block, ref settings, false, false); } if (!retval) { break; } } retval = retval && anyBlockVoxelHit; Debug.Assert(i == 0); m_touchingGrids[i] = DetectTouchingGrid(); } else { var settingsLocal = m_settings.GetGridPlacementSettings(grid.GridSizeEnum, grid.IsStatic && !MyCubeBuilder.Static.DynamicMode); retval = retval && MyCubeGrid.TestPlacementArea(grid, grid.IsStatic, ref settingsLocal, (BoundingBoxD)grid.PositionComp.LocalAABB, false); } BoundingBoxD aabb = (BoundingBoxD)grid.PositionComp.LocalAABB; MatrixD invGridWorlMatrix = grid.PositionComp.WorldMatrixNormalizedInv; // Character collisions. if (MySector.MainCamera != null) { Vector3D cameraPos = Vector3D.Transform(MySector.MainCamera.Position, invGridWorlMatrix); retval = retval && aabb.Contains(cameraPos) != ContainmentType.Contains; } if (retval) { m_tmpCollisionPoints.Clear(); MyCubeBuilder.PrepareCharacterCollisionPoints(m_tmpCollisionPoints); foreach (var pt in m_tmpCollisionPoints) { Vector3D ptLocal = Vector3D.Transform(pt, invGridWorlMatrix); retval = retval && aabb.Contains(ptLocal) != ContainmentType.Contains; if (!retval) { break; } } } } return(retval); }
public void Subtract(ref BoundingBoxD originalBox, ref BoundingBoxD bb) { double min, max; SelectMinMax(ref bb, m_axis, out min, out max); bool minInserted = false; double prevLimit = m_min; double cumul = 0.0; for (int i = 0; i < m_entries.Count; ++i) { SamplingEntry entry = m_entries[i]; if (!minInserted) { if (entry.UpperLimit >= min) { if (entry.UpperLimit == min) { minInserted = true; } else // (entry.UpperLimit > min) { if (prevLimit == min) { minInserted = true; i--; continue; } minInserted = true; SamplingEntry insertedEntry = SamplingEntry.Divide(ref entry, prevLimit, cumul, m_weightMult, min); m_entries[i] = entry; m_entries.Insert(i, insertedEntry); entry = insertedEntry; } } } else { if (prevLimit < max) { if (entry.UpperLimit > max) { SamplingEntry insertedEntry = SamplingEntry.Divide(ref entry, prevLimit, cumul, m_weightMult, max); m_entries[i] = entry; m_entries.Insert(i, insertedEntry); entry = insertedEntry; } if (entry.UpperLimit <= max) { if (entry.Sampler == null) { if (m_axis == Base6Directions.Axis.ForwardBackward) { entry.Full = true; entry.CumulativeWeight = cumul; } else { if (entry.Full == false) // Full entries can be kept as they are { Base6Directions.Axis nextAxis = m_axis == Base6Directions.Axis.LeftRight ? Base6Directions.Axis.UpDown : Base6Directions.Axis.ForwardBackward; double min2, max2; SelectMinMax(ref originalBox, nextAxis, out min2, out max2); double range = m_max - m_min; double volume = m_weightMult * range; double relativeWidth = (entry.UpperLimit - prevLimit) / range; double newRange = max2 - min2; entry.Sampler = new IntervalSampler(min2, max2, (volume * relativeWidth) / newRange, nextAxis); } } } if (entry.Sampler != null) { entry.Sampler.Subtract(ref originalBox, ref bb); entry.CumulativeWeight = cumul + entry.Sampler.TotalWeight; } m_entries[i] = entry; } } else { if (entry.Sampler == null) { if (entry.Full) { entry.CumulativeWeight = cumul; } else { entry.CumulativeWeight = cumul + (entry.UpperLimit - prevLimit) * m_weightMult; } } else { entry.CumulativeWeight = cumul + entry.Sampler.TotalWeight; } m_entries[i] = entry; } } prevLimit = entry.UpperLimit; cumul = entry.CumulativeWeight; } m_totalWeight = cumul; }
private bool TestPlacement() { bool retval = true; for (int i = 0; i < PreviewGrids.Count; ++i) { var grid = PreviewGrids[i]; var settings = m_settings.GetGridPlacementSettings(grid); if (MySession.Static.SurvivalMode && !MyCubeBuilder.DeveloperSpectatorIsBuilding) { if (i == 0 && !MyCubeBuilder.Static.DynamicMode) { MatrixD invMatrix = grid.PositionComp.WorldMatrixNormalizedInv; if (!MyCubeBuilderGizmo.DefaultGizmoCloseEnough(ref invMatrix, (BoundingBoxD)grid.PositionComp.LocalAABB, grid.GridSize, MyCubeBuilder.Static.IntersectionDistance) || MySession.GetCameraControllerEnum() == MyCameraControllerEnum.Spectator) { m_visible = false; return(false); } } if (!MySession.Static.SimpleSurvival && MySession.ControlledEntity is MyCharacter) { foreach (var block in grid.GetBlocks()) { retval &= (MySession.ControlledEntity as MyCharacter).CanStartConstruction(block.BlockDefinition); if (!retval) { break; } } } if (i == 0 && MySession.Static.SimpleSurvival) { retval = retval && MyCubeBuilder.Static.CanBuildBlockSurvivalTime(); } if (!retval) { return(false); } } if (MyCubeBuilder.Static.DynamicMode) { if (!m_dynamicBuildAllowed) { var settingsLocal = grid.GridSizeEnum == MyCubeSize.Large ? MyPerGameSettings.PastingSettings.LargeGrid : MyPerGameSettings.PastingSettings.SmallGrid; foreach (var block in grid.GetBlocks()) { Vector3 minLocal = block.Min * PreviewGrids[i].GridSize - Vector3.Half * PreviewGrids[i].GridSize; Vector3 maxLocal = block.Max * PreviewGrids[i].GridSize + Vector3.Half * PreviewGrids[i].GridSize; BoundingBoxD aabbLocal = new BoundingBoxD(minLocal, maxLocal); retval = retval && MyCubeGrid.TestPlacementArea(grid, grid.IsStatic, ref settingsLocal, aabbLocal, true); } } } else if (i == 0 && m_hitEntity is MyCubeGrid && IsSnapped && SnapMode == MyGridPlacementSettings.SnapMode.Base6Directions) { var hitGrid = m_hitEntity as MyCubeGrid; bool smallOnLargeGrid = hitGrid.GridSizeEnum == MyCubeSize.Large && grid.GridSizeEnum == MyCubeSize.Small; if (smallOnLargeGrid) { retval = retval && MyCubeGrid.TestPlacementArea(grid, ref settings, (BoundingBoxD)grid.PositionComp.LocalAABB, false /*, hitGrid*/); } else { retval = retval && TestGridPlacementOnGrid(grid, ref settings, hitGrid); } } else if (i == 0 && m_hitEntity is MyVoxelMap) { foreach (var block in grid.CubeBlocks) { if (block.FatBlock is MyCompoundCubeBlock) { MyCompoundCubeBlock compoundBlock = block.FatBlock as MyCompoundCubeBlock; foreach (var blockInCompound in compoundBlock.GetBlocks()) { retval = retval && TestBlockPlacementArea(blockInCompound, ref settings, false); if (!retval) { break; } } } else { retval = retval && TestBlockPlacementArea(block, ref settings, false); } if (!retval) { break; } } } else { var settingsLocal = m_settings.GetGridPlacementSettings(grid, grid.IsStatic && !MyCubeBuilder.Static.DynamicMode); retval = retval && MyCubeGrid.TestPlacementArea(grid, grid.IsStatic, ref settingsLocal, (BoundingBoxD)grid.PositionComp.LocalAABB, false); } BoundingBoxD aabb = (BoundingBoxD)grid.PositionComp.LocalAABB; MatrixD invGridWorlMatrix = grid.PositionComp.GetWorldMatrixNormalizedInv(); // Character collisions. if (MySector.MainCamera != null) { Vector3D cameraPos = Vector3D.Transform(MySector.MainCamera.Position, invGridWorlMatrix); retval = retval && aabb.Contains(cameraPos) != ContainmentType.Contains; } if (retval) { m_tmpCollisionPoints.Clear(); MyCubeBuilder.PrepareCharacterCollisionPoints(m_tmpCollisionPoints); foreach (var pt in m_tmpCollisionPoints) { Vector3D ptLocal = Vector3D.Transform(pt, invGridWorlMatrix); retval = retval && aabb.Contains(ptLocal) != ContainmentType.Contains; if (!retval) { break; } } } } return(retval); }
private void GetPrediction(IMyEntity entity, out BoundingBoxD box) { var predictionOffset = ComputePredictionOffset(entity); box = entity.WorldAABB; if (entity.Physics.AngularVelocity.Sum > 0.03f) { var extents = entity.LocalAABB.HalfExtents.Length(); box = new BoundingBoxD(box.Center - extents, box.Center + extents); } if (box.Extents.Max() > MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES) box.Inflate(MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES); else box.InflateToMinimum(new Vector3(MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES)); box.Translate(predictionOffset); }
public static Vector3D GetRandomPosition(ref BoundingBoxD box) { return(box.Center + GetRandomVector3() * box.HalfExtents); }
public unsafe void QuerySurfaceParameters(Vector3D localOrigin, ref BoundingBoxD queryBounds, List<Vector3> queries, List<MySurfaceParams> results) { localOrigin -= Planet.PositionLeftBottomCorner; using (Planet.Storage.Pin()) { var bounds = (BoundingBox)queryBounds.Translate(-Planet.PositionLeftBottomCorner); Planet.Provider.Shape.PrepareCache(); Planet.Provider.Material.PrepareRulesForBox(ref bounds); if (results.Capacity != queries.Count) { results.Capacity = queries.Count; } fixed (MySurfaceParams* pars = results.GetInternalArray()) { for (int i = 0; i < queries.Count; ++i) { Planet.Provider.ComputeCombinedMaterialAndSurface(queries[i] + localOrigin, true, out pars[i]); pars[i].Position -= localOrigin; } } results.SetSize(queries.Count); } }
public override void OnAddedToContainer() { base.OnAddedToContainer(); m_triggerAABB = Entity.PositionComp.WorldAABB.Inflate(m_size / 2); m_updateTick = MyRandom.Instance.Next(UpdateFrequency - 1); }
public void GetLocalBinBB(ref Vector3I binPosition, out BoundingBoxD output) { output.Min = (Vector3D)(binPosition * this.m_cellSize); output.Max = output.Min + new Vector3(this.m_cellSize); }
/// <summary> /// Invalidates intersected tiles of navmesh managers, if they were generated /// </summary> /// <param name="areaBox"></param> public void InvalidateArea(BoundingBoxD areaBox) { var planet = GetPlanet(areaBox.Center); AreaChanged(planet, areaBox); }
public void MoveObject(ulong id, BoundingBoxD aabb, Vector3 velocity) { System.Diagnostics.Debug.Assert(id != CLUSTERED_OBJECT_ID_UNITIALIZED, "Unitialized object in cluster!"); MyObjectData objectData; if (m_objectsData.TryGetValue(id, out objectData)) { System.Diagnostics.Debug.Assert(!objectData.ActivationHandler.IsStaticForCluster, "Cannot move static object!"); var oldAABB = objectData.AABB; objectData.AABB = aabb; aabb = AdjustAABBByVelocity(aabb, velocity); System.Diagnostics.Debug.Assert(m_clusters.Contains(objectData.Cluster)); var newContainmentType = objectData.Cluster.AABB.Contains(aabb); if (newContainmentType != ContainmentType.Contains && !SingleCluster.HasValue && !ForcedClusters) { if (newContainmentType == ContainmentType.Disjoint) { //Probably caused by teleport m_clusterTree.OverlapAllBoundingBox(ref aabb, m_returnedClusters); if ((m_returnedClusters.Count == 1) && (m_returnedClusters[0].AABB.Contains(aabb) == ContainmentType.Contains)) { //Just move object from one cluster to another var oldCluster = objectData.Cluster; RemoveObjectFromCluster(objectData, false); if (oldCluster.Objects.Count == 0) { RemoveCluster(oldCluster); } AddObjectToCluster(m_returnedClusters[0], objectData.Id, false); } else { aabb.InflateToMinimum(IdealClusterSize); ReorderClusters(aabb.Include(oldAABB), id); } } else { aabb.InflateToMinimum(IdealClusterSize); ReorderClusters(aabb.Include(oldAABB), id); } } System.Diagnostics.Debug.Assert(m_objectsData[id].Cluster.AABB.Contains(objectData.AABB) == ContainmentType.Contains || SingleCluster.HasValue, "Inconsistency in clusters"); } //foreach (var ob in m_objectsData) //{ // if (ob.Value.ActivationHandler.IsStatic && ob.Value.Cluster != null) // System.Diagnostics.Debug.Assert(ob.Value.Cluster.AABB.Contains(ob.Value.AABB) != ContainmentType.Disjoint, "Inconsistency in clusters"); // else // if (!ob.Value.ActivationHandler.IsStatic) // System.Diagnostics.Debug.Assert(ob.Value.Cluster.AABB.Contains(ob.Value.AABB) == ContainmentType.Contains, "Inconsistency in clusters"); //} }
private Vector3D?FindSuitableJumpLocation(Vector3D desiredLocation) { BoundingBoxD shipBBox = GetAggregateBBox(); // 1 Km distante to other objects to prevent spawning in bases shipBBox.Inflate(1000f); BoundingBoxD regionBBox = shipBBox.GetInflated(shipBBox.HalfExtents * 10); regionBBox.Translate(desiredLocation - regionBBox.Center); MyProceduralWorldGenerator.Static.OverlapAllPlanetSeedsInSphere(new BoundingSphereD(regionBBox.Center, regionBBox.HalfExtents.AbsMax()), m_objectsInRange); Vector3D currentSearchPosition = desiredLocation; foreach (var planet in m_objectsInRange) { if (planet.BoundingVolume.Contains(currentSearchPosition) != ContainmentType.Disjoint) { Vector3D v = currentSearchPosition - planet.BoundingVolume.Center; v.Normalize(); v *= planet.BoundingVolume.HalfExtents * 1.5; currentSearchPosition = planet.BoundingVolume.Center + v; break; } } m_objectsInRange.Clear(); MyProceduralWorldGenerator.Static.OverlapAllAsteroidSeedsInSphere(new BoundingSphereD(regionBBox.Center, regionBBox.HalfExtents.AbsMax()), m_objectsInRange); foreach (var asteroid in m_objectsInRange) { m_obstaclesInRange.Add(asteroid.BoundingVolume); } m_objectsInRange.Clear(); MyGamePruningStructure.GetAllTopMostEntitiesInBox <MyEntity>(ref regionBBox, m_entitiesInRange); // Inflate the obstacles so we only need to check the center of the ship for collisions foreach (var entity in m_entitiesInRange) { if (!(entity is MyPlanet)) { m_obstaclesInRange.Add(entity.PositionComp.WorldAABB.GetInflated(shipBBox.HalfExtents)); } } int maxStepCount = 10; int stepCount = 0; // When we collide with an obsticle, we add it here BoundingBoxD?aggregateCollidedObstacles = null; bool obstructed = false; bool found = false; while (stepCount < maxStepCount) { stepCount++; obstructed = false; foreach (var obstacle in m_obstaclesInRange) { var contains = obstacle.Contains(currentSearchPosition); if (contains == ContainmentType.Contains || contains == ContainmentType.Intersects) { if (!aggregateCollidedObstacles.HasValue) { aggregateCollidedObstacles = obstacle; } aggregateCollidedObstacles = aggregateCollidedObstacles.Value.Include(obstacle); aggregateCollidedObstacles = aggregateCollidedObstacles.Value.Inflate(1.0); currentSearchPosition = ClosestPointOnBounds(aggregateCollidedObstacles.Value, currentSearchPosition); obstructed = true; break; } } if (!obstructed) { // No obstacle found, return current search position found = true; break; } } m_obstaclesInRange.Clear(); m_entitiesInRange.Clear(); m_objectsInRange.Clear(); if (found) { return(currentSearchPosition); } else { return(null); } }
public void Deserialize(List <BoundingBoxD> list) { //Remove all foreach (var obj in m_objectsData.Values) { if (obj.Cluster != null) { RemoveObjectFromCluster(obj, true); } else { } } foreach (var obj in m_objectsData.Values) { if (obj.Cluster != null) { obj.ActivationHandler.FinishRemoveBatch(obj.Cluster.UserData); obj.Cluster = null; } } foreach (MyCluster oldCluster in m_clusters) { if (OnFinishBatch != null) { OnFinishBatch(oldCluster.UserData); } } while (m_clusters.Count > 0) { RemoveCluster(m_clusters[0]); } for (int i = 0; i < list.Count; i++) { BoundingBoxD aabb = list[i]; CreateCluster(ref aabb); } foreach (var obj in m_objectsData) { m_clusterTree.OverlapAllBoundingBox(ref obj.Value.AABB, m_returnedClusters); if (m_returnedClusters.Count != 1 && !(obj.Value.ActivationHandler.IsStaticForCluster)) { throw new Exception(String.Format("Inconsistent objects and deserialized clusters. Entity name: {0}, Found clusters: {1}, Replicable exists: {2}", obj.Value.Tag, m_returnedClusters.Count, GetEntityReplicableExistsById(obj.Value.EntityId))); } if (m_returnedClusters.Count == 1) { AddObjectToCluster(m_returnedClusters[0], obj.Key, true); } } foreach (var cluster in m_clusters) { if (OnFinishBatch != null) { OnFinishBatch(cluster.UserData); } foreach (var ob in cluster.Objects) { if (m_objectsData[ob].ActivationHandler != null) { m_objectsData[ob].ActivationHandler.FinishAddBatch(); } } } }
/// <summary> /// Adds environment item to internal collections. Creates render and physics data. /// </summary> /// <returns>True if successfully added, otherwise false.</returns> private bool AddItem(MyEnvironmentItemDefinition itemDefinition, ref MatrixD worldMatrix, ref BoundingBoxD aabbWorld, HkStaticCompoundShape sectorRootShape, Dictionary <MyStringId, HkShape> subtypeIdToShape) { if (!MyFakes.ENABLE_ENVIRONMENT_ITEMS) { return(true); } Debug.Assert(m_definition.ContainsItemDefinition(itemDefinition), String.Format("Environment item with definition '{0}' not found in class '{1}'", itemDefinition.Id, m_definition.Id)); if (!m_definition.ContainsItemDefinition(itemDefinition)) { return(false); } //MyDefinitionId defId = new MyDefinitionId(envItemObjectBuilderType, subtypeId.ToString()); MyModel model = MyModels.GetModelOnlyData(itemDefinition.Model); if (model == null) { //Debug.Fail(String.Format("Environment item model of '{0}' not found, skipping the item...", itemDefinition.Id)); return(false); } int localId = worldMatrix.Translation.GetHashCode(); MyEnvironmentItemData data = new MyEnvironmentItemData() { Id = localId, SubtypeId = itemDefinition.Id.SubtypeId, Transform = new MyTransformD(ref worldMatrix), Enabled = true, SectorInstanceId = -1 }; //Preload split planes //VRageRender.MyRenderProxy.PreloadMaterials(model.AssetName); aabbWorld.Include(model.BoundingBox.Transform(worldMatrix)); CheckModelConsistency(itemDefinition); MatrixD transform = data.Transform.TransformMatrix; Vector3I sectorId = MyEnvironmentSector.GetSectorId(transform.Translation, m_definition.SectorSize); MyEnvironmentSector sector; if (!m_sectors.TryGetValue(sectorId, out sector)) { sector = new MyEnvironmentSector(sectorId); m_sectors.Add(sectorId, sector); } // Adds instance of the given model. Local matrix specified might be changed internally in renderer. Matrix transformL = (Matrix)transform; data.SectorInstanceId = sector.AddInstance(itemDefinition.Id.SubtypeId, ref transformL, model.BoundingBox, m_instanceFlags, m_definition.MaxViewDistance); int physicsShapeInstanceId; if (AddPhysicsShape(data.SubtypeId, model, ref transform, sectorId, sectorRootShape, subtypeIdToShape, out physicsShapeInstanceId)) { // Map to data index - note that itemData is added after this to its list! m_physicsShapeInstanceIdToLocalId[physicsShapeInstanceId] = localId; m_localIdToPhysicsShapeInstanceId[localId] = physicsShapeInstanceId; } data.Transform = new MyTransformD(transform); if (m_itemsData.ContainsKey(localId)) { Debug.Fail("More items on same place! " + transform.Translation.ToString()); } else { m_itemsData.Add(localId, data); } return(true); }
public static Vector3I SizeInt(this BoundingBoxD box) { var size = box.Size; return(new Vector3I((int)size.X, (int)size.Y, (int)size.Z)); }
public override void Init(MyObjectBuilder_EntityBase objectBuilder) { base.Init(objectBuilder); Init(null, null, null, null); BoundingBoxD aabbWorld = BoundingBoxD.CreateInvalid(); Dictionary <MyStringId, HkShape> subtypeIdToShape = new Dictionary <MyStringId, HkShape>(); HkStaticCompoundShape sectorRootShape = new HkStaticCompoundShape(HkReferencePolicy.None); var builder = (MyObjectBuilder_EnvironmentItems)objectBuilder; MyDefinitionId defId = new MyDefinitionId(builder.TypeId, builder.SubtypeId); // Compatibility if (builder.SubtypeId == MyStringId.NullOrEmpty) { if (objectBuilder is MyObjectBuilder_Bushes) { defId = new MyDefinitionId(typeof(MyObjectBuilder_DestroyableItems), "Bushes"); } else if (objectBuilder is MyObjectBuilder_TreesMedium) { defId = new MyDefinitionId(typeof(MyObjectBuilder_Trees), "TreesMedium"); } else if (objectBuilder is MyObjectBuilder_Trees) { defId = new MyDefinitionId(typeof(MyObjectBuilder_Trees), "Trees"); } } if (!MyDefinitionManager.Static.TryGetDefinition <MyEnvironmentItemsDefinition>(defId, out m_definition)) { Debug.Assert(false, "Could not find definition " + defId.ToString() + " for environment items!"); return; } if (builder.Items != null) { foreach (var item in builder.Items) { MyStringId itemSubtype = MyStringId.GetOrCompute(item.SubtypeName); Debug.Assert(m_definition.ContainsItemDefinition(itemSubtype)); if (!m_definition.ContainsItemDefinition(itemSubtype)) { continue; } MatrixD worldMatrix = item.PositionAndOrientation.GetMatrix(); AddItem(m_definition.GetItemDefinition(itemSubtype), ref worldMatrix, ref aabbWorld, sectorRootShape, subtypeIdToShape); } } PrepareItems(sectorRootShape, ref aabbWorld); foreach (var pair in subtypeIdToShape) { pair.Value.RemoveReference(); } NeedsUpdate |= MyEntityUpdateEnum.EACH_FRAME; }
private bool AddCell(Vector3I cellPos) { MyCellCoord coord = new MyCellCoord(NAVMESH_LOD, cellPos); var generatedMesh = MyPrecalcComponent.IsoMesher.Precalc(new MyIsoMesherArgs() { Storage = m_voxelMap.Storage, GeometryCell = coord, }); if (generatedMesh == null) { m_processedCells.Add(ref cellPos); m_higherLevelHelper.AddExplored(ref cellPos); return(false); } ulong packedCoord = coord.PackId64(); List <DebugDrawEdge> debugEdgesList = new List <DebugDrawEdge>(); m_debugCellEdges[packedCoord] = debugEdgesList; MyVoxelPathfinding.CellId cellId = new MyVoxelPathfinding.CellId() { VoxelMap = m_voxelMap, Pos = cellPos }; MyTrace.Send(TraceWindow.Ai, "Adding cell " + cellPos); m_connectionHelper.ClearCell(); m_vertexMapping.Init(generatedMesh.VerticesCount); // Prepare list of possibly intersecting cube grids for voxel-grid navmesh intersection testing Vector3D bbMin = m_voxelMap.PositionLeftBottomCorner + (m_cellSize * (new Vector3D(-0.125) + cellPos)); Vector3D bbMax = m_voxelMap.PositionLeftBottomCorner + (m_cellSize * (Vector3D.One + cellPos)); BoundingBoxD cellBB = new BoundingBoxD(bbMin, bbMax); m_tmpGridList.Clear(); m_navmeshCoordinator.PrepareVoxelTriangleTests(cellBB, m_tmpGridList); Vector3D voxelMapCenter = m_voxelMap.PositionComp.GetPosition(); Vector3 centerDisplacement = voxelMapCenter - m_voxelMap.PositionLeftBottomCorner; // This is needed for correct edge classification - to tell, whether the edges are inner or outer edges of the cell ProfilerShort.Begin("Triangle preprocessing"); for (int i = 0; i < generatedMesh.TrianglesCount; i++) { short a = generatedMesh.Triangles[i].VertexIndex0; short b = generatedMesh.Triangles[i].VertexIndex1; short c = generatedMesh.Triangles[i].VertexIndex2; Vector3 aPos, bPos, cPos; Vector3 vert; generatedMesh.GetUnpackedPosition(a, out vert); aPos = vert - centerDisplacement; generatedMesh.GetUnpackedPosition(b, out vert); bPos = vert - centerDisplacement; generatedMesh.GetUnpackedPosition(c, out vert); cPos = vert - centerDisplacement; bool invalidTriangle = false; if ((bPos - aPos).LengthSquared() <= MyVoxelConnectionHelper.OUTER_EDGE_EPSILON_SQ) { m_vertexMapping.Union(a, b); invalidTriangle = true; } if ((cPos - aPos).LengthSquared() <= MyVoxelConnectionHelper.OUTER_EDGE_EPSILON_SQ) { m_vertexMapping.Union(a, c); invalidTriangle = true; } if ((cPos - bPos).LengthSquared() <= MyVoxelConnectionHelper.OUTER_EDGE_EPSILON_SQ) { m_vertexMapping.Union(b, c); invalidTriangle = true; } if (invalidTriangle) { continue; } m_connectionHelper.PreprocessInnerEdge(a, b); m_connectionHelper.PreprocessInnerEdge(b, c); m_connectionHelper.PreprocessInnerEdge(c, a); } ProfilerShort.End(); ProfilerShort.Begin("Free face sorting"); // Ensure that the faces have increasing index numbers Mesh.SortFreeFaces(); ProfilerShort.End(); m_higherLevelHelper.OpenNewCell(coord); ProfilerShort.Begin("Adding triangles"); for (int i = 0; i < generatedMesh.TrianglesCount; i++) { short a = generatedMesh.Triangles[i].VertexIndex0; short b = generatedMesh.Triangles[i].VertexIndex1; short c = generatedMesh.Triangles[i].VertexIndex2; short setA = (short)m_vertexMapping.Find(a); short setB = (short)m_vertexMapping.Find(b); short setC = (short)m_vertexMapping.Find(c); if (setA == setB || setB == setC || setA == setC) { continue; } Vector3 aPos, bPos, cPos; Vector3 vert; generatedMesh.GetUnpackedPosition(a, out vert); aPos = vert - centerDisplacement; generatedMesh.GetUnpackedPosition(b, out vert); bPos = vert - centerDisplacement; generatedMesh.GetUnpackedPosition(c, out vert); cPos = vert - centerDisplacement; if (MyFakes.NAVMESH_PRESUMES_DOWNWARD_GRAVITY) { Vector3 normal = (cPos - aPos).Cross(bPos - aPos); normal.Normalize(); if (normal.Dot(ref Vector3.Up) <= Math.Cos(MathHelper.ToRadians(54.0f))) { continue; } } Vector3D aTformed = aPos + voxelMapCenter; Vector3D bTformed = bPos + voxelMapCenter; Vector3D cTformed = cPos + voxelMapCenter; bool intersecting = false; m_tmpLinkCandidates.Clear(); m_navmeshCoordinator.TestVoxelNavmeshTriangle(ref aTformed, ref bTformed, ref cTformed, m_tmpGridList, m_tmpLinkCandidates, out intersecting); if (intersecting) { m_tmpLinkCandidates.Clear(); continue; } if (!m_connectionHelper.IsInnerEdge(a, b)) { debugEdgesList.Add(new DebugDrawEdge(aTformed, bTformed)); } if (!m_connectionHelper.IsInnerEdge(b, c)) { debugEdgesList.Add(new DebugDrawEdge(bTformed, cTformed)); } if (!m_connectionHelper.IsInnerEdge(c, a)) { debugEdgesList.Add(new DebugDrawEdge(cTformed, aTformed)); } int edgeAB = m_connectionHelper.TryGetAndRemoveEdgeIndex(b, a, ref bPos, ref aPos); int edgeBC = m_connectionHelper.TryGetAndRemoveEdgeIndex(c, b, ref cPos, ref bPos); int edgeCA = m_connectionHelper.TryGetAndRemoveEdgeIndex(a, c, ref aPos, ref cPos); int formerAB = edgeAB; int formerBC = edgeBC; int formerCA = edgeCA; ProfilerShort.Begin("AddTriangle"); var tri = AddTriangle(ref aPos, ref bPos, ref cPos, ref edgeAB, ref edgeBC, ref edgeCA); ProfilerShort.End(); CheckMeshConsistency(); m_higherLevelHelper.AddTriangle(tri.Index); if (formerAB == -1) { m_connectionHelper.AddEdgeIndex(a, b, ref aPos, ref bPos, edgeAB); } if (formerBC == -1) { m_connectionHelper.AddEdgeIndex(b, c, ref bPos, ref cPos, edgeBC); } if (formerCA == -1) { m_connectionHelper.AddEdgeIndex(c, a, ref cPos, ref aPos, edgeCA); } // TODO: Instead of this, just add the tri into a list of tris that want to connect with the link candidates //m_navmeshCoordinator.TryAddVoxelNavmeshLinks(tri, cellId, m_tmpLinkCandidates); foreach (var candidate in m_tmpLinkCandidates) { List <MyNavigationPrimitive> primitives = null; if (!m_tmpCubeLinkCandidates.TryGetValue(candidate, out primitives)) { primitives = m_primitiveListPool.Allocate(); m_tmpCubeLinkCandidates.Add(candidate, primitives); } primitives.Add(tri); } m_tmpLinkCandidates.Clear(); } ProfilerShort.End(); m_tmpGridList.Clear(); m_connectionHelper.ClearCell(); m_vertexMapping.Clear(); Debug.Assert(!m_processedCells.Contains(ref cellPos)); m_processedCells.Add(ref cellPos); m_higherLevelHelper.AddExplored(ref cellPos); // Find connected components in the current cell's subgraph of the navigation mesh m_higherLevelHelper.ProcessCellComponents(); m_higherLevelHelper.CloseCell(); // Create navmesh links using the navmesh coordinator, taking into consideration the high level components m_navmeshCoordinator.TryAddVoxelNavmeshLinks2(cellId, m_tmpCubeLinkCandidates); m_navmeshCoordinator.UpdateVoxelNavmeshCellHighLevelLinks(cellId); foreach (var candidate in m_tmpCubeLinkCandidates) { candidate.Value.Clear(); m_primitiveListPool.Deallocate(candidate.Value); } m_tmpCubeLinkCandidates.Clear(); return(true); }
public unsafe void CalculateRotationHints(MatrixD drawMatrix, bool draw, bool fixedAxes = false, bool hideForwardAndUpArrows = false) { int num6; string controlButtonName; string str2; string str3; string str4; string str5; string str6; Vector3D zero; Vector3D vectord14; Vector3D vectord15; Vector3D vectord16; Vector3D vectord17; Vector3D vectord18; Vector3D vectord19; Vector3D vectord20; Vector3D vectord21; Vector3D vectord22; Vector3D vectord23; Vector3D vectord24; int num13; int num14; int num15; int num16; int num17; int num18; int num20; int num21; float num22; Vector3D vectord25; Vector3D vectord26; Vector3D vectord27; bool flag2; bool flag3; bool flag5; bool flag6; Vector3D vectord29; Vector3D vectord30; Vector3D vectord31; Vector3D vectord32; int num28; bool flag7; Vector3 vector3; Vector3D vectord38; Vector3 vector8; Vector3D vectord39; Vector3 vector9; int num29; bool flag8; Vector3 vector10; Matrix viewMatrix = (Matrix)MySector.MainCamera.ViewMatrix; MatrixD matrix = MatrixD.Invert(viewMatrix); if (!drawMatrix.IsValid()) { return; } else { if (viewMatrix.IsValid()) { int num7; int num8; int num9; int num10; int num11; int num12; MatrixD *xdPtr1 = (MatrixD *)ref matrix; xdPtr1.Translation = ((drawMatrix.Translation - (7.0 * matrix.Forward)) + (1.0 * matrix.Left)) - (0.60000002384185791 * matrix.Up); MatrixD *xdPtr2 = (MatrixD *)ref drawMatrix; xdPtr2.Translation -= matrix.Translation; this.m_viewProjection.CameraPosition = matrix.Translation; matrix.Translation = Vector3D.Zero; Matrix matrix2 = (Matrix)MatrixD.Transpose(matrix); this.m_viewProjection.ViewAtZero = matrix2; float num = 2.75f; Vector2 screenSizeFromNormalizedSize = MyGuiManager.GetScreenSizeFromNormalizedSize(Vector2.One, false); int num2 = (int)(screenSizeFromNormalizedSize.X / num); int num3 = (int)(screenSizeFromNormalizedSize.Y / num); int num4 = 0; int num5 = 0; this.m_viewProjection.Viewport = new MyViewport((float)((((int)MySector.MainCamera.Viewport.Width) - num2) - num4), (float)num5, (float)num2, (float)num3); this.m_viewProjection.Projection = Matrix.CreatePerspectiveFieldOfView(0.7853982f, ((float)num2) / ((float)num3), 0.1f, 10f); BoundingBoxD localbox = new BoundingBoxD(-new Vector3(MyDefinitionManager.Static.GetCubeSize(MyCubeSize.Large) * 0.5f), new Vector3(MyDefinitionManager.Static.GetCubeSize(MyCubeSize.Large)) * 0.5f); num6 = 0; MyRenderProxy.AddBillboardViewProjection(num6, this.m_viewProjection); if (draw) { Color red = Color.Red; Color green = Color.Green; Color blue = Color.Blue; Color white = Color.White; Color color5 = Color.White; Color color6 = Color.White; Color wire = Color.White; MyStringId?lineMaterial = null; MySimpleObjectDraw.DrawTransparentBox(ref drawMatrix, ref localbox, ref red, ref green, ref blue, ref white, ref color5, ref color6, ref wire, MySimpleObjectRasterizer.Solid, 1, 0.04f, new MyStringId?(ID_SQUARE_FULL_COLOR), lineMaterial, false, num6, MyBillboard.BlendTypeEnum.LDR, 1f, null); } new MyOrientedBoundingBoxD(Vector3D.Transform(localbox.Center, drawMatrix), localbox.HalfExtents, Quaternion.CreateFromRotationMatrix(drawMatrix)).GetCorners(this.m_cubeVertices, 0); GetClosestCubeEdge(this.m_cubeVertices, Vector3D.Zero, MyOrientedBoundingBox.StartXVertices, MyOrientedBoundingBox.EndXVertices, out num7, out num8); Vector3D from = this.m_cubeVertices[MyOrientedBoundingBox.StartXVertices[num7]]; Vector3D to = this.m_cubeVertices[MyOrientedBoundingBox.EndXVertices[num7]]; Vector3D vectord3 = this.m_cubeVertices[MyOrientedBoundingBox.StartXVertices[num8]]; Vector3D vectord4 = this.m_cubeVertices[MyOrientedBoundingBox.EndXVertices[num8]]; GetClosestCubeEdge(this.m_cubeVertices, Vector3D.Zero, MyOrientedBoundingBox.StartYVertices, MyOrientedBoundingBox.EndYVertices, out num9, out num10); Vector3D vectord5 = this.m_cubeVertices[MyOrientedBoundingBox.StartYVertices[num9]]; Vector3D vectord6 = this.m_cubeVertices[MyOrientedBoundingBox.EndYVertices[num9]]; Vector3D vectord7 = this.m_cubeVertices[MyOrientedBoundingBox.StartYVertices[num10]]; Vector3D vectord8 = this.m_cubeVertices[MyOrientedBoundingBox.EndYVertices[num10]]; GetClosestCubeEdge(this.m_cubeVertices, Vector3D.Zero, MyOrientedBoundingBox.StartZVertices, MyOrientedBoundingBox.EndZVertices, out num11, out num12); Vector3D vectord9 = this.m_cubeVertices[MyOrientedBoundingBox.StartZVertices[num11]]; Vector3D vectord10 = this.m_cubeVertices[MyOrientedBoundingBox.EndZVertices[num11]]; Vector3D vectord11 = this.m_cubeVertices[MyOrientedBoundingBox.StartZVertices[num12]]; Vector3D vectord12 = this.m_cubeVertices[MyOrientedBoundingBox.EndZVertices[num12]]; this.m_cubeEdges.Clear(); BoxEdge item = new BoxEdge { Axis = 0, Edge = new LineD(from, to) }; this.m_cubeEdges.Add(item); item = new BoxEdge { Axis = 1, Edge = new LineD(vectord5, vectord6) }; this.m_cubeEdges.Add(item); item = new BoxEdge { Axis = 2, Edge = new LineD(vectord9, vectord10) }; this.m_cubeEdges.Add(item); if (!fixedAxes) { int num23; this.RotationRightAxis = GetBestAxis(this.m_cubeEdges, MySector.MainCamera.WorldMatrix.Right, out num23); this.RotationRightDirection = num23; this.RotationUpAxis = GetBestAxis(this.m_cubeEdges, MySector.MainCamera.WorldMatrix.Up, out num23); this.RotationUpDirection = num23; this.RotationForwardAxis = GetBestAxis(this.m_cubeEdges, MySector.MainCamera.WorldMatrix.Forward, out num23); this.RotationForwardDirection = num23; } controlButtonName = MyInput.Static.GetGameControl(MyControlsSpace.CUBE_ROTATE_HORISONTAL_POSITIVE).GetControlButtonName(MyGuiInputDeviceEnum.Keyboard); str2 = MyInput.Static.GetGameControl(MyControlsSpace.CUBE_ROTATE_HORISONTAL_NEGATIVE).GetControlButtonName(MyGuiInputDeviceEnum.Keyboard); str3 = MyInput.Static.GetGameControl(MyControlsSpace.CUBE_ROTATE_VERTICAL_POSITIVE).GetControlButtonName(MyGuiInputDeviceEnum.Keyboard); str4 = MyInput.Static.GetGameControl(MyControlsSpace.CUBE_ROTATE_VERTICAL_NEGATIVE).GetControlButtonName(MyGuiInputDeviceEnum.Keyboard); str5 = MyInput.Static.GetGameControl(MyControlsSpace.CUBE_ROTATE_ROLL_POSITIVE).GetControlButtonName(MyGuiInputDeviceEnum.Keyboard); str6 = MyInput.Static.GetGameControl(MyControlsSpace.CUBE_ROTATE_ROLL_NEGATIVE).GetControlButtonName(MyGuiInputDeviceEnum.Keyboard); if (MyInput.Static.IsJoystickConnected() && MyInput.Static.IsJoystickLastUsed) { controlButtonName = MyControllerHelper.GetCodeForControl(MySpaceBindingCreator.CX_BUILD_MODE, MyControlsSpace.CUBE_ROTATE_HORISONTAL_POSITIVE).ToString(); str2 = MyControllerHelper.GetCodeForControl(MySpaceBindingCreator.CX_BUILD_MODE, MyControlsSpace.CUBE_ROTATE_HORISONTAL_NEGATIVE).ToString(); str3 = MyControllerHelper.GetCodeForControl(MySpaceBindingCreator.CX_BUILD_MODE, MyControlsSpace.CUBE_ROTATE_VERTICAL_POSITIVE).ToString(); str4 = MyControllerHelper.GetCodeForControl(MySpaceBindingCreator.CX_BUILD_MODE, MyControlsSpace.CUBE_ROTATE_VERTICAL_NEGATIVE).ToString(); str5 = MyControllerHelper.GetCodeForControl(MySpaceBindingCreator.CX_BUILD_MODE, MyControlsSpace.CUBE_ROTATE_ROLL_POSITIVE).ToString(); str6 = MyControllerHelper.GetCodeForControl(MySpaceBindingCreator.CX_BUILD_MODE, MyControlsSpace.CUBE_ROTATE_ROLL_NEGATIVE).ToString(); } zero = Vector3D.Zero; vectord14 = Vector3D.Zero; vectord15 = Vector3D.Zero; vectord16 = Vector3D.Zero; vectord17 = Vector3D.Zero; vectord18 = Vector3D.Zero; vectord19 = Vector3D.Zero; vectord20 = Vector3D.Zero; vectord21 = Vector3D.Zero; vectord22 = Vector3D.Zero; vectord23 = Vector3D.Zero; vectord24 = Vector3D.Zero; num13 = -1; num14 = -1; num15 = -1; num16 = -1; num17 = -1; num18 = -1; int num19 = -1; num20 = -1; num21 = -1; if (this.RotationRightAxis == 0) { zero = from; vectord14 = to; vectord19 = vectord3; vectord20 = vectord4; num13 = 0; num16 = num7; num19 = num8; } else if (this.RotationRightAxis == 1) { zero = vectord5; vectord14 = vectord6; vectord19 = vectord7; vectord20 = vectord8; num13 = 1; num16 = num9; num19 = num10; } else if (this.RotationRightAxis == 2) { zero = vectord9; vectord14 = vectord10; vectord19 = vectord11; vectord20 = vectord12; num13 = 2; num16 = num11; num19 = num12; } if (this.RotationUpAxis == 0) { vectord15 = from; vectord16 = to; vectord21 = vectord3; vectord22 = vectord4; num14 = 0; num17 = num7; num20 = num8; } else if (this.RotationUpAxis == 1) { vectord15 = vectord5; vectord16 = vectord6; vectord21 = vectord7; vectord22 = vectord8; num14 = 1; num17 = num9; num20 = num10; } else if (this.RotationUpAxis == 2) { vectord15 = vectord9; vectord16 = vectord10; vectord21 = vectord11; vectord22 = vectord12; num14 = 2; num17 = num11; num20 = num12; } if (this.RotationForwardAxis == 0) { vectord17 = from; vectord18 = to; vectord23 = vectord3; vectord24 = vectord4; num15 = 0; num18 = num7; num21 = num8; } else if (this.RotationForwardAxis == 1) { vectord17 = vectord5; vectord18 = vectord6; vectord23 = vectord7; vectord24 = vectord8; num15 = 1; num18 = num9; num21 = num10; } else if (this.RotationForwardAxis == 2) { vectord17 = vectord9; vectord18 = vectord10; vectord23 = vectord11; vectord24 = vectord12; num15 = 2; num18 = num11; num21 = num12; } num22 = 0.5448648f; if (!draw) { return; } else { vectord25 = Vector3.Normalize(vectord14 - zero); vectord26 = Vector3.Normalize(vectord16 - vectord15); vectord27 = Vector3.Normalize(vectord18 - vectord17); Vector3D forwardVector = MySector.MainCamera.ForwardVector; float num24 = Math.Abs(Vector3.Dot((Vector3)forwardVector, (Vector3)vectord25)); float num25 = Math.Abs(Vector3.Dot((Vector3)forwardVector, (Vector3)vectord26)); float num26 = Math.Abs(Vector3.Dot((Vector3)forwardVector, (Vector3)vectord27)); bool flag = false; flag2 = false; flag3 = false; bool flag4 = false; flag5 = false; flag6 = false; float num27 = 0.4f; if (num24 < num27) { if (num25 < num27) { flag6 = true; flag = true; flag2 = true; } else if (num26 >= num27) { flag2 = true; flag3 = true; } else { flag5 = true; flag = true; flag3 = true; } } else if (num25 < num27) { if (num24 < num27) { flag6 = true; flag = true; flag2 = true; } else if (num26 >= num27) { flag = true; flag3 = true; } else { flag4 = true; flag2 = true; flag3 = true; } } else if (num26 < num27) { if (num24 < num27) { flag5 = true; flag = true; flag3 = true; } else if (num25 >= num27) { flag2 = true; flag = true; } else { flag5 = true; flag = true; flag3 = true; } } if (hideForwardAndUpArrows && (this.RotationRightAxis != 1)) { goto TR_0025; } if (!flag4) { if (!flag) { Vector3 vector4; Vector3 vector5; MyOrientedBoundingBox.GetNormalBetweenEdges(num13, num16, num16 + 1, out vector5); MyOrientedBoundingBox.GetNormalBetweenEdges(num13, num16, num16 - 1, out vector4); Vector3D vectord34 = (zero + vectord14) * 0.5; Vector3D vectord35 = Vector3D.TransformNormal(vector5, drawMatrix); Vector3D vectord36 = Vector3D.TransformNormal(vector4, drawMatrix); MyTransparentGeometry.AddBillboardOriented(ID_ARROW_GREEN, Vector4.One, (vectord34 + (vectord35 * 0.30000001192092896)) - (vectord36 * 0.0099999997764825821), (Vector3)vectord25, (Vector3)vectord35, 0.5f, num6, MyBillboard.BlendTypeEnum.LDR); MyTransparentGeometry.AddBillboardOriented(ID_ARROW_GREEN, Vector4.One, (vectord34 + (vectord36 * 0.30000001192092896)) - (vectord35 * 0.0099999997764825821), (Vector3)vectord25, (Vector3)vectord36, 0.5f, num6, MyBillboard.BlendTypeEnum.LDR); MyRenderProxy.DebugDrawText3D((vectord34 + (vectord35 * 0.30000001192092896)) - (vectord36 * 0.0099999997764825821), (this.RotationRightDirection < 0) ? controlButtonName : str2, Color.White, num22, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, num6, false); MyRenderProxy.DebugDrawText3D((vectord34 + (vectord36 * 0.30000001192092896)) - (vectord35 * 0.0099999997764825821), (this.RotationRightDirection < 0) ? str2 : controlButtonName, Color.White, num22, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, num6, false); goto TR_0025; } else { Vector3 vector; Vector3 vector2; MyOrientedBoundingBox.GetNormalBetweenEdges(num13, num16, num19, out vector2); vectord29 = (zero + vectord14) * 0.5; vectord30 = Vector3D.TransformNormal(vector2, drawMatrix); MyOrientedBoundingBox.GetNormalBetweenEdges(num13, num19, num16, out vector); vectord31 = (vectord19 + vectord20) * 0.5; vectord32 = Vector3D.TransformNormal(vector, drawMatrix); flag7 = false; if ((num16 == 0) && (num19 == 3)) { num28 = num16 + 1; goto TR_0029; } if ((num16 >= num19) && ((num16 != 3) || (num19 != 0))) { num28 = num16 + 1; goto TR_0029; } } } else { Vector3D vectord28 = (((vectord17 + vectord18) + vectord23) + vectord24) * 0.25; MyTransparentGeometry.AddBillboardOriented(ID_ARROW_LEFT_GREEN, Vector4.One, (vectord28 - ((this.RotationForwardDirection * vectord27) * 0.20000000298023224)) - ((this.RotationRightDirection * vectord25) * 0.0099999997764825821), (Vector3)(-this.RotationUpDirection * vectord26), (Vector3)(-this.RotationForwardDirection * vectord27), 0.2f, num6, MyBillboard.BlendTypeEnum.LDR); MyTransparentGeometry.AddBillboardOriented(ID_ARROW_RIGHT_GREEN, Vector4.One, (vectord28 + ((this.RotationForwardDirection * vectord27) * 0.20000000298023224)) - ((this.RotationRightDirection * vectord25) * 0.0099999997764825821), (Vector3)(this.RotationUpDirection * vectord26), (Vector3)(this.RotationForwardDirection * vectord27), 0.2f, num6, MyBillboard.BlendTypeEnum.LDR); MyRenderProxy.DebugDrawText3D((vectord28 - ((this.RotationForwardDirection * vectord27) * 0.20000000298023224)) - ((this.RotationRightDirection * vectord25) * 0.0099999997764825821), str2, Color.White, num22, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, num6, false); MyRenderProxy.DebugDrawText3D((vectord28 + ((this.RotationForwardDirection * vectord27) * 0.20000000298023224)) - ((this.RotationRightDirection * vectord25) * 0.0099999997764825821), controlButtonName, Color.White, num22, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, num6, false); goto TR_0025; } goto TR_002B; } goto TR_0029; } else { return; } goto TR_002B; } goto TR_0029; TR_0013: if (!hideForwardAndUpArrows || (this.RotationForwardAxis == 1)) { if (flag6) { Vector3D vectord41 = (((zero + vectord14) + vectord19) + vectord20) * 0.25; MyTransparentGeometry.AddBillboardOriented(ID_ARROW_LEFT_BLUE, Vector4.One, (vectord41 + ((this.RotationUpDirection * vectord26) * 0.20000000298023224)) - ((this.RotationForwardDirection * vectord27) * 0.0099999997764825821), (Vector3)(-this.RotationRightDirection * vectord25), (Vector3)(this.RotationUpDirection * vectord26), 0.2f, num6, MyBillboard.BlendTypeEnum.LDR); MyTransparentGeometry.AddBillboardOriented(ID_ARROW_RIGHT_BLUE, Vector4.One, (vectord41 - ((this.RotationUpDirection * vectord26) * 0.20000000298023224)) - ((this.RotationForwardDirection * vectord27) * 0.0099999997764825821), (Vector3)(this.RotationRightDirection * vectord25), (Vector3)(-this.RotationUpDirection * vectord26), 0.2f, num6, MyBillboard.BlendTypeEnum.LDR); MyRenderProxy.DebugDrawText3D((vectord41 + ((this.RotationUpDirection * vectord26) * 0.20000000298023224)) - ((this.RotationForwardDirection * vectord27) * 0.0099999997764825821), str5, Color.White, num22, false, MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_CENTER, num6, false); MyRenderProxy.DebugDrawText3D((vectord41 - ((this.RotationUpDirection * vectord26) * 0.20000000298023224)) - ((this.RotationForwardDirection * vectord27) * 0.0099999997764825821), str6, Color.White, num22, false, MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_CENTER, num6, false); return; } if (!flag3) { Vector3 vector22; Vector3 vector23; MyOrientedBoundingBox.GetNormalBetweenEdges(num15, num18, num18 + 1, out vector23); MyOrientedBoundingBox.GetNormalBetweenEdges(num15, num18, num18 - 1, out vector22); Vector3D vectord44 = (vectord17 + vectord18) * 0.5; Vector3 upVector = Vector3.TransformNormal(vector23, drawMatrix); Vector3 vector25 = Vector3.TransformNormal(vector22, drawMatrix); MyTransparentGeometry.AddBillboardOriented(ID_ARROW_BLUE, Vector4.One, (vectord44 + (upVector * 0.3f)) - (vector25 * 0.01f), (Vector3)vectord27, upVector, 0.5f, num6, MyBillboard.BlendTypeEnum.LDR); MyTransparentGeometry.AddBillboardOriented(ID_ARROW_BLUE, Vector4.One, (vectord44 + (vector25 * 0.3f)) - (upVector * 0.01f), (Vector3)vectord27, vector25, 0.5f, num6, MyBillboard.BlendTypeEnum.LDR); MyRenderProxy.DebugDrawText3D((vectord44 + (upVector * 0.3f)) - (vector25 * 0.01f), (this.RotationForwardDirection < 0) ? str5 : str6, Color.White, num22, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, num6, false); MyRenderProxy.DebugDrawText3D((vectord44 + (vector25 * 0.3f)) - (upVector * 0.01f), (this.RotationForwardDirection < 0) ? str6 : str5, Color.White, num22, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, num6, false); } else { Vector3 vector16; Vector3 vector17; int num30; Vector3 vector20; MyOrientedBoundingBox.GetNormalBetweenEdges(num15, num18, num21, out vector17); Vector3D vectord42 = (vectord17 + vectord18) * 0.5; Vector3 upVector = Vector3.TransformNormal(vector17, drawMatrix); MyOrientedBoundingBox.GetNormalBetweenEdges(num15, num21, num18, out vector16); Vector3D vectord43 = (vectord23 + vectord24) * 0.5; Vector3 vector19 = Vector3.TransformNormal(vector16, drawMatrix); bool flag9 = false; if ((num18 == 0) && (num21 == 3)) { num30 = num18 + 1; } else if ((num18 >= num21) && ((num18 != 3) || (num21 != 0))) { num30 = num18 + 1; } else { num30 = num18 - 1; flag9 = true; } if (this.RotationForwardDirection < 0) { flag9 = !flag9; } MyOrientedBoundingBox.GetNormalBetweenEdges(num15, num18, num30, out vector20); Vector3 vector21 = Vector3.TransformNormal(vector20, drawMatrix); MyTransparentGeometry.AddBillboardOriented(ID_ARROW_BLUE, Vector4.One, (vectord42 + (upVector * 0.4f)) - (vector21 * 0.01f), (Vector3)vectord27, vector19, 0.5f, num6, MyBillboard.BlendTypeEnum.LDR); MyTransparentGeometry.AddBillboardOriented(ID_ARROW_BLUE, Vector4.One, (vectord43 + (vector19 * 0.4f)) - (vector21 * 0.01f), (Vector3)vectord27, upVector, 0.5f, num6, MyBillboard.BlendTypeEnum.LDR); MyRenderProxy.DebugDrawText3D((vectord42 + (upVector * 0.3f)) - (vector21 * 0.01f), flag9 ? str5 : str6, Color.White, num22, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, num6, false); MyRenderProxy.DebugDrawText3D((vectord43 + (vector19 * 0.3f)) - (vector21 * 0.01f), flag9 ? str6 : str5, Color.White, num22, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, num6, false); return; } } return; TR_0017: if (this.RotationUpDirection < 0) { flag8 = !flag8; } MyOrientedBoundingBox.GetNormalBetweenEdges(num14, num17, num29, out vector10); Vector3 vector11 = Vector3.TransformNormal(vector10, drawMatrix); MyTransparentGeometry.AddBillboardOriented(ID_ARROW_RED, Vector4.One, (vectord38 + (vector8 * 0.4f)) - (vector11 * 0.01f), (Vector3)vectord26, vector9, 0.5f, num6, MyBillboard.BlendTypeEnum.LDR); MyTransparentGeometry.AddBillboardOriented(ID_ARROW_RED, Vector4.One, (vectord39 + (vector9 * 0.4f)) - (vector11 * 0.01f), (Vector3)vectord26, vector8, 0.5f, num6, MyBillboard.BlendTypeEnum.LDR); MyRenderProxy.DebugDrawText3D((vectord38 + (vector8 * 0.3f)) - (vector11 * 0.01f), flag8 ? str4 : str3, Color.White, num22, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, num6, false); MyRenderProxy.DebugDrawText3D((vectord39 + (vector9 * 0.3f)) - (vector11 * 0.01f), flag8 ? str3 : str4, Color.White, num22, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, num6, false); goto TR_0013; TR_0025: if (hideForwardAndUpArrows && (this.RotationUpAxis != 1)) { goto TR_0013; } if (!flag5) { if (!flag2) { Vector3 vector12; Vector3 vector13; MyOrientedBoundingBox.GetNormalBetweenEdges(num14, num17, num17 + 1, out vector13); MyOrientedBoundingBox.GetNormalBetweenEdges(num14, num17, num17 - 1, out vector12); Vector3D vectord40 = (vectord15 + vectord16) * 0.5; Vector3 upVector = Vector3.TransformNormal(vector13, drawMatrix); Vector3 vector15 = Vector3.TransformNormal(vector12, drawMatrix); MyTransparentGeometry.AddBillboardOriented(ID_ARROW_RED, Vector4.One, (vectord40 + (upVector * 0.3f)) - (vector15 * 0.01f), (Vector3)vectord26, upVector, 0.5f, num6, MyBillboard.BlendTypeEnum.LDR); MyTransparentGeometry.AddBillboardOriented(ID_ARROW_RED, Vector4.One, (vectord40 + (vector15 * 0.3f)) - (upVector * 0.01f), (Vector3)vectord26, vector15, 0.5f, num6, MyBillboard.BlendTypeEnum.LDR); MyRenderProxy.DebugDrawText3D((vectord40 + (upVector * 0.6f)) - (vector15 * 0.01f), (this.RotationUpDirection > 0) ? str3 : str4, Color.White, num22, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, num6, false); MyRenderProxy.DebugDrawText3D((vectord40 + (vector15 * 0.6f)) - (upVector * 0.01f), (this.RotationUpDirection > 0) ? str4 : str3, Color.White, num22, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, num6, false); goto TR_0013; } else { Vector3 vector6; Vector3 vector7; MyOrientedBoundingBox.GetNormalBetweenEdges(num14, num17, num20, out vector7); vectord38 = (vectord15 + vectord16) * 0.5; vector8 = Vector3.TransformNormal(vector7, drawMatrix); MyOrientedBoundingBox.GetNormalBetweenEdges(num14, num20, num17, out vector6); vectord39 = (vectord21 + vectord22) * 0.5; vector9 = Vector3.TransformNormal(vector6, drawMatrix); flag8 = false; if ((num17 == 0) && (num20 == 3)) { num29 = num17 + 1; goto TR_0017; } if ((num17 >= num20) && ((num17 != 3) || (num20 != 0))) { num29 = num17 + 1; goto TR_0017; } } } else { Vector3D vectord37 = (((vectord17 + vectord18) + vectord23) + vectord24) * 0.25; MyTransparentGeometry.AddBillboardOriented(ID_ARROW_LEFT_RED, Vector4.One, (vectord37 - ((this.RotationRightDirection * vectord25) * 0.20000000298023224)) - ((this.RotationUpDirection * vectord26) * 0.0099999997764825821), (Vector3)(-this.RotationForwardDirection * vectord27), (Vector3)(-this.RotationRightDirection * vectord25), 0.2f, num6, MyBillboard.BlendTypeEnum.LDR); MyTransparentGeometry.AddBillboardOriented(ID_ARROW_RIGHT_RED, Vector4.One, (vectord37 + ((this.RotationRightDirection * vectord25) * 0.20000000298023224)) - ((this.RotationUpDirection * vectord26) * 0.0099999997764825821), (Vector3)(this.RotationForwardDirection * vectord27), (Vector3)(this.RotationRightDirection * vectord25), 0.2f, num6, MyBillboard.BlendTypeEnum.LDR); MyRenderProxy.DebugDrawText3D((vectord37 - ((this.RotationRightDirection * vectord25) * 0.20000000298023224)) - ((this.RotationUpDirection * vectord26) * 0.0099999997764825821), str3, Color.White, num22, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, num6, false); MyRenderProxy.DebugDrawText3D((vectord37 + ((this.RotationRightDirection * vectord25) * 0.20000000298023224)) - ((this.RotationUpDirection * vectord26) * 0.0099999997764825821), str4, Color.White, num22, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, num6, false); goto TR_0013; } num29 = num17 - 1; flag8 = true; goto TR_0017; TR_0029: if (this.RotationRightDirection < 0) { flag7 = !flag7; } MyOrientedBoundingBox.GetNormalBetweenEdges(num13, num16, num28, out vector3); Vector3D vectord33 = Vector3D.TransformNormal(vector3, drawMatrix); MyTransparentGeometry.AddBillboardOriented(ID_ARROW_GREEN, Vector4.One, (vectord29 + (vectord30 * 0.40000000596046448)) - (vectord33 * 0.0099999997764825821), (Vector3)vectord25, (Vector3)vectord32, 0.5f, num6, MyBillboard.BlendTypeEnum.LDR); MyTransparentGeometry.AddBillboardOriented(ID_ARROW_GREEN, Vector4.One, (vectord31 + (vectord32 * 0.40000000596046448)) - (vectord33 * 0.0099999997764825821), (Vector3)vectord25, (Vector3)vectord30, 0.5f, num6, MyBillboard.BlendTypeEnum.LDR); MyRenderProxy.DebugDrawText3D((vectord29 + (vectord30 * 0.30000001192092896)) - (vectord33 * 0.0099999997764825821), flag7 ? controlButtonName : str2, Color.White, num22, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, num6, false); MyRenderProxy.DebugDrawText3D((vectord31 + (vectord32 * 0.30000001192092896)) - (vectord33 * 0.0099999997764825821), flag7 ? str2 : controlButtonName, Color.White, num22, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, num6, false); goto TR_0025; TR_002B: num28 = num16 - 1; flag7 = true; goto TR_0029; }
public void DebugDraw() { //if (m_lodIndex > 5) // return; // if (m_lodIndex == 1) // { // float sizeInMetres = MyVoxelCoordSystems.RenderCellSizeInMeters(m_lodIndex); // //var start = localFarCameraBox.Min; // //var end = localFarCameraBox.Max; // var start = m_localNearCameraBox.Min; // var end = m_localNearCameraBox.Max; // Vector3I coord = start; // Color nearColor = Color.Yellow; // Color farColor = Color.White; // var startF = m_localFarCameraBox.Min; // var endF = m_localFarCameraBox.Max; // Vector3I coordF = startF; //// for (var it = new Vector3I_RangeIterator(ref startF, ref endF); ////it.IsValid(); it.GetNext(out coordF)) //// { //// Vector3D min = Vector3D.Transform((Vector3D)(sizeInMetres * coordF), m_parent.m_worldMatrix); //// Vector3D max = Vector3D.Transform((Vector3D)(sizeInMetres * coordF + new Vector3(sizeInMetres)), m_parent.m_worldMatrix); //// BoundingBoxD aabb = new BoundingBoxD(min, max); //// MyRenderProxy.DebugDrawAABB(aabb, farColor, 1, 1, false); //// if (Vector3D.Distance(CameraFrustumGetter().Matrix.Translation, aabb.Center) < 200) //// MyRenderProxy.DebugDrawText3D(aabb.Center, coordF.ToString(), farColor, 0.5f, false); //// } // for (var it = new Vector3I_RangeIterator(ref start, ref end); //it.IsValid(); it.GetNext(out coord)) // { // Vector3D min = Vector3D.Transform((Vector3D)(sizeInMetres * coord), m_clipmap.m_worldMatrix); // Vector3D max = Vector3D.Transform((Vector3D)(sizeInMetres * coord + new Vector3(sizeInMetres)), m_clipmap.m_worldMatrix); // BoundingBoxD aabb = new BoundingBoxD(min, max); // MyRenderProxy.DebugDrawAABB(aabb, nearColor, 1, 1, false); // } // Vector3D center = Vector3D.Transform(m_localPosition, m_clipmap.m_worldMatrix); // MyRenderProxy.DebugDrawSphere(center, m_nearDistance, nearColor, 1, false); // MyRenderProxy.DebugDrawSphere(center, m_farDistance, farColor, 1, false); // } var camera = m_clipmap.LastCameraPosition; //if (m_lodIndex < 6) { float sizeInMetres = MyVoxelCoordSystems.RenderCellSizeInMeters(m_lodIndex); Color color = LOD_COLORS[m_lodIndex] + new Vector4(0.2f); foreach (var cell in m_storedCellData) { if (!cell.Value.InScene) { continue; } MyCellCoord cellStr = new MyCellCoord(); cellStr.SetUnpack(cell.Key); var coordF = cellStr.CoordInLod; Vector3D min = Vector3D.Transform((Vector3D)(sizeInMetres * coordF), m_clipmap.m_worldMatrix); Vector3D max = Vector3D.Transform((Vector3D)(sizeInMetres * coordF + new Vector3(sizeInMetres)), m_clipmap.m_worldMatrix); BoundingBoxD aabb = new BoundingBoxD(min, max); double distance = Vector3D.Distance(camera, aabb.Center); //if (distance < sizeInMetres * 4) MyRenderProxy.DebugDrawAABB(aabb, color, 1, 1, true); if (distance < sizeInMetres * 2) { MyRenderProxy.DebugDrawText3D(aabb.Center, String.Format("{0}:{1}", m_lodIndex, coordF.ToString()), color, 0.7f, false); } } if (m_storedCellData.Count > 0) { Vector3D center = Vector3D.Transform(m_localPosition, m_clipmap.m_worldMatrix); //MyRenderProxy.DebugDrawSphere(center, m_farDistance, color, 1, false); } } }
public static void RenderCellCoordToWorldAABB(Vector3D referenceVoxelMapPosition, ref MyCellCoord renderCell, out BoundingBoxD worldAABB) { RenderCellCoordToLocalAABB(ref renderCell, out worldAABB); worldAABB = worldAABB.Translate(referenceVoxelMapPosition); }
private bool QueryEmptyOrFull(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { ////return false; var bb = new BoundingBox(new Vector3(minX, minY, minZ), new Vector3(maxX, maxY, maxZ)); if (bb.Volume() < 100) return false; //bb.Translate(m_voxelMap.StorageMin); var result = m_voxelMap.Storage.Intersect(ref bb, false) != ContainmentType.Intersects; { var bbd = new BoundingBoxD(new Vector3(minX, minY, minZ) * 8, new Vector3(maxX, maxY, maxZ) * 8); bbd.Transform(Entity.WorldMatrix); var obb = new MyOrientedBoundingBoxD(bbd, Entity.WorldMatrix); MyRenderProxy.DebugDrawAABB(bbd, result ? Color.Green : Color.Red, 1, 1, false); } return result; }
public static void GeometryCellCoordToWorldAABB(Vector3D referenceVoxelMapPosition, ref Vector3I geometryCellCoord, out BoundingBoxD worldAABB) { Vector3D center; GeometryCellCoordToLocalPosition(ref geometryCellCoord, out center); LocalPositionToWorldPosition(referenceVoxelMapPosition, ref center, out center); worldAABB = new BoundingBoxD(center, center + MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES); }
// Iterate over sector boxes in a range. // TODO: Dumb version of this for small boxes private unsafe void RasterSectorsForPhysics(BoundingBoxD range) { range.InflateToMinimum(EnvironmentDefinition.SectorSize); Vector2I top = new Vector2I(1 << m_clipmaps[0].Depth) - 1; Vector3D* pos = stackalloc Vector3D[8]; range.GetCornersUnsafe(pos); // bitmask for faces, 7th bit is simple bit int markedFaces = 0; int firstFace = 0; for (var i = 0; i < 8; ++i) { Vector3D copy = pos[i]; int index = MyPlanetCubemapHelper.FindCubeFace(ref copy); firstFace = index; index = 1 << index; if ((markedFaces & ~index) != 0) markedFaces |= 0x40; markedFaces |= index; } // This way we can ensure a single code path. int startFace = 0; int endFace = 5; // If we only encounter one face we narrow it down. if ((markedFaces & 0x40) == 0) { startFace = endFace = firstFace; } for (int face = startFace; face <= endFace; ++face) { if (((1 << face) & markedFaces) == 0) continue; double size = m_clipmaps[face].LeafSize; // Offset var offset = 1 << m_clipmaps[face].Depth - 1; BoundingBox2D bounds = BoundingBox2D.CreateInvalid(); for (int i = 0; i < 8; ++i) { Vector3D copy = pos[i]; Vector2D normCoords; MyPlanetCubemapHelper.ProjectForFace(ref copy, face, out normCoords); bounds.Include(normCoords); } bounds.Min += 1; bounds.Min *= offset; bounds.Max += 1; bounds.Max *= offset; // Calculate bounds in sectors. var start = new Vector2I((int)bounds.Min.X, (int)bounds.Min.Y); var end = new Vector2I((int)bounds.Max.X, (int)bounds.Max.Y); Vector2I.Max(ref start, ref Vector2I.Zero, out start); Vector2I.Min(ref end, ref top, out end); for (int x = start.X; x <= end.X; ++x) for (int y = start.Y; y <= end.Y; ++y) { EnsurePhysicsSector(x, y, face); } } }
public static void VoxelCoordToWorldAABB(Vector3D referenceVoxelMapPosition, ref Vector3I voxelCoord, out BoundingBoxD worldAABB) { Vector3D worldCenter; VoxelCoordToWorldPosition(referenceVoxelMapPosition, ref voxelCoord, out worldCenter); worldAABB = new BoundingBoxD(worldCenter, worldCenter + MyVoxelConstants.VOXEL_SIZE_IN_METRES); }
private void UpdatePreview() { if (PreviewGrids == null) { return; } if (m_visible == false || HasPreviewBBox == false) { return; } // Switch off shadows - does not work //foreach (var grid in PreviewGrids) //{ // grid.Render.CastShadows = false; // foreach (var block in grid.GetBlocks()) // { // if (block.FatBlock != null) // { // block.FatBlock.Render.CastShadows = false; // } // } //} string lineMaterial = m_canBePlaced ? "GizmoDrawLine" : "GizmoDrawLineRed"; Color white = Color.White; foreach (var grid in PreviewGrids) { BoundingBoxD localAABB = (BoundingBoxD)grid.PositionComp.LocalAABB; MatrixD drawMatrix = grid.PositionComp.WorldMatrix; MySimpleObjectDraw.DrawTransparentBox(ref drawMatrix, ref localAABB, ref white, MySimpleObjectRasterizer.Wireframe, 1, 0.04f, lineMaterial: lineMaterial); //foreach (var block in grid.GetBlocks()) //{ // if (block.FatBlock != null) // MyEntities.EnableEntityBoundingBoxDraw(block.FatBlock, true, color, lineWidth: 0.04f); //} } Vector4 red = new Vector4(Color.Red.ToVector3() * 0.8f, 1); if (RemoveBlocksInMultiBlock.Count > 0) { m_tmpBlockPositionsSet.Clear(); MyCubeBuilder.GetAllBlocksPositions(RemoveBlocksInMultiBlock, m_tmpBlockPositionsSet); foreach (var position in m_tmpBlockPositionsSet) { MyCubeBuilder.DrawSemiTransparentBox(position, position, RemoveBlock.CubeGrid, red, lineMaterial: "GizmoDrawLineRed"); } m_tmpBlockPositionsSet.Clear(); } else if (RemoveBlock != null) { MyCubeBuilder.DrawSemiTransparentBox(RemoveBlock.CubeGrid, RemoveBlock, red, lineMaterial: "GizmoDrawLineRed"); } }
public override void RecalcPosition(Vector3D playerPosition) { base.RecalcPosition(playerPosition); Center = new Vector3D(_contentBounds.Center.X + 0.5f + PositionX, _contentBounds.Center.Y + 0.5f + PositionY, _contentBounds.Center.Z + 0.5f + PositionZ); WorldAABB = new BoundingBoxD(PositionAndOrientation.Value.Position, PositionAndOrientation.Value.Position + new Vector3D(Size)); }