private static void BuildDesignationGeometry(RawPrimitive Into, VoxelChunk Chunk, Cache Cache, DesignationSet Designations, WorldManager World, VoxelHandle v) { // Todo: Store designations per chunk. foreach (var designation in Designations == null ? new List <DesignationSet.VoxelDesignation>() : Designations.EnumerateDesignations(v).ToList()) { if ((designation.Type & World.Renderer.PersistentSettings.VisibleTypes) != designation.Type) // If hidden by player, do not draw. { return; } var designationProperties = Library.GetDesignationTypeProperties(designation.Type).Value; var designationVisible = false; if (designation.Type == DesignationType.Put) { designationVisible = v.Coordinate.Y < World.Renderer.PersistentSettings.MaxViewingLevel; } else { designationVisible = VoxelHelpers.DoesVoxelHaveVisibleSurface(World, v); } if (designationVisible && Library.GetVoxelPrimitive(Library.DesignationVoxelType).HasValue(out BoxPrimitive designationPrimitive)) { switch (designationProperties.DrawType) { case DesignationDrawType.FullBox: for (int i = 0; i < 6; i++) { BuildVoxelFaceGeometry(Into, Chunk, Cache, designationPrimitive, v, designationProperties.Color, designationPrimitive.UVs, DesignationTransform, (BoxFace)i, false); } break; case DesignationDrawType.TopBox: BuildVoxelFaceGeometry(Into, Chunk, Cache, designationPrimitive, v, designationProperties.Color, designationPrimitive.UVs, DesignationTransform, 0, false); break; case DesignationDrawType.PreviewVoxel: { if (Library.GetVoxelType(designation.Tag.ToString()).HasValue(out VoxelType voxelType) && Library.GetVoxelPrimitive(voxelType).HasValue(out BoxPrimitive previewPrimitive)) { var offsetMatrix = Matrix.Identity; if (!v.IsEmpty) { offsetMatrix = Matrix.CreateTranslation(0.0f, 0.1f, 0.0f); } for (int i = 0; i < 6; i++) { BuildVoxelFaceGeometry(Into, Chunk, Cache, previewPrimitive, v, designationProperties.Color, previewPrimitive.UVs, offsetMatrix, (BoxFace)i, false); } } } break; } } } }
private static void BuildDesignationGeometry(RawPrimitive Into, VoxelChunk Chunk, Cache Cache, DesignationSet Designations, WorldManager World, VoxelHandle v) { var designations = Designations == null ? new List <DesignationSet.VoxelDesignation>() : Designations.EnumerateDesignations(v).ToList(); int maxViewingLevel = World.Renderer.PersistentSettings.MaxViewingLevel; foreach (var designation in designations) { if ((designation.Type & World.Renderer.PersistentSettings.VisibleTypes) == designation.Type) { var props = Library.GetDesignationTypeProperties(designation.Type); var designationVisible = false; if (designation.Type == DesignationType.Put) { designationVisible = v.Coordinate.Y < maxViewingLevel; } else { designationVisible = VoxelHelpers.DoesVoxelHaveVisibleSurface(World, v); } if (designationVisible) { var desPrim = Library.GetVoxelPrimitive(Library.DesignationVoxelType); switch (props.DrawType) { case DrawBoxType.FullBox: for (int i = 0; i < 6; i++) { BuildVoxelFaceGeometry(Into, Chunk, Cache, desPrim, v, props.Color, desPrim.UVs, DesignationTransform, i, false); } break; case DrawBoxType.TopBox: BuildVoxelFaceGeometry(Into, Chunk, Cache, desPrim, v, props.Color, desPrim.UVs, DesignationTransform, 0, false); break; case DrawBoxType.PreviewVoxel: { var previewPrim = Library.GetVoxelPrimitive(Library.GetVoxelType(designation.Tag.ToString())); var offsetMatrix = Matrix.Identity; if (!v.IsEmpty) { offsetMatrix = Matrix.CreateTranslation(0.0f, 0.1f, 0.0f); } for (int i = 0; i < 6; i++) { BuildVoxelFaceGeometry(Into, Chunk, Cache, previewPrim, v, props.Color, previewPrim.UVs, offsetMatrix, i, false); } } break; } } } } }
private void HandleMouseButton(ButtonState ButtonState, VoxelHandle underMouse, bool newVoxel, bool altPressed, ref bool ButtonPressed, InputManager.MouseButton Button) { // If the left mouse button is pressed, update the slection buffer. if (ButtonPressed) { // On release, select voxels. if (ButtonState == ButtonState.Released) { ReleaseSound.Play(World.Renderer.CursorLightPos); ButtonPressed = false; if (SelectionBuffer.Count > 0) { var t = new List <VoxelHandle>(SelectionBuffer); SelectionBuffer.Clear(); Selected.Invoke(t, Button); } BoxYOffset = 0; PrevBoxYOffsetInt = 0; } // Otherwise, update the selection buffer else { if (SelectionBuffer.Count == 0) { FirstVoxel = underMouse; SelectionBuffer.Add(underMouse); } else { SelectionBuffer.Clear(); SelectionBuffer.Add(FirstVoxel); SelectionBuffer.Add(underMouse); BoundingBox buffer = GetSelectionBox(); // Update the selection box to account for offsets from mouse wheel. if (BoxYOffset > 0) { buffer.Max.Y = MathFunctions.Clamp(buffer.Max.Y + (int)BoxYOffset, 0, World.WorldSizeInVoxels.Y - 1); } else if (BoxYOffset < 0) { buffer.Min.Y = MathFunctions.Clamp(buffer.Min.Y - (int)BoxYOffset, 0, World.WorldSizeInVoxels.Y - 1); } SelectionBuffer = Select(buffer, FirstVoxel.WorldPosition, underMouse.WorldPosition).ToList(); if (!altPressed && Brush.CullUnseenVoxels && SelectionType == VoxelSelectionType.SelectFilled) { SelectionBuffer.RemoveAll(v => { if (v.Equals(underMouse)) { return(false); } if (World.PersistentData.Designations.IsVoxelDesignation(v, DesignationType.Put)) { return(false); // Treat put designations as solid. } return(!VoxelHelpers.DoesVoxelHaveVisibleSurface(World, v)); }); } if (newVoxel) { DragSound.Play(World.Renderer.CursorLightPos, SelectionBuffer.Count / 20.0f); Dragged.Invoke(SelectionBuffer, Button); } } } } // If the mouse was not previously pressed, but is now pressed, then notify us of that. else if (ButtonState == ButtonState.Pressed) { ClickSound.Play(World.Renderer.CursorLightPos);; ButtonPressed = true; BoxYOffset = 0; PrevBoxYOffsetInt = 0; } }
public void Update() { MouseState mouse = Mouse.GetState(); KeyboardState keyboard = Keyboard.GetState(); var underMouse = GetVoxelUnderMouse(); // Keep track of whether a new voxel has been selected. bool newVoxel = underMouse.IsValid && underMouse != VoxelUnderMouse; if (!underMouse.IsValid) { return; } VoxelUnderMouse = underMouse; // Update the cursor light. World.CursorLightPos = underMouse.WorldPosition + new Vector3(0.5f, 0.5f, 0.5f); // Get the type of the voxel and display it to the player. if (Enabled && !underMouse.IsEmpty && underMouse.IsExplored) { string info = underMouse.Type.Name; // If it belongs to a room, display that information. if (World.PlayerFaction.RoomBuilder.IsInRoom(underMouse)) { Room room = World.PlayerFaction.RoomBuilder.GetMostLikelyRoom(underMouse); if (room != null) { info += " (" + room.ID + ")"; } } World.ShowInfo(info); } // Do nothing if not enabled. if (!Enabled) { return; } bool altPressed = false; // If the left or right ALT keys are pressed, we can adjust the height of the selection // for building pits and tall walls using the mouse wheel. if (keyboard.IsKeyDown(Keys.LeftAlt) || keyboard.IsKeyDown(Keys.RightAlt)) { var change = mouse.ScrollWheelValue - LastMouseWheel; BoxYOffset += (change) * 0.01f; int offset = (int)BoxYOffset; if (offset != PrevBoxYOffsetInt) { DragSound.Play(World.CursorLightPos); newVoxel = true; } PrevBoxYOffsetInt = offset; altPressed = true; } else { PrevBoxYOffsetInt = 0; } LastMouseWheel = mouse.ScrollWheelValue; // Draw a box around the current voxel under the mouse. if (underMouse.IsValid) { BoundingBox box = underMouse.GetBoundingBox().Expand(0.05f); Drawer3D.DrawBox(box, CurrentColor, CurrentWidth, true); } // If the left mouse button is pressed, update the slection buffer. if (isLeftPressed) { // On release, select voxels. if (mouse.LeftButton == ButtonState.Released) { ReleaseSound.Play(World.CursorLightPos); isLeftPressed = false; LeftReleasedCallback(); BoxYOffset = 0; PrevBoxYOffsetInt = 0; } // Otherwise, update the selection buffer else { if (SelectionBuffer.Count == 0) { FirstVoxel = underMouse; SelectionBuffer.Add(underMouse); } else { SelectionBuffer.Clear(); SelectionBuffer.Add(FirstVoxel); SelectionBuffer.Add(underMouse); BoundingBox buffer = GetSelectionBox(); // Update the selection box to account for offsets from mouse wheel. if (BoxYOffset > 0) { buffer.Max.Y += (int)BoxYOffset; } else if (BoxYOffset < 0) { buffer.Min.Y += (int)BoxYOffset; } SelectionBuffer = Select(buffer, FirstVoxel.WorldPosition, underMouse.WorldPosition).ToList(); if (!altPressed && Brush != VoxelBrush.Stairs) { if (SelectionType == VoxelSelectionType.SelectFilled) { SelectionBuffer.RemoveAll(v => { if (v.Equals(underMouse)) { return(false); } return(v.IsExplored && !VoxelHelpers.DoesVoxelHaveVisibleSurface( Chunks.ChunkData, v)); }); } } if (newVoxel) { DragSound.Play(World.CursorLightPos, SelectionBuffer.Count / 20.0f); Dragged.Invoke(SelectionBuffer, InputManager.MouseButton.Left); } } } } // If the mouse was not previously pressed, but is now pressed, then notify us of that. else if (mouse.LeftButton == ButtonState.Pressed) { ClickSound.Play(World.CursorLightPos);; isLeftPressed = true; BoxYOffset = 0; PrevBoxYOffsetInt = 0; } // Case where the right mouse button is pressed (mirrors left mouse button) // TODO(Break this into a function) if (isRightPressed) { if (mouse.RightButton == ButtonState.Released) { ReleaseSound.Play(World.CursorLightPos); isRightPressed = false; RightReleasedCallback(); BoxYOffset = 0; PrevBoxYOffsetInt = 0; } else { if (SelectionBuffer.Count == 0) { SelectionBuffer.Add(underMouse); FirstVoxel = underMouse; } else { SelectionBuffer.Clear(); SelectionBuffer.Add(FirstVoxel); SelectionBuffer.Add(underMouse); BoundingBox buffer = GetSelectionBox(); if (BoxYOffset > 0) { buffer.Max.Y += (int)BoxYOffset; } else if (BoxYOffset < 0) { buffer.Min.Y += (int)BoxYOffset; } SelectionBuffer = VoxelHelpers.EnumerateCoordinatesInBoundingBox(buffer) .Select(c => new VoxelHandle(Chunks.ChunkData, c)) .Where(v => v.IsValid) .ToList(); if (newVoxel) { DragSound.Play(World.CursorLightPos, SelectionBuffer.Count / 20.0f); Dragged.Invoke(SelectionBuffer, InputManager.MouseButton.Right); } } } } else if (mouse.RightButton == ButtonState.Pressed) { ClickSound.Play(World.CursorLightPos); RightPressedCallback(); BoxYOffset = 0; isRightPressed = true; } }