public static void LoadDefinition(this MyHudBlockInfo blockInfo, MyCubeBlockDefinition definition, DictionaryReader<MyDefinitionId, int> materials, bool merge = true) { InitBlockInfo(blockInfo, definition); foreach (var material in materials) { var componentDefinition = MyDefinitionManager.Static.GetComponentDefinition(material.Key); var info = new MyHudBlockInfo.ComponentInfo(); if (componentDefinition == null) { MyPhysicalItemDefinition physicalDefinition = null; if (!MyDefinitionManager.Static.TryGetPhysicalItemDefinition(material.Key, out physicalDefinition)) continue; info.ComponentName = physicalDefinition.DisplayNameText; info.Icon = physicalDefinition.Icon; info.DefinitionId = physicalDefinition.Id; info.TotalCount = 1; } else { info.DefinitionId = componentDefinition.Id; info.ComponentName = componentDefinition.DisplayNameText; info.Icon = componentDefinition.Icon; info.TotalCount = material.Value; } blockInfo.Components.Add(info); } if (merge) MergeSameComponents(blockInfo, definition); }
public static void LoadDefinition(this MyHudBlockInfo blockInfo, MyCubeBlockDefinition definition, bool merge = true) { InitBlockInfo(blockInfo, definition); if (definition.MultiBlock != null) { MyDefinitionId defId = new MyDefinitionId(typeof(MyObjectBuilder_MultiBlockDefinition), definition.MultiBlock); MyMultiBlockDefinition multiBlockDef = MyDefinitionManager.Static.GetMultiBlockDefinition(defId); if (multiBlockDef != null) { foreach (var blockPart in multiBlockDef.BlockDefinitions) { MyCubeBlockDefinition cubeBlockDef = null; MyDefinitionManager.Static.TryGetDefinition(blockPart.Id, out cubeBlockDef); if (cubeBlockDef != null) { AddComponentsForBlock(blockInfo, cubeBlockDef); } } } } else { AddComponentsForBlock(blockInfo, definition); } if (merge) MergeSameComponents(blockInfo, definition); }
public void Adapt(IMyInventoryItem inventoryItem) { m_physItem = null; m_blockDef = null; var poob = inventoryItem.Content as MyObjectBuilder_PhysicalObject; if (poob != null) Adapt(poob.GetObjectId()); else Adapt(inventoryItem.GetDefinitionId()); }
public MyGeneratedBlockLocation(MySlimBlock refBlock, MyCubeBlockDefinition blockDefinition, Vector3I position, Vector3I forward, Vector3I up, ushort? blockIdInCompound = null, MyGridInfo gridInfo = null) { RefBlock = refBlock; BlockDefinition = blockDefinition; Position = position; Orientation = new MyBlockOrientation(Base6Directions.GetDirection(ref forward), Base6Directions.GetDirection(ref up)); BlockIdInCompound = blockIdInCompound; GridInfo = gridInfo; GeneratedBlockType = MyStringId.NullOrEmpty; }
public MyGeneratedBlockLocation(MySlimBlock refBlock, MyCubeBlockDefinition blockDefinition, Vector3I position, MyBlockOrientation orientation, ushort? blockIdInCompound = null, MyGridInfo gridInfo = null) { RefBlock = refBlock; BlockDefinition = blockDefinition; Position = position; Orientation = orientation; BlockIdInCompound = blockIdInCompound; GridInfo = gridInfo; GeneratedBlockType = MyStringId.NullOrEmpty; }
public bool TryAdapt(MyDefinitionId itemDefinition) { m_physItem = null; m_blockDef = null; if (MyDefinitionManager.Static.TryGetPhysicalItemDefinition(itemDefinition, out m_physItem)) return true; if (MyDefinitionManager.Static.TryGetCubeBlockDefinition(itemDefinition, out m_blockDef)) return true; return false; }
public void Initialize(ref MyBlockBuildArea area, MyCubeBlockDefinition definition) { m_definition = definition; m_orientation = new MyBlockOrientation(area.OrientationForward, area.OrientationUp); m_posInGrid = area.PosInGrid; m_blockMin = area.BlockMin; m_blockMax = area.BlockMax; m_stepDelta = area.StepDelta; m_lookup.Clear(); }
private static void InitBlockInfo(MyHudBlockInfo blockInfo, MyCubeBlockDefinition definition) { blockInfo.BlockName = definition.DisplayNameText; blockInfo.BlockIcon = definition.Icon; blockInfo.BlockIntegrity = 0; blockInfo.CriticalComponentIndex = -1; blockInfo.CriticalIntegrity = 0; blockInfo.OwnershipIntegrity = 0; blockInfo.MissingComponentIndex = -1; blockInfo.Components.Clear(); }
public MyCubeBlockDefinitionWithVariants(MyCubeBlockDefinition definition, int variantIndex) { m_baseDefinition = definition; m_variantIndex = variantIndex; if (m_baseDefinition.Variants == null || m_baseDefinition.Variants.Count == 0) { m_variantIndex = -1; } else if (m_variantIndex != -1) { m_variantIndex %= m_baseDefinition.Variants.Count; } }
private static void AddComponentsForBlock(MyHudBlockInfo blockInfo, MyCubeBlockDefinition definition) { for (int i = 0; i < definition.Components.Length; ++i) { var comp = definition.Components[i]; var info = new MyHudBlockInfo.ComponentInfo(); info.DefinitionId = comp.Definition.Id; info.ComponentName = comp.Definition.DisplayNameText; info.Icon = comp.Definition.Icon; info.TotalCount = comp.Count; blockInfo.Components.Add(info); } }
public static void LoadDefinition(this MyHudBlockInfo blockInfo, MyCubeBlockDefinition definition, DictionaryReader<MyDefinitionId, int> materials, bool merge = true) { InitBlockInfo(blockInfo, definition); foreach (var material in materials) { var componentDefinition = MyDefinitionManager.Static.GetComponentDefinition(material.Key); var info = new MyHudBlockInfo.ComponentInfo(); info.DefinitionId = componentDefinition.Id; info.ComponentName = componentDefinition.DisplayNameText; info.Icon = componentDefinition.Icon; info.TotalCount = material.Value; blockInfo.Components.Add(info); } if (merge) MergeSameComponents(blockInfo, definition); }
// This function does some modifications to the cube block's object builder before it's built, usually integrity changes, etc... public virtual void BeforeCreateBlock(MyCubeBlockDefinition definition, MyEntity builder, MyObjectBuilder_CubeBlock ob, bool buildAsAdmin) { if (definition.EntityComponents == null) return; if (ob.ComponentContainer == null) { ob.ComponentContainer = new MyObjectBuilder_ComponentContainer(); } foreach (var componentOb in definition.EntityComponents) { var data = new MyObjectBuilder_ComponentContainer.ComponentData(); data.TypeId = componentOb.Key.ToString(); data.Component = componentOb.Value; ob.ComponentContainer.Components.Add(data); } }
public static MyObjectBuilder_BlockNavigationDefinition GetDefaultObjectBuilder(MyCubeBlockDefinition blockDefinition) { MyObjectBuilder_BlockNavigationDefinition ob = m_tmpDefaultOb; m_tmpStringBuilder.Clear(); m_tmpStringBuilder.Append("Default_"); m_tmpStringBuilder.Append(blockDefinition.Size.X); m_tmpStringBuilder.Append("_"); m_tmpStringBuilder.Append(blockDefinition.Size.Y); m_tmpStringBuilder.Append("_"); m_tmpStringBuilder.Append(blockDefinition.Size.Z); ob.Id = new MyDefinitionId(typeof(MyObjectBuilder_BlockNavigationDefinition), m_tmpStringBuilder.ToString()); ob.Size = blockDefinition.Size; ob.Center = blockDefinition.Center; return ob; }
public static void LoadDefinition(this MyHudBlockInfo blockInfo, MyCubeBlockDefinition definition, bool merge = true) { blockInfo.BlockName = definition.DisplayNameText; blockInfo.BlockIcon = definition.Icon; blockInfo.BlockIntegrity = 0; blockInfo.CriticalComponentIndex = -1; blockInfo.CriticalIntegrity = 0; blockInfo.OwnershipIntegrity = 0; blockInfo.MissingComponentIndex = -1; blockInfo.Components.Clear(); for (int i = 0; i < definition.Components.Length; ++i) { var comp = definition.Components[i]; var info = new MyHudBlockInfo.ComponentInfo(); info.ComponentName = comp.Definition.DisplayNameText; info.Icon = comp.Definition.Icon; info.TotalCount = comp.Count; blockInfo.Components.Add(info); } // Merge same components if (merge) { for (int i = definition.Components.Length - 1; i >= 0; i--) { for (int j = i - 1; j >= 0; j--) { if (definition.Components[i].Definition == definition.Components[j].Definition) { var info = blockInfo.Components[j]; info.TotalCount += blockInfo.Components[i].TotalCount; blockInfo.Components[j] = info; blockInfo.Components.RemoveAt(i); break; } } } } }
private static WeaponDescription CreateFrom(MyCubeBlockDefinition definition) { if (string.IsNullOrWhiteSpace(definition.DescriptionString)) return new WeaponDescription(); WeaponDescription desc = new WeaponDescription(); try { XML_Amendments<WeaponDescription> ammender = new XML_Amendments<WeaponDescription>(desc); ammender.AmendAll(definition.DescriptionString, true); return ammender.Deserialize(); } catch (Exception ex) { Logger.debugNotify("Failed to load description for a weapon", 10000, Logger.severity.ERROR); Logger log = new Logger("WeaponDescription", () => definition.Id.ToString()); log.alwaysLog("Failed to load description for a weapon", Logger.severity.ERROR); log.alwaysLog("Exception: " + ex, Logger.severity.ERROR); return new WeaponDescription(); } }
public void Init(MyObjectBuilder_CubeBlock objectBuilder, MyCubeGrid cubeGrid, MyCubeBlock fatBlock) { ProfilerShort.Begin("SlimBlock.Init(objectBuilder, ...)"); Debug.Assert(cubeGrid != null); FatBlock = fatBlock; m_soundEmitter.Entity = FatBlock; if (objectBuilder is MyObjectBuilder_CompoundCubeBlock) BlockDefinition = MyCompoundCubeBlock.GetCompoundCubeBlockDefinition(); else BlockDefinition = MyDefinitionManager.Static.GetCubeBlockDefinition(objectBuilder.GetId()); m_componentStack = new MyComponentStack(BlockDefinition, objectBuilder.IntegrityPercent, objectBuilder.BuildPercent); if (MyCubeGridDefinitions.GetCubeRotationOptions(BlockDefinition) == MyRotationOptionsEnum.None) { objectBuilder.BlockOrientation = MyBlockOrientation.Identity; } DeformationRatio = BlockDefinition.DeformationRatio; Min = objectBuilder.Min; Orientation = objectBuilder.BlockOrientation; if (!Orientation.IsValid) Orientation = MyBlockOrientation.Identity; Debug.Assert(Orientation.IsValid, "Orientation of block is not valid."); CubeGrid = cubeGrid; ColorMaskHSV = objectBuilder.ColorMaskHSV; if (BlockDefinition.CubeDefinition != null) { //Ensure we have always only one distinct orientation use Orientation = MyCubeGridDefinitions.GetTopologyUniqueOrientation(BlockDefinition.CubeDefinition.CubeTopology, Orientation); } ComputeMax(BlockDefinition, Orientation, ref Min, out Max); Matrix localMatrix; Orientation.GetMatrix(out localMatrix); Position = ComputePositionInGrid(ref localMatrix); UpdateShowParts(); if (FatBlock == null) { bool isRenderedAsModel = !String.IsNullOrEmpty(BlockDefinition.Model); bool showConstructionModel = BlockDefinition.BlockTopology == MyBlockTopology.Cube && !ShowParts; if (isRenderedAsModel || showConstructionModel) { FatBlock = new MyCubeBlock(); m_soundEmitter.Entity = FatBlock; } } if (FatBlock != null) { ProfilerShort.Begin("FatBlock.Init(objectBuilder, ...)"); FatBlock.SlimBlock = this; FatBlock.Init(objectBuilder, cubeGrid); ProfilerShort.End(); } if (objectBuilder.ConstructionStockpile != null) { EnsureConstructionStockpileExists(); m_stockpile.Init(objectBuilder.ConstructionStockpile); } else if (objectBuilder.ConstructionInventory != null) // Backwards compatibility { EnsureConstructionStockpileExists(); m_stockpile.Init(objectBuilder.ConstructionInventory); } if (FatBlock == null || FatBlock.GetType() == typeof(MyCubeBlock)) m_objectBuilder = new MyObjectBuilder_CubeBlock(); if (MyFakes.SHOW_DAMAGE_EFFECTS && FatBlock != null && BlockDefinition.RationEnoughForDamageEffect(Integrity / MaxIntegrity)) {//start effect if (CurrentDamage>0)//fix for weird simple blocks having FatBlock - old save? { FatBlock.SetDamageEffect(true); } } ProfilerShort.End(); }
/// <summary> /// Called when block is destroyed before being removed from grid /// </summary> //public void OnDestroy() //{ // if (FatBlock != null) // { // Profiler.Begin("MySlimBlock.OnDestroy"); // FatBlock.OnDestroy(); // Profiler.End(); // } //} public static void ComputeMax(MyCubeBlockDefinition definition, MyBlockOrientation orientation, ref Vector3I min, out Vector3I max) { Vector3I size = definition.Size - 1; MatrixI localMatrix = new MatrixI(orientation); Vector3I.TransformNormal(ref size, ref localMatrix, out size); Vector3I.Abs(ref size, out size); max = min + size; }
public abstract void GetBlockPlacementMaterials(MyCubeBlockDefinition definition, Vector3I position, MyBlockOrientation orientation, MyCubeGrid grid);
public void Init(MyObjectBuilder_GunBase objectBuilder, MyCubeBlockDefinition cubeBlockDefinition, IMyGunBaseUser gunBaseUser) { if (cubeBlockDefinition is MyWeaponBlockDefinition) { MyWeaponBlockDefinition weaponBlockDefinition = cubeBlockDefinition as MyWeaponBlockDefinition; Init(objectBuilder, weaponBlockDefinition.WeaponDefinitionId, gunBaseUser); } else { // Backward compatibility MyDefinitionId weaponDefinitionId = GetBackwardCompatibleDefinitionId(cubeBlockDefinition.Id.TypeId); Init(objectBuilder, weaponDefinitionId, gunBaseUser); } }
// Convention: All these functions will erase the RequiredMaterials first thing when they're called public abstract void GetGridSpawnMaterials(MyCubeBlockDefinition definition, MatrixD worldMatrix, bool isStatic);
public float GetBlockMass(string model, MyCubeBlockDefinition def) { var sh = BlockShapePool.GetBreakableShape(model, def); var mass = sh.GetMass(); BlockShapePool.EnqueShape(model, def.Id, sh); return mass; }
public void InitPressurization() { IsCubePressurized = new Dictionary <Vector3I, Dictionary <Vector3I, bool> >(); for (int i = 0; i < Size.X; i++) { for (int j = 0; j < Size.Y; j++) { for (int k = 0; k < Size.Z; k++) { Vector3 originalStartOffset = new Vector3(i, j, k); Vector3 originalEndOffset = new Vector3(i, j, k) + Vector3.One; Vector3I intOffset = new Vector3I(i, j, k); IsCubePressurized[intOffset] = new Dictionary <Vector3I, bool>(); foreach (var direction in Base6Directions.IntDirections) { var normal = direction; IsCubePressurized[intOffset][normal] = false; if (normal.X == 1 && i != Size.X - 1) { continue; } if (normal.X == -1 && i != 0) { continue; } if (normal.Y == 1 && j != Size.Y - 1) { continue; } if (normal.Y == -1 && j != 0) { continue; } if (normal.Z == 1 && k != Size.Z - 1) { continue; } if (normal.Z == -1 && k != 0) { continue; } foreach (var mountPoint in MountPoints) { if (normal == mountPoint.Normal) { int wallIndex = MyCubeBlockDefinition.GetMountPointWallIndex(Base6Directions.GetDirection(ref normal)); Vector3I blockSize = Size; Vector3 originalStart = mountPoint.Start; Vector3 originalEnd = mountPoint.End; Vector3 start, end; MyCubeBlockDefinition.UntransformMountPointPosition(ref originalStart, wallIndex, blockSize, out start); MyCubeBlockDefinition.UntransformMountPointPosition(ref originalEnd, wallIndex, blockSize, out end); Vector3 endOffset; Vector3 startOffset; MyCubeBlockDefinition.UntransformMountPointPosition(ref originalStartOffset, wallIndex, blockSize, out startOffset); MyCubeBlockDefinition.UntransformMountPointPosition(ref originalEndOffset, wallIndex, blockSize, out endOffset); Vector3 eo = new Vector3(Math.Max(startOffset.X, endOffset.X), Math.Max(startOffset.Y, endOffset.Y), Math.Max(startOffset.Z, endOffset.Z)); Vector3 so = new Vector3(Math.Min(startOffset.X, endOffset.X), Math.Min(startOffset.Y, endOffset.Y), Math.Min(startOffset.Z, endOffset.Z)); if (start.X - 0.05 <= so.X && end.X + 0.05 > eo.X && start.Y - 0.05 <= so.Y && end.Y + 0.05 > eo.Y) { IsCubePressurized[intOffset][normal] = true; break; } } } } } } } }
//public static ObservableCollection<InventoryEditorModel> GetInventory(this MyObjectBuilder_EntityBase objectBuilderBase) //{ // var inventoryEditors = new ObservableCollection<InventoryEditorModel>(); // if (objectBuilderBase.ComponentContainer != null) // { // var inventoryBase = objectBuilderBase.ComponentContainer.Components.FirstOrDefault(e => e.TypeId == "MyInventoryBase"); // if (inventoryBase != null) // { // var singleInventory = inventoryBase.Component as MyObjectBuilder_Inventory; // if (singleInventory != null) // { // var iem = ParseInventory(singleInventory); // if (iem != null) // inventoryEditors.Add(iem); // } // var aggregate = inventoryBase.Component as MyObjectBuilder_InventoryAggregate; // if (aggregate != null) // foreach (var field in aggregate.Inventories) // { // var iem = ParseInventory(field as MyObjectBuilder_Inventory); // if (iem != null) // inventoryEditors.Add(iem); // } // } // } // return inventoryEditors; //} public static ObservableCollection<InventoryEditorModel> GetInventory(this MyObjectBuilder_ComponentContainer componentContainer, MyCubeBlockDefinition definition = null) { var inventoryEditors = new ObservableCollection<InventoryEditorModel>(); if (componentContainer != null) { var inventoryBase = componentContainer.Components.FirstOrDefault(e => e.TypeId == "MyInventoryBase"); if (inventoryBase != null) { var singleInventory = inventoryBase.Component as MyObjectBuilder_Inventory; if (singleInventory != null) { var iem = ParseInventory(singleInventory, definition); if (iem != null) inventoryEditors.Add(iem); } var aggregate = inventoryBase.Component as MyObjectBuilder_InventoryAggregate; if (aggregate != null) foreach (var field in aggregate.Inventories) { var iem = ParseInventory(field as MyObjectBuilder_Inventory, definition); if (iem != null) inventoryEditors.Add(iem); } } } return inventoryEditors; }
private static InventoryEditorModel ParseInventory(MyObjectBuilder_Inventory inventory, MyCubeBlockDefinition definition = null) { if (inventory == null) return null; float volumeMultiplier = 1f; // Unsure if there should be a default of 1 if there isn't a InventorySize defined. if (definition == null) volumeMultiplier = 0.4f; else { var definitionType = definition.GetType(); var invSizeField = definitionType.GetField("InventorySize"); var inventoryMaxVolumeField = definitionType.GetField("InventoryMaxVolume"); if (invSizeField != null) { var invSize = (Vector3)invSizeField.GetValue(definition); volumeMultiplier = invSize.X * invSize.Y * invSize.Z; } if (inventoryMaxVolumeField != null) { var maxSize = (float)inventoryMaxVolumeField.GetValue(definition); volumeMultiplier = MathHelper.Min(volumeMultiplier, maxSize); } } var settings = SpaceEngineersCore.WorldResource.Checkpoint.Settings; return new InventoryEditorModel(inventory, volumeMultiplier * 1000 * settings.InventorySizeMultiplier, null) { Name = inventory.InventoryFlags.ToString(), IsValid = true }; }
/// <summary> /// Checkes whether blocks A and B have matching mount point on one of their sides. Each block is given by its /// definition, rotation and position in grid. Position has to be relative to same center. Also, normal relative to block A specifies /// wall which is used for checking. /// </summary> public static bool CheckMountPointsForSide(MyCubeBlockDefinition defA, MyCubeBlockDefinition.MountPoint[] mountPointsA, ref MyBlockOrientation orientationA, ref Vector3I positionA, ref Vector3I normalA, MyCubeBlockDefinition defB, MyCubeBlockDefinition.MountPoint[] mountPointsB, ref MyBlockOrientation orientationB, ref Vector3I positionB) { TransformMountPoints(m_cacheMountPointsA, defA, mountPointsA, ref orientationA); TransformMountPoints(m_cacheMountPointsB, defB, mountPointsB, ref orientationB); return CheckMountPointsForSide(m_cacheMountPointsA, ref orientationA, ref positionA, defA.Id, ref normalA, m_cacheMountPointsB, ref orientationB, ref positionB, defB.Id); }
public static bool CheckNeighborMountPointsForCompound( Vector3 currentMin, Vector3 currentMax, MyCubeBlockDefinition.MountPoint thisMountPoint, ref Vector3I thisMountPointTransformedNormal, MyCubeBlockDefinition thisDefinition, Vector3I neighborPosition, MyCubeBlockDefinition neighborDefinition, MyCubeBlockDefinition.MountPoint[] neighborMountPoints, MyBlockOrientation neighborOrientation, List<MyCubeBlockDefinition.MountPoint> otherMountPoints) { if (!thisMountPoint.Enabled) return false; var currentBox = new BoundingBox(currentMin - neighborPosition, currentMax - neighborPosition); TransformMountPoints(otherMountPoints, neighborDefinition, neighborMountPoints, ref neighborOrientation); foreach (var otherMountPoint in otherMountPoints) { // Skip mount points which exclude themselves (are not allowed to touch). if ((((thisMountPoint.ExclusionMask & otherMountPoint.PropertiesMask) != 0 || (thisMountPoint.PropertiesMask & otherMountPoint.ExclusionMask) != 0) && thisDefinition.Id != neighborDefinition.Id) || !otherMountPoint.Enabled) continue; // Check normals on compound side with the same direction (we are in the same block) if (MyFakes.ENABLE_TEST_BLOCK_CONNECTIVITY_CHECK && (thisMountPointTransformedNormal - otherMountPoint.Normal != Vector3I.Zero)) continue; var otherBox = new BoundingBox(Vector3.Min(otherMountPoint.Start, otherMountPoint.End), Vector3.Max(otherMountPoint.Start, otherMountPoint.End)); if (currentBox.Intersects(otherBox)) return true; } return false; }
/// <summary> /// Performs check whether small cube block given by its definition, rotation can be connected to large grid. /// Function checks whether a mount point on placed block exists in opposite direction than addNomal. /// </summary> /// <param name="grid">Grid in which the check is performed.</param> /// <param name="def">Definition of small cube block for checking.</param> /// <param name="rotation">Rotation of the small cube block.</param> /// <param name="addNormal">Grid hit normal.</param> /// <returns>True when small block can be connected, otherwise false.</returns> public static bool CheckConnectivitySmallBlockToLargeGrid(MyCubeGrid grid, MyCubeBlockDefinition def, ref Quaternion rotation, ref Vector3I addNormal) { Debug.Assert(grid.GridSizeEnum == MyCubeSize.Large); Debug.Assert(def.CubeSize == MyCubeSize.Small); ProfilerShort.Begin("MyCubeBuilder.CheckMountPoints"); try { var mountPoints = def.MountPoints; if (mountPoints == null) return false; for (int i = 0; i < mountPoints.Length; ++i) { var thisMountPoint = mountPoints[i]; Vector3I transformedNormal; Vector3I.Transform(ref thisMountPoint.Normal, ref rotation, out transformedNormal); Debug.Assert(transformedNormal.RectangularLength() == 1); if (addNormal == -transformedNormal) return true; } return false; } finally { m_cacheNeighborBlocks.Clear(); ProfilerShort.End(); } }
public override bool ConnectionAllowed(ref Vector3I otherBlockMinPos, ref Vector3I otherBlockMaxPos, ref Vector3I faceNormal, MyCubeBlockDefinition def) { return ConnectionAllowedInternal(ref faceNormal, def); }
protected static void AddFastBuildModelWithSubparts(ref MatrixD matrix, List<MatrixD> matrices, List<string> models, MyCubeBlockDefinition blockDefinition) { if (string.IsNullOrEmpty(blockDefinition.Model)) return; matrices.Add(matrix); models.Add(blockDefinition.Model); var data = new MyEntitySubpart.Data(); MyCubeBlockDefinition subBlockDefinition; MatrixD subBlockMatrix; Vector3 dummyPosition; MyModel modelData = MyModels.GetModelOnlyData(blockDefinition.Model); foreach (var dummy in modelData.Dummies) { if (MyEntitySubpart.GetSubpartFromDummy(blockDefinition.Model, dummy.Key, dummy.Value, ref data)) { MatrixD mCopy = MatrixD.Multiply(data.InitialTransform, matrix); matrices.Add(mCopy); models.Add(data.File); } else if (MyFakes.ENABLE_SUBBLOCKS && MyCubeBlock.GetSubBlockDataFromDummy(blockDefinition, dummy.Key, dummy.Value, false, out subBlockDefinition, out subBlockMatrix, out dummyPosition)) { if (!string.IsNullOrEmpty(subBlockDefinition.Model)) { // Repair subblock matrix to have int axes (because preview renderer does not allow such non integer rotation). Vector3I forward = Vector3I.Round(Vector3.DominantAxisProjection(subBlockMatrix.Forward)); Vector3I invForward = Vector3I.One - Vector3I.Abs(forward); Vector3I right = Vector3I.Round(Vector3.DominantAxisProjection((Vector3)subBlockMatrix.Right * invForward)); Vector3I up; Vector3I.Cross(ref right, ref forward, out up); subBlockMatrix.Forward = forward; subBlockMatrix.Right = right; subBlockMatrix.Up = up; MatrixD mCopy = MatrixD.Multiply(subBlockMatrix, matrix); matrices.Add(mCopy); models.Add(subBlockDefinition.Model); } } } }
private bool ConnectionAllowedInternal(ref Vector3I faceNormal, MyCubeBlockDefinition def) { if (IsWorking) return true; if (def != this.BlockDefinition) return true; Base6Directions.Direction connectionDirection = Orientation.TransformDirectionInverse(Base6Directions.GetDirection(faceNormal)); if (connectionDirection != m_forward) return true; return false; }
/// <summary> /// Performs check whether cube block given by its definition, rotation and position is connected to some other /// block in a given grid. /// </summary> /// <param name="grid">Grid in which the check is performed.</param> /// <param name="rotation">Rotation of the cube block within grid.</param> /// <param name="position">Position of the cube block within grid.</param> /// <returns>True when there is a connectable neighbor connected by a mount point, otherwise false.</returns> public static bool CheckConnectivity(IMyGridConnectivityTest grid, MyCubeBlockDefinition def, MyCubeBlockDefinition.MountPoint[] mountPoints, ref Quaternion rotation, ref Vector3I position) { ProfilerShort.Begin("MyCubeBuilder.CheckMountPoints"); try { if (mountPoints == null) return false; var center = def.Center; var size = def.Size; Vector3I rotatedSize; Vector3I rotatedCenter; Vector3I.Transform(ref center, ref rotation, out rotatedCenter); Vector3I.Transform(ref size, ref rotation, out rotatedSize); for (int i = 0; i < mountPoints.Length; ++i) { var thisMountPoint = mountPoints[i]; Vector3 centeredStart = thisMountPoint.Start - center; Vector3 centeredEnd = thisMountPoint.End - center; if (MyFakes.ENABLE_TEST_BLOCK_CONNECTIVITY_CHECK) { // This code is used to avoid mixed start, end values, overlapped values on sides. So as result we need precise neighbour(s). Not neighbours touched on edges. // Start and end sometimes have exchanged values Vector3 start = Vector3.Min(thisMountPoint.Start, thisMountPoint.End); Vector3 end = Vector3.Max(thisMountPoint.Start, thisMountPoint.End); // Clamp only overlapped values on sides not thickness of aabb of mount point Vector3I clampMask = Vector3I.One - Vector3I.Abs(thisMountPoint.Normal); Vector3I invClampMask = Vector3I.One - clampMask; Vector3 clampedStart = invClampMask * start + Vector3.Clamp(start, Vector3.Zero, size) * clampMask + 0.001f * clampMask; Vector3 clampedEnd = invClampMask * end + Vector3.Clamp(end, Vector3.Zero, size) * clampMask - 0.001f * clampMask; centeredStart = clampedStart - center; centeredEnd = clampedEnd - center; } var centeredStartI = Vector3I.Floor(centeredStart); var centeredEndI = Vector3I.Floor(centeredEnd); Vector3 rotatedStart, rotatedEnd; Vector3.Transform(ref centeredStart, ref rotation, out rotatedStart); Vector3.Transform(ref centeredEnd, ref rotation, out rotatedEnd); Vector3I rotatedStartICorrect, rotatedEndICorrect; Vector3I.Transform(ref centeredStartI, ref rotation, out rotatedStartICorrect); Vector3I.Transform(ref centeredEndI, ref rotation, out rotatedEndICorrect); // Correction of rotation. Normally we perform computations in integers and so these are not needed, but when // transforming floats, we can end up rotating eg. 0.5f to -0.5f which, after Floor operation, would be like rotation of 0 to -1 (ie. wrong). // By rotating both floored and floating point versions, I can find out what change occured and handle it accordingly. var rotatedStartI = Vector3I.Floor(rotatedStart); var rotatedEndI = Vector3I.Floor(rotatedEnd); var correctionStart = rotatedStartICorrect - rotatedStartI; var correctionEnd = rotatedEndICorrect - rotatedEndI; rotatedStart += correctionStart; rotatedEnd += correctionEnd; Vector3 gridPosStart = position + rotatedStart; Vector3 gridPosEnd = position + rotatedEnd; m_cacheNeighborBlocks.Clear(); var currentMin = Vector3.Min(gridPosStart, gridPosEnd); var currentMax = Vector3.Max(gridPosStart, gridPosEnd); var minI = Vector3I.Floor(currentMin); var maxI = Vector3I.Floor(currentMax); grid.GetConnectedBlocks(minI, maxI, m_cacheNeighborBlocks); //MyCubeBuilder.Static.GetOverlappedGizmoBlocks(minI, maxI, m_cacheNeighborBlocks); if (m_cacheNeighborBlocks.Count == 0) continue; Vector3I transformedNormal; Vector3I.Transform(ref thisMountPoint.Normal, ref rotation, out transformedNormal); Debug.Assert(transformedNormal.RectangularLength() == 1); minI -= transformedNormal; maxI -= transformedNormal; Vector3I transformedNormalNegative = -transformedNormal; foreach (var neighbor in m_cacheNeighborBlocks.Values) { if (neighbor.Position == position) { if (MyFakes.ENABLE_COMPOUND_BLOCKS) { // If this neighbor does not want to connect, check another one if (neighbor.FatBlock != null && neighbor.FatBlock.CheckConnectionAllowed && !neighbor.FatBlock.ConnectionAllowed(ref minI, ref maxI, ref transformedNormalNegative, def)) continue; if (neighbor.FatBlock is MyCompoundCubeBlock) { MyCompoundCubeBlock compoundBlock = neighbor.FatBlock as MyCompoundCubeBlock; foreach (var blockInCompound in compoundBlock.GetBlocks()) { var blockInCompoundMountPoints = blockInCompound.BlockDefinition.GetBuildProgressModelMountPoints(blockInCompound.BuildLevelRatio); if (CheckNeighborMountPointsForCompound(currentMin, currentMax, thisMountPoint, ref transformedNormal, def, neighbor.Position, blockInCompound.BlockDefinition, blockInCompoundMountPoints, blockInCompound.Orientation, m_cacheMountPointsA)) return true; } } else { continue; } } else { continue; } } else { // If this neighbor does not want to connect, check another one if (neighbor.FatBlock != null && neighbor.FatBlock.CheckConnectionAllowed && !neighbor.FatBlock.ConnectionAllowed(ref minI, ref maxI, ref transformedNormalNegative, def)) continue; if (neighbor.FatBlock is MyCompoundCubeBlock) { MyCompoundCubeBlock compoundBlock = neighbor.FatBlock as MyCompoundCubeBlock; foreach (var blockInCompound in compoundBlock.GetBlocks()) { var blockInCompoundMountPoints = blockInCompound.BlockDefinition.GetBuildProgressModelMountPoints(blockInCompound.BuildLevelRatio); if (CheckNeighborMountPoints(currentMin, currentMax, thisMountPoint, ref transformedNormal, def, neighbor.Position, blockInCompound.BlockDefinition, blockInCompoundMountPoints, blockInCompound.Orientation, m_cacheMountPointsA)) return true; } } else { var buildLevelRatio = 1.0f; if(neighbor.FatBlock != null && neighbor.FatBlock.SlimBlock != null) buildLevelRatio = neighbor.FatBlock.SlimBlock.BuildLevelRatio; var neighborMountPoints = neighbor.Definition.GetBuildProgressModelMountPoints(buildLevelRatio); if (CheckNeighborMountPoints(currentMin, currentMax, thisMountPoint, ref transformedNormal, def, neighbor.Position, neighbor.Definition, neighborMountPoints, neighbor.Orientation, m_cacheMountPointsA)) return true; } } } } return false; } finally { m_cacheNeighborBlocks.Clear(); ProfilerShort.End(); } }