protected bool CubeExistsOnPosition(Vector3I pos) { MySlimBlock block = m_grid.GetCubeBlock(pos); if (block != null) { if (block.FatBlock is MyCompoundCubeBlock) { MyCompoundCubeBlock compoundBlock = block.FatBlock as MyCompoundCubeBlock; foreach (var blockInCompound in compoundBlock.GetBlocks()) { if (!blockInCompound.BlockDefinition.IsGeneratedBlock) { return(true); } } } else { if (!block.BlockDefinition.IsGeneratedBlock) { return(true); } } } return(false); }
private bool IsPressurized(Vector3I startPos, Vector3I endPos) { var startBlock = m_cubeGrid.GetCubeBlock(startPos); var endBlock = m_cubeGrid.GetCubeBlock(endPos); if (startBlock == endBlock) { if (startBlock != null) { return(startBlock.BlockDefinition.IsAirTight); } else { return(false); } } if (startBlock != null && (startBlock.BlockDefinition.IsAirTight || IsPressurized(startBlock, startPos, endPos - startPos))) { return(true); } else { return(endBlock != null && (endBlock.BlockDefinition.IsAirTight || IsPressurized(endBlock, endPos, startPos - endPos))); } }
/// <summary> /// Action distance is taken into account /// </summary> protected MySlimBlock GetTargetBlock() { if (ReachesCube(m_toolActionDistance) && m_targetGrid != null) { return(m_targetGrid.GetCubeBlock(m_targetCube)); } return(null); }
public void AddConveyorBlock(IMyConveyorEndpointBlock endpointBlock) { if (endpointBlock is MyShipConnector) { m_connectors.Add(endpointBlock as MyShipConnector); } m_tmpConveyorPositionList.Clear(); var endpoint = endpointBlock.ConveyorEndpoint; for (int i = 0; i < endpoint.GetLineCount(); ++i) { var position = endpoint.GetPosition(i); var line = endpoint.GetConveyorLine(i); if (m_deserializedLines != null && m_deserializedLines.Contains(line)) { continue; } var otherBlock = m_grid.GetCubeBlock(position.NeighbourGridPosition); if (otherBlock == null) { m_lines.Add(line); continue; } var otherEndpointBlock = otherBlock.FatBlock as IMyConveyorEndpointBlock; var otherSegmentBlock = otherBlock.FatBlock as IMyConveyorSegmentBlock; if (otherSegmentBlock != null) { if (!TryMergeEndpointSegment(endpointBlock, otherSegmentBlock, position)) { m_lines.Add(line); } } else if (otherEndpointBlock != null) { if (!TryMergeEndpointEndpoint(endpointBlock, otherEndpointBlock, position, position.GetConnectingPosition())) { m_lines.Add(line); } } else { m_lines.Add(line); } } m_tmpConveyorPositionList.Clear(); }
static void GetIntVectorsInSphere(MyCubeGrid grid, Vector3I center, double radius, List <RadiatedBlock> points) { points.Clear(); radius *= grid.GridSizeR; double radiusSq = radius * radius; int radiusCeil = (int)Math.Ceiling(radius); int i, j, k; for (i = -radiusCeil; i <= radiusCeil; ++i) { for (j = -radiusCeil; j <= radiusCeil; ++j) { for (k = -radiusCeil; k <= radiusCeil; ++k) { if (i * i + j * j + k * k < radiusSq) { var vector3I = center + new Vector3I(i, j, k); IMySlimBlock slim = grid.GetCubeBlock(vector3I); if (slim != null) { var radiatedBlock = new RadiatedBlock { Center = center, Slim = slim, Position = vector3I }; points.Add(radiatedBlock); } } } } } }
private void MyCubeGridsOnBlockBuilt(MyCubeGrid myCubeGrid, MySlimBlock mySlimBlock) { if (mySlimBlock == null || !myCubeGrid.IsStatic) { return; } // Avoid multiple queues for compound block additions. var slimBlock = myCubeGrid.GetCubeBlock(mySlimBlock.Min); if (slimBlock != null) { var compound = slimBlock.FatBlock as MyCompoundCubeBlock; if (compound != null && mySlimBlock.FatBlock != compound) { return; } } BoundingBoxD blockAabb; mySlimBlock.GetWorldBoundingBox(out blockAabb, true); m_cubeBlocksPending.Add(myCubeGrid, blockAabb); //Debug.Print("CubeGrid {0}: Block added at {1}.", myCubeGrid, mySlimBlock.Position); }
static void OnRemoveShapeFromFractureComponentMessage(ref RemoveShapeFromFractureComponentMsg msg, MyNetworkClient sender) { Debug.Assert(!Sync.IsServer); Debug.Assert(msg.ShapeNames != null && msg.ShapeNames.Length > 0); MyEntity entity; if (MyEntities.TryGetEntityById(msg.Grid, out entity)) { MyCubeGrid grid = entity as MyCubeGrid; var cubeBlock = grid.GetCubeBlock(msg.Position); if (cubeBlock != null && cubeBlock.FatBlock != null) { var compound = cubeBlock.FatBlock as MyCompoundCubeBlock; if (compound != null) { var blockInCompound = compound.GetBlock(msg.CompoundBlockId); if (blockInCompound != null) { RemoveFractureComponentChildShapes(blockInCompound, msg.ShapeNames); } } else { RemoveFractureComponentChildShapes(cubeBlock, msg.ShapeNames); } } } }
public virtual bool IsTargetValid() { switch (this.m_currentTarget) { case MyAiTargetEnum.GRID: case MyAiTargetEnum.ENTITY: return(this.IsEntityReachable(this.m_targetEntity)); case MyAiTargetEnum.CUBE: case MyAiTargetEnum.COMPOUND_BLOCK: { MyCubeGrid targetEntity = this.m_targetEntity as MyCubeGrid; if (targetEntity == null) { return(false); } MySlimBlock cubeBlock = targetEntity.GetCubeBlock(this.m_targetCube); return((cubeBlock != null) ? ((cubeBlock.FatBlock == null) ? this.IsEntityReachable(targetEntity) : this.IsEntityReachable(cubeBlock.FatBlock)) : false); } case MyAiTargetEnum.CHARACTER: { MyCharacter targetEntity = this.m_targetEntity as MyCharacter; return((targetEntity != null) && this.IsEntityReachable(targetEntity)); } case MyAiTargetEnum.ENVIRONMENT_ITEM: case MyAiTargetEnum.VOXEL: return(true); } return(false); }
static void OnCreateFractureComponentMessage(long gridId, Vector3I position, ushort compoundBlockId, [Serialize(MyObjectFlags.Dynamic, DynamicSerializerType = typeof(MyObjectBuilderDynamicSerializer))] MyObjectBuilder_FractureComponentBase component) { MyEntity entity; if (MyEntities.TryGetEntityById(gridId, out entity)) { MyCubeGrid grid = entity as MyCubeGrid; var cubeBlock = grid.GetCubeBlock(position); if (cubeBlock != null && cubeBlock.FatBlock != null) { var compound = cubeBlock.FatBlock as MyCompoundCubeBlock; if (compound != null) { var blockInCompound = compound.GetBlock(compoundBlockId); if (blockInCompound != null) { AddFractureComponent(component, blockInCompound.FatBlock); } } else { AddFractureComponent(component, cubeBlock.FatBlock); } } } }
static void OnCreateFractureComponentMessage(ref CreateFractureComponentMsg msg, MyNetworkClient sender) { Debug.Assert(!Sync.IsServer); MyEntity entity; if (MyEntities.TryGetEntityById(msg.Grid, out entity)) { MyCubeGrid grid = entity as MyCubeGrid; var cubeBlock = grid.GetCubeBlock(msg.Position); if (cubeBlock != null && cubeBlock.FatBlock != null) { var compound = cubeBlock.FatBlock as MyCompoundCubeBlock; if (compound != null) { var blockInCompound = compound.GetBlock(msg.CompoundBlockId); if (blockInCompound != null) { AddFractureComponent(msg.FractureComponent, blockInCompound.FatBlock); } } else { AddFractureComponent(msg.FractureComponent, cubeBlock.FatBlock); } } } }
static void OnRemoveShapeFromFractureComponentMessage(long gridId, Vector3I position, ushort compoundBlockId, string[] shapeNames) { Debug.Assert(shapeNames != null && shapeNames.Length > 0); MyEntity entity; if (MyEntities.TryGetEntityById(gridId, out entity)) { MyCubeGrid grid = entity as MyCubeGrid; var cubeBlock = grid.GetCubeBlock(position); if (cubeBlock != null && cubeBlock.FatBlock != null) { var compound = cubeBlock.FatBlock as MyCompoundCubeBlock; if (compound != null) { var blockInCompound = compound.GetBlock(compoundBlockId); if (blockInCompound != null) { RemoveFractureComponentChildShapes(blockInCompound, shapeNames); } } else { RemoveFractureComponentChildShapes(cubeBlock, shapeNames); } } } }
private bool CanWeldTo(MyEntity entity, ref Matrix otherBodySpacePivot) { if (BreakForce < MyObjectBuilder_LandingGear.MaxSolverImpulse) { return(false); } MyCubeGrid grid = entity as MyCubeGrid; if (grid == null) { var block = entity as MyCubeBlock; if (block != null) { grid = block.CubeGrid; } } if (grid != null) { Vector3I cube; grid.FixTargetCube(out cube, otherBodySpacePivot.Translation * grid.GridSizeR); var hangar = grid.GetCubeBlock(cube); if (hangar != null && hangar.FatBlock is MyAirtightHangarDoor) { return(false); } } else if (entity.Parent != null) { return(false); } return(true); }
public static Vector3D?GetLineIntersectionExactAll(MyCubeGrid grid, ref LineD line, out double distance, out IMySlimBlock intersectedBlock) { intersectedBlock = (IMySlimBlock)null; distance = 3.40282346638529E+38; Vector3I?nullable = new Vector3I?(); Vector3I zero = Vector3I.Zero; double distanceSquared = double.MaxValue; if (grid.GetLineIntersectionExactGrid(ref line, ref zero, ref distanceSquared)) { distanceSquared = Math.Sqrt(distanceSquared); nullable = new Vector3I?(zero); } if (!nullable.HasValue) { return(new Vector3D?()); } distance = distanceSquared; intersectedBlock = grid.GetCubeBlock(nullable.Value); if (intersectedBlock == null) { return(new Vector3D?()); } return(new Vector3D?((Vector3D)zero)); }
/// <summary> /// <param name="sync"></param> arg determines if it sends the paint request using the API, and automatically checks skin ownership. Must be false for mod-added skins. /// </summary> public void PaintBlock(bool sync, IMyCubeGrid grid, Vector3I gridPosition, PaintMaterial paint, ulong originalSenderSteamId) { IMySlimBlock slim = grid.GetCubeBlock(gridPosition); if (sync) { grid.SkinBlocks(gridPosition, gridPosition, paint.ColorMask, paint.Skin?.String); if (paint.Skin.HasValue) { // check if skin was applied to alert player CheckSkinned[slim] = new CheckData(paint.Skin.Value); // add or replace SetUpdateMethods(UpdateFlags.UPDATE_AFTER_SIM, true); } } else { // NOTE getting a MySlimBlock and sending it straight to arguments avoids getting prohibited errors. MyCubeGrid gridInternal = (MyCubeGrid)grid; gridInternal.ChangeColorAndSkin(gridInternal.GetCubeBlock(gridPosition), paint.ColorMask, paint.Skin); if (paint.Skin.HasValue) { CheckSkinned.Remove(slim); // prevent alerting if skin gets changed into an always-owned one } } }
protected override void DrawHud() { MyHud.BlockInfo.Visible = false; if (m_targetProjectionCube == null || m_targetProjectionGrid == null) { base.DrawHud(); return; } var block = m_targetProjectionGrid.GetCubeBlock(m_targetProjectionCube); if (block == null) { base.DrawHud(); return; } // Get first block from compound. if (MyFakes.ENABLE_COMPOUND_BLOCKS && block.FatBlock is MyCompoundCubeBlock) { MyCompoundCubeBlock compoundBlock = block.FatBlock as MyCompoundCubeBlock; if (compoundBlock.GetBlocksCount() > 0) { block = compoundBlock.GetBlocks().First(); } else { Debug.Assert(false); } } MyHud.BlockInfo.Visible = true; MyHud.BlockInfo.MissingComponentIndex = 0; MyHud.BlockInfo.BlockName = block.BlockDefinition.DisplayNameText; MyHud.BlockInfo.BlockIcons = block.BlockDefinition.Icons; MyHud.BlockInfo.BlockIntegrity = 0.01f; MyHud.BlockInfo.CriticalIntegrity = block.BlockDefinition.CriticalIntegrityRatio; MyHud.BlockInfo.CriticalComponentIndex = block.BlockDefinition.CriticalGroup; MyHud.BlockInfo.OwnershipIntegrity = block.BlockDefinition.OwnershipIntegrityRatio; //SetBlockComponents(MyHud.BlockInfo, block); MyHud.BlockInfo.Components.Clear(); for (int i = 0; i < block.ComponentStack.GroupCount; i++) { var info = block.ComponentStack.GetGroupInfo(i); var component = new MyHudBlockInfo.ComponentInfo(); component.DefinitionId = info.Component.Id; component.ComponentName = info.Component.DisplayNameText; component.Icons = info.Component.Icons; component.TotalCount = info.TotalCount; component.MountedCount = 0; component.StockpileCount = 0; MyHud.BlockInfo.Components.Add(component); } }
protected void CreateRotorGrid(out MyCubeGrid rotorGrid, out MyAttachableTopBlockBase rotorBlock, long builtBy, MyCubeBlockDefinitionGroup rotorGroup) { Debug.Assert(Sync.IsServer, "Rotor grid can be created only on server"); if (rotorGroup == null) { rotorGrid = null; rotorBlock = null; return; } var gridSize = CubeGrid.GridSizeEnum; float size = MyDefinitionManager.Static.GetCubeSize(gridSize); var matrix = MatrixD.CreateWorld(Vector3D.Transform(DummyPosition, CubeGrid.WorldMatrix), WorldMatrix.Forward, WorldMatrix.Up); var definition = rotorGroup[gridSize]; Debug.Assert(definition != null); var block = MyCubeGrid.CreateBlockObjectBuilder(definition, Vector3I.Zero, MyBlockOrientation.Identity, MyEntityIdentifier.AllocateId(), OwnerId, fullyBuilt: MySession.Static.CreativeMode); var gridBuilder = MyObjectBuilderSerializer.CreateNewObject <MyObjectBuilder_CubeGrid>(); gridBuilder.GridSizeEnum = gridSize; gridBuilder.IsStatic = false; gridBuilder.PositionAndOrientation = new MyPositionAndOrientation(matrix); gridBuilder.CubeBlocks.Add(block); var grid = MyEntityFactory.CreateEntity <MyCubeGrid>(gridBuilder); grid.Init(gridBuilder); rotorGrid = grid; MyMotorRotor rotor = (MyMotorRotor)rotorGrid.GetCubeBlock(Vector3I.Zero).FatBlock; rotorBlock = rotor; rotorGrid.PositionComp.SetPosition(rotorGrid.WorldMatrix.Translation - (Vector3D.Transform(rotor.DummyPosLoc, rotorGrid.WorldMatrix) - rotorGrid.WorldMatrix.Translation)); if (!CanPlaceRotor(rotorBlock, builtBy)) { rotorGrid = null; rotorBlock = null; grid.Close(); return; } MyEntities.Add(grid); if (MyFakes.ENABLE_SENT_GROUP_AT_ONCE) { MyMultiplayer.ReplicateImmediatelly(MyExternalReplicable.FindByObject(grid), MyExternalReplicable.FindByObject(CubeGrid)); } MatrixD masterToSlave = rotorBlock.CubeGrid.WorldMatrix * MatrixD.Invert(WorldMatrix); m_connectionState.Value = new State() { TopBlockId = rotorBlock.EntityId, MasterToSlave = masterToSlave }; }
private void CreateTopGrid(out MyCubeGrid topGrid, out MyAttachableTopBlockBase topBlock, long builtBy, MyCubeBlockDefinitionGroup topGroup) { if (topGroup == null) { topGrid = null; topBlock = null; return; } var gridSize = CubeGrid.GridSizeEnum; float size = MyDefinitionManager.Static.GetCubeSize(gridSize); var matrix = GetTopGridMatrix(); var definition = topGroup[gridSize]; Debug.Assert(definition != null); var block = MyCubeGrid.CreateBlockObjectBuilder(definition, Vector3I.Zero, MyBlockOrientation.Identity, MyEntityIdentifier.AllocateId(), OwnerId, fullyBuilt: MySession.Static.CreativeMode); var gridBuilder = MyObjectBuilderSerializer.CreateNewObject <MyObjectBuilder_CubeGrid>(); gridBuilder.GridSizeEnum = gridSize; gridBuilder.IsStatic = false; gridBuilder.PositionAndOrientation = new MyPositionAndOrientation(matrix); gridBuilder.CubeBlocks.Add(block); var grid = MyEntityFactory.CreateEntity <MyCubeGrid>(gridBuilder); grid.Init(gridBuilder); topGrid = grid; topBlock = (MyAttachableTopBlockBase)topGrid.GetCubeBlock(Vector3I.Zero).FatBlock; if (!CanPlaceTop(topBlock, builtBy)) { topGrid = null; topBlock = null; grid.Close(); return; } //topGrid.SetPosition(topGrid.WorldMatrix.Translation - (topBlock.WorldMatrix.Translation/*Vector3.Transform(topBlock.DummyPosLoc, topGrid.WorldMatrix) - topGrid.WorldMatrix.Translation*/)); MyEntities.Add(grid); if (MyFakes.ENABLE_SENT_GROUP_AT_ONCE) { MyMultiplayer.ReplicateImmediatelly(MyExternalReplicable.FindByObject(grid), MyExternalReplicable.FindByObject(CubeGrid)); } MatrixD masterToSlave = topBlock.CubeGrid.WorldMatrix * MatrixD.Invert(WorldMatrix); m_connectionState.Value = new State() { TopBlockId = topBlock.EntityId, MasterToSlave = masterToSlave }; }
public void OnWorldPosChanged(ref MatrixD newTransform) { MatrixD worldPos = newTransform; m_caster.OnWorldPositionChanged(ref worldPos); var entitiesInRange = this.m_caster.EntitiesInRange; float closestDistance = float.MaxValue; MyEntity closestEntity = null; int itemId = 0; if (!m_isPointOfRefSet) { m_pointOfReference = worldPos.Translation; } if (entitiesInRange != null && entitiesInRange.Count > 0) { // int i = 0; foreach (var entity in entitiesInRange.Values) { float distanceSq = (float)Vector3D.DistanceSquared(entity.DetectionPoint, m_pointOfReference); if (entity.Entity.Physics != null && entity.Entity.Physics.Enabled) { if (distanceSq < closestDistance) { closestEntity = entity.Entity; itemId = entity.ItemId; this.m_distanceToHitSq = distanceSq; this.m_hitPosition = entity.DetectionPoint; closestDistance = distanceSq; } } // ++i; } } this.m_hitCubeGrid = closestEntity as MyCubeGrid; this.m_hitBlock = null; this.m_hitDestroaybleObj = closestEntity as IMyDestroyableObject; this.m_hitFloatingObject = closestEntity as MyFloatingObject; this.m_hitCharacter = closestEntity as MyCharacter; this.m_hitEnvironmentSector = closestEntity as MyEnvironmentSector; this.m_environmentItem = itemId; if (m_hitCubeGrid != null) { var invWorld = m_hitCubeGrid.PositionComp.WorldMatrixNormalizedInv; var gridLocalPos = Vector3D.Transform(this.m_hitPosition, invWorld); Vector3I blockPos; m_hitCubeGrid.FixTargetCube(out blockPos, gridLocalPos / m_hitCubeGrid.GridSize); m_hitBlock = m_hitCubeGrid.GetCubeBlock(blockPos); } }
protected virtual bool TryDrillBlocks(MyCubeGrid grid, Vector3 worldPoint, bool onlyCheck, out MyStringHash blockMaterial) { var invWorld = grid.PositionComp.WorldMatrixNormalizedInv; var gridLocalPosCenter = Vector3.Transform(m_sensor.Center, invWorld); var gridLocalPos = Vector3.Transform(m_sensor.FrontPoint, invWorld); var gridLocalTarget = Vector3.Transform(worldPoint, invWorld); var gridSpacePos = Vector3I.Round(gridLocalPos / grid.GridSize); var block = grid.GetCubeBlock(gridSpacePos); if (block != null) { if (block.BlockDefinition.PhysicalMaterial.Id.SubtypeId == MyStringHash.NullOrEmpty) { blockMaterial = m_metalMaterial; } else { blockMaterial = block.BlockDefinition.PhysicalMaterial.Id.SubtypeId; } } else { blockMaterial = MyStringHash.NullOrEmpty; } int createDebris = 0; if (!onlyCheck) { if (block != null && block is IMyDestroyableObject && block.CubeGrid.BlocksDestructionEnabled) { var destroyable = (block as IMyDestroyableObject); destroyable.DoDamage(60, MyDamageType.Drill, Sync.IsServer, attackerId: m_drillEntity != null ? m_drillEntity.EntityId : 0); createDebris = grid.Physics.ApplyDeformation(0.25f, 1.5f, 2f, gridLocalTarget, Vector3.Normalize(gridLocalPos - gridLocalPosCenter), MyDamageType.Drill, attackerId: m_drillEntity != null ? m_drillEntity.EntityId : 0); } } m_target = createDebris != 0 ? null : block; bool success = false; if (block != null) { if (createDebris != 0) { BoundingSphereD bsphere = m_cutOut.Sphere; BoundingBoxD aabb = BoundingBoxD.CreateFromSphere(bsphere); MyDebris.Static.CreateExplosionDebris(ref bsphere, block.CubeGrid, ref aabb, 0.3f); } success = true; } return(success); }
private bool UpdateProjection(MyCubeBlock projector, MyCubeGrid projectedGrid, MyObjectBuilder_ProjectorBase projectorBuilder) { // god f*****g damnit object builders MyCubeGrid cubeGrid = projector.CubeGrid; MyObjectBuilder_CubeGrid gridBuilder = (MyObjectBuilder_CubeGrid)projectedGrid.GetObjectBuilder(); bool found = false; foreach (MyObjectBuilder_CubeBlock blockBuilder in gridBuilder.CubeBlocks) { Vector3 worldPosition = projectedGrid.GridIntegerToWorld(blockBuilder.Min); Vector3I realPosition = cubeGrid.WorldToGridInteger(worldPosition); var realBlock = (IMySlimBlock)cubeGrid.GetCubeBlock(realPosition); MyCubeBlockDefinition blockDefinition; MyDefinitionManager.Static.TryGetCubeBlockDefinition(blockBuilder.GetId(), out blockDefinition); if (realBlock != null) // && blockDefinition.Id == new MyDefinitionId(realBlock.GetType())) { //Logging.Instance.WriteLine(string.Format("Found overlap - {0} {1}", blockBuilder.GetId(), realBlock.GetObjectBuilder().GetId())); } else { //Logging.Instance.WriteLine(string.Format("No block at position: {0}", blockBuilder.GetId())); if (CanBuildBlock(blockBuilder, projectedGrid, projector, cubeGrid, projectorBuilder)) { //Logging.Instance.WriteLine(string.Format("No block at position: {0}", blockBuilder.GetId())); var slimBlock = (IMySlimBlock)projectedGrid.GetCubeBlock(blockBuilder.Min); if (slimBlock != null && slimBlock.CubeGrid.GetPosition() != Vector3D.Zero) { //Logging.Instance.WriteLine(string.Format("Adding block: {0}", blockBuilder.GetId())); PotentialTargetList.Add(slimBlock); found = true; } } else { using (m_lock.AcquireExclusiveUsing()) { foreach (var item in blockDefinition.Components) { if (!ComponentsRequired.ContainsKey(item.Definition.Id.SubtypeName)) { ComponentsRequired.Add(item.Definition.Id.SubtypeName, item.Count); } else { ComponentsRequired[item.Definition.Id.SubtypeName] += item.Count; } } } } } } return(found); }
/// <summary> /// Move blocks in m_projectedBlocks to m_damagedBlocks if they are touching any real blocks /// </summary> private void ProjectedToDamaged() { foreach (IMySlimBlock block in m_projectedBlocks) { MyCubeGrid projected = (MyCubeGrid)block.CubeGrid; MyCubeGrid projectorGrid = projected.Projector.CubeGrid; if (projected.Closed || projected.Projector.Closed || !projected.Projector.IsWorking || projectorGrid.Closed) { Log.DebugLog("projection closed"); continue; } Vector3I min = projectorGrid.WorldToGridInteger(projected.GridIntegerToWorld(block.Min())); if (projectorGrid.GetCubeBlock(min) != null) { Log.DebugLog("space is occupied: " + min); m_projectedBlocks.Remove(block); continue; } IMyCubeBlock cubeBlock = block.FatBlock; if (cubeBlock != null) { Vector3I max = projectorGrid.WorldToGridInteger(projected.GridIntegerToWorld(block.Max())); MatrixD invOrient = projectorGrid.PositionComp.WorldMatrixNormalizedInv.GetOrientation(); Vector3 forward = Vector3D.Transform(cubeBlock.WorldMatrix.Forward, ref invOrient); Vector3 up = Vector3D.Transform(cubeBlock.WorldMatrix.Up, ref invOrient); MyBlockOrientation orient = new MyBlockOrientation(Base6Directions.GetClosestDirection(ref forward), Base6Directions.GetClosestDirection(ref up)); if (projectorGrid.CanPlaceBlock(min, max, orient, ((MyCubeBlock)cubeBlock).BlockDefinition)) { Log.DebugLog("can place fatblock: " + cubeBlock.DisplayNameText + ", position: " + min + ", world: " + projectorGrid.GridIntegerToWorld(min)); m_damagedBlocks.Add(block); m_projectedBlocks.Remove(block); } continue; } // no fatblock, cannot get definition if (projectorGrid.IsTouchingAnyNeighbor(min, min)) { Log.DebugLog("can place slimblock: " + block.ToString() + ", position: " + min + ", world: " + projectorGrid.GridIntegerToWorld(min)); m_damagedBlocks.Add(block); m_projectedBlocks.Remove(block); } } m_projectedBlocks.ApplyRemovals(); }
/// <summary> /// Intended for quite small refreshes (few blocks). /// Collect is faster for large refresh. /// Removes also dirty mass elements. /// </summary> public void CollectArea(MyCubeGrid grid, HashSet <Vector3I> dirtyBlocks, MyVoxelSegmentation segmenter, MyVoxelSegmentationType segmentationType, IDictionary <Vector3I, HkMassElement> massResults) { ProfilerShort.Begin("Remove dirty"); foreach (var pos in dirtyBlocks) { if (massResults != null) { massResults.Remove(pos); } var block = grid.GetCubeBlock(pos); if (block != null) { if (DisabledBlocks != null && DisabledBlocks.ContainsKey(block)) { continue; } m_tmpRefreshSet.Add(block); } } ProfilerShort.End(); ProfilerShort.Begin("Add new"); foreach (var block in m_tmpRefreshSet) { if (block.FatBlock is MyCompoundCubeBlock) { ProfilerShort.Begin("Collect compound"); CollectCompoundBlock((MyCompoundCubeBlock)block.FatBlock, massResults); //Debug.Assert(IsValid(), "Overlapping shapes detected, block shapes cannot overlap!"); ProfilerShort.End(); } else { ProfilerShort.Begin("Collect block"); CollectBlock(block, block.BlockDefinition.PhysicsOption, massResults); //Debug.Assert(IsValid(), "Overlapping shapes detected, block shapes cannot overlap!"); ProfilerShort.End(); } } ProfilerShort.End(); ProfilerShort.Begin("IsValidTest"); Debug.Assert(IsValid(), "Overlapping shapes detected, block shapes cannot overlap! Uncomment upper asserts to find what block caused this"); ProfilerShort.End(); ProfilerShort.Begin("Add segments"); AddSegmentedParts(grid.GridSize, segmenter, segmentationType); ProfilerShort.End(); m_tmpCubes.Clear(); m_tmpRefreshSet.Clear(); // Clear is required, we certainly don't want to hold last reference to blocks }
protected void CreateRotorGrid(out MyCubeGrid rotorGrid, out MyMotorRotor rotorBlock, long builtBy, MyCubeBlockDefinitionGroup rotorGroup) { if (rotorGroup == null) { CreateRotorGridFailed(builtBy, out rotorGrid, out rotorBlock); return; } var gridSize = CubeGrid.GridSizeEnum; float size = MyDefinitionManager.Static.GetCubeSize(gridSize); var matrix = MatrixD.CreateWorld(Vector3D.Transform(DummyPosition, CubeGrid.WorldMatrix), WorldMatrix.Forward, WorldMatrix.Up); var definition = rotorGroup[gridSize]; Debug.Assert(definition != null); var block = MyCubeGrid.CreateBlockObjectBuilder(definition, Vector3I.Zero, MyBlockOrientation.Identity, MyEntityIdentifier.AllocateId(), OwnerId, fullyBuilt: MySession.Static.CreativeMode); var gridBuilder = MyObjectBuilderSerializer.CreateNewObject <MyObjectBuilder_CubeGrid>(); gridBuilder.GridSizeEnum = gridSize; gridBuilder.IsStatic = false; gridBuilder.PositionAndOrientation = new MyPositionAndOrientation(matrix); gridBuilder.CubeBlocks.Add(block); var grid = MyEntityFactory.CreateEntity <MyCubeGrid>(gridBuilder); grid.Init(gridBuilder); rotorGrid = grid; rotorBlock = (MyMotorRotor)rotorGrid.GetCubeBlock(Vector3I.Zero).FatBlock; rotorGrid.PositionComp.SetPosition(rotorGrid.WorldMatrix.Translation - (Vector3D.Transform(rotorBlock.DummyPosLoc, rotorGrid.WorldMatrix) - rotorGrid.WorldMatrix.Translation)); if (!CanPlaceRotor(rotorBlock, builtBy)) { CreateRotorGridFailed(builtBy, out rotorGrid, out rotorBlock); grid.Close(); return; } if (Sync.IsServer) { MyEntities.Add(grid); MySyncCreate.SendEntityCreated(grid.GetObjectBuilder()); } else { grid.Close(); } }
/// <summary> /// Tests a line for intersection with models of blocks on the grid. /// </summary> public static bool Intersects(this MyCubeGrid grid, ref LineD localLine, List <Vector3I> rayCastPositions, out MyIntersectionResultLineTriangleEx?result, IntersectionFlags flags = DefaultFlags) { rayCastPositions.Clear(); grid.RayCastCellsLocal(ref localLine.From, ref localLine.To, rayCastPositions); for (int i = 0; i < rayCastPositions.Count; i++) { MySlimBlock slim = grid.GetCubeBlock(rayCastPositions[i]); if (slim != null && Intersects(slim, ref localLine, out result, flags)) { return(true); } } result = null; return(false); }
static MySlimBlock GetContactBlock(MyCubeGrid grid, Vector3D worldPosition, float graceDistance) { graceDistance = Math.Max(Math.Abs(graceDistance), grid.GridSize * 0.2f); graceDistance += 1f; MatrixD invWorld = grid.PositionComp.GetWorldMatrixNormalizedInv(); Vector3D localVelocity = Vector3D.TransformNormal(grid.Physics.LinearVelocity * Sandbox.Common.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS, invWorld); Vector3D localPos; Vector3D.Transform(ref worldPosition, ref invWorld, out localPos); // MW:TODO optimize var min1 = Vector3I.Round((localPos - graceDistance - localVelocity) / grid.GridSize); var max1 = Vector3I.Round((localPos + graceDistance + localVelocity) / grid.GridSize); var min2 = Vector3I.Round((localPos + graceDistance - localVelocity) / grid.GridSize); var max2 = Vector3I.Round((localPos - graceDistance + localVelocity) / grid.GridSize); Vector3I min = Vector3I.Min(Vector3I.Min(Vector3I.Min(min1, max1), min2), max2); Vector3I max = Vector3I.Max(Vector3I.Max(Vector3I.Max(min1, max1), min2), max2); MySlimBlock resultBlock = null; float distSq = float.MaxValue; // TODO: optimize this, it should be possible using normal from contact Vector3I pos; for (pos.X = min.X; pos.X <= max.X; pos.X++) { for (pos.Y = min.Y; pos.Y <= max.Y; pos.Y++) { for (pos.Z = min.Z; pos.Z <= max.Z; pos.Z++) { var block = grid.GetCubeBlock(pos); if (block != null) { var testDistSq = (float)(pos * grid.GridSize - localPos).LengthSquared(); if (testDistSq < distSq) { distSq = testDistSq; resultBlock = block; } } } } } return(resultBlock); }
public virtual bool IsTargetValid() { switch (m_currentTarget) { case MyAiTargetEnum.CHARACTER: { MyCharacter target = m_targetEntity as MyCharacter; return(target != null && IsEntityReachable(target)); } case MyAiTargetEnum.CUBE: case MyAiTargetEnum.COMPOUND_BLOCK: { MyCubeGrid target = m_targetEntity as MyCubeGrid; if (target == null) { return(false); } MySlimBlock block = target.GetCubeBlock(m_targetCube); if (block == null) { return(false); } if (block.FatBlock != null) { return(IsEntityReachable(block.FatBlock)); } else { return(IsEntityReachable(target)); } } case MyAiTargetEnum.VOXEL: case MyAiTargetEnum.ENVIRONMENT_ITEM: return(true); case MyAiTargetEnum.ENTITY: case MyAiTargetEnum.GRID: return(IsEntityReachable(m_targetEntity)); default: return(false); } }
internal void Init(MyObjectBuilder_BlockGroup builder) { Debug.Assert(m_grid != null); Name.Clear().Append(builder.Name); foreach (var blockPosition in builder.Blocks) { var slimBlock = m_grid.GetCubeBlock(blockPosition); if (slimBlock != null) { MyTerminalBlock block = slimBlock.FatBlock as MyTerminalBlock; if (block != null) { Blocks.Add(block); continue; } } //Can happen when grid is split //Debug.Fail("Block in group not found!"); } }
protected virtual bool TryDrillBlocks(MyCubeGrid grid, Vector3 worldPoint, bool onlyCheck) { var invWorld = grid.PositionComp.GetWorldMatrixNormalizedInv(); var gridLocalPosCenter = Vector3.Transform(m_sensor.Center, invWorld); var gridLocalPos = Vector3.Transform(m_sensor.FrontPoint, invWorld); var gridLocalTarget = Vector3.Transform(worldPoint, invWorld); var gridSpacePos = Vector3I.Round(gridLocalPos / grid.GridSize); var block = grid.GetCubeBlock(gridSpacePos); bool createDebris = false; if (!onlyCheck && MySession.Static.DestructibleBlocks) { if (block != null && block is IMyDestroyableObject) { var destroyable = (block as IMyDestroyableObject); destroyable.DoDamage(60, MyDamageType.Drill, Sync.IsServer); } createDebris = grid.Physics.ApplyDeformation(0.25f, 1.5f, 2f, gridLocalTarget, Vector3.Normalize(gridLocalPos - gridLocalPosCenter), MyDamageType.Drill); } m_target = createDebris ? null : block; bool success = false; if (block != null) { if (createDebris) { BoundingSphereD bsphere = m_cutOut.Sphere; BoundingBoxD aabb = BoundingBoxD.CreateFromSphere(bsphere); MyDebris.Static.CreateExplosionDebris(ref bsphere, block.CubeGrid, ref aabb, 0.3f); } success = true; } return(success); }
private void CreateTopGrid(out MyCubeGrid topGrid, out MyPistonTop topBlock, MyCubeBlockDefinitionGroup topGroup) { if (topGroup == null) { topGrid = null; topBlock = null; return; } var gridSize = CubeGrid.GridSizeEnum; float size = MyDefinitionManager.Static.GetCubeSize(gridSize); var matrix = MatrixD.CreateWorld(Vector3D.Transform(m_constraintBasePos, Subpart3.WorldMatrix), WorldMatrix.Forward, WorldMatrix.Up); var definition = topGroup[gridSize]; Debug.Assert(definition != null); var block = MyCubeGrid.CreateBlockObjectBuilder(definition, Vector3I.Zero, MyBlockOrientation.Identity, MyEntityIdentifier.AllocateId(), OwnerId, fullyBuilt: MySession.Static.CreativeMode); var gridBuilder = Sandbox.Common.ObjectBuilders.Serializer.MyObjectBuilderSerializer.CreateNewObject <MyObjectBuilder_CubeGrid>(); gridBuilder.GridSizeEnum = gridSize; gridBuilder.IsStatic = false; gridBuilder.PositionAndOrientation = new MyPositionAndOrientation(matrix); gridBuilder.CubeBlocks.Add(block); var grid = MyEntityFactory.CreateEntity <MyCubeGrid>(gridBuilder); grid.Init(gridBuilder); topGrid = grid; topBlock = (MyPistonTop)topGrid.GetCubeBlock(Vector3I.Zero).FatBlock; //topGrid.SetPosition(topGrid.WorldMatrix.Translation - (topBlock.WorldMatrix.Translation/*Vector3.Transform(topBlock.DummyPosLoc, topGrid.WorldMatrix) - topGrid.WorldMatrix.Translation*/)); MyEntities.Add(grid); MySyncCreate.SendEntityCreated(grid.GetObjectBuilder()); m_topBlockId = topBlock.EntityId; }
public virtual bool IsMemoryTargetValid(MyBBMemoryTarget targetMemory) { if (targetMemory != null) { switch (targetMemory.TargetType) { case MyAiTargetEnum.GRID: case MyAiTargetEnum.ENTITY: { VRage.Game.Entity.MyEntity entity = null; return(Sandbox.Game.Entities.MyEntities.TryGetEntityById(targetMemory.EntityId.Value, out entity, false) && this.IsEntityReachable(entity)); } case MyAiTargetEnum.CUBE: case MyAiTargetEnum.COMPOUND_BLOCK: { MyCubeGrid grid = null; if (!Sandbox.Game.Entities.MyEntities.TryGetEntityById <MyCubeGrid>(targetMemory.EntityId.Value, out grid, false)) { return(false); } MySlimBlock cubeBlock = grid.GetCubeBlock(targetMemory.BlockPosition); return((cubeBlock != null) ? ((cubeBlock.FatBlock == null) ? this.IsEntityReachable(grid) : this.IsEntityReachable(cubeBlock.FatBlock)) : false); } case MyAiTargetEnum.CHARACTER: { MyCharacter character = null; return(Sandbox.Game.Entities.MyEntities.TryGetEntityById <MyCharacter>(targetMemory.EntityId.Value, out character, false) && this.IsEntityReachable(character)); } case MyAiTargetEnum.ENVIRONMENT_ITEM: case MyAiTargetEnum.VOXEL: return(true); } } return(false); }
protected void CreateRotorGrid(out MyCubeGrid rotorGrid, out MyMotorRotor rotorBlock, long builtBy, MyCubeBlockDefinitionGroup rotorGroup) { Debug.Assert(Sync.IsServer, "Rotor grid can be created only on server"); if (rotorGroup == null) { rotorGrid = null; rotorBlock = null; return; } var gridSize = CubeGrid.GridSizeEnum; float size = MyDefinitionManager.Static.GetCubeSize(gridSize); var matrix = MatrixD.CreateWorld(Vector3D.Transform(DummyPosition, CubeGrid.WorldMatrix), WorldMatrix.Forward, WorldMatrix.Up); var definition = rotorGroup[gridSize]; Debug.Assert(definition != null); var block = MyCubeGrid.CreateBlockObjectBuilder(definition, Vector3I.Zero, MyBlockOrientation.Identity, MyEntityIdentifier.AllocateId(), OwnerId, fullyBuilt: MySession.Static.CreativeMode); var gridBuilder = MyObjectBuilderSerializer.CreateNewObject<MyObjectBuilder_CubeGrid>(); gridBuilder.GridSizeEnum = gridSize; gridBuilder.IsStatic = false; gridBuilder.PositionAndOrientation = new MyPositionAndOrientation(matrix); gridBuilder.CubeBlocks.Add(block); var grid = MyEntityFactory.CreateEntity<MyCubeGrid>(gridBuilder); grid.Init(gridBuilder); rotorGrid = grid; rotorBlock = (MyMotorRotor)rotorGrid.GetCubeBlock(Vector3I.Zero).FatBlock; rotorGrid.PositionComp.SetPosition(rotorGrid.WorldMatrix.Translation - (Vector3D.Transform(rotorBlock.DummyPosLoc, rotorGrid.WorldMatrix) - rotorGrid.WorldMatrix.Translation)); if (!CanPlaceRotor(rotorBlock, builtBy)) { rotorGrid = null; rotorBlock = null; grid.Close(); return; } MyEntities.Add(grid); MatrixD masterToSlave = rotorBlock.CubeGrid.WorldMatrix * MatrixD.Invert(WorldMatrix); m_rotorBlockId.Value = new State() { OtherEntityId = rotorBlock.EntityId, MasterToSlave = masterToSlave}; }
private void MirrorGizmoSpace(MyGizmoSpaceProperties targetSpace, MyGizmoSpaceProperties sourceSpace, MySymmetrySettingModeEnum mirrorPlane, Vector3I mirrorPosition, bool isOdd, MyCubeBlockDefinition cubeBlockDefinition, MyCubeGrid cubeGrid) { targetSpace.m_addPos = MirrorBlockByPlane(mirrorPlane, mirrorPosition, isOdd, sourceSpace.m_addPos); targetSpace.m_localMatrixAdd.Translation = targetSpace.m_addPos; targetSpace.m_addDir = MirrorDirByPlane(mirrorPlane, mirrorPosition, isOdd, sourceSpace.m_addDir); targetSpace.m_removePos = MirrorBlockByPlane(mirrorPlane, mirrorPosition, isOdd, sourceSpace.m_removePos); targetSpace.m_removeBlock = cubeGrid.GetCubeBlock(targetSpace.m_removePos); if (sourceSpace.m_startBuild.HasValue) targetSpace.m_startBuild = MirrorBlockByPlane(mirrorPlane, mirrorPosition, isOdd, sourceSpace.m_startBuild.Value); else targetSpace.m_startBuild = null; if (sourceSpace.m_continueBuild.HasValue) targetSpace.m_continueBuild = MirrorBlockByPlane(mirrorPlane, mirrorPosition, isOdd, sourceSpace.m_continueBuild.Value); else targetSpace.m_continueBuild = null; if (sourceSpace.m_startRemove.HasValue) targetSpace.m_startRemove = MirrorBlockByPlane(mirrorPlane, mirrorPosition, isOdd, sourceSpace.m_startRemove.Value); else targetSpace.m_startRemove = null; //Find block axis ortogonal to mirror plane normal Vector3 mirrorNormal = Vector3.Zero; switch (mirrorPlane) { case MySymmetrySettingModeEnum.XPlane: mirrorNormal = Vector3.Right; break; case MySymmetrySettingModeEnum.YPlane: mirrorNormal = Vector3.Up; break; case MySymmetrySettingModeEnum.ZPlane: mirrorNormal = Vector3.Forward; break; default: System.Diagnostics.Debug.Assert(false); break; } var blockMirrorAxis = Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.None; if (MyUtils.IsZero(Math.Abs(Vector3.Dot(sourceSpace.m_localMatrixAdd.Right, mirrorNormal)) - 1.0f)) { blockMirrorAxis = Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.X; } else if (MyUtils.IsZero(Math.Abs(Vector3.Dot(sourceSpace.m_localMatrixAdd.Up, mirrorNormal)) - 1.0f)) { blockMirrorAxis = Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.Y; } else if (MyUtils.IsZero(Math.Abs(Vector3.Dot(sourceSpace.m_localMatrixAdd.Forward, mirrorNormal)) - 1.0f)) { blockMirrorAxis = Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.Z; } var blockMirrorOption = Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.None; switch (blockMirrorAxis) { case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.X: blockMirrorOption = cubeBlockDefinition.SymmetryX; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.Y: blockMirrorOption = cubeBlockDefinition.SymmetryY; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.Z: blockMirrorOption = cubeBlockDefinition.SymmetryZ; break; default: System.Diagnostics.Debug.Assert(false); break; } switch (blockMirrorOption) { case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.X: targetSpace.m_localMatrixAdd = Matrix.CreateRotationX(MathHelper.Pi) * sourceSpace.m_localMatrixAdd; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.Y: //targetSpace.m_gizmoLocalMatrixAdd = sourceSpace.m_gizmoLocalMatrixAdd; targetSpace.m_localMatrixAdd = Matrix.CreateRotationY(MathHelper.Pi) * sourceSpace.m_localMatrixAdd; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.Z: case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.ZThenOffsetX: targetSpace.m_localMatrixAdd = Matrix.CreateRotationZ(MathHelper.Pi) * sourceSpace.m_localMatrixAdd; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.HalfX: targetSpace.m_localMatrixAdd = Matrix.CreateRotationX(-MathHelper.PiOver2) * sourceSpace.m_localMatrixAdd; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.HalfY: targetSpace.m_localMatrixAdd = Matrix.CreateRotationY(-MathHelper.PiOver2) * sourceSpace.m_localMatrixAdd; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.HalfZ: targetSpace.m_localMatrixAdd = Matrix.CreateRotationZ(-MathHelper.PiOver2) * sourceSpace.m_localMatrixAdd; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.XHalfY: targetSpace.m_localMatrixAdd = Matrix.CreateRotationX(MathHelper.Pi) * sourceSpace.m_localMatrixAdd; targetSpace.m_localMatrixAdd = Matrix.CreateRotationY(MathHelper.PiOver2) * targetSpace.m_localMatrixAdd; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.YHalfY: targetSpace.m_localMatrixAdd = Matrix.CreateRotationY(MathHelper.Pi) * sourceSpace.m_localMatrixAdd; targetSpace.m_localMatrixAdd = Matrix.CreateRotationY(MathHelper.PiOver2) * targetSpace.m_localMatrixAdd; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.ZHalfY: targetSpace.m_localMatrixAdd = Matrix.CreateRotationZ(MathHelper.Pi) * sourceSpace.m_localMatrixAdd; targetSpace.m_localMatrixAdd = Matrix.CreateRotationY(MathHelper.PiOver2) * targetSpace.m_localMatrixAdd; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.XHalfX: targetSpace.m_localMatrixAdd = Matrix.CreateRotationX(MathHelper.Pi) * sourceSpace.m_localMatrixAdd; targetSpace.m_localMatrixAdd = Matrix.CreateRotationX(-MathHelper.PiOver2) * targetSpace.m_localMatrixAdd; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.YHalfX: targetSpace.m_localMatrixAdd = Matrix.CreateRotationY(MathHelper.Pi) * sourceSpace.m_localMatrixAdd; targetSpace.m_localMatrixAdd = Matrix.CreateRotationX(-MathHelper.PiOver2) * targetSpace.m_localMatrixAdd; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.ZHalfX: targetSpace.m_localMatrixAdd = Matrix.CreateRotationZ(MathHelper.Pi) * sourceSpace.m_localMatrixAdd; targetSpace.m_localMatrixAdd = Matrix.CreateRotationX(-MathHelper.PiOver2) * targetSpace.m_localMatrixAdd; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.XHalfZ: targetSpace.m_localMatrixAdd = Matrix.CreateRotationX(MathHelper.Pi) * sourceSpace.m_localMatrixAdd; targetSpace.m_localMatrixAdd = Matrix.CreateRotationZ(-MathHelper.PiOver2) * targetSpace.m_localMatrixAdd; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.YHalfZ: targetSpace.m_localMatrixAdd = Matrix.CreateRotationY(MathHelper.Pi) * sourceSpace.m_localMatrixAdd; targetSpace.m_localMatrixAdd = Matrix.CreateRotationZ(-MathHelper.PiOver2) * targetSpace.m_localMatrixAdd; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.ZHalfZ: targetSpace.m_localMatrixAdd = Matrix.CreateRotationZ(MathHelper.Pi) * sourceSpace.m_localMatrixAdd; targetSpace.m_localMatrixAdd = Matrix.CreateRotationZ(-MathHelper.PiOver2) * targetSpace.m_localMatrixAdd; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.XMinusHalfZ: targetSpace.m_localMatrixAdd = Matrix.CreateRotationX(MathHelper.Pi) * sourceSpace.m_localMatrixAdd; targetSpace.m_localMatrixAdd = Matrix.CreateRotationZ(MathHelper.PiOver2) * targetSpace.m_localMatrixAdd; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.YMinusHalfZ: targetSpace.m_localMatrixAdd = Matrix.CreateRotationY(MathHelper.Pi) * sourceSpace.m_localMatrixAdd; targetSpace.m_localMatrixAdd = Matrix.CreateRotationZ(MathHelper.PiOver2) * targetSpace.m_localMatrixAdd; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.ZMinusHalfZ: targetSpace.m_localMatrixAdd = Matrix.CreateRotationZ(MathHelper.Pi) * sourceSpace.m_localMatrixAdd; targetSpace.m_localMatrixAdd = Matrix.CreateRotationZ(MathHelper.PiOver2) * targetSpace.m_localMatrixAdd; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.XMinusHalfX: targetSpace.m_localMatrixAdd = Matrix.CreateRotationX(MathHelper.Pi) * sourceSpace.m_localMatrixAdd; targetSpace.m_localMatrixAdd = Matrix.CreateRotationX(MathHelper.PiOver2) * targetSpace.m_localMatrixAdd; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.YMinusHalfX: targetSpace.m_localMatrixAdd = Matrix.CreateRotationY(MathHelper.Pi) * sourceSpace.m_localMatrixAdd; targetSpace.m_localMatrixAdd = Matrix.CreateRotationX(MathHelper.PiOver2) * targetSpace.m_localMatrixAdd; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.ZMinusHalfX: targetSpace.m_localMatrixAdd = Matrix.CreateRotationZ(MathHelper.Pi) * sourceSpace.m_localMatrixAdd; targetSpace.m_localMatrixAdd = Matrix.CreateRotationX(MathHelper.PiOver2) * targetSpace.m_localMatrixAdd; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.MinusHalfX: targetSpace.m_localMatrixAdd = Matrix.CreateRotationX(MathHelper.PiOver2) * sourceSpace.m_localMatrixAdd; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.MinusHalfY: targetSpace.m_localMatrixAdd = Matrix.CreateRotationY(MathHelper.PiOver2) * sourceSpace.m_localMatrixAdd; break; case Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.MinusHalfZ: targetSpace.m_localMatrixAdd = Matrix.CreateRotationZ(MathHelper.PiOver2) * sourceSpace.m_localMatrixAdd; break; default: targetSpace.m_localMatrixAdd = sourceSpace.m_localMatrixAdd; break; } if (!string.IsNullOrEmpty(sourceSpace.m_blockDefinition.MirroringBlock)) { targetSpace.m_blockDefinition = MyDefinitionManager.Static.GetCubeBlockDefinition(new MyDefinitionId(typeof(MyObjectBuilder_CubeBlock), sourceSpace.m_blockDefinition.MirroringBlock)); } else targetSpace.m_blockDefinition = sourceSpace.m_blockDefinition; // Correct mirroring of objects with center offset // if (blockMirrorOption == Common.ObjectBuilders.Definitions.MySymmetryAxisEnum.None) if (cubeBlockDefinition.SymmetryX == MySymmetryAxisEnum.None && cubeBlockDefinition.SymmetryY == MySymmetryAxisEnum.None && cubeBlockDefinition.SymmetryZ == MySymmetryAxisEnum.None) { Vector3 min = sourceSpace.m_min * cubeGrid.GridSize - new Vector3(cubeGrid.GridSize / 2); Vector3 max = sourceSpace.m_max * cubeGrid.GridSize + new Vector3(cubeGrid.GridSize / 2); BoundingBox box = new BoundingBox(min, max); //Mirroring algorithm // 1. Find vector from closest source box side to mirror (vector A) // 2. Find vector from source box pos to opposite side (vector B) // 3. Correct mirrored position is source box pos + A - B if (box.Size.X > 1 * cubeGrid.GridSize || box.Size.Y > 1 * cubeGrid.GridSize || box.Size.Z > 1 * cubeGrid.GridSize) { //align to mirror BoundingBox worldAABB = box.Transform((Matrix)cubeGrid.WorldMatrix); //VRageRender.MyRenderProxy.DebugDrawAABB(worldAABB, Vector3.One, 1, 1, false); Vector3 sourceCenterFloatLocal = sourceSpace.m_localMatrixAdd.Translation * cubeGrid.GridSize; Vector3 sourceCenterWorld = Vector3.Transform(sourceCenterFloatLocal, cubeGrid.WorldMatrix); //VRageRender.MyRenderProxy.DebugDrawSphere(sourceCenterWorld, 0.5f, Vector3.One, 1, false, false); Vector3I localToMirror = mirrorPosition - new Vector3I(sourceSpace.m_localMatrixAdd.Translation); Vector3 floatLocalToMirror = localToMirror * cubeGrid.GridSize; if (isOdd) { floatLocalToMirror.X -= cubeGrid.GridSize / 2; floatLocalToMirror.Y -= cubeGrid.GridSize / 2; floatLocalToMirror.Z += cubeGrid.GridSize / 2; } Vector3 fullFloatLocalToMirror = floatLocalToMirror; Vector3 alignedFloatLocalToMirror = Vector3.Clamp(sourceCenterFloatLocal + floatLocalToMirror, box.Min, box.Max) - sourceCenterFloatLocal; Vector3 alignedFloatLocalToBoxEnd = Vector3.Clamp(sourceCenterFloatLocal + floatLocalToMirror * 100, box.Min, box.Max) - sourceCenterFloatLocal; Vector3 oppositeFromMirror = Vector3.Clamp(sourceCenterFloatLocal - floatLocalToMirror * 100, box.Min, box.Max) - sourceCenterFloatLocal; if (mirrorPlane == MySymmetrySettingModeEnum.XPlane || mirrorPlane == MySymmetrySettingModeEnum.XPlaneOdd) { oppositeFromMirror.Y = 0; oppositeFromMirror.Z = 0; alignedFloatLocalToMirror.Y = 0; alignedFloatLocalToMirror.Z = 0; fullFloatLocalToMirror.Y = 0; fullFloatLocalToMirror.Z = 0; alignedFloatLocalToBoxEnd.Y = 0; alignedFloatLocalToBoxEnd.Z = 0; } else if (mirrorPlane == MySymmetrySettingModeEnum.YPlane || mirrorPlane == MySymmetrySettingModeEnum.YPlaneOdd) { oppositeFromMirror.X = 0; oppositeFromMirror.Z = 0; alignedFloatLocalToMirror.X = 0; alignedFloatLocalToMirror.Z = 0; fullFloatLocalToMirror.X = 0; fullFloatLocalToMirror.Z = 0; alignedFloatLocalToBoxEnd.X = 0; alignedFloatLocalToBoxEnd.Z = 0; } else if (mirrorPlane == MySymmetrySettingModeEnum.ZPlane || mirrorPlane == MySymmetrySettingModeEnum.ZPlaneOdd) { oppositeFromMirror.Y = 0; oppositeFromMirror.X = 0; alignedFloatLocalToMirror.Y = 0; alignedFloatLocalToMirror.X = 0; fullFloatLocalToMirror.Y = 0; fullFloatLocalToMirror.X = 0; alignedFloatLocalToBoxEnd.Y = 0; alignedFloatLocalToBoxEnd.X = 0; } Vector3 sideLocalToMirror = fullFloatLocalToMirror - alignedFloatLocalToMirror; Vector3 alignedWorldToMirror = Vector3.TransformNormal(alignedFloatLocalToMirror, cubeGrid.WorldMatrix); Vector3 fullWorldToMirror = Vector3.TransformNormal(fullFloatLocalToMirror, cubeGrid.WorldMatrix); Vector3 oppositeWorldToMirror = Vector3.TransformNormal(oppositeFromMirror, cubeGrid.WorldMatrix); //VRageRender.MyRenderProxy.DebugDrawLine3D(sourceCenterWorld, sourceCenterWorld + alignedWorldToMirror, Color.Red, Color.Red, false); //VRageRender.MyRenderProxy.DebugDrawLine3D(sourceCenterWorld + alignedWorldToMirror, sourceCenterWorld + fullWorldToMirror, Color.Yellow, Color.Yellow, false); //VRageRender.MyRenderProxy.DebugDrawLine3D(sourceCenterWorld, sourceCenterWorld + oppositeWorldToMirror, Color.Blue, Color.Blue, false); bool isInsideMirror = false; if (fullFloatLocalToMirror.LengthSquared() < alignedFloatLocalToBoxEnd.LengthSquared()) { isInsideMirror = true; } Vector3 newOffsetFromMirror = sideLocalToMirror; Vector3 newOffsetFromBox = -oppositeFromMirror; Vector3 newOffsetFromMirrorWorld = Vector3.TransformNormal(newOffsetFromMirror, cubeGrid.WorldMatrix); Vector3 newOffsetFromBoxWorld = Vector3.TransformNormal(newOffsetFromBox, cubeGrid.WorldMatrix); Vector3 mirrorPositionWorld = sourceCenterWorld + fullWorldToMirror; //VRageRender.MyRenderProxy.DebugDrawLine3D(mirrorPositionWorld, mirrorPositionWorld + newOffsetFromMirrorWorld, Color.Yellow, Color.Yellow, false); //VRageRender.MyRenderProxy.DebugDrawLine3D(mirrorPositionWorld + newOffsetFromMirrorWorld, mirrorPositionWorld + newOffsetFromMirrorWorld + newOffsetFromBoxWorld, Color.Blue, Color.Blue, false); Vector3 newLocalFromMirror = newOffsetFromMirror + newOffsetFromBox; Vector3 newWorldFromMirror = Vector3.TransformNormal(newLocalFromMirror, cubeGrid.WorldMatrix); //VRageRender.MyRenderProxy.DebugDrawLine3D(mirrorPositionWorld, mirrorPositionWorld + newWorldFromMirror, Color.Green, Color.Green, false); Vector3 fromMirrorFloat = sourceSpace.m_localMatrixAdd.Translation + (fullFloatLocalToMirror + newLocalFromMirror) / cubeGrid.GridSize; if (!isInsideMirror) { Vector3 worldFromMirror = Vector3.TransformNormal(fromMirrorFloat, cubeGrid.WorldMatrix); //VRageRender.MyRenderProxy.DebugDrawLine3D(sourceCenterWorld, sourceCenterWorld + worldFromMirror, Color.White, Color.Black, false); Vector3 newPos = fromMirrorFloat;// / CurrentGrid.GridSize; //VRageRender.MyRenderProxy.DebugDrawSphere(Vector3.Transform(targetSpace.m_gizmoAddPos * CurrentGrid.GridSize, CurrentGrid.WorldMatrix), 0.2f, Vector3.One, 1, false); targetSpace.m_mirroringOffset = new Vector3I(newPos) - targetSpace.m_addPos; targetSpace.m_addPos += targetSpace.m_mirroringOffset; targetSpace.m_removePos += targetSpace.m_mirroringOffset; targetSpace.m_removeBlock = cubeGrid.GetCubeBlock(targetSpace.m_removePos); targetSpace.m_addDir = sourceSpace.m_addDir; targetSpace.m_localMatrixAdd.Translation = targetSpace.m_addPos; if (targetSpace.m_startBuild != null) targetSpace.m_startBuild = targetSpace.m_startBuild + targetSpace.m_mirroringOffset; } else { targetSpace.m_mirroringOffset = Vector3I.Zero; targetSpace.m_addPos = sourceSpace.m_addPos; targetSpace.m_removePos = sourceSpace.m_removePos; targetSpace.m_removeBlock = cubeGrid.GetCubeBlock(sourceSpace.m_removePos); } } } if (blockMirrorOption == MySymmetryAxisEnum.ZThenOffsetX) { Vector3I offset = new Vector3I(targetSpace.m_localMatrixAdd.Down); targetSpace.m_mirroringOffset = offset; targetSpace.m_addPos += targetSpace.m_mirroringOffset; targetSpace.m_removePos += targetSpace.m_mirroringOffset; targetSpace.m_removeBlock = cubeGrid.GetCubeBlock(targetSpace.m_removePos); //targetSpace.m_gizmoAddDir = sourceSpace.m_gizmoAddDir; targetSpace.m_localMatrixAdd.Translation += offset; } targetSpace.m_worldMatrixAdd = targetSpace.m_localMatrixAdd * cubeGrid.WorldMatrix; Debug.Assert(!targetSpace.m_worldMatrixAdd.IsNan(), "Invalid gizmo matrix"); }
private void MyCubeGridsOnBlockBuilt(MyCubeGrid myCubeGrid, MySlimBlock mySlimBlock) { if (mySlimBlock == null || !myCubeGrid.IsStatic) return; // Avoid multiple queues for compound block additions. var compound = myCubeGrid.GetCubeBlock(mySlimBlock.Min).FatBlock as MyCompoundCubeBlock; if (compound != null && mySlimBlock.FatBlock != compound) return; BoundingBoxD blockAabb; mySlimBlock.GetWorldBoundingBox(out blockAabb, true); m_cubeBlocksPending.Add(myCubeGrid, blockAabb); //Debug.Print("CubeGrid {0}: Block added at {1}.", myCubeGrid, mySlimBlock.Position); }
static MySlimBlock GetContactBlock(MyCubeGrid grid, Vector3D worldPosition, float graceDistance) { graceDistance = Math.Max(Math.Abs(graceDistance), grid.GridSize * 0.2f); graceDistance += 1f; MatrixD invWorld = grid.PositionComp.GetWorldMatrixNormalizedInv(); Vector3D localVelocity = Vector3D.TransformNormal(grid.Physics.LinearVelocity * Sandbox.Common.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS, invWorld); Vector3D localPos; Vector3D.Transform(ref worldPosition, ref invWorld, out localPos); var min1 = Vector3I.Round((localPos - graceDistance - localVelocity) / grid.GridSize); var max1 = Vector3I.Round((localPos + graceDistance + localVelocity) / grid.GridSize); var min2 = Vector3I.Round((localPos + graceDistance - localVelocity) / grid.GridSize); var max2 = Vector3I.Round((localPos - graceDistance + localVelocity) / grid.GridSize); Vector3I min = Vector3I.Min(Vector3I.Min(Vector3I.Min(min1, max1), min2), max2); Vector3I max = Vector3I.Max(Vector3I.Max(Vector3I.Max(min1, max1), min2), max2); MySlimBlock resultBlock = null; float distSq = float.MaxValue; // TODO: optimize this, it should be possible using normal from contact Vector3I pos; for (pos.X = min.X; pos.X <= max.X; pos.X++) { for (pos.Y = min.Y; pos.Y <= max.Y; pos.Y++) { for (pos.Z = min.Z; pos.Z <= max.Z; pos.Z++) { var block = grid.GetCubeBlock(pos); if (block != null) { var testDistSq = (float)(pos * grid.GridSize - localPos).LengthSquared(); if (testDistSq < distSq) { distSq = testDistSq; resultBlock = block; } } } } } return resultBlock; }
private void CreateTopGrid(out MyCubeGrid topGrid, out MyPistonTop topBlock, MyCubeBlockDefinitionGroup topGroup) { if (topGroup == null) { topGrid = null; topBlock = null; return; } var gridSize = CubeGrid.GridSizeEnum; float size = MyDefinitionManager.Static.GetCubeSize(gridSize); var matrix = MatrixD.CreateWorld(Vector3D.Transform(m_constraintBasePos, Subpart3.WorldMatrix), WorldMatrix.Forward, WorldMatrix.Up); var definition = topGroup[gridSize]; Debug.Assert(definition != null); var block = MyCubeGrid.CreateBlockObjectBuilder(definition, Vector3I.Zero, MyBlockOrientation.Identity, MyEntityIdentifier.AllocateId(), OwnerId, fullyBuilt: MySession.Static.CreativeMode); var gridBuilder = Sandbox.Common.ObjectBuilders.Serializer.MyObjectBuilderSerializer.CreateNewObject<MyObjectBuilder_CubeGrid>(); gridBuilder.GridSizeEnum = gridSize; gridBuilder.IsStatic = false; gridBuilder.PositionAndOrientation = new MyPositionAndOrientation(matrix); gridBuilder.CubeBlocks.Add(block); var grid = MyEntityFactory.CreateEntity<MyCubeGrid>(gridBuilder); grid.Init(gridBuilder); topGrid = grid; topBlock = (MyPistonTop)topGrid.GetCubeBlock(Vector3I.Zero).FatBlock; //topGrid.SetPosition(topGrid.WorldMatrix.Translation - (topBlock.WorldMatrix.Translation/*Vector3.Transform(topBlock.DummyPosLoc, topGrid.WorldMatrix) - topGrid.WorldMatrix.Translation*/)); MyEntities.Add(grid); MySyncCreate.SendEntityCreated(grid.GetObjectBuilder()); m_topBlockId = topBlock.EntityId; }
protected void CreateRotorGrid(out MyCubeGrid rotorGrid, out MyMotorRotor rotorBlock, long builtBy, MyCubeBlockDefinitionGroup rotorGroup) { if (rotorGroup == null) { CreateRotorGridFailed(builtBy, out rotorGrid, out rotorBlock); return; } var gridSize = CubeGrid.GridSizeEnum; float size = MyDefinitionManager.Static.GetCubeSize(gridSize); var matrix = MatrixD.CreateWorld(Vector3D.Transform(DummyPosition,CubeGrid.WorldMatrix), WorldMatrix.Forward, WorldMatrix.Up); var definition = rotorGroup[gridSize]; Debug.Assert(definition != null); var block = MyCubeGrid.CreateBlockObjectBuilder(definition, Vector3I.Zero, MyBlockOrientation.Identity, MyEntityIdentifier.AllocateId(), OwnerId, fullyBuilt: MySession.Static.CreativeMode); var gridBuilder = Sandbox.Common.ObjectBuilders.Serializer.MyObjectBuilderSerializer.CreateNewObject<MyObjectBuilder_CubeGrid>(); gridBuilder.GridSizeEnum = gridSize; gridBuilder.IsStatic = false; gridBuilder.PositionAndOrientation = new MyPositionAndOrientation(matrix); gridBuilder.CubeBlocks.Add(block); var grid = MyEntityFactory.CreateEntity<MyCubeGrid>(gridBuilder); grid.Init(gridBuilder); rotorGrid = grid; rotorBlock = (MyMotorRotor)rotorGrid.GetCubeBlock(Vector3I.Zero).FatBlock; rotorGrid.PositionComp.SetPosition(rotorGrid.WorldMatrix.Translation - (Vector3D.Transform(rotorBlock.DummyPosLoc, rotorGrid.WorldMatrix) - rotorGrid.WorldMatrix.Translation)); if (!CanPlaceRotor(rotorBlock, builtBy)) { CreateRotorGridFailed(builtBy, out rotorGrid, out rotorBlock); grid.Close(); return; } if (Sync.IsServer) { MyEntities.Add(grid); MySyncCreate.SendEntityCreated(grid.GetObjectBuilder()); } else grid.Close(); }
private void CreateTopGrid(out MyCubeGrid topGrid, out MyAttachableTopBlockBase topBlock, long builtBy, MyCubeBlockDefinitionGroup topGroup) { if (topGroup == null) { topGrid = null; topBlock = null; return; } var gridSize = CubeGrid.GridSizeEnum; float size = MyDefinitionManager.Static.GetCubeSize(gridSize); var matrix = MatrixD.CreateWorld(Vector3D.Transform(m_constraintBasePos, Subpart3.WorldMatrix), WorldMatrix.Forward, WorldMatrix.Up); var definition = topGroup[gridSize]; Debug.Assert(definition != null); var block = MyCubeGrid.CreateBlockObjectBuilder(definition, Vector3I.Zero, MyBlockOrientation.Identity, MyEntityIdentifier.AllocateId(), OwnerId, fullyBuilt: MySession.Static.CreativeMode); var gridBuilder = MyObjectBuilderSerializer.CreateNewObject<MyObjectBuilder_CubeGrid>(); gridBuilder.GridSizeEnum = gridSize; gridBuilder.IsStatic = false; gridBuilder.PositionAndOrientation = new MyPositionAndOrientation(matrix); gridBuilder.CubeBlocks.Add(block); var grid = MyEntityFactory.CreateEntity<MyCubeGrid>(gridBuilder); grid.Init(gridBuilder); topGrid = grid; topBlock = (MyPistonTop)topGrid.GetCubeBlock(Vector3I.Zero).FatBlock; if (!CanPlaceTop(topBlock, builtBy)) { topGrid = null; topBlock = null; grid.Close(); return; } //topGrid.SetPosition(topGrid.WorldMatrix.Translation - (topBlock.WorldMatrix.Translation/*Vector3.Transform(topBlock.DummyPosLoc, topGrid.WorldMatrix) - topGrid.WorldMatrix.Translation*/)); MyEntities.Add(grid); if (MyFakes.ENABLE_SENT_GROUP_AT_ONCE) { MyMultiplayer.ReplicateImmediatelly(MyExternalReplicable.FindByObject(grid), MyExternalReplicable.FindByObject(CubeGrid)); } }
/// <summary> /// Intended for quite small refreshes (few blocks). /// Collect is faster for large refresh. /// Removes also dirty mass elements. /// </summary> public void CollectArea(MyCubeGrid grid, HashSet<Vector3I> dirtyBlocks, MyVoxelSegmentation segmenter, MyVoxelSegmentationType segmentationType, IDictionary<Vector3I, HkMassElement> massResults) { ProfilerShort.Begin("Remove dirty"); foreach (var pos in dirtyBlocks) { if(massResults != null) massResults.Remove(pos); var block = grid.GetCubeBlock(pos); if (block != null) { m_tmpRefreshSet.Add(block); } } ProfilerShort.End(); ProfilerShort.Begin("Add new"); foreach (var block in m_tmpRefreshSet) { if (block.FatBlock is MyCompoundCubeBlock) { ProfilerShort.Begin("Collect compound"); CollectCompoundBlock((MyCompoundCubeBlock)block.FatBlock, massResults); //Debug.Assert(IsValid(), "Overlapping shapes detected, block shapes cannot overlap!"); ProfilerShort.End(); } else { ProfilerShort.Begin("Collect block"); CollectBlock(block, block.BlockDefinition.PhysicsOption, massResults); //Debug.Assert(IsValid(), "Overlapping shapes detected, block shapes cannot overlap!"); ProfilerShort.End(); } } ProfilerShort.End(); ProfilerShort.Begin("IsValidTest"); Debug.Assert(IsValid(), "Overlapping shapes detected, block shapes cannot overlap! Uncomment upper asserts to find what block caused this"); ProfilerShort.End(); ProfilerShort.Begin("Add segments"); AddSegmentedParts(grid.GridSize, segmenter, segmentationType); ProfilerShort.End(); m_tmpCubes.Clear(); m_tmpRefreshSet.Clear(); // Clear is required, we certainly don't want to hold last reference to blocks }
private static void ExpandBlock(Vector3I cubePos, MyCubeGrid grid, HashSet<MySlimBlock> existingBlocks, HashSet<Vector3I> expandResult) { var block = grid.GetCubeBlock(cubePos); if (block != null && existingBlocks.Add(block)) { Vector3I current; for (current.X = block.Min.X; current.X <= block.Max.X; ++current.X) for (current.Y = block.Min.Y; current.Y <= block.Max.Y; ++current.Y) for (current.Z = block.Min.Z; current.Z <= block.Max.Z; ++current.Z) { expandResult.Add(current); } } }