void AddFastBuildModels(MyCubeBuilderGizmo.MyGizmoSpaceProperties gizmoSpace, MatrixD baseMatrix, List<MatrixD> matrices, List<string> models, MyCubeBlockDefinition definition) { AddFastBuildModelWithSubparts(ref baseMatrix, matrices, models, definition); if (CurrentBlockDefinition != null && gizmoSpace.m_startBuild != null && gizmoSpace.m_continueBuild != null) { Vector3I rotatedSize; Vector3I.TransformNormal(ref CurrentBlockDefinition.Size, ref gizmoSpace.m_localMatrixAdd, out rotatedSize); rotatedSize = Vector3I.Abs(rotatedSize); Vector3I stepDelta; Vector3I counter; int stepCount; ComputeSteps(gizmoSpace.m_startBuild.Value, gizmoSpace.m_continueBuild.Value, rotatedSize, out stepDelta, out counter, out stepCount); Vector3I offset = Vector3I.Zero; for (int i = 0; i < counter.X; i += 1, offset.X += stepDelta.X) { offset.Y = 0; for (int j = 0; j < counter.Y; j += 1, offset.Y += stepDelta.Y) { offset.Z = 0; for (int k = 0; k < counter.Z; k += 1, offset.Z += stepDelta.Z) { Vector3I pos = offset; Vector3 offsetFloat; if (CurrentGrid != null) { offsetFloat = Vector3.Transform(pos * CurrentGrid.GridSize, CurrentGrid.WorldMatrix.GetOrientation()); } else { float gridSize = MyDefinitionManager.Static.GetCubeSize(CurrentBlockDefinition.CubeSize); offsetFloat = pos * gridSize; } var matrix = baseMatrix; matrix.Translation += offsetFloat; AddFastBuildModelWithSubparts(ref matrix, matrices, models, definition); } } } } }
private bool AddBlocksToBuildQueueOrSpawn(MyCubeBuilderGizmo.MyGizmoSpaceProperties gizmoSpace) { bool added = true; if (GridAndBlockValid) { if (PlacingSmallGridOnLargeStatic) { Vector3 offset = Vector3.Abs(Vector3.TransformNormal(MyCubeBlock.GetBlockGridOffset(gizmoSpace.m_blockDefinition), gizmoSpace.m_worldMatrixAdd)); MatrixD gridWorldMatrix = gizmoSpace.m_worldMatrixAdd; gridWorldMatrix.Translation -= offset; MySyncCreate.RequestStaticGridSpawn(gizmoSpace.m_blockDefinition, gridWorldMatrix); MyGuiAudio.PlaySound(MyGuiSounds.HudPlaceBlock); } else { m_blocksBuildQueue.Add(new MyCubeGrid.MyBlockLocation(gizmoSpace.m_blockDefinition.Id, gizmoSpace.m_min, gizmoSpace.m_max, gizmoSpace.m_centerPos, gizmoSpace.LocalOrientation, MyEntityIdentifier.AllocateId(), MySession.LocalPlayerId, MySession.LocalCharacter.EntityId)); } } else if (VoxelMapAndBlockValid && !DynamicMode) { Vector3 offset = Vector3.Abs(Vector3.TransformNormal(MyCubeBlock.GetBlockGridOffset(gizmoSpace.m_blockDefinition), gizmoSpace.m_worldMatrixAdd)); MatrixD gridWorldMatrix = gizmoSpace.m_worldMatrixAdd; gridWorldMatrix.Translation -= offset; MySyncCreate.RequestStaticGridSpawn(gizmoSpace.m_blockDefinition, gridWorldMatrix); } else if (DynamicMode) { MatrixD gridWorldMatrix = gizmoSpace.m_worldMatrixAdd; MySyncCreate.RequestDynamicGridSpawn(gizmoSpace.m_blockDefinition, gridWorldMatrix); MyGuiAudio.PlaySound(MyGuiSounds.HudPlaceBlock); } else { added = false; } return added; }
public MyCubeBuilder() { m_gizmo = new MyCubeBuilderGizmo(); InitializeNotifications(); }
private void UpdateGizmo_Grid(MyCubeBuilderGizmo.MyGizmoSpaceProperties gizmoSpace, bool add, bool remove, bool draw) { Color green = new Color(Color.Green * 0.6f, 1f); Color red = new Color(Color.Red * 0.8f, 1); Color yellow = Color.Yellow; Color black = Color.Black; Color gray = Color.Gray; Color white = Color.White; if (add) { if (gizmoSpace.m_startBuild != null && gizmoSpace.m_continueBuild != null) { gizmoSpace.m_buildAllowed = true; } if (PlacingSmallGridOnLargeStatic && gizmoSpace.m_positionsSmallOnLarge.Count == 0) return; if (CurrentBlockDefinition != null) { Matrix addOrientationMat = gizmoSpace.m_localMatrixAdd.GetOrientation(); MyBlockOrientation gizmoAddOrientation = new MyBlockOrientation(ref addOrientationMat); if (!PlacingSmallGridOnLargeStatic) { gizmoSpace.m_buildAllowed &= CheckValidBlockRotation(gizmoSpace.m_localMatrixAdd, CurrentBlockDefinition.Direction, CurrentBlockDefinition.Rotation) && CurrentGrid.CanPlaceBlock(gizmoSpace.m_min, gizmoSpace.m_max, gizmoAddOrientation, gizmoSpace.m_blockDefinition); } if (!PlacingSmallGridOnLargeStatic && MySession.Static.SurvivalMode && !DeveloperSpectatorIsBuilding) { Vector3 localMin = (m_gizmo.SpaceDefault.m_min - new Vector3(0.5f)) * CurrentGrid.GridSize; Vector3 localMax = (m_gizmo.SpaceDefault.m_max + new Vector3(0.5f)) * CurrentGrid.GridSize; BoundingBoxD gizmoBox = new BoundingBoxD(localMin, localMax); if (!MyCubeBuilderGizmo.DefaultGizmoCloseEnough(ref m_invGridWorldMatrix, gizmoBox, CurrentGrid.GridSize, IntersectionDistance) || MySession.GetCameraControllerEnum() == MyCameraControllerEnum.Spectator) { gizmoSpace.m_buildAllowed = false; gizmoSpace.m_removeBlock = null; return; } if (!MySession.Static.SimpleSurvival && MySession.ControlledEntity is MyCharacter) { gizmoSpace.m_buildAllowed &= (MySession.ControlledEntity as MyCharacter).CanStartConstruction(CurrentBlockDefinition); } if (MySession.Static.SimpleSurvival) { gizmoSpace.m_buildAllowed &= CanBuildBlockSurvivalTime(); } } // Check whether mount points match any of its neighbors (only if we can build here though). if (gizmoSpace.m_buildAllowed) { Quaternion.CreateFromRotationMatrix(ref gizmoSpace.m_localMatrixAdd, out gizmoSpace.m_rotation); if (gizmoSpace.SymmetryPlane == MySymmetrySettingModeEnum.Disabled && !PlacingSmallGridOnLargeStatic) gizmoSpace.m_buildAllowed = MyCubeGrid.CheckConnectivity(CurrentGrid, CurrentBlockDefinition, ref gizmoSpace.m_rotation, ref gizmoSpace.m_centerPos); } Color color = green; UpdateShowGizmoCube(gizmoSpace, CurrentGrid.GridSize); // Disable building from cockpit if (MySession.ControlledEntity != null && MySession.ControlledEntity is MyCockpit && !DeveloperSpectatorIsBuilding) { gizmoSpace.m_showGizmoCube = false; return; } gizmoSpace.m_buildAllowed &= gizmoSpace.m_showGizmoCube; Vector3 temp; Vector3D worldCenter = Vector3D.Zero; Vector3D worldPos = gizmoSpace.m_worldMatrixAdd.Translation; MatrixD drawMatrix = gizmoSpace.m_worldMatrixAdd; int posIndex = 0; for (temp.X = 0; temp.X < CurrentBlockDefinition.Size.X; temp.X++) for (temp.Y = 0; temp.Y < CurrentBlockDefinition.Size.Y; temp.Y++) for (temp.Z = 0; temp.Z < CurrentBlockDefinition.Size.Z; temp.Z++) { color = gizmoSpace.m_buildAllowed ? green : gray; if (PlacingSmallGridOnLargeStatic) { float smallToLarge = MyDefinitionManager.Static.GetCubeSize(CurrentBlockDefinition.CubeSize) / CurrentGrid.GridSize; Vector3D gridPosition = gizmoSpace.m_positionsSmallOnLarge[posIndex++]; Vector3I gridPositionInt = Vector3I.Round(gridPosition / smallToLarge); Vector3D tempWorldPos = Vector3D.Transform(gridPosition * CurrentGrid.GridSize, CurrentGrid.WorldMatrix); worldCenter += tempWorldPos; drawMatrix.Translation = tempWorldPos; MyCubeGrid.GetCubeParts(CurrentBlockDefinition, gridPositionInt, gizmoSpace.m_localMatrixAdd.GetOrientation(), CurrentGrid.GridSize, gizmoSpace.m_cubeModelsTemp, gizmoSpace.m_cubeMatricesTemp, gizmoSpace.m_cubeNormals, gizmoSpace.m_patternOffsets); if (gizmoSpace.m_showGizmoCube) { for (int i = 0; i < gizmoSpace.m_cubeMatricesTemp.Count; i++) { MatrixD modelMatrix = gizmoSpace.m_cubeMatricesTemp[i]; modelMatrix.Translation *= smallToLarge; modelMatrix = modelMatrix * CurrentGrid.WorldMatrix; modelMatrix.Translation = tempWorldPos; gizmoSpace.m_cubeMatricesTemp[i] = modelMatrix; } m_gizmo.AddFastBuildParts(gizmoSpace, CurrentBlockDefinition, CurrentGrid); m_gizmo.UpdateGizmoCubeParts(gizmoSpace, m_renderData, ref m_invGridWorldMatrix); } } else { Vector3I gridPosition = gizmoSpace.m_positions[posIndex++]; Vector3D tempWorldPos = Vector3D.Transform(gridPosition * CurrentGrid.GridSize, CurrentGrid.WorldMatrix); worldCenter += tempWorldPos; drawMatrix.Translation = tempWorldPos; //if (temp == center) //{ // //if bigger block, show its center with black color // if (CurrentBlockDefinition.Size.Size > 1) // color = black; // if (gizmoSpace.SymmetryPlane == MySymmetrySettingModeEnum.Disabled) // { // //VRageRender.MyRenderProxy.DebugDrawLine3D(tempWorldPos, tempWorldPos - worldDir * CurrentGrid.GridSize, Color.Purple, Color.Gray, false); // //VRageRender.MyRenderProxy.DebugDrawAxis(drawMatrix, 2, false); // } //} MyCubeGrid.GetCubeParts(CurrentBlockDefinition, gridPosition, gizmoSpace.m_localMatrixAdd.GetOrientation(), CurrentGrid.GridSize, gizmoSpace.m_cubeModelsTemp, gizmoSpace.m_cubeMatricesTemp, gizmoSpace.m_cubeNormals, gizmoSpace.m_patternOffsets); if (gizmoSpace.m_showGizmoCube) { for (int i = 0; i < gizmoSpace.m_cubeMatricesTemp.Count; i++) { MatrixD modelMatrix = gizmoSpace.m_cubeMatricesTemp[i] * CurrentGrid.WorldMatrix; modelMatrix.Translation = tempWorldPos; gizmoSpace.m_cubeMatricesTemp[i] = modelMatrix; } m_gizmo.AddFastBuildParts(gizmoSpace, CurrentBlockDefinition, CurrentGrid); m_gizmo.UpdateGizmoCubeParts(gizmoSpace, m_renderData, ref m_invGridWorldMatrix, CurrentBlockDefinition); } //for (int i = 0; i < gizmoSpace.m_gizmoCubeRenderIds.Count; i++) //{ // Matrix modelMatrix = gizmoSpace.m_gizmoCubeMatricesTemp[i]; // VRageRender.MyRenderProxy.UpdateRenderObject(gizmoSpace.m_gizmoCubeRenderIds[i], ref modelMatrix, false); //} //MySimpleObjectDraw.DrawTransparentBox(ref drawMatrix, // ref box, ref color, MySimpleObjectRasterizer.Solid, 1, 0.04f); } } //calculate world center for block model worldCenter /= CurrentBlockDefinition.Size.Size; drawMatrix.Translation = worldCenter; float gridSize = PlacingSmallGridOnLargeStatic ? MyDefinitionManager.Static.GetCubeSize(CurrentBlockDefinition.CubeSize) : CurrentGrid.GridSize; BoundingBoxD localAABB = new BoundingBoxD(-CurrentBlockDefinition.Size * gridSize * 0.5f, CurrentBlockDefinition.Size * gridSize * 0.5f); if (PlacingSmallGridOnLargeStatic) { if (MySession.Static.SurvivalMode && !DeveloperSpectatorIsBuilding) { MatrixD invDrawMatrix = Matrix.Invert(drawMatrix); if (!MyCubeBuilderGizmo.DefaultGizmoCloseEnough(ref invDrawMatrix, localAABB, gridSize, IntersectionDistance) || MySession.GetCameraControllerEnum() == MyCameraControllerEnum.Spectator) { gizmoSpace.m_buildAllowed = false; gizmoSpace.m_removeBlock = null; return; } if (!MySession.Static.SimpleSurvival && MySession.ControlledEntity is MyCharacter) { gizmoSpace.m_buildAllowed &= (MySession.ControlledEntity as MyCharacter).CanStartConstruction(CurrentBlockDefinition); } if (MySession.Static.SimpleSurvival) { gizmoSpace.m_buildAllowed &= CanBuildBlockSurvivalTime(); } } var settings = MyPerGameSettings.BuildingSettings.GetGridPlacementSettings(CurrentGrid); // Orientation is identity (local), because it is represented in world matrix also. MyBlockOrientation orientation = new MyBlockOrientation(ref Quaternion.Identity); bool placementTest = CheckValidBlockRotation(gizmoSpace.m_localMatrixAdd, CurrentBlockDefinition.Direction, CurrentBlockDefinition.Rotation) && MyCubeGrid.TestBlockPlacementArea(CurrentBlockDefinition, orientation, drawMatrix, ref settings, localAABB, false); gizmoSpace.m_buildAllowed &= placementTest; if (gizmoSpace.m_buildAllowed && gizmoSpace.SymmetryPlane == MySymmetrySettingModeEnum.Disabled) gizmoSpace.m_buildAllowed &= MyCubeGrid.CheckConnectivitySmallBlockToLargeGrid(CurrentGrid, CurrentBlockDefinition, ref gizmoSpace.m_rotation, ref gizmoSpace.m_addDir); gizmoSpace.m_worldMatrixAdd = drawMatrix; } //color = gizmoSpace.m_buildAllowed ? green : gray; color = Color.White; string lineMaterial = gizmoSpace.m_buildAllowed ? "GizmoDrawLine" : "GizmoDrawLineRed"; if (gizmoSpace.SymmetryPlane == MySymmetrySettingModeEnum.Disabled) { MySimpleObjectDraw.DrawTransparentBox(ref drawMatrix, ref localAABB, ref color, MySimpleObjectRasterizer.Wireframe, 1, 0.04f, lineMaterial: lineMaterial); m_rotationHints.CalculateRotationHints(drawMatrix, localAABB, !MyHud.MinimalHud && MySandboxGame.Config.RotationHints && draw && MyFakes.ENABLE_ROTATION_HINTS); } gizmoSpace.m_cubeMatricesTemp.Clear(); gizmoSpace.m_cubeModelsTemp.Clear(); if (gizmoSpace.m_showGizmoCube) { // Draw mount points of added cube block as yellow squares in neighboring cells. if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_MOUNT_POINTS) { float cubeSize = MyDefinitionManager.Static.GetCubeSize(CurrentBlockDefinition.CubeSize); if (!PlacingSmallGridOnLargeStatic) cubeSize = CurrentGrid.GridSize; DrawMountPoints(cubeSize, CurrentBlockDefinition, ref drawMatrix); } Vector3D rotatedModelOffset; Vector3D.TransformNormal(ref CurrentBlockDefinition.ModelOffset, ref gizmoSpace.m_worldMatrixAdd, out rotatedModelOffset); drawMatrix.Translation = worldCenter + rotatedModelOffset; AddFastBuildModels(gizmoSpace, drawMatrix, gizmoSpace.m_cubeMatricesTemp, gizmoSpace.m_cubeModelsTemp, gizmoSpace.m_blockDefinition); Debug.Assert(gizmoSpace.m_cubeMatricesTemp.Count == gizmoSpace.m_cubeModelsTemp.Count); for (int i = 0; i < gizmoSpace.m_cubeMatricesTemp.Count; ++i) { string model = gizmoSpace.m_cubeModelsTemp[i]; if (!string.IsNullOrEmpty(model)) m_renderData.AddInstance(MyModel.GetId(model), gizmoSpace.m_cubeMatricesTemp[i], ref m_invGridWorldMatrix); } } } } if (gizmoSpace.m_startRemove != null && gizmoSpace.m_continueBuild != null) { gizmoSpace.m_buildAllowed = true; Vector3I stepDelta; Vector3I counter; int stepCount; ComputeSteps(gizmoSpace.m_startRemove.Value, gizmoSpace.m_continueBuild.Value, Vector3I.One, out stepDelta, out counter, out stepCount); var matrix = CurrentGrid.WorldMatrix; BoundingBoxD aabb = BoundingBoxD.CreateInvalid(); aabb.Include((gizmoSpace.m_startRemove.Value * CurrentGrid.GridSize)); aabb.Include((gizmoSpace.m_continueBuild.Value * CurrentGrid.GridSize)); aabb.Min -= new Vector3(CurrentGrid.GridSize / 2.0f + 0.02f); aabb.Max += new Vector3(CurrentGrid.GridSize / 2.0f + 0.02f); MySimpleObjectDraw.DrawTransparentBox(ref matrix, ref aabb, ref white, MySimpleObjectRasterizer.Wireframe, counter, 0.04f, null, "GizmoDrawLineRed", true); Color faceColor = new Color(Color.Red * 0.2f, 0.3f); MySimpleObjectDraw.DrawTransparentBox(ref matrix, ref aabb, ref faceColor, MySimpleObjectRasterizer.Solid, 0, 0.04f, "Square", null, true); } else if (remove && gizmoSpace.m_showGizmoCube && ShowRemoveGizmo) { if (gizmoSpace.m_removeBlock != null) DrawSemiTransparentBox(CurrentGrid, gizmoSpace.m_removeBlock, red, lineMaterial: "GizmoDrawLineRed"); if (gizmoSpace.m_removeBlock != null && MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_REMOVE_CUBE_COORDS) { var block = gizmoSpace.m_removeBlock; var grid = block.CubeGrid; Matrix gridMatrix = grid.WorldMatrix; Vector3 blockWorldPos = Vector3.Transform(block.Position * grid.GridSize, gridMatrix); // Show forward-up //if (block.FatBlock != null) //{ // MyRenderProxy.DebugDrawLine3D(block.FatBlock.WorldMatrix.Translation, block.FatBlock.WorldMatrix.Translation + block.FatBlock.WorldMatrix.Forward, Color.Red, Color.Red, false); // MyRenderProxy.DebugDrawLine3D(block.FatBlock.WorldMatrix.Translation, block.FatBlock.WorldMatrix.Translation + block.FatBlock.WorldMatrix.Up, Color.Green, Color.Green, false); //} MyRenderProxy.DebugDrawText3D(blockWorldPos, block.Position.ToString(), Color.White, 1.0f, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER); } } else { if (MySession.Static.SurvivalMode && (MySession.GetCameraControllerEnum() != MyCameraControllerEnum.Spectator || MyFinalBuildConstants.IS_OFFICIAL)) { Vector3 localMin = (m_gizmo.SpaceDefault.m_min - new Vector3(0.5f)) * CurrentGrid.GridSize; Vector3 localMax = (m_gizmo.SpaceDefault.m_max + new Vector3(0.5f)) * CurrentGrid.GridSize; BoundingBoxD gizmoBox = new BoundingBoxD(localMin, localMax); if (!MyCubeBuilderGizmo.DefaultGizmoCloseEnough(ref m_invGridWorldMatrix, gizmoBox, CurrentGrid.GridSize, IntersectionDistance)) { gizmoSpace.m_removeBlock = null; } } } }
private void UpdateShowGizmoCube(MyCubeBuilderGizmo.MyGizmoSpaceProperties gizmoSpace, float gridSize) { if (CurrentBlockDefinition == null) return; // Disable gizmo cubes when the camera is inside the currently displayed cube or where the character is inside the cube gizmoSpace.m_showGizmoCube = true; if (MySector.MainCamera != null) { gizmoSpace.m_showGizmoCube = gizmoSpace.m_showGizmoCube && !m_gizmo.PointInsideGizmo(MySector.MainCamera.Position, gizmoSpace.SourceSpace, ref m_invGridWorldMatrix, gridSize, inflate: 0.05f, onVoxel: CurrentVoxelMap != null); } if (MySession.ControlledEntity != null && MySession.ControlledEntity is MyCharacter) { m_collisionTestPoints.Clear(); PrepareCharacterCollisionPoints(m_collisionTestPoints); gizmoSpace.m_showGizmoCube = gizmoSpace.m_showGizmoCube && !m_gizmo.PointsInsideGizmo(m_collisionTestPoints, gizmoSpace.SourceSpace, ref m_invGridWorldMatrix, gridSize, inflate: 0.05f, onVoxel: CurrentVoxelMap != null); } }
private void UpdateGizmo_DynamicMode(MyCubeBuilderGizmo.MyGizmoSpaceProperties gizmoSpace) { Debug.Assert(DynamicMode); float gridSize = MyDefinitionManager.Static.GetCubeSize(CurrentBlockDefinition.CubeSize); BoundingBoxD localAABB = new BoundingBoxD(-CurrentBlockDefinition.Size * gridSize * 0.5f, CurrentBlockDefinition.Size * gridSize * 0.5f); var settings = CurrentBlockDefinition.CubeSize == MyCubeSize.Large ? MyPerGameSettings.PastingSettings.LargeGrid : MyPerGameSettings.PastingSettings.SmallGrid; MatrixD drawMatrix = gizmoSpace.m_worldMatrixAdd; if (MySession.Static.SurvivalMode && !DeveloperSpectatorIsBuilding) { //MatrixD inverseDrawMatrix = MatrixD.Invert(drawMatrix); //if (!MyCubeBuilderGizmo.DefaultGizmoCloseEnough(ref inverseDrawMatrix, localAABB, gridSize, IntersectionDistance) // || MySession.GetCameraControllerEnum() == MyCameraControllerEnum.Spectator) //{ // gizmoSpace.m_buildAllowed = false; // gizmoSpace.m_removeBlock = null; //} if (!MySession.Static.SimpleSurvival && MySession.ControlledEntity is MyCharacter) { gizmoSpace.m_buildAllowed &= (MySession.ControlledEntity as MyCharacter).CanStartConstruction(CurrentBlockDefinition); } if (MySession.Static.SimpleSurvival) { gizmoSpace.m_buildAllowed &= CanBuildBlockSurvivalTime(); } } // m_buildAllowed is set in shape cast if (!gizmoSpace.m_dynamicBuildAllowed) { bool placementTest = MyCubeGrid.TestBlockPlacementArea(CurrentBlockDefinition, null, drawMatrix, ref settings, localAABB, DynamicMode); gizmoSpace.m_buildAllowed &= placementTest; } gizmoSpace.m_showGizmoCube = true; gizmoSpace.m_cubeMatricesTemp.Clear(); gizmoSpace.m_cubeModelsTemp.Clear(); if (gizmoSpace.m_showGizmoCube) UpdateShowGizmoCube(gizmoSpace, gridSize); if (gizmoSpace.m_showGizmoCube) { Color color = Color.White; string lineMaterial = gizmoSpace.m_buildAllowed ? "GizmoDrawLine" : "GizmoDrawLineRed"; if (gizmoSpace.SymmetryPlane == MySymmetrySettingModeEnum.Disabled) { MySimpleObjectDraw.DrawTransparentBox(ref drawMatrix, ref localAABB, ref color, MySimpleObjectRasterizer.Wireframe, 1, 0.04f, lineMaterial: lineMaterial); } AddFastBuildModels(gizmoSpace, MatrixD.Identity, gizmoSpace.m_cubeMatricesTemp, gizmoSpace.m_cubeModelsTemp, gizmoSpace.m_blockDefinition); Debug.Assert(gizmoSpace.m_cubeMatricesTemp.Count == gizmoSpace.m_cubeModelsTemp.Count); for (int i = 0; i < gizmoSpace.m_cubeMatricesTemp.Count; ++i) { string model = gizmoSpace.m_cubeModelsTemp[i]; if (!string.IsNullOrEmpty(model)) { m_renderData.AddInstance(MyModel.GetId(model), gizmoSpace.m_cubeMatricesTemp[i], ref MatrixD.Identity); } } } }
private void UpdateGizmo_VoxelMap(MyCubeBuilderGizmo.MyGizmoSpaceProperties gizmoSpace, bool add, bool remove, bool draw) { Color green = new Color(Color.Green * 0.6f, 1f); Color red = new Color(Color.Red * 0.8f, 1); Color yellow = Color.Yellow; Color blue = Color.Blue; //Vector4 black = Color.Black.ToVector4(); Color gray = Color.Gray; float gridSize = MyDefinitionManager.Static.GetCubeSize(CurrentBlockDefinition.CubeSize); Vector3 temp; Vector3D worldCenter = Vector3D.Zero; Vector3D worldPos = gizmoSpace.m_worldMatrixAdd.Translation; MatrixD drawMatrix = gizmoSpace.m_worldMatrixAdd; Color color = green; UpdateShowGizmoCube(gizmoSpace, gridSize); int posIndex = 0; for (temp.X = 0; temp.X < CurrentBlockDefinition.Size.X; temp.X++) for (temp.Y = 0; temp.Y < CurrentBlockDefinition.Size.Y; temp.Y++) for (temp.Z = 0; temp.Z < CurrentBlockDefinition.Size.Z; temp.Z++) { color = gizmoSpace.m_buildAllowed ? green : gray; Vector3I gridPosition = gizmoSpace.m_positions[posIndex++]; Vector3D tempWorldPos = gridPosition * gridSize; if (!MyPerGameSettings.BuildingSettings.StaticGridAlignToCenter) tempWorldPos -= 0.5 * gridSize; worldCenter += tempWorldPos; drawMatrix.Translation = tempWorldPos; MyCubeGrid.GetCubeParts(CurrentBlockDefinition, gridPosition, gizmoSpace.m_localMatrixAdd.GetOrientation(), gridSize, gizmoSpace.m_cubeModelsTemp, gizmoSpace.m_cubeMatricesTemp, gizmoSpace.m_cubeNormals, gizmoSpace.m_patternOffsets); if (gizmoSpace.m_showGizmoCube) { for (int i = 0; i < gizmoSpace.m_cubeMatricesTemp.Count; i++) { MatrixD modelMatrix = gizmoSpace.m_cubeMatricesTemp[i]; modelMatrix.Translation = tempWorldPos; gizmoSpace.m_cubeMatricesTemp[i] = modelMatrix; } m_gizmo.AddFastBuildParts(gizmoSpace, CurrentBlockDefinition, null); m_gizmo.UpdateGizmoCubeParts(gizmoSpace, m_renderData, ref MatrixD.Identity); } } //calculate world center for block model worldCenter /= CurrentBlockDefinition.Size.Size; drawMatrix.Translation = worldCenter; BoundingBoxD localAABB = new BoundingBoxD(-CurrentBlockDefinition.Size * gridSize * 0.5f, CurrentBlockDefinition.Size * gridSize * 0.5f); var settings = CurrentBlockDefinition.CubeSize == MyCubeSize.Large ? MyPerGameSettings.BuildingSettings.LargeStaticGrid : MyPerGameSettings.BuildingSettings.SmallStaticGrid; MyBlockOrientation blockOrientation = new MyBlockOrientation(ref Quaternion.Identity); bool placementTest = CheckValidBlockRotation(gizmoSpace.m_worldMatrixAdd, CurrentBlockDefinition.Direction, CurrentBlockDefinition.Rotation) && MyCubeGrid.TestBlockPlacementArea(CurrentBlockDefinition, blockOrientation, drawMatrix, ref settings, localAABB, false); gizmoSpace.m_buildAllowed &= placementTest; gizmoSpace.m_buildAllowed &= gizmoSpace.m_showGizmoCube; gizmoSpace.m_worldMatrixAdd = drawMatrix; if (MySession.Static.SurvivalMode && !DeveloperSpectatorIsBuilding) { BoundingBoxD gizmoBox = localAABB.Transform(ref drawMatrix); if (!MyCubeBuilderGizmo.DefaultGizmoCloseEnough(ref MatrixD.Identity, gizmoBox, gridSize, IntersectionDistance) || MySession.GetCameraControllerEnum() == MyCameraControllerEnum.Spectator) { gizmoSpace.m_buildAllowed = false; gizmoSpace.m_showGizmoCube = false; gizmoSpace.m_removeBlock = null; return; } if (!MySession.Static.SimpleSurvival && MySession.ControlledEntity is MyCharacter) { gizmoSpace.m_buildAllowed &= (MySession.ControlledEntity as MyCharacter).CanStartConstruction(CurrentBlockDefinition); } if (MySession.Static.SimpleSurvival) { gizmoSpace.m_buildAllowed &= CanBuildBlockSurvivalTime(); } } //color = gizmoSpace.m_buildAllowed ? green : gray; color = Color.White; string lineMaterial = gizmoSpace.m_buildAllowed ? "GizmoDrawLine" : "GizmoDrawLineRed"; if (gizmoSpace.SymmetryPlane == MySymmetrySettingModeEnum.Disabled) { MySimpleObjectDraw.DrawTransparentBox(ref drawMatrix, ref localAABB, ref color, MySimpleObjectRasterizer.Wireframe, 1, 0.04f, lineMaterial: lineMaterial); m_rotationHints.CalculateRotationHints(drawMatrix, localAABB, !MyHud.MinimalHud && MySandboxGame.Config.RotationHints && draw && MyFakes.ENABLE_ROTATION_HINTS); } gizmoSpace.m_cubeMatricesTemp.Clear(); gizmoSpace.m_cubeModelsTemp.Clear(); if (gizmoSpace.m_showGizmoCube) { // Draw mount points of added cube block as yellow squares in neighboring cells. if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_MOUNT_POINTS) { DrawMountPoints(gridSize, CurrentBlockDefinition, ref drawMatrix); } AddFastBuildModels(gizmoSpace, MatrixD.Identity, gizmoSpace.m_cubeMatricesTemp, gizmoSpace.m_cubeModelsTemp, gizmoSpace.m_blockDefinition); Debug.Assert(gizmoSpace.m_cubeMatricesTemp.Count == gizmoSpace.m_cubeModelsTemp.Count); for (int i = 0; i < gizmoSpace.m_cubeMatricesTemp.Count; ++i) { string model = gizmoSpace.m_cubeModelsTemp[i]; if (!string.IsNullOrEmpty(model)) m_renderData.AddInstance(MyModel.GetId(model), gizmoSpace.m_cubeMatricesTemp[i], ref MatrixD.Identity); } } }
private void UpdateGizmo(MyCubeBuilderGizmo.MyGizmoSpaceProperties gizmoSpace, bool add, bool remove, bool draw) { if (!gizmoSpace.Enabled) return; if (MyFakes.ENABLE_BATTLE_SYSTEM && MySession.Static.Battle) { gizmoSpace.m_showGizmoCube = false; gizmoSpace.m_buildAllowed = false; return; } if (CurrentGrid != null) { UpdateGizmo_Grid(gizmoSpace, add, remove, draw); } else if (CurrentVoxelMap != null) { UpdateGizmo_VoxelMap(gizmoSpace, add, remove, draw); } else if (DynamicMode) { UpdateGizmo_DynamicMode(gizmoSpace); } }
private void UpdateGizmo(MyCubeBuilderGizmo.MyGizmoSpaceProperties gizmoSpace, bool add, bool remove, bool draw) { if (!gizmoSpace.Enabled) return; if (CurrentGrid != null) { UpdateGizmo_Grid(gizmoSpace, add, remove, draw); } else if (CurrentVoxelMap != null) { UpdateGizmo_VoxelMap(gizmoSpace, add, remove, draw); } else if (DynamicMode) { UpdateGizmo_DynamicMode(gizmoSpace); } }
private bool AddBlocksToBuildQueueOrSpawn(MyCubeBuilderGizmo.MyGizmoSpaceProperties gizmoSpace) { return AddBlocksToBuildQueueOrSpawn(gizmoSpace.m_blockDefinition, ref gizmoSpace.m_worldMatrixAdd, gizmoSpace.m_min, gizmoSpace.m_max, gizmoSpace.m_centerPos, gizmoSpace.LocalOrientation); }
void AddFastBuildModels(MyCubeBuilderGizmo.MyGizmoSpaceProperties gizmoSpace, MatrixD baseMatrix, List<MatrixD> matrices, List<string> models, MyCubeBlockDefinition definition) { AddFastBuildModels(baseMatrix, ref gizmoSpace.m_localMatrixAdd, matrices, models, definition, gizmoSpace.m_startBuild, gizmoSpace.m_continueBuild); }
private bool IntersectsCharacterOrCamera(MyCubeBuilderGizmo.MyGizmoSpaceProperties gizmoSpace, float gridSize, ref MatrixD inverseBlockInGridWorldMatrix) { if (CurrentBlockDefinition == null) return false; bool intersects = false; if (MySector.MainCamera != null) { intersects = m_gizmo.PointInsideGizmo(MySector.MainCamera.Position, gizmoSpace.SourceSpace, ref inverseBlockInGridWorldMatrix, gridSize, inflate: 0.05f, onVoxel: CurrentVoxelBase != null, dynamicMode: DynamicMode); } if (intersects) return true; if (MySession.Static.ControlledEntity != null && MySession.Static.ControlledEntity is MyCharacter) { m_collisionTestPoints.Clear(); PrepareCharacterCollisionPoints(m_collisionTestPoints); intersects = m_gizmo.PointsAABBIntersectsGizmo(m_collisionTestPoints, gizmoSpace.SourceSpace, ref inverseBlockInGridWorldMatrix, gridSize, inflate: 0.05f, onVoxel: CurrentVoxelBase != null, dynamicMode: DynamicMode); } return intersects; }
private void UpdateGizmo_Grid(MyCubeBuilderGizmo.MyGizmoSpaceProperties gizmoSpace, bool add, bool remove, bool draw) { ProfilerShort.Begin("Colors"); Color green = new Color(Color.Green * 0.6f, 1f); Color red = new Color(Color.Red * 0.8f, 1); Color yellow = Color.Yellow; Color black = Color.Black; Color gray = Color.Gray; Color white = Color.White; ProfilerShort.BeginNextBlock("Add"); if (add) { if (!m_animationLock) { gizmoSpace.m_animationLastMatrix = gizmoSpace.m_localMatrixAdd; } MatrixD animationMatrix = gizmoSpace.m_localMatrixAdd; if (MySandboxGame.Config.AnimatedRotation && gizmoSpace.m_animationProgress < 1) { animationMatrix = MatrixD.Slerp(gizmoSpace.m_animationLastMatrix, gizmoSpace.m_localMatrixAdd, gizmoSpace.m_animationProgress); } else if (MySandboxGame.Config.AnimatedRotation && gizmoSpace.m_animationProgress >= 1) { m_animationLock = false; gizmoSpace.m_animationLastMatrix = gizmoSpace.m_localMatrixAdd; } MatrixD modelTransform = animationMatrix * CurrentGrid.WorldMatrix; if (gizmoSpace.m_startBuild != null && gizmoSpace.m_continueBuild != null) { gizmoSpace.m_buildAllowed = true; } if (PlacingSmallGridOnLargeStatic && gizmoSpace.m_positionsSmallOnLarge.Count == 0) { ProfilerShort.End(); return; } ProfilerShort.Begin("CurrentBlockDefinition"); if (CurrentBlockDefinition != null) { ProfilerShort.Begin("GetOrientation"); Matrix addOrientationMat = gizmoSpace.m_localMatrixAdd.GetOrientation(); MyBlockOrientation gizmoAddOrientation = new MyBlockOrientation(ref addOrientationMat); ProfilerShort.BeginNextBlock("PlacingSmallGridOnLargeStatic"); // Test free space in the cube grid (& valid rotation of the block) if (!PlacingSmallGridOnLargeStatic) { ProfilerShort.Begin("CheckValidBlockRotation"); bool isValidBlockRotation = CheckValidBlockRotation(gizmoSpace.m_localMatrixAdd, CurrentBlockDefinition.Direction, CurrentBlockDefinition.Rotation); ProfilerShort.BeginNextBlock("CanPlaceBlock"); bool canPlaceBlock = CurrentGrid.CanPlaceBlock(gizmoSpace.m_min, gizmoSpace.m_max, gizmoAddOrientation, gizmoSpace.m_blockDefinition); ProfilerShort.BeginNextBlock("m_buildAllowed"); gizmoSpace.m_buildAllowed &= isValidBlockRotation && canPlaceBlock; ProfilerShort.End(); } ProfilerShort.BeginNextBlock("IsAdminModeEnabled"); MyCubeBuilder.BuildComponent.GetBlockPlacementMaterials(gizmoSpace.m_blockDefinition, gizmoSpace.m_addPos, gizmoAddOrientation, CurrentGrid); if (MySession.Static.IsAdminModeEnabled(Sync.MyId) == false) { gizmoSpace.m_buildAllowed &= MyCubeBuilder.BuildComponent.HasBuildingMaterials(MySession.Static.LocalCharacter); } ProfilerShort.BeginNextBlock("SurvivalMode"); // In survival, check whether you're close enough, and have enough materials or haven't built for long enough if (!PlacingSmallGridOnLargeStatic && MySession.Static.SurvivalMode && MySession.Static.IsAdminModeEnabled(Sync.MyId) == false && !SpectatorIsBuilding) { Vector3 localMin = (m_gizmo.SpaceDefault.m_min - new Vector3(0.5f)) * CurrentGrid.GridSize; Vector3 localMax = (m_gizmo.SpaceDefault.m_max + new Vector3(0.5f)) * CurrentGrid.GridSize; BoundingBoxD gizmoBox = new BoundingBoxD(localMin, localMax); if (!MyCubeBuilderGizmo.DefaultGizmoCloseEnough(ref m_invGridWorldMatrix, gizmoBox, CurrentGrid.GridSize, IntersectionDistance) || CameraControllerSpectator) { gizmoSpace.m_buildAllowed = false; gizmoSpace.m_removeBlock = null; ProfilerShort.End(); ProfilerShort.End(); ProfilerShort.End(); return; } } ProfilerShort.BeginNextBlock("m_buildAllowed"); // Check whether mount points match any of its neighbors (only if we can build here though). if (gizmoSpace.m_buildAllowed) { ProfilerShort.Begin("CreateFromRotationMatrix"); Quaternion.CreateFromRotationMatrix(ref gizmoSpace.m_localMatrixAdd, out gizmoSpace.m_rotation); ProfilerShort.BeginNextBlock("SymmetryPlane"); if (gizmoSpace.SymmetryPlane == MySymmetrySettingModeEnum.Disabled && !PlacingSmallGridOnLargeStatic) { ProfilerShort.Begin("GetBuildProgressModelMountPoints"); var mountPoints = CurrentBlockDefinition.GetBuildProgressModelMountPoints(MyComponentStack.NewBlockIntegrity); ProfilerShort.BeginNextBlock("CheckConnectivity"); gizmoSpace.m_buildAllowed = MyCubeGrid.CheckConnectivity(CurrentGrid, CurrentBlockDefinition, mountPoints, ref gizmoSpace.m_rotation, ref gizmoSpace.m_centerPos); ProfilerShort.End(); } ProfilerShort.End(); } Color color = green; ProfilerShort.BeginNextBlock("DisableInside"); // Disable gizmo cubes when the camera is inside the currently displayed cube or where the character is inside the cube if (PlacingSmallGridOnLargeStatic) { var invMatrix = MatrixD.Invert(gizmoSpace.m_worldMatrixAdd); gizmoSpace.m_showGizmoCube = !IntersectsCharacterOrCamera(gizmoSpace, CurrentGrid.GridSize, ref invMatrix); } else { gizmoSpace.m_showGizmoCube = !IntersectsCharacterOrCamera(gizmoSpace, CurrentGrid.GridSize, ref m_invGridWorldMatrix); } gizmoSpace.m_buildAllowed &= gizmoSpace.m_showGizmoCube; Vector3 temp; Vector3D worldCenter = Vector3D.Zero; Vector3D worldPos = gizmoSpace.m_worldMatrixAdd.Translation; MatrixD drawMatrix = gizmoSpace.m_worldMatrixAdd; ProfilerShort.BeginNextBlock("DrawGizmo"); int posIndex = 0; for (temp.X = 0; temp.X < CurrentBlockDefinition.Size.X; temp.X++) for (temp.Y = 0; temp.Y < CurrentBlockDefinition.Size.Y; temp.Y++) for (temp.Z = 0; temp.Z < CurrentBlockDefinition.Size.Z; temp.Z++) #region if(PlacingSmallGridOnLargeStatic) if (PlacingSmallGridOnLargeStatic) { float smallToLarge = MyDefinitionManager.Static.GetCubeSize(CurrentBlockDefinition.CubeSize) / CurrentGrid.GridSize; Vector3D gridPosition = gizmoSpace.m_positionsSmallOnLarge[posIndex++]; Vector3I gridPositionInt = Vector3I.Round(gridPosition / smallToLarge); Vector3D tempWorldPos = Vector3D.Transform(gridPosition * CurrentGrid.GridSize, CurrentGrid.WorldMatrix); worldCenter += tempWorldPos; drawMatrix.Translation = tempWorldPos; MyCubeGrid.GetCubeParts(CurrentBlockDefinition, gridPositionInt, gizmoSpace.m_localMatrixAdd.GetOrientation(), CurrentGrid.GridSize, gizmoSpace.m_cubeModelsTemp, gizmoSpace.m_cubeMatricesTemp, gizmoSpace.m_cubeNormals, gizmoSpace.m_patternOffsets); if (gizmoSpace.m_showGizmoCube) { for (int i = 0; i < gizmoSpace.m_cubeMatricesTemp.Count; i++) { MatrixD modelMatrix = gizmoSpace.m_cubeMatricesTemp[i]; modelMatrix.Translation *= smallToLarge; modelMatrix = modelMatrix * CurrentGrid.WorldMatrix; modelMatrix.Translation = tempWorldPos; gizmoSpace.m_cubeMatricesTemp[i] = modelMatrix; } m_gizmo.AddFastBuildParts(gizmoSpace, CurrentBlockDefinition, CurrentGrid); m_gizmo.UpdateGizmoCubeParts(gizmoSpace, m_renderData, ref m_invGridWorldMatrix); } } #endregion else { Vector3I gridPosition = gizmoSpace.m_positions[posIndex++]; Vector3D tempWorldPos = Vector3D.Transform(gridPosition * CurrentGrid.GridSize, CurrentGrid.WorldMatrix); worldCenter += gridPosition * CurrentGrid.GridSize; MyCubeGrid.GetCubePartsWithoutTopologyCheck( CurrentBlockDefinition, gridPosition, animationMatrix.GetOrientation(), CurrentGrid.GridSize, gizmoSpace.m_cubeModelsTemp, gizmoSpace.m_cubeMatricesTemp, gizmoSpace.m_cubeNormals, gizmoSpace.m_patternOffsets ); //armor render if (gizmoSpace.m_showGizmoCube) { for (int i = 0; i < gizmoSpace.m_cubeMatricesTemp.Count; i++) { MatrixD modelMatrix = gizmoSpace.m_cubeMatricesTemp[i] * CurrentGrid.WorldMatrix; modelMatrix.Translation = tempWorldPos; gizmoSpace.m_cubeMatricesTemp[i] = modelMatrix; } m_gizmo.AddFastBuildParts(gizmoSpace, CurrentBlockDefinition, CurrentGrid); m_gizmo.UpdateGizmoCubeParts(gizmoSpace, m_renderData, ref m_invGridWorldMatrix, CurrentBlockDefinition); } } //calculate world center for block model worldCenter /= CurrentBlockDefinition.Size.Size; if (!m_animationLock) { gizmoSpace.m_animationProgress = 0; gizmoSpace.m_animationLastPosition = worldCenter; } else if (MySandboxGame.Config.AnimatedRotation && gizmoSpace.m_animationProgress < 1) { worldCenter = Vector3D.Lerp(gizmoSpace.m_animationLastPosition, worldCenter, gizmoSpace.m_animationProgress); } worldCenter = Vector3D.Transform(worldCenter, CurrentGrid.WorldMatrix); drawMatrix.Translation = worldCenter; float gridSize = PlacingSmallGridOnLargeStatic ? MyDefinitionManager.Static.GetCubeSize(CurrentBlockDefinition.CubeSize) : CurrentGrid.GridSize; BoundingBoxD localAABB = new BoundingBoxD(-CurrentBlockDefinition.Size * gridSize * 0.5f, CurrentBlockDefinition.Size * gridSize * 0.5f); // Test voxel only here. Cube placement was tested earlier. var settingsVoxelTest = CubeBuilderDefinition.BuildingSettings.GetGridPlacementSettings(CurrentBlockDefinition.CubeSize, CurrentGrid.IsStatic); MyBlockOrientation orientation = new MyBlockOrientation(ref Quaternion.Identity); bool voxelTest = MyCubeGrid.TestVoxelPlacement(CurrentBlockDefinition, settingsVoxelTest, false, drawMatrix, localAABB); gizmoSpace.m_buildAllowed &= voxelTest; ProfilerShort.BeginNextBlock("CheckConnectivity"); #region if(PlacingSmallGridOnLargeStatic) if (PlacingSmallGridOnLargeStatic) { if (MySession.Static.SurvivalMode && !SpectatorIsBuilding && MySession.Static.IsAdminModeEnabled(Sync.MyId) == false) { MatrixD invDrawMatrix = Matrix.Invert(drawMatrix); MyCubeBuilder.BuildComponent.GetBlockPlacementMaterials(CurrentBlockDefinition, gizmoSpace.m_addPos, gizmoAddOrientation, CurrentGrid); gizmoSpace.m_buildAllowed &= MyCubeBuilder.BuildComponent.HasBuildingMaterials(MySession.Static.LocalCharacter); if (!MyCubeBuilderGizmo.DefaultGizmoCloseEnough(ref invDrawMatrix, localAABB, gridSize, IntersectionDistance) || CameraControllerSpectator) { gizmoSpace.m_buildAllowed = false; gizmoSpace.m_removeBlock = null; ProfilerShort.End(); ProfilerShort.End(); ProfilerShort.End(); return; } } var settings = CubeBuilderDefinition.BuildingSettings.GetGridPlacementSettings(CurrentGrid.GridSizeEnum, CurrentGrid.IsStatic); // Orientation is identity (local), because it is represented in world matrix also. bool placementTest = CheckValidBlockRotation(gizmoSpace.m_localMatrixAdd, CurrentBlockDefinition.Direction, CurrentBlockDefinition.Rotation) && MyCubeGrid.TestBlockPlacementArea(CurrentBlockDefinition, orientation, drawMatrix, ref settings, localAABB, !CurrentGrid.IsStatic, testVoxel: false); gizmoSpace.m_buildAllowed &= placementTest; if (gizmoSpace.m_buildAllowed && gizmoSpace.SymmetryPlane == MySymmetrySettingModeEnum.Disabled) gizmoSpace.m_buildAllowed &= MyCubeGrid.CheckConnectivitySmallBlockToLargeGrid(CurrentGrid, CurrentBlockDefinition, ref gizmoSpace.m_rotation, ref gizmoSpace.m_addDir); gizmoSpace.m_worldMatrixAdd = drawMatrix; } #endregion color = Color.White; string lineMaterial = gizmoSpace.m_buildAllowed ? "GizmoDrawLine" : "GizmoDrawLineRed"; ProfilerShort.BeginNextBlock("SymmetryPlane 2"); if (gizmoSpace.SymmetryPlane == MySymmetrySettingModeEnum.Disabled) { ProfilerShort.Begin("DrawTransparentBox"); #region if(MyFakes.ENABLE_VR_BUILDING) if (MyFakes.ENABLE_VR_BUILDING) { Vector3 centerOffset = -0.5f * gizmoSpace.m_addDir; if (gizmoSpace.m_addPosSmallOnLarge != null) { float smallToLarge = MyDefinitionManager.Static.GetCubeSize(CurrentBlockDefinition.CubeSize) / CurrentGrid.GridSize; centerOffset = -0.5f * smallToLarge * gizmoSpace.m_addDir; } centerOffset *= CurrentGrid.GridSize; Vector3I rotatedSize = Vector3I.Round(Vector3.Abs(Vector3.TransformNormal((Vector3)CurrentBlockDefinition.Size, gizmoSpace.m_localMatrixAdd))); Vector3I invAddDir = Vector3I.One - Vector3I.Abs(gizmoSpace.m_addDir); Vector3 halfExtends = gridSize * 0.5f * (rotatedSize * invAddDir) + 0.02f * Vector3I.Abs(gizmoSpace.m_addDir); BoundingBoxD vrAabb = new BoundingBoxD(-halfExtends + centerOffset, halfExtends + centerOffset); MySimpleObjectDraw.DrawTransparentBox(ref drawMatrix, ref vrAabb, ref color, MySimpleObjectRasterizer.Wireframe, 1, gizmoSpace.m_addPosSmallOnLarge != null ? 0.04f : 0.06f, null, lineMaterial, false, -1, 0); } #endregion else { //Wireframe box modelTransform.Translation = drawMatrix.Translation; MySimpleObjectDraw.DrawTransparentBox(ref modelTransform, ref localAABB, ref color, MySimpleObjectRasterizer.Wireframe, 1, 0.04f, null, lineMaterial, false, -1, 0); } ProfilerShort.End(); } ProfilerShort.BeginNextBlock("Clear"); gizmoSpace.m_cubeMatricesTemp.Clear(); gizmoSpace.m_cubeModelsTemp.Clear(); ProfilerShort.BeginNextBlock("m_showGizmoCube"); if (gizmoSpace.m_showGizmoCube) { #region Draw_mount_points // Draw mount points of added cube block as yellow squares in neighboring cells. if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_MOUNT_POINTS) { float cubeSize = MyDefinitionManager.Static.GetCubeSize(CurrentBlockDefinition.CubeSize); if (!PlacingSmallGridOnLargeStatic) cubeSize = CurrentGrid.GridSize; DrawMountPoints(cubeSize, CurrentBlockDefinition, ref drawMatrix); } #endregion Vector3D rotatedModelOffset; Vector3D.TransformNormal(ref CurrentBlockDefinition.ModelOffset, ref gizmoSpace.m_worldMatrixAdd, out rotatedModelOffset); modelTransform.Translation = worldCenter + CurrentGrid.GridScale * rotatedModelOffset; //Render add gizmo for model AddFastBuildModels(gizmoSpace, modelTransform, gizmoSpace.m_cubeMatricesTemp, gizmoSpace.m_cubeModelsTemp, gizmoSpace.m_blockDefinition); Debug.Assert(gizmoSpace.m_cubeMatricesTemp.Count == gizmoSpace.m_cubeModelsTemp.Count); for (int i = 0; i < gizmoSpace.m_cubeMatricesTemp.Count; ++i) { string model = gizmoSpace.m_cubeModelsTemp[i]; if (!string.IsNullOrEmpty(model)) m_renderData.AddInstance(MyModel.GetId(model), gizmoSpace.m_cubeMatricesTemp[i], ref m_invGridWorldMatrix); } } if (gizmoSpace.SymmetryPlane == MySymmetrySettingModeEnum.Disabled) { ProfilerShort.BeginNextBlock("CalculateRotationHints"); m_rotationHints.CalculateRotationHints(modelTransform, localAABB, !MyHud.MinimalHud && MySandboxGame.Config.RotationHints && draw && MyFakes.ENABLE_ROTATION_HINTS); } ProfilerShort.End(); } ProfilerShort.End(); } #region AfterAdd ProfilerShort.BeginNextBlock("After Add"); if (gizmoSpace.m_startRemove != null && gizmoSpace.m_continueBuild != null) { gizmoSpace.m_buildAllowed = true; ProfilerShort.Begin("DrawRemovingCubes"); DrawRemovingCubes(gizmoSpace.m_startRemove, gizmoSpace.m_continueBuild, gizmoSpace.m_removeBlock); ProfilerShort.End(); } else if (remove && gizmoSpace.m_showGizmoCube && ShowRemoveGizmo) { ProfilerShort.Begin("ShowRemoveGizmo"); if (gizmoSpace.m_removeBlocksInMultiBlock.Count > 0) { m_tmpBlockPositionsSet.Clear(); GetAllBlocksPositions(gizmoSpace.m_removeBlocksInMultiBlock, m_tmpBlockPositionsSet); foreach (var position in m_tmpBlockPositionsSet) DrawSemiTransparentBox(position, position, CurrentGrid, red, lineMaterial: "GizmoDrawLineRed"); m_tmpBlockPositionsSet.Clear(); } else if (gizmoSpace.m_removeBlock != null) { if (!MyFakes.ENABLE_VR_BUILDING) DrawSemiTransparentBox(CurrentGrid, gizmoSpace.m_removeBlock, red, lineMaterial: "GizmoDrawLineRed"); } if (gizmoSpace.m_removeBlock != null && MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_REMOVE_CUBE_COORDS) { var block = gizmoSpace.m_removeBlock; var grid = block.CubeGrid; Matrix gridMatrix = grid.WorldMatrix; Vector3 blockWorldPos = Vector3.Transform(block.Position * grid.GridSize, gridMatrix); // Show forward-up //if (block.FatBlock != null) //{ // MyRenderProxy.DebugDrawLine3D(block.FatBlock.WorldMatrix.Translation, block.FatBlock.WorldMatrix.Translation + block.FatBlock.WorldMatrix.Forward, Color.Red, Color.Red, false); // MyRenderProxy.DebugDrawLine3D(block.FatBlock.WorldMatrix.Translation, block.FatBlock.WorldMatrix.Translation + block.FatBlock.WorldMatrix.Up, Color.Green, Color.Green, false); //} MyRenderProxy.DebugDrawText3D(blockWorldPos, block.Position.ToString(), Color.White, 1.0f, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER); } ProfilerShort.End(); } else { ProfilerShort.Begin("SurvivalMode distance check"); if (MySession.Static.SurvivalMode && (!CameraControllerSpectator || MyFinalBuildConstants.IS_OFFICIAL)) { Vector3 localMin = (m_gizmo.SpaceDefault.m_min - new Vector3(0.5f)) * CurrentGrid.GridSize; Vector3 localMax = (m_gizmo.SpaceDefault.m_max + new Vector3(0.5f)) * CurrentGrid.GridSize; BoundingBoxD gizmoBox = new BoundingBoxD(localMin, localMax); if (!MyCubeBuilderGizmo.DefaultGizmoCloseEnough(ref m_invGridWorldMatrix, gizmoBox, CurrentGrid.GridSize, IntersectionDistance)) { gizmoSpace.m_removeBlock = null; } } ProfilerShort.End(); } ProfilerShort.End(); //*/ #endregion gizmoSpace.m_animationProgress += m_animationSpeed; }
private void UpdateGizmo_VoxelMap(MyCubeBuilderGizmo.MyGizmoSpaceProperties gizmoSpace, bool add, bool remove, bool draw) { if (!m_animationLock) { gizmoSpace.m_animationLastMatrix = gizmoSpace.m_localMatrixAdd; } MatrixD animationMatrix = gizmoSpace.m_localMatrixAdd; if (MySandboxGame.Config.AnimatedRotation && gizmoSpace.m_animationProgress < 1) { animationMatrix = MatrixD.Slerp(gizmoSpace.m_animationLastMatrix, gizmoSpace.m_localMatrixAdd, gizmoSpace.m_animationProgress); } else if (MySandboxGame.Config.AnimatedRotation && gizmoSpace.m_animationProgress >= 1) { m_animationLock = false; gizmoSpace.m_animationLastMatrix = gizmoSpace.m_localMatrixAdd; } Color green = new Color(Color.Green * 0.6f, 1f); float gridSize = MyDefinitionManager.Static.GetCubeSize(CurrentBlockDefinition.CubeSize); Vector3 temp; Vector3D worldCenter = Vector3D.Zero; MatrixD drawMatrix = gizmoSpace.m_worldMatrixAdd; MatrixD localOrientation = animationMatrix.GetOrientation(); Color color = green; gizmoSpace.m_showGizmoCube = !IntersectsCharacterOrCamera(gizmoSpace, gridSize, ref MatrixD.Identity); int posIndex = 0; for (temp.X = 0; temp.X < CurrentBlockDefinition.Size.X; temp.X++) for (temp.Y = 0; temp.Y < CurrentBlockDefinition.Size.Y; temp.Y++) for (temp.Z = 0; temp.Z < CurrentBlockDefinition.Size.Z; temp.Z++) { Vector3I gridPosition = gizmoSpace.m_positions[posIndex++]; Vector3D gridRelative = gridPosition * gridSize; if (!CubeBuilderDefinition.BuildingSettings.StaticGridAlignToCenter) gridRelative += new Vector3D(0.5 * gridSize, 0.5 * gridSize, -0.5 * gridSize); Vector3D tempWorldPos = Vector3D.Transform(gridRelative, gizmoSpace.m_worldMatrixAdd); worldCenter += gridRelative; MyCubeGrid.GetCubePartsWithoutTopologyCheck( CurrentBlockDefinition, gridPosition, localOrientation, gridSize, gizmoSpace.m_cubeModelsTemp, gizmoSpace.m_cubeMatricesTemp, gizmoSpace.m_cubeNormals, gizmoSpace.m_patternOffsets ); if (gizmoSpace.m_showGizmoCube) { for (int i = 0; i < gizmoSpace.m_cubeMatricesTemp.Count; i++) { MatrixD modelMatrix = gizmoSpace.m_cubeMatricesTemp[i] * gizmoSpace.m_worldMatrixAdd; modelMatrix.Translation = tempWorldPos; gizmoSpace.m_cubeMatricesTemp[i] = modelMatrix; } drawMatrix.Translation = tempWorldPos; MatrixD invDrawMatrix = MatrixD.Invert(localOrientation * drawMatrix); m_gizmo.AddFastBuildParts(gizmoSpace, CurrentBlockDefinition, null); m_gizmo.UpdateGizmoCubeParts(gizmoSpace, m_renderData, ref invDrawMatrix, CurrentBlockDefinition); } } //calculate world center for block model worldCenter /= CurrentBlockDefinition.Size.Size; if (!m_animationLock) { gizmoSpace.m_animationProgress = 0; gizmoSpace.m_animationLastPosition = worldCenter; } else if (MySandboxGame.Config.AnimatedRotation && gizmoSpace.m_animationProgress < 1) { worldCenter = Vector3D.Lerp(gizmoSpace.m_animationLastPosition, worldCenter, gizmoSpace.m_animationProgress); } worldCenter = Vector3D.Transform(worldCenter, gizmoSpace.m_worldMatrixAdd); drawMatrix.Translation = worldCenter; drawMatrix = localOrientation * drawMatrix; BoundingBoxD localAABB = new BoundingBoxD(-CurrentBlockDefinition.Size * gridSize * 0.5f, CurrentBlockDefinition.Size * gridSize * 0.5f); var settings = CurrentBlockDefinition.CubeSize == MyCubeSize.Large ? CubeBuilderDefinition.BuildingSettings.LargeStaticGrid : CubeBuilderDefinition.BuildingSettings.SmallStaticGrid; MyBlockOrientation blockOrientation = new MyBlockOrientation(ref Quaternion.Identity); bool placementTest = CheckValidBlockRotation(gizmoSpace.m_localMatrixAdd, CurrentBlockDefinition.Direction, CurrentBlockDefinition.Rotation) && MyCubeGrid.TestBlockPlacementArea(CurrentBlockDefinition, blockOrientation, drawMatrix, ref settings, localAABB, false); gizmoSpace.m_buildAllowed &= placementTest; gizmoSpace.m_buildAllowed &= gizmoSpace.m_showGizmoCube; gizmoSpace.m_worldMatrixAdd = drawMatrix; BuildComponent.GetGridSpawnMaterials(CurrentBlockDefinition, drawMatrix, true); if (MySession.Static.IsAdminModeEnabled(Sync.MyId) == false) { gizmoSpace.m_buildAllowed &= BuildComponent.HasBuildingMaterials(MySession.Static.LocalCharacter); } if (MySession.Static.SurvivalMode && !SpectatorIsBuilding && MySession.Static.IsAdminModeEnabled(Sync.MyId) == false) { BoundingBoxD gizmoBox = localAABB.TransformFast(ref drawMatrix); if (!MyCubeBuilderGizmo.DefaultGizmoCloseEnough(ref MatrixD.Identity, gizmoBox, gridSize, IntersectionDistance) || CameraControllerSpectator) { gizmoSpace.m_buildAllowed = false; gizmoSpace.m_showGizmoCube = false; gizmoSpace.m_removeBlock = null; return; } } color = Color.White; string lineMaterial = gizmoSpace.m_buildAllowed ? "GizmoDrawLine" : "GizmoDrawLineRed"; if (gizmoSpace.SymmetryPlane == MySymmetrySettingModeEnum.Disabled) { MySimpleObjectDraw.DrawTransparentBox(ref drawMatrix, ref localAABB, ref color, MySimpleObjectRasterizer.Wireframe, 1, 0.04f, lineMaterial: lineMaterial); m_rotationHints.CalculateRotationHints(drawMatrix, localAABB, !MyHud.MinimalHud && MySandboxGame.Config.RotationHints && draw && MyFakes.ENABLE_ROTATION_HINTS); } gizmoSpace.m_cubeMatricesTemp.Clear(); gizmoSpace.m_cubeModelsTemp.Clear(); if (gizmoSpace.m_showGizmoCube) { // Draw mount points of added cube block as yellow squares in neighboring cells. if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_MOUNT_POINTS) { DrawMountPoints(gridSize, CurrentBlockDefinition, ref drawMatrix); } AddFastBuildModels(gizmoSpace, MatrixD.Identity, gizmoSpace.m_cubeMatricesTemp, gizmoSpace.m_cubeModelsTemp, gizmoSpace.m_blockDefinition); Debug.Assert(gizmoSpace.m_cubeMatricesTemp.Count == gizmoSpace.m_cubeModelsTemp.Count); for (int i = 0; i < gizmoSpace.m_cubeMatricesTemp.Count; ++i) { string model = gizmoSpace.m_cubeModelsTemp[i]; if (!string.IsNullOrEmpty(model)) m_renderData.AddInstance(MyModel.GetId(model), gizmoSpace.m_cubeMatricesTemp[i], ref MatrixD.Identity); } } gizmoSpace.m_animationProgress += m_animationSpeed; }
private void UpdateGizmo_DynamicMode(MyCubeBuilderGizmo.MyGizmoSpaceProperties gizmoSpace) { Debug.Assert(DynamicMode); gizmoSpace.m_animationProgress = 1; float gridSize = MyDefinitionManager.Static.GetCubeSize(CurrentBlockDefinition.CubeSize); BoundingBoxD localAABB = new BoundingBoxD(-CurrentBlockDefinition.Size * gridSize * 0.5f, CurrentBlockDefinition.Size * gridSize * 0.5f); var settings = CurrentBlockDefinition.CubeSize == MyCubeSize.Large ? CubeBuilderDefinition.BuildingSettings.LargeGrid : CubeBuilderDefinition.BuildingSettings.SmallGrid; MatrixD drawMatrix = gizmoSpace.m_worldMatrixAdd; MyCubeGrid.GetCubeParts(CurrentBlockDefinition, Vector3I.Zero, Matrix.Identity, gridSize, gizmoSpace.m_cubeModelsTemp, gizmoSpace.m_cubeMatricesTemp, gizmoSpace.m_cubeNormals, gizmoSpace.m_patternOffsets); if (gizmoSpace.m_showGizmoCube) { //MatrixD invDrawMatrix = MatrixD.Invert(gizmoSpace.m_worldMatrixAdd); m_gizmo.AddFastBuildParts(gizmoSpace, CurrentBlockDefinition, null); m_gizmo.UpdateGizmoCubeParts(gizmoSpace, m_renderData, ref MatrixD.Identity, CurrentBlockDefinition); } BuildComponent.GetGridSpawnMaterials(CurrentBlockDefinition, drawMatrix, false); if (MySession.Static.IsAdminModeEnabled(Sync.MyId) == false) { gizmoSpace.m_buildAllowed &= BuildComponent.HasBuildingMaterials(MySession.Static.LocalCharacter); } MatrixD inverseDrawMatrix = MatrixD.Invert(drawMatrix); if (MySession.Static.SurvivalMode && !SpectatorIsBuilding && !MySession.Static.IsAdminModeEnabled(Sync.MyId)) { if (!MyCubeBuilderGizmo.DefaultGizmoCloseEnough(ref inverseDrawMatrix, localAABB, gridSize, IntersectionDistance) || MySession.Static.GetCameraControllerEnum() == MyCameraControllerEnum.Spectator) { gizmoSpace.m_buildAllowed = false; gizmoSpace.m_removeBlock = null; } if (CameraControllerSpectator) { gizmoSpace.m_showGizmoCube = false; gizmoSpace.m_buildAllowed = false; return; } } // m_buildAllowed is set in shape cast if (!gizmoSpace.m_dynamicBuildAllowed) { bool placementTest = MyCubeGrid.TestBlockPlacementArea(CurrentBlockDefinition, null, drawMatrix, ref settings, localAABB, DynamicMode);//DynamicModeVoxelTest); gizmoSpace.m_buildAllowed &= placementTest; } gizmoSpace.m_showGizmoCube = true; gizmoSpace.m_cubeMatricesTemp.Clear(); gizmoSpace.m_cubeModelsTemp.Clear(); m_rotationHints.CalculateRotationHints(drawMatrix, localAABB, !MyHud.MinimalHud && MySandboxGame.Config.RotationHints && MyFakes.ENABLE_ROTATION_HINTS); // In dynamic mode gizmo cube is shown even if it intersects character gizmoSpace.m_buildAllowed &= !IntersectsCharacterOrCamera(gizmoSpace, gridSize, ref inverseDrawMatrix); if (gizmoSpace.m_showGizmoCube) { Color color = Color.White; string lineMaterial = gizmoSpace.m_buildAllowed ? "GizmoDrawLine" : "GizmoDrawLineRed"; if (gizmoSpace.SymmetryPlane == MySymmetrySettingModeEnum.Disabled) { MySimpleObjectDraw.DrawTransparentBox(ref drawMatrix, ref localAABB, ref color, MySimpleObjectRasterizer.Wireframe, 1, 0.04f, lineMaterial: lineMaterial); } AddFastBuildModels(gizmoSpace, MatrixD.Identity, gizmoSpace.m_cubeMatricesTemp, gizmoSpace.m_cubeModelsTemp, gizmoSpace.m_blockDefinition); Debug.Assert(gizmoSpace.m_cubeMatricesTemp.Count == gizmoSpace.m_cubeModelsTemp.Count); for (int i = 0; i < gizmoSpace.m_cubeMatricesTemp.Count; ++i) { string model = gizmoSpace.m_cubeModelsTemp[i]; if (!string.IsNullOrEmpty(model)) { var mId = MyModel.GetId(model); m_renderData.AddInstance(mId, gizmoSpace.m_cubeMatricesTemp[i], ref MatrixD.Identity); } } } }
protected virtual void UpdateGizmo(MyCubeBuilderGizmo.MyGizmoSpaceProperties gizmoSpace, bool add, bool remove, bool draw) { if (!gizmoSpace.Enabled) return; ProfilerShort.Begin("CanBuild"); if (MyCubeBuilder.Static.canBuild == false) { gizmoSpace.m_showGizmoCube = false; gizmoSpace.m_buildAllowed = false; } if (MyFakes.ENABLE_BATTLE_SYSTEM && MySession.Static.Battle) { gizmoSpace.m_showGizmoCube = false; gizmoSpace.m_buildAllowed = false; ProfilerShort.End(); return; } if (DynamicMode) { ProfilerShort.BeginNextBlock("UpdateGizmo_DynamicMode"); UpdateGizmo_DynamicMode(gizmoSpace); } else if (CurrentGrid != null) { ProfilerShort.BeginNextBlock("UpdateGizmo_Grid"); UpdateGizmo_Grid(gizmoSpace, add, remove, draw); } //if (CurrentGrid != null) //{ // ProfilerShort.BeginNextBlock("UpdateGizmo_Grid"); // UpdateGizmo_Grid(gizmoSpace, add, remove, draw); //} //else if (DynamicMode) //{ // ProfilerShort.BeginNextBlock("UpdateGizmo_DynamicMode"); // UpdateGizmo_DynamicMode(gizmoSpace); //} else// if (CurrentVoxelBase != null) { ProfilerShort.BeginNextBlock("UpdateGizmo_VoxelMap"); UpdateGizmo_VoxelMap(gizmoSpace, add, remove, draw); } ProfilerShort.End(); }