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); } } } }
public void RotateAsteroid(VRageMath.Quaternion quaternion) { var sourceFile = SourceVoxelFilepath ?? VoxelFilepath; var asteroid = new MyVoxelMap(); asteroid.Load(sourceFile, SpaceEngineersCore.Resources.GetDefaultMaterialName(), true); var newAsteroid = new MyVoxelMap(); var transSize = Vector3I.Transform(asteroid.Size, quaternion); var newSize = Vector3I.Abs(transSize); newAsteroid.Init(Vector3D.Zero, newSize, SpaceEngineersCore.Resources.GetDefaultMaterialName()); Vector3I coords; for (coords.Z = 0; coords.Z < asteroid.Size.Z; coords.Z++) { for (coords.Y = 0; coords.Y < asteroid.Size.Y; coords.Y++) { for (coords.X = 0; coords.X < asteroid.Size.X; coords.X++) { byte volume = 0xff; string cellMaterial; asteroid.GetVoxelMaterialContent(ref coords, out cellMaterial, out volume); var newCoord = Vector3I.Transform(coords, quaternion); // readjust the points, as rotation occurs arround 0,0,0. newCoord.X = newCoord.X < 0 ? newCoord.X - transSize.X : newCoord.X; newCoord.Y = newCoord.Y < 0 ? newCoord.Y - transSize.Y : newCoord.Y; newCoord.Z = newCoord.Z < 0 ? newCoord.Z - transSize.Z : newCoord.Z; newAsteroid.SetVoxelContent(volume, ref newCoord); newAsteroid.SetVoxelMaterialAndIndestructibleContent(cellMaterial, 0xff, ref newCoord); } } } var tempfilename = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension); newAsteroid.Save(tempfilename); SourceVoxelFilepath = tempfilename; }
// Contributed by Conrad "Redshift" Morgan protected static IEnumerable<Vector3I> LineEnumerator(Vector3I a, Vector3I b) { Vector3I pixel = a; Vector3I d = b - a; Vector3I inc = new Vector3I(Math.Sign(d.X), Math.Sign(d.Y), Math.Sign(d.Z)); d = d.Abs(); Vector3I d2 = d * 2; int x, y, z; if ((d.X >= d.Y) && (d.X >= d.Z)) { x = 0; y = 1; z = 2; } else if ((d.Y >= d.X) && (d.Y >= d.Z)) { x = 1; y = 2; z = 0; } else { x = 2; y = 0; z = 1; } int err1 = d2[y] - d[x]; int err2 = d2[z] - d[x]; for (int i = 0; i < d[x]; i++) { yield return pixel; if (err1 > 0) { pixel[y] += inc[y]; err1 -= d2[x]; } if (err2 > 0) { pixel[z] += inc[z]; err2 -= d2[x]; } err1 += d2[y]; err2 += d2[z]; pixel[x] += inc[x]; } yield return b; }
/// <summary> /// Checks if blocks are neigbors to block(s) in aabbForNeighbors. /// </summary> private static void CheckNeighborBlocks(MySlimBlock block, BoundingBoxD aabbForNeighbors, MyCubeGrid cubeGrid, List <MySlimBlock> blocks) { var compositeTransformToGrid = block.CubeGrid.WorldMatrix * cubeGrid.PositionComp.WorldMatrixNormalizedInv; var aabbForNeighborsInGrid = aabbForNeighbors.TransformFast(ref compositeTransformToGrid); Vector3I start = Vector3I.Round(cubeGrid.GridSizeR * aabbForNeighborsInGrid.Min); Vector3I end = Vector3I.Round(cubeGrid.GridSizeR * aabbForNeighborsInGrid.Max); Vector3I startIt = Vector3I.Min(start, end); Vector3I endIt = Vector3I.Max(start, end); for (int slimBlockIndex = blocks.Count - 1; slimBlockIndex >= 0; --slimBlockIndex) { var slimBlock = blocks[slimBlockIndex]; bool found = false; Vector3I_RangeIterator itBlockInGridPos = new Vector3I_RangeIterator(ref slimBlock.Min, ref slimBlock.Max); var posInGrid = itBlockInGridPos.Current; for (; itBlockInGridPos.IsValid(); itBlockInGridPos.GetNext(out posInGrid)) { Vector3I_RangeIterator itBlockPos = new Vector3I_RangeIterator(ref startIt, ref endIt); var pos = itBlockPos.Current; for (; itBlockPos.IsValid(); itBlockPos.GetNext(out pos)) { Vector3I diff = Vector3I.Abs(posInGrid - pos); if (pos == posInGrid || diff.X + diff.Y + diff.Z == 1) { found = true; break; } } if (found) { break; } } if (!found) { blocks.RemoveAt(slimBlockIndex); } } }
protected void DrawBuildingStepsCount(Vector3I?startBuild, Vector3I?startRemove, Vector3I?continueBuild, ref Matrix localMatrixAdd) { var startPosition = startBuild ?? startRemove; if (startPosition != null && continueBuild != null) { Vector3I rotatedSize; Vector3I.TransformNormal(ref CurrentBlockDefinition.Size, ref localMatrixAdd, out rotatedSize); rotatedSize = Vector3I.Abs(rotatedSize); int stepCount; Vector3I stepDelta; Vector3I counter; ComputeSteps(startPosition.Value, continueBuild.Value, startBuild.HasValue ? rotatedSize : Vector3I.One, out stepDelta, out counter, out stepCount); m_cubeCountStringBuilder.Clear(); m_cubeCountStringBuilder.Append(" "); m_cubeCountStringBuilder.AppendInt32(stepCount); MyGuiManager.DrawString(MyFontEnum.White, m_cubeCountStringBuilder, new Vector2(0.5f, 0.5f), 1.5f); } }
static DeformationTable CreateTable(Vector3I normal) { DeformationTable result = new DeformationTable(); result.Normal = normal; Vector3I centerBone = new Vector3I(1, 1, 1); var absNormal = Vector3I.Abs(normal); var mask = new Vector3I(1, 1, 1) - absNormal; mask *= 2; for (int x = -mask.X; x <= mask.X; x++) { for (int y = -mask.Y; y <= mask.Y; y++) { for (int z = -mask.Z; z <= mask.Z; z++) { var offset = new Vector3I(x, y, z); float maxOffset = Math.Max(Math.Abs(z), Math.Max(Math.Abs(x), Math.Abs(y))); float ratio = 1; if (maxOffset > 1) { ratio = 0.3f; } float moveDist = ratio * MyGridConstants.DEFORMATION_TABLE_BASE_MOVE_DIST; Vector3I offsetA = centerBone + new Vector3I(x, y, z) + normal; result.OffsetTable.Add(offsetA, -normal * moveDist); result.MinOffset = Vector3I.Min(result.MinOffset, offset); result.MaxOffset = Vector3I.Max(result.MaxOffset, offset); } } } return(result); }
private int GetBlockTotalEstimate() { Vector3I nabs = normal.Abs(); return(Math.Max(Math.Max(nabs.X, nabs.Y), nabs.Z) / 2); }
protected static void AddFastBuildModelWithSubparts(ref MatrixD matrix, List <MatrixD> matrices, List <string> models, MyCubeBlockDefinition blockDefinition, float gridScale) { 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 = VRage.Game.Models.MyModels.GetModelOnlyData(blockDefinition.Model); modelData.Rescale(gridScale); foreach (var dummy in modelData.Dummies) { if (MyEntitySubpart.GetSubpartFromDummy(blockDefinition.Model, dummy.Key, dummy.Value, ref data)) { // Rescale model var model = VRage.Game.Models.MyModels.GetModelOnlyData(data.File); if (model != null) { model.Rescale(gridScale); } 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)) { // Rescale model var model = VRage.Game.Models.MyModels.GetModelOnlyData(subBlockDefinition.Model); if (model != null) { model.Rescale(gridScale); } // 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); } } } // Precache models for generated blocks if (MyFakes.ENABLE_GENERATED_BLOCKS && !blockDefinition.IsGeneratedBlock && blockDefinition.GeneratedBlockDefinitions != null) { foreach (var generatedBlockDefId in blockDefinition.GeneratedBlockDefinitions) { MyCubeBlockDefinition generatedBlockDef; if (MyDefinitionManager.Static.TryGetCubeBlockDefinition(generatedBlockDefId, out generatedBlockDef)) { var model = VRage.Game.Models.MyModels.GetModelOnlyData(generatedBlockDef.Model); if (model != null) { model.Rescale(gridScale); } } } } }
public override void Draw() { base.Draw(); //VRageRender.MyRenderProxy.DebugDrawAABB(m_cubeBuilderAABB, Vector3.One, 1, 1, false); if (BlockCreationIsActivated) { MyHud.Crosshair.Position = MyHudCrosshair.ScreenCenter; } if (IsActivated) { if (DynamicMode) { CurrentGrid = null; CurrentVoxelMap = null; } else { ChoosePlacementObject(); } } if (ShipCreationIsActivated) { m_shipCreationClipboard.Update(); ShipCreationClipboard.CalculateRotationHints(m_rotationHints, m_rotationHintRotating); } else if (CopyPasteIsActivated) { Clipboard.CalculateRotationHints(m_rotationHints, m_rotationHintRotating); } else if (CopyPasteFloatingObjectIsActivated) { FloatingObjectClipboard.CalculateRotationHints(m_rotationHints, m_rotationHintRotating); } else if (MultiBlockCreationIsActivated) { m_multiBlockCreationClipboard.CalculateRotationHints(m_rotationHints, false); } if (!BuildInputValid || MultiBlockCreationIsActivated || ShipCreationIsActivated || CopyPasteIsActivated || CopyPasteFloatingObjectIsActivated) { m_renderData.ClearInstanceData(); m_renderData.UpdateRenderInstanceData(); m_renderData.UpdateRenderEntitiesData(CurrentGrid != null ? CurrentGrid.WorldMatrix : MatrixD.Identity, UseTransparency); if (!ShipCreationIsActivated && !CopyPasteIsActivated && !MultiBlockCreationIsActivated) { m_rotationHints.Clear(); VRageRender.MyRenderProxy.RemoveBillboardViewProjection(0); } if (MyFakes.ENABLE_DEBUG_DRAW_TEXTURE_NAMES) { DebugDrawModelTextures(); } if (MultiBlockCreationIsActivated) { UpdateBlockInfoHud(); } return; } var startPosition = m_gizmo.SpaceDefault.m_startBuild ?? m_gizmo.SpaceDefault.m_startRemove; if (startPosition != null && m_gizmo.SpaceDefault.m_continueBuild != null) { Vector3I rotatedSize; Vector3I.TransformNormal(ref CurrentBlockDefinition.Size, ref m_gizmo.SpaceDefault.m_localMatrixAdd, out rotatedSize); rotatedSize = Vector3I.Abs(rotatedSize); int stepCount; Vector3I stepDelta; Vector3I counter; ComputeSteps(startPosition.Value, m_gizmo.SpaceDefault.m_continueBuild.Value, m_gizmo.SpaceDefault.m_startBuild.HasValue ? rotatedSize : Vector3I.One, out stepDelta, out counter, out stepCount); m_cubeCountStringBuilder.Clear(); m_cubeCountStringBuilder.Append(" "); m_cubeCountStringBuilder.AppendInt32(stepCount); MyGuiManager.DrawString(MyFontEnum.White, m_cubeCountStringBuilder, new Vector2(0.5f, 0.5f), 1.5f); } bool addPos = m_gizmo.SpaceDefault.m_startBuild.HasValue; bool removePos = false; if (DynamicMode) { Vector3D freePlacementIntersectionPoint = GetFreeSpacePlacementPosition(out m_gizmo.SpaceDefault.m_dynamicBuildAllowed); m_gizmo.SpaceDefault.m_worldMatrixAdd.Translation = freePlacementIntersectionPoint; addPos = true; } else { if (m_gizmo.SpaceDefault.m_startBuild == null && m_gizmo.SpaceDefault.m_startRemove == null) { if (!FreezeGizmo) { float gridSize = MyDefinitionManager.Static.GetCubeSize(CurrentBlockDefinition.CubeSize); addPos = GetAddAndRemovePositions(gridSize, PlacingSmallGridOnLargeStatic, out m_gizmo.SpaceDefault.m_addPos, out m_gizmo.SpaceDefault.m_addPosSmallOnLarge, out m_gizmo.SpaceDefault.m_addDir, out m_gizmo.SpaceDefault.m_removePos, out m_gizmo.SpaceDefault.m_removeBlock, out m_gizmo.SpaceDefault.m_blockIdInCompound); } if (addPos) { if (PlacingSmallGridOnLargeStatic) { m_gizmo.SpaceDefault.m_localMatrixAdd.Translation = m_gizmo.SpaceDefault.m_addPosSmallOnLarge.Value; } else { m_gizmo.SpaceDefault.m_localMatrixAdd.Translation = m_gizmo.SpaceDefault.m_addPos; } if (CurrentGrid != null) { m_gizmo.SpaceDefault.m_worldMatrixAdd = m_gizmo.SpaceDefault.m_localMatrixAdd * CurrentGrid.WorldMatrix; } else { m_gizmo.SpaceDefault.m_worldMatrixAdd = m_gizmo.SpaceDefault.m_localMatrixAdd; } Debug.Assert(!m_gizmo.SpaceDefault.m_worldMatrixAdd.IsNan(), "Invalid gizmo matrix"); if (m_gizmo.SpaceDefault.m_removeBlock != null) { removePos = true; } } } } bool buildingDisabledByCockpit = MySession.ControlledEntity != null && MySession.ControlledEntity is MyCockpit && !DeveloperSpectatorIsBuilding; //bool buildingDisabledByCockpit = true; if (!buildingDisabledByCockpit) { if (IsInSymmetrySettingMode) { m_gizmo.SpaceDefault.m_continueBuild = null; addPos = false; removePos = false; if (m_gizmo.SpaceDefault.m_removeBlock != null) { var min = (m_gizmo.SpaceDefault.m_removeBlock.Min * CurrentGrid.GridSize); var max = (m_gizmo.SpaceDefault.m_removeBlock.Max * CurrentGrid.GridSize); Vector3 center = (min + max) * 0.5f; Color color = DrawSymmetryPlane(m_symmetrySettingMode, CurrentGrid, center); DrawSemiTransparentBox(CurrentGrid, m_gizmo.SpaceDefault.m_removeBlock, color.ToVector4()); } } if (CurrentGrid != null && (UseSymmetry || IsInSymmetrySettingMode)) { if (CurrentGrid.XSymmetryPlane != null) { Vector3 center = CurrentGrid.XSymmetryPlane.Value * CurrentGrid.GridSize; DrawSymmetryPlane(CurrentGrid.XSymmetryOdd ? MySymmetrySettingModeEnum.XPlaneOdd : MySymmetrySettingModeEnum.XPlane, CurrentGrid, center); } if (CurrentGrid.YSymmetryPlane != null) { Vector3 center = CurrentGrid.YSymmetryPlane.Value * CurrentGrid.GridSize; DrawSymmetryPlane(CurrentGrid.YSymmetryOdd ? MySymmetrySettingModeEnum.YPlaneOdd : MySymmetrySettingModeEnum.YPlane, CurrentGrid, center); } if (CurrentGrid.ZSymmetryPlane != null) { Vector3 center = CurrentGrid.ZSymmetryPlane.Value * CurrentGrid.GridSize; DrawSymmetryPlane(CurrentGrid.ZSymmetryOdd ? MySymmetrySettingModeEnum.ZPlaneOdd : MySymmetrySettingModeEnum.ZPlane, CurrentGrid, center); } } } UpdateGizmos(addPos, removePos, true); m_renderData.UpdateRenderInstanceData(); if (DynamicMode || CurrentVoxelMap != null) { MatrixD drawMatrix = m_gizmo.SpaceDefault.m_worldMatrixAdd; Vector3D rotatedModelOffset; Vector3D.TransformNormal(ref CurrentBlockDefinition.ModelOffset, ref drawMatrix, out rotatedModelOffset); drawMatrix.Translation = drawMatrix.Translation + rotatedModelOffset; m_renderData.UpdateRenderEntitiesData(drawMatrix, UseTransparency); } else { m_renderData.UpdateRenderEntitiesData(CurrentGrid != null ? CurrentGrid.WorldMatrix : MatrixD.Identity, UseTransparency); } UpdateBlockInfoHud(); DebugDraw(); }
/// <summary> /// Casts preview grids aabbs and get shortest distance. Returns shortest intersection or null. /// </summary> protected Vector3D?GetFreeSpacePlacementPositionGridAabbs(bool copyPaste, out bool buildAllowed) { Vector3D?freePlacementIntersectionPoint = null; buildAllowed = true; float gridSize = PreviewGrids[0].GridSize; double shortestDistance = double.MaxValue; double?currentRayInts = MyCubeBuilder.GetCurrentRayIntersection(); if (currentRayInts.HasValue) { shortestDistance = currentRayInts.Value; } Vector3D worldRefPointOffset = Vector3D.Zero; if (copyPaste) { Matrix firstGridOrientation = GetFirstGridOrientationMatrix(); worldRefPointOffset = Vector3.TransformNormal(m_dragPointToPositionLocal, firstGridOrientation); } Vector3D worldRefPoint = PreviewGrids[0].GridIntegerToWorld(Vector3I.Zero); foreach (var grid in PreviewGrids) { Vector3 halfExt = grid.PositionComp.LocalAABB.HalfExtents; Vector3 minLocal = grid.Min * grid.GridSize - Vector3.Half * grid.GridSize; Vector3 maxLocal = grid.Max * grid.GridSize + Vector3.Half * grid.GridSize; MatrixD gridWorlTransform = MatrixD.Identity; gridWorlTransform.Translation = 0.5f * (minLocal + maxLocal); gridWorlTransform = gridWorlTransform * grid.WorldMatrix; Vector3I size = grid.Max - grid.Min + Vector3I.One; Vector3 sizeOffset = Vector3I.Abs((size % 2) - Vector3I.One) * 0.5 * grid.GridSize; sizeOffset = Vector3.TransformNormal(sizeOffset, grid.WorldMatrix); Vector3D offset = gridWorlTransform.Translation + worldRefPointOffset - worldRefPoint /*- sizeOffset*/;// Vector3.Zero;// gridWorlTransform.Translation + worldRefPointOffset - worldRefPoint; HkShape shape = new HkBoxShape(halfExt); Vector3D rayStart = MyCubeBuilder.IntersectionStart + offset; double castPlaneDistanceToRayStart = DistanceFromCharacterPlane(ref rayStart); rayStart -= castPlaneDistanceToRayStart * MyCubeBuilder.IntersectionDirection; Vector3D rayEnd = MyCubeBuilder.IntersectionStart + (m_dragDistance - castPlaneDistanceToRayStart) * MyCubeBuilder.IntersectionDirection + offset; MatrixD matrix = gridWorlTransform; matrix.Translation = rayStart; try { float?dist = MyPhysics.CastShape(rayEnd, shape, ref matrix, MyPhysics.CollisionLayers.CollisionLayerWithoutCharacter); if (dist.HasValue && dist.Value != 0f) { Vector3D intersectionPoint = rayStart + dist.Value * (rayEnd - rayStart); const bool debugDraw = true; if (debugDraw) { Color green = Color.Green; BoundingBoxD localAABB = new BoundingBoxD(-halfExt, halfExt); localAABB.Inflate(0.03f); MatrixD drawMatrix = matrix; drawMatrix.Translation = intersectionPoint; MySimpleObjectDraw.DrawTransparentBox(ref drawMatrix, ref localAABB, ref green, MySimpleObjectRasterizer.Wireframe, 1, 0.04f); } double fixedDistance = DistanceFromCharacterPlane(ref intersectionPoint) - castPlaneDistanceToRayStart; if (fixedDistance <= 0) { fixedDistance = 0; shortestDistance = 0; buildAllowed = false; break; } if (fixedDistance < shortestDistance) { shortestDistance = fixedDistance; } } else { buildAllowed = false; } } finally { shape.RemoveReference(); } } if (shortestDistance != 0 && shortestDistance < m_dragDistance) { freePlacementIntersectionPoint = MyCubeBuilder.IntersectionStart + shortestDistance * MyCubeBuilder.IntersectionDirection; } else { buildAllowed = false; } return(freePlacementIntersectionPoint); }
// ReSharper restore InconsistentNaming public void DebugDraw(bool force = false) { force |= ForceDebugDraw; if (!force && !Settings.DebugDraw) { return; } var transform = Grid.WorldMatrix; var gridSize = Grid.GridSize; foreach (var room in Construction.Rooms) { if (force || Settings.DebugDrawBlocks) { var localAABB = new BoundingBoxD((room.BoundingBox.Min - 0.5f) * gridSize, (room.BoundingBox.Max + 0.5f) * gridSize); MySimpleObjectDraw.DrawTransparentBox(ref transform, ref localAABB, ref DebugColorBlocksTotal, MySimpleObjectRasterizer.Wireframe, 1, .02f); } if (force || Settings.DebugDrawReservedTotal && room.Part.ReservedSpaces.Any()) { var temp = Utilities.TransformBoundingBox(room.Part.ReservedSpace, room.Transform); var tmpAABB = new BoundingBoxD((temp.Min - 0.5f) * gridSize, (temp.Max + 0.5f) * gridSize); MySimpleObjectDraw.DrawTransparentBox(ref transform, ref tmpAABB, ref DebugColorReservedSpaceTotal, MySimpleObjectRasterizer.Wireframe, 1, .02f); } if (force || Settings.DebugDrawReserved) { foreach (var rs in room.Part.ReservedSpaces) { var temp = Utilities.TransformBoundingBox(rs.Box, room.Transform); var tmpAABB = new BoundingBoxD(temp.Min * gridSize, (temp.Max + 1) * gridSize); tmpAABB = tmpAABB.Inflate(-0.02); Color color; if (rs.IsShared && rs.IsOptional) { color = DebugColorReservedSpaceBoth; } else if (rs.IsShared) { color = DebugColorReservedSpaceShared; } else if (rs.IsOptional) { color = DebugColorReservedSpaceOptional; } else { color = DebugColorReservedSpace; } MySimpleObjectDraw.DrawTransparentBox(ref transform, ref tmpAABB, ref color, MySimpleObjectRasterizer.Wireframe, 1, .005f); } } // ReSharper disable once InvertIf if (force || Settings.DebugDrawMountPoints) { foreach (var mount in room.MountPoints) { foreach (var block in mount.MountPoint.Blocks) { var anchorLoc = (Vector3)block.AnchorLocation; var opposeLoc = (Vector3)(block.AnchorLocation + (block.MountDirection * 2)); opposeLoc += 0.5f * Vector3.Abs(Vector3I.One - Vector3I.Abs(block.MountDirection)); // hacky way to get perp. components anchorLoc -= 0.5f * Vector3.Abs(Vector3I.One - Vector3I.Abs(block.MountDirection)); var anchor = gridSize * Vector3.Transform(anchorLoc, room.Transform.GetFloatMatrix()); var oppose = gridSize * Vector3.Transform(opposeLoc, room.Transform.GetFloatMatrix()); var tmpAABB = new BoundingBoxD(Vector3.Min(anchor, oppose), Vector3.Max(anchor, oppose)); MySimpleObjectDraw.DrawTransparentBox(ref transform, ref tmpAABB, ref DebugColorMountPoint, MySimpleObjectRasterizer.Solid, 1, .02f); } } } } }
private new void FixSnapTransformationBase6() { Debug.Assert(CopiedGrids.Count > 0); if (CopiedGrids.Count == 0) { return; } var hitGrid = m_hitEntity as MyCubeGrid; if (hitGrid == null) { return; } // Fix rotation of the first pasted grid Matrix hitGridRotation = hitGrid.WorldMatrix.GetOrientation(); Matrix firstRotation = PreviewGrids[0].WorldMatrix.GetOrientation(); Matrix newFirstRotation = Matrix.AlignRotationToAxes(ref firstRotation, ref hitGridRotation); Matrix rotationDelta = Matrix.Invert(firstRotation) * newFirstRotation; foreach (var grid in PreviewGrids) { Matrix rotation = grid.WorldMatrix.GetOrientation(); rotation = rotation * rotationDelta; Matrix rotationInv = Matrix.Invert(rotation); Vector3D position = m_pastePosition; MatrixD newWorld = MatrixD.CreateWorld(position, rotation.Forward, rotation.Up); Debug.Assert(newWorld.GetOrientation().IsRotation()); grid.PositionComp.SetWorldMatrix(newWorld); } bool smallOnLargeGrid = hitGrid.GridSizeEnum == MyCubeSize.Large && PreviewGrids[0].GridSizeEnum == MyCubeSize.Small; if (smallOnLargeGrid) { Vector3 pasteOffset = TransformLargeGridHitCoordToSmallGrid(m_hitPos, hitGrid.PositionComp.WorldMatrixNormalizedInv, hitGrid.GridSize); m_pastePosition = hitGrid.GridIntegerToWorld(pasteOffset); } else { // Find a collision-free position for the first paste grid along the raycast normal Vector3I collisionTestStep = Vector3I.Round(m_hitNormal); Vector3I pasteOffset = hitGrid.WorldToGridInteger(m_pastePosition); Vector3I previewGridMin = PreviewGrids[0].Min; Vector3I previewGridMax = PreviewGrids[0].Max; Vector3I previewGridSize = previewGridMax - previewGridMin + Vector3I.One; Vector3D previewGridSizeInWorld = Vector3D.TransformNormal((Vector3D)previewGridSize, PreviewGrids[0].WorldMatrix); Vector3I previewGridSizeInHitGrid = Vector3I.Abs(Vector3I.Round(Vector3D.TransformNormal(previewGridSizeInWorld, hitGrid.PositionComp.WorldMatrixNormalizedInv))); int attemptsCount = Math.Abs(Vector3I.Dot(ref collisionTestStep, ref previewGridSizeInHitGrid)); Debug.Assert(attemptsCount > 0); int i; for (i = 0; i < attemptsCount; ++i) { if (hitGrid.CanMergeCubes(PreviewGrids[0], pasteOffset)) { break; } pasteOffset += collisionTestStep; } if (i == attemptsCount) { pasteOffset = hitGrid.WorldToGridInteger(m_pastePosition); } m_pastePosition = hitGrid.GridIntegerToWorld(pasteOffset); } // Move all the grids according to the collision-free position of the first one for (int i = 0; i < PreviewGrids.Count; ++i) { var grid = PreviewGrids[i]; MatrixD matrix = grid.WorldMatrix; matrix.Translation = m_pastePosition + Vector3.Transform(m_copiedGridOffsets[i], rotationDelta); grid.PositionComp.SetWorldMatrix(matrix); } if (MyDebugDrawSettings.DEBUG_DRAW_COPY_PASTE) { MyRenderProxy.DebugDrawLine3D(m_hitPos, m_hitPos + m_hitNormal, Color.Red, Color.Green, false); } }
public override bool Invoke(ulong steamId, long playerId, string messageText) { if (messageText.StartsWith("/rotateroid ", StringComparison.InvariantCultureIgnoreCase)) { var match = Regex.Match(messageText, @"/rotateroid\s{1,}(?<Key>.+){1,}\s{1,}(?<X>[+-]?((\d+(\.\d*)?)|(\.\d+)))\s{1,}(?<Y>[+-]?((\d+(\.\d*)?)|(\.\d+)))\s{1,}(?<Z>[+-]?((\d+(\.\d*)?)|(\.\d+)))", RegexOptions.IgnoreCase); if (match.Success) { var rotateVector = new Vector3( double.Parse(match.Groups["X"].Value, CultureInfo.InvariantCulture), double.Parse(match.Groups["Y"].Value, CultureInfo.InvariantCulture), double.Parse(match.Groups["Z"].Value, CultureInfo.InvariantCulture)); var searchName = match.Groups["Key"].Value; var currentAsteroidList = new List <IMyVoxelBase>(); IMyVoxelBase originalAsteroid = null; MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.StorageName.Equals(searchName, StringComparison.InvariantCultureIgnoreCase)); if (currentAsteroidList.Count == 1) { originalAsteroid = currentAsteroidList[0]; } else { MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.StorageName.IndexOf(searchName, StringComparison.InvariantCultureIgnoreCase) >= 0); if (currentAsteroidList.Count == 1) { originalAsteroid = currentAsteroidList[0]; } } List <IMyVoxelBase> asteroidCache = CommandAsteroidsList.GetAsteroidCache(steamId); int index; if (searchName.Substring(0, 1) == "#" && Int32.TryParse(searchName.Substring(1), out index) && index > 0 && index <= asteroidCache.Count) { originalAsteroid = asteroidCache[index - 1]; } if (originalAsteroid == null) { MyAPIGateway.Utilities.SendMessage(steamId, "Cannot find asteroid", string.Format("'{0}'", searchName)); return(true); } var quaternion = Quaternion.CreateFromYawPitchRoll(rotateVector.X / (180 / MathHelper.Pi), rotateVector.Y / (180 / MathHelper.Pi), rotateVector.Z / (180 / MathHelper.Pi)); var oldStorage = originalAsteroid.Storage; var oldCache = new MyStorageData(); oldCache.Resize(oldStorage.Size); oldStorage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, 0, Vector3I.Zero, oldStorage.Size - 1); var transSize = Vector3I.Transform(oldStorage.Size, quaternion); var newSize = Vector3I.Abs(transSize); var newName = Support.CreateUniqueStorageName(originalAsteroid.StorageName); var newVoxelMap = Support.CreateNewAsteroid(newName, newSize, originalAsteroid.PositionLeftBottomCorner); var cache = new MyStorageData(); var min = Vector3I.Zero; var max = newSize - 1; cache.Resize(min, max); Vector3I p; for (p.Z = 0; p.Z < oldStorage.Size.Z; ++p.Z) { for (p.Y = 0; p.Y < oldStorage.Size.Y; ++p.Y) { for (p.X = 0; p.X < oldStorage.Size.X; ++p.X) { var content = oldCache.Content(ref p); var material = oldCache.Material(ref p); var newP = Vector3I.Transform(p, quaternion); // readjust the points, as rotation occurs arround 0,0,0. newP.X = newP.X < 0 ? newP.X - transSize.X - 1 : newP.X; newP.Y = newP.Y < 0 ? newP.Y - transSize.Y - 1 : newP.Y; newP.Z = newP.Z < 0 ? newP.Z - transSize.Z - 1 : newP.Z; cache.Content(ref newP, content); cache.Material(ref newP, material); } } } newVoxelMap.Storage.WriteRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, min, max); MyAPIGateway.Entities.RemoveEntity((IMyEntity)originalAsteroid); // Invalidate the cache, to force user to select again to prevent possible corruption by using an old cache. asteroidCache.Clear(); return(true); } } return(false); }
private static void CheckNeighborBlocks(MySlimBlock block, BoundingBoxD aabbForNeighbors, MyCubeGrid cubeGrid, List <MySlimBlock> blocks) { MatrixD m = block.CubeGrid.WorldMatrix * cubeGrid.PositionComp.WorldMatrixNormalizedInv; BoundingBoxD xd2 = aabbForNeighbors.TransformFast(ref m); Vector3I vectori = Vector3I.Round((Vector3D)(cubeGrid.GridSizeR * xd2.Max)); Vector3I vectori1 = Vector3I.Round((Vector3D)(cubeGrid.GridSizeR * xd2.Min)); Vector3I start = Vector3I.Min(vectori1, vectori); Vector3I end = Vector3I.Max(vectori1, vectori); int index = blocks.Count - 1; while (true) { bool flag; while (true) { if (index < 0) { return; } MySlimBlock block2 = blocks[index]; flag = false; Vector3I_RangeIterator iterator = new Vector3I_RangeIterator(ref block2.Min, ref block2.Max); Vector3I current = iterator.Current; while (true) { if (!iterator.IsValid()) { break; } Vector3I_RangeIterator iterator2 = new Vector3I_RangeIterator(ref start, ref end); Vector3I next = iterator2.Current; while (true) { if (iterator2.IsValid()) { Vector3I vectori6 = Vector3I.Abs(current - next); if ((next != current) && (((vectori6.X + vectori6.Y) + vectori6.Z) != 1)) { iterator2.GetNext(out next); continue; } flag = true; } if (flag) { break; } else { iterator.GetNext(out current); } break; } } break; } if (!flag) { blocks.RemoveAt(index); } index--; } }
protected static void AddFastBuildModelWithSubparts(ref MatrixD matrix, List <MatrixD> matrices, List <string> models, MyCubeBlockDefinition blockDefinition, float gridScale) { if (!string.IsNullOrEmpty(blockDefinition.Model)) { matrices.Add(matrix); models.Add(blockDefinition.Model); MyEntitySubpart.Data outData = new MyEntitySubpart.Data(); MyModel modelOnlyData = MyModels.GetModelOnlyData(blockDefinition.Model); modelOnlyData.Rescale(gridScale); foreach (KeyValuePair <string, MyModelDummy> pair in modelOnlyData.Dummies) { MyCubeBlockDefinition definition; MatrixD xd; Vector3 vector; if (MyEntitySubpart.GetSubpartFromDummy(blockDefinition.Model, pair.Key, pair.Value, ref outData)) { MyModel model = MyModels.GetModelOnlyData(outData.File); if (model != null) { model.Rescale(gridScale); } MatrixD item = MatrixD.Multiply(outData.InitialTransform, matrix); matrices.Add(item); models.Add(outData.File); continue; } if (MyFakes.ENABLE_SUBBLOCKS && (MyCubeBlock.GetSubBlockDataFromDummy(blockDefinition, pair.Key, pair.Value, false, out definition, out xd, out vector) && !string.IsNullOrEmpty(definition.Model))) { Vector3I vectori4; MyModel model2 = MyModels.GetModelOnlyData(definition.Model); if (model2 != null) { model2.Rescale(gridScale); } Vector3I vectori = Vector3I.Round(Vector3.DominantAxisProjection((Vector3)xd.Forward)); Vector3I vectori2 = Vector3I.One - Vector3I.Abs(vectori); Vector3I vectori3 = Vector3I.Round(Vector3.DominantAxisProjection((Vector3)(xd.Right * vectori2))); Vector3I.Cross(ref vectori3, ref vectori, out vectori4); xd.Forward = (Vector3D)vectori; xd.Right = (Vector3D)vectori3; xd.Up = (Vector3D)vectori4; MatrixD item = MatrixD.Multiply(xd, matrix); matrices.Add(item); models.Add(definition.Model); } } if ((MyFakes.ENABLE_GENERATED_BLOCKS && !blockDefinition.IsGeneratedBlock) && (blockDefinition.GeneratedBlockDefinitions != null)) { foreach (MyDefinitionId id in blockDefinition.GeneratedBlockDefinitions) { MyCubeBlockDefinition definition2; if (MyDefinitionManager.Static.TryGetCubeBlockDefinition(id, out definition2)) { MyModel model3 = MyModels.GetModelOnlyData(definition2.Model); if (model3 != null) { model3.Rescale(gridScale); } } } } } }
private void update_rendered_images(int limit) { int count = 0; char newchar = 'X'; if (!shadows_baked) { limit = initial_limit; } if (coords_to_render.Count == 0) { //render_index=0; //show_damage=false; //damage_iterator=(damage_iterator+1)%4; //if (damage_iterator==0) show_damage=false; if (shadows_rendered) { shadows_baked = true; } shadows_rendered = true; } if (shadows_rendered && !shadows_baked) { //The reason we're doing this is to avoid crazy render state dependency for a one-time function. bake_shadows(); coords_to_render = new List <Vector3I>(coords_ship_full); return; } while (count < limit && coords_to_render.Count > 0) { count++; Vector3I testvec = coords_to_render[0]; newchar = normal; if (!coords_ship_now.Contains(testvec)) { newchar = gone; } if (coords_terminal_now.Contains(testvec)) { if (!coords_terminal_working.Contains(testvec)) { newchar = broken; } if (!coords_terminal_nothacked.Contains(testvec)) { newchar = hacked; } } for (int r = 0; r < 6; r++) { Vector3I rotsize = Vector3I.Abs(Rotate3I(shipSizeVector, r)); Vector3I rotscanned = Vector3I.Abs(Rotate3I(testvec - shipCoordMin, r)); Vector3I rotcursor = Vector3I.Abs(Rotate3I(cursor_vec - shipCoordMin, r)); if (drawcursor && ( rotscanned.X == rotcursor.X || rotscanned.Y == rotcursor.Y)) { newchar = cursor; } int xyindex = rotscanned.X + (rotsize.Y - rotscanned.Y) * (rotsize.X + 1); char oldchar = GetCharAt(rendered_images[r][0][rotscanned.Z], xyindex); char oldchar_flat = GetCharAt(rendered_images[r][1][0], xyindex); if (!shadows_rendered) { rendered_shadows[r][1][0] = ReplaceAt(rendered_shadows[r][1][0], xyindex, shadow); continue; } for (int i = 0; i < 2; i++) { if (i == 1) { rendered_images[r][i][0] = ReplaceAt(rendered_images[r][i][0], xyindex, newchar); } if (i == 0) { rendered_images[r][i][rotscanned.Z] = ReplaceAt(rendered_images[r][i][rotscanned.Z], xyindex, newchar); } } } coords_to_render.Remove(testvec); } }