From 02146108baa38fe00eacc65881fb178fd04e827e Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sun, 27 Sep 2015 17:14:04 -0400 Subject: [PATCH] Fix highlighted block, add crosshairs --- TrueCraft.API/Vector3.cs | 8 + TrueCraft.Client/Content/icons.png | Bin 0 -> 1418 bytes TrueCraft.Client/Modules/HUDModule.cs | 38 +++++ TrueCraft.Client/Modules/HighlightModule.cs | 87 +++++------ .../Modules/PlayerControlModule.cs | 12 ++ TrueCraft.Client/MultiplayerClient.cs | 3 +- TrueCraft.Client/Rendering/BlockRenderer.cs | 48 +++--- .../Rendering/Blocks/SnowRenderer.cs | 6 +- .../Rendering/Blocks/WheatRenderer.cs | 6 +- .../Rendering/FlatQuadRenderer.cs | 32 ++-- TrueCraft.Client/Rendering/TextureMapper.cs | 2 + TrueCraft.Client/TrueCraft.Client.csproj | 6 +- TrueCraft.Client/TrueCraftGame.cs | 20 ++- TrueCraft.Client/VoxelCast.cs | 146 ++++-------------- 14 files changed, 204 insertions(+), 210 deletions(-) create mode 100644 TrueCraft.Client/Content/icons.png create mode 100644 TrueCraft.Client/Modules/HUDModule.cs diff --git a/TrueCraft.API/Vector3.cs b/TrueCraft.API/Vector3.cs index 26970ef..8b878a3 100644 --- a/TrueCraft.API/Vector3.cs +++ b/TrueCraft.API/Vector3.cs @@ -79,6 +79,14 @@ namespace TrueCraft.API return new Vector3(Math.Floor(X), Math.Floor(Y), Math.Floor(Z)); } + /// + /// Rounds the decimal component of each part of this Vector3. + /// + public Vector3 Round() + { + return new Vector3(Math.Round(X), Math.Round(Y), Math.Round(Z)); + } + /// /// Clamps the vector to within the specified value. /// diff --git a/TrueCraft.Client/Content/icons.png b/TrueCraft.Client/Content/icons.png new file mode 100644 index 0000000000000000000000000000000000000000..590a89e5d4c315054856da6c7e1a008fdb02eb69 GIT binary patch literal 1418 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|G$6&6C~?lu%}vcK0dg4_oQqNu zOHxx5$}>wc6x=<115)%-*%=sE-g&w>hE&{od)qKi+FgY0fqCP)3EWGRf-Tq;5?I@6 z+gAuJ3S0XytZ1r2N27_C6>HWaHI4`8+ISBeo?&ijU8&`l%DhQCJ|U>%v`+YL@1PWw zz&~~k2Z}7D0w>%%e{*Kwkxx%9F0T3;-#$nAdCj|BZwkJwh&yl1XK?q}rmp?hU%R@v z?7u&MM_)&XNY?h-y}MpdxwPX!{fm-w>-_!H)|Go5wa=Z?(NXg~udl=7{QTvgz8;yK zmofiEafyhaU}kmoqg^Zc*G$@S=F$4g@4qWQpVQ^E)>ww`@%1UkSmU1`Jn2~zt@UGB zVUSmP>)$t#NA^}fuYVA@G5q(HRtGz)t{uhdkB)YKe%#Zw_m(@y1~0qpwQoY_MPC>B z-}>tch&Zr{^}wpCk}9jMdsq73ye)a_{x9jIv&;%#fB!x9vfgFMlpvn=!`Cu@pUaqa z-{kLoOX-YP7J`D`*_%UjKe#VnURZA+;s5#duaMe}du!JnxZii{_OAoG&N7^9bqM_P zn9uZRwBD_b6}*k?OIZ&@9$zU|vGs?(6w}p5;!JlmD%mc#z4%(SHM(Kxd%?MW%S&Is zGf=Xc>-Sddfz4wVmp>J+uU#qaiTw4)HtJ>k7XCFM3NcSkr%9B*QfS}2*M7fBM9M2W zU5232yt{E^{ExyS(Dlm#;^pS7bBmsWUv=$ExwG=Ff-oF3C?TbLR(2^l<+> zdHMQdvxH7YgU4U$_b><4oSNRpG=KIk@%5svzi)q(e|){`^}z&#x{%*Cb$@>U*!5>+ zd>;F{Jhlr`LZSETx5u}*NX2gd+8JN>Z{;@sVC#afz|_z1!0P6WyLX~98k+6p<9^M~ z+kM}@VyAtuw7|qN^Y2mLPd>llzCQZzdOan*)&9!Q84~&=4;UR@60~RK$_cxVTk>yL zE0^$Uo&8MnLFRhq>6_U=f?e*GJZ|T+OZ(?OZw=*dxMO?n&KgxqsrnUlY2O{CBUHa#onyVwhISmr!!P{#)tSqxU5^uKxWUx&Qy7_15eMtfF68HZut84Dj(x+cIm`)jb6t-7-*vw3ZM-(colors); - var texcoords = new[] - { - Vector2.UnitX + Vector2.UnitY, - Vector2.UnitY, - Vector2.Zero, - Vector2.UnitX - }; - int[] indicies; - var verticies = BlockRenderer.CreateUniformCube(Microsoft.Xna.Framework.Vector3.Zero, - texcoords, VisibleFaces.All, 0, out indicies, Color.White); - HighlightMesh = new Mesh(Game, verticies, indicies); - HighlightEffect = new BasicEffect(Game.GraphicsDevice); - HighlightEffect.EnableDefaultLighting(); - HighlightEffect.DirectionalLight0.SpecularColor = Color.Black.ToVector3(); - HighlightEffect.DirectionalLight1.SpecularColor = Color.Black.ToVector3(); - HighlightEffect.DirectionalLight2.SpecularColor = Color.Black.ToVector3(); - HighlightEffect.TextureEnabled = true; - HighlightEffect.Texture = HighlightTexture; HighlightEffect.VertexColorEnabled = true; } @@ -66,18 +55,19 @@ namespace TrueCraft.Client.Modules Matrix.CreateRotationY(MathHelper.ToRadians(Game.Client.Yaw))); var cast = VoxelCast.Cast(Game.Client.World, - new TrueCraft.API.Ray(Game.Camera.Position, - new TrueCraft.API.Vector3(direction.X, direction.Y, direction.Z)), - Game.BlockRepository, TrueCraftGame.Reach); + new TRay(Game.Camera.Position, new TVector3(direction.X, direction.Y, direction.Z)), + Game.BlockRepository, (int)TrueCraftGame.Reach); if (cast == null) HighlightedBlock = -Coordinates3D.One; else { HighlightedBlock = cast.Item1; - HighlightEffect.World = Matrix.CreateScale(1.02f) * - Matrix.CreateTranslation(new Microsoft.Xna.Framework.Vector3( - cast.Item1.X, cast.Item1.Y, cast.Item1.Z)); + HighlightEffect.World = + Matrix.CreateTranslation(new XVector3(-0.5f)) * + Matrix.CreateScale(1.01f) * + Matrix.CreateTranslation(new XVector3(0.5f)) * + Matrix.CreateTranslation(new XVector3(cast.Item1.X, cast.Item1.Y, cast.Item1.Z)); } } @@ -87,8 +77,13 @@ namespace TrueCraft.Client.Modules if (HighlightedBlock != -Coordinates3D.One) { - Game.GraphicsDevice.DepthStencilState = DepthStencilState.None; - HighlightMesh.Draw(HighlightEffect); + foreach (var pass in HighlightEffect.CurrentTechnique.Passes) + { + pass.Apply(); + HighlightEffect.GraphicsDevice.DrawUserIndexedPrimitives( + PrimitiveType.LineList, CubeVerticies, 0, + CubeVerticies.Length, CubeIndicies, 0, CubeIndicies.Length / 2); + } } } } diff --git a/TrueCraft.Client/Modules/PlayerControlModule.cs b/TrueCraft.Client/Modules/PlayerControlModule.cs index af9aea1..c844f3d 100644 --- a/TrueCraft.Client/Modules/PlayerControlModule.cs +++ b/TrueCraft.Client/Modules/PlayerControlModule.cs @@ -11,10 +11,12 @@ namespace TrueCraft.Client.Modules { private TrueCraftGame Game { get; set; } private Vector3 Delta { get; set; } + private bool Capture { get; set; } public PlayerControlModule(TrueCraftGame game) { Game = game; + Capture = true; } public bool KeyDown(GameTime gameTime, KeyboardKeyEventArgs e) @@ -55,6 +57,14 @@ namespace TrueCraft.Client.Modules Delta += Vector3.Backward; return true; + case Keys.I: + Game.Client.Position = Game.Client.Position.Floor(); + return true; + + case Keys.Tab: + Capture = !Capture; + return true; + case Keys.Space: if (Math.Floor(Game.Client.Position.Y) == Game.Client.Position.Y) Game.Client.Velocity += TrueCraft.API.Vector3.Up * 0.3; @@ -96,6 +106,8 @@ namespace TrueCraft.Client.Modules public void MouseMove(GameTime gameTime, MouseMoveEventArgs e) { + if (!Capture) + return; var centerX = Game.GraphicsDevice.Viewport.Width / 2; var centerY = Game.GraphicsDevice.Viewport.Height / 2; Mouse.SetPosition(centerX, centerY); diff --git a/TrueCraft.Client/MultiplayerClient.cs b/TrueCraft.Client/MultiplayerClient.cs index 0d6ce0b..eb74f92 100644 --- a/TrueCraft.Client/MultiplayerClient.cs +++ b/TrueCraft.Client/MultiplayerClient.cs @@ -256,7 +256,8 @@ namespace TrueCraft.Client { get { - return new BoundingBox(Position, Position + Size); + var pos = Position - new Vector3(Width / 2, 0, Depth / 2); + return new BoundingBox(pos, pos + Size); } } diff --git a/TrueCraft.Client/Rendering/BlockRenderer.cs b/TrueCraft.Client/Rendering/BlockRenderer.cs index 8a27cda..f8b6ca5 100644 --- a/TrueCraft.Client/Rendering/BlockRenderer.cs +++ b/TrueCraft.Client/Rendering/BlockRenderer.cs @@ -147,50 +147,50 @@ namespace TrueCraft.Client.Rendering CubeMesh[0] = new[] // Positive Z face { - new Vector3(0.5f, -0.5f, 0.5f), - new Vector3(-0.5f, -0.5f, 0.5f), - new Vector3(-0.5f, 0.5f, 0.5f), - new Vector3(0.5f, 0.5f, 0.5f) + new Vector3(1, 0, 1), + new Vector3(0, 0, 1), + new Vector3(0, 1, 1), + new Vector3(1, 1, 1) }; CubeMesh[1] = new[] // Negative Z face { - new Vector3(-0.5f, -0.5f, -0.5f), - new Vector3(0.5f, -0.5f, -0.5f), - new Vector3(0.5f, 0.5f, -0.5f), - new Vector3(-0.5f, 0.5f, -0.5f) + new Vector3(0, 0, 0), + new Vector3(1, 0, 0), + new Vector3(1, 1, 0), + new Vector3(0, 1, 0) }; CubeMesh[2] = new[] // Positive X face { - new Vector3(0.5f, -0.5f, -0.5f), - new Vector3(0.5f, -0.5f, 0.5f), - new Vector3(0.5f, 0.5f, 0.5f), - new Vector3(0.5f, 0.5f, -0.5f) + new Vector3(1, 0, 0), + new Vector3(1, 0, 1), + new Vector3(1, 1, 1), + new Vector3(1, 1, 0) }; CubeMesh[3] = new[] // Negative X face { - new Vector3(-0.5f, -0.5f, 0.5f), - new Vector3(-0.5f, -0.5f, -0.5f), - new Vector3(-0.5f, 0.5f, -0.5f), - new Vector3(-0.5f, 0.5f, 0.5f) + new Vector3(0, 0, 1), + new Vector3(0, 0, 0), + new Vector3(0, 1, 0), + new Vector3(0, 1, 1) }; CubeMesh[4] = new[] // Positive Y face { - new Vector3(0.5f, 0.5f, 0.5f), - new Vector3(-0.5f, 0.5f, 0.5f), - new Vector3(-0.5f, 0.5f, -0.5f), - new Vector3(0.5f, 0.5f, -0.5f) + new Vector3(1, 1, 1), + new Vector3(0, 1, 1), + new Vector3(0, 1, 0), + new Vector3(1, 1, 0) }; CubeMesh[5] = new[] // Negative Y face { - new Vector3(0.5f, -0.5f, -0.5f), - new Vector3(-0.5f, -0.5f, -0.5f), - new Vector3(-0.5f, -0.5f, 0.5f), - new Vector3(0.5f, -0.5f, 0.5f) + new Vector3(1, 0, 0), + new Vector3(0, 0, 0), + new Vector3(0, 0, 1), + new Vector3(1, 0, 1) }; } } diff --git a/TrueCraft.Client/Rendering/Blocks/SnowRenderer.cs b/TrueCraft.Client/Rendering/Blocks/SnowRenderer.cs index 6a16e2a..a8eff25 100644 --- a/TrueCraft.Client/Rendering/Blocks/SnowRenderer.cs +++ b/TrueCraft.Client/Rendering/Blocks/SnowRenderer.cs @@ -27,17 +27,13 @@ namespace TrueCraft.Client.Rendering.Blocks public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset, VisibleFaces faces, Tuple textureMap, int indiciesOffset, out int[] indicies) { - var overhead = new Vector3(0.5f, 0.5f, 0.5f); - var cube = CreateUniformCube(overhead, Texture, faces, indiciesOffset, out indicies, Color.White); + var cube = CreateUniformCube(Vector3.Zero, Texture, faces, indiciesOffset, out indicies, Color.White); var heightMultiplier = new Vector3(1, ((descriptor.Metadata + 1) / 16f), 1); for (int i = 0; i < cube.Length; i++) { if (cube[i].Position.Y > 0) - { cube[i].Position *= heightMultiplier; - } cube[i].Position += offset; - cube[i].Position -= overhead; } return cube; } diff --git a/TrueCraft.Client/Rendering/Blocks/WheatRenderer.cs b/TrueCraft.Client/Rendering/Blocks/WheatRenderer.cs index debaf0c..2f75b09 100644 --- a/TrueCraft.Client/Rendering/Blocks/WheatRenderer.cs +++ b/TrueCraft.Client/Rendering/Blocks/WheatRenderer.cs @@ -46,10 +46,11 @@ namespace TrueCraft.Client.Rendering indicies = new int[4 * 2 * 6]; var verticies = new VertexPositionNormalColorTexture[4 * 2 * 6]; int[] _indicies; + var center = new Vector3(-0.5f, -0.5f, -0.5f); for (int _side = 0; _side < 4; _side++) // Y faces are the last two in the CubeFace enum, so we can just iterate to 4 { var side = (CubeFace)_side; - var quad = CreateQuad(side, Vector3.Zero, texture, 0, indiciesOffset, out _indicies, Color.White); + var quad = CreateQuad(side, center, texture, 0, indiciesOffset, out _indicies, Color.White); if (side == CubeFace.NegativeX || side == CubeFace.PositiveX) { for (int i = 0; i < quad.Length; i++) @@ -73,7 +74,7 @@ namespace TrueCraft.Client.Rendering for (int _side = 0; _side < 4; _side++) { var side = (CubeFace)_side; - var quad = CreateQuad(side, Vector3.Zero, texture, 0, indiciesOffset, out _indicies, Color.White); + var quad = CreateQuad(side, center, texture, 0, indiciesOffset, out _indicies, Color.White); if (side == CubeFace.NegativeX || side == CubeFace.PositiveX) { for (int i = 0; i < quad.Length; i++) @@ -98,6 +99,7 @@ namespace TrueCraft.Client.Rendering for (int i = 0; i < verticies.Length; i++) { verticies[i].Position.Y -= 1 / 16f; + verticies[i].Position -= center; } return verticies; } diff --git a/TrueCraft.Client/Rendering/FlatQuadRenderer.cs b/TrueCraft.Client/Rendering/FlatQuadRenderer.cs index d53106e..94da96d 100644 --- a/TrueCraft.Client/Rendering/FlatQuadRenderer.cs +++ b/TrueCraft.Client/Rendering/FlatQuadRenderer.cs @@ -80,34 +80,34 @@ namespace TrueCraft.Client.Rendering QuadMesh[0] = new[] { - new Vector3(0.5f, -0.5f, 0.5f), - new Vector3(-0.5f, -0.5f, -0.5f), - new Vector3(-0.5f, 0.5f, -0.5f), - new Vector3(0.5f, 0.5f, 0.5f) + new Vector3(1, 0, 1), + new Vector3(0, 0, 0), + new Vector3(0, 1, 0), + new Vector3(1, 1, 1) }; QuadMesh[1] = new[] { - new Vector3(-0.5f, -0.5f, -0.5f), - new Vector3(0.5f, -0.5f, 0.5f), - new Vector3(0.5f, 0.5f, 0.5f), - new Vector3(-0.5f, 0.5f, -0.5f) + new Vector3(0, 0, 0), + new Vector3(1, 0, 1), + new Vector3(1, 1, 1), + new Vector3(0, 1, 0) }; QuadMesh[2] = new[] { - new Vector3(-0.5f, -0.5f, 0.5f), - new Vector3(0.5f, -0.5f, -0.5f), - new Vector3(0.5f, 0.5f, -0.5f), - new Vector3(-0.5f, 0.5f, 0.5f) + new Vector3(0, 0, 1), + new Vector3(1, 0, 0), + new Vector3(1, 1, 0), + new Vector3(0, 1, 1) }; QuadMesh[3] = new[] { - new Vector3(0.5f, -0.5f, -0.5f), - new Vector3(-0.5f, -0.5f, 0.5f), - new Vector3(-0.5f, 0.5f, 0.5f), - new Vector3(0.5f, 0.5f, -0.5f) + new Vector3(1, 0, 0), + new Vector3(0, 0, 1), + new Vector3(0, 1, 1), + new Vector3(1, 1, 0) }; } } diff --git a/TrueCraft.Client/Rendering/TextureMapper.cs b/TrueCraft.Client/Rendering/TextureMapper.cs index 0e0486c..a6557d1 100644 --- a/TrueCraft.Client/Rendering/TextureMapper.cs +++ b/TrueCraft.Client/Rendering/TextureMapper.cs @@ -31,6 +31,8 @@ namespace TrueCraft.Client.Rendering Defaults.Add("items.png", new PngReader().Read(File.OpenRead("Content/items.png"), graphicsDevice)); Defaults.Add("terrain.png", new PngReader().Read(File.OpenRead("Content/terrain.png"), graphicsDevice)); + Defaults.Add("gui/gui.png", new PngReader().Read(File.OpenRead("Content/gui.png"), graphicsDevice)); + Defaults.Add("gui/icons.png", new PngReader().Read(File.OpenRead("Content/icons.png"), graphicsDevice)); } /// diff --git a/TrueCraft.Client/TrueCraft.Client.csproj b/TrueCraft.Client/TrueCraft.Client.csproj index 47c8691..3655bf5 100644 --- a/TrueCraft.Client/TrueCraft.Client.csproj +++ b/TrueCraft.Client/TrueCraft.Client.csproj @@ -132,6 +132,7 @@ + @@ -230,8 +231,11 @@ PreserveNewest + + PreserveNewest + - + \ No newline at end of file diff --git a/TrueCraft.Client/TrueCraftGame.cs b/TrueCraft.Client/TrueCraftGame.cs index 2e0adbe..4fcb959 100644 --- a/TrueCraft.Client/TrueCraftGame.cs +++ b/TrueCraft.Client/TrueCraftGame.cs @@ -28,6 +28,7 @@ namespace TrueCraft.Client public ConcurrentBag PendingMainThreadActions { get; set; } public double Bobbing { get; set; } public ChunkModule ChunkModule { get; set; } + public float ScaleFactor { get; set; } private List Modules { get; set; } private SpriteBatch SpriteBatch { get; set; } @@ -43,7 +44,7 @@ namespace TrueCraft.Client private GameTime GameTime { get; set; } private DebugInfoModule DebugInfoModule { get; set; } - public static readonly int Reach = 5; + public static readonly double Reach = 3; public IBlockRepository BlockRepository { @@ -63,6 +64,7 @@ namespace TrueCraft.Client Graphics.PreferredBackBufferWidth = UserSettings.Local.WindowResolution.Width; Graphics.PreferredBackBufferHeight = UserSettings.Local.WindowResolution.Height; Graphics.ApplyChanges(); + Window.ClientSizeChanged += Window_ClientSizeChanged; Client = client; EndPoint = endPoint; LastPhysicsUpdate = DateTime.MinValue; @@ -80,6 +82,16 @@ namespace TrueCraft.Client Components.Add(mouseComponent); } + void Window_ClientSizeChanged(object sender, EventArgs e) + { + if (GraphicsDevice.Viewport.Width < 640 || GraphicsDevice.Viewport.Height < 480) + ScaleFactor = 0.5f; + else if (GraphicsDevice.Viewport.Width < 978 || GraphicsDevice.Viewport.Height < 720) + ScaleFactor = 1.0f; + else + ScaleFactor = 1.5f; + } + protected override void Initialize() { Modules = new List(); @@ -92,6 +104,7 @@ namespace TrueCraft.Client Modules.Add(ChunkModule); Modules.Add(new HighlightModule(this)); Modules.Add(new PlayerControlModule(this)); + Modules.Add(new HUDModule(this)); Modules.Add(DebugInfoModule); Client.PropertyChanged += HandleClientPropertyChanged; @@ -111,6 +124,8 @@ namespace TrueCraft.Client Window.ClientSizeChanged += (sender, e) => CreateRenderTarget(); CreateRenderTarget(); SpriteBatch = new SpriteBatch(GraphicsDevice); + + Window_ClientSizeChanged(null, null); } private void CreateRenderTarget() @@ -235,9 +250,10 @@ namespace TrueCraft.Client var bobbing = Bobbing * 1.5; var xbob = Math.Cos(bobbing + Math.PI / 2) * bobbingMultiplier; var ybob = Math.Sin(Math.PI / 2 - (2 * bobbing)) * bobbingMultiplier; + Camera.Position = new TrueCraft.API.Vector3( Client.Position.X + xbob - (Client.Size.Width / 2), - Client.Position.Y + (Client.Size.Height - 0.5) + ybob, + Client.Position.Y + Client.Size.Height + ybob, Client.Position.Z - (Client.Size.Depth / 2)); Camera.Pitch = Client.Pitch; diff --git a/TrueCraft.Client/VoxelCast.cs b/TrueCraft.Client/VoxelCast.cs index 0ac6efb..9fdb467 100644 --- a/TrueCraft.Client/VoxelCast.cs +++ b/TrueCraft.Client/VoxelCast.cs @@ -15,122 +15,42 @@ namespace TrueCraft.Client // Thanks to http://gamedev.stackexchange.com/questions/47362/cast-ray-to-select-block-in-voxel-game public static Tuple Cast(ReadOnlyWorld world, - Ray ray, IBlockRepository repository, double max) + Ray ray, IBlockRepository repository, int max) { - var origin = ray.Position.Floor(); - var direction = ray.Direction; - var step = new Vector3(SigNum(ray.Direction.X), SigNum(ray.Direction.Y), SigNum(ray.Direction.Z)); - var tMax = new Vector3( - IntBound(origin.X, direction.X), - IntBound(origin.Y, direction.Y), - IntBound(origin.Z, direction.Z)); - var tDelta = new Vector3( - step.X / direction.X, - step.Y / direction.Y, - step.Z / direction.Z); - BlockFace face = BlockFace.PositiveY; + // TODO: There are more efficient ways of doing this, fwiw - if (ray.Direction == Vector3.Zero) + double min = max * 2; + var pick = -Coordinates3D.One; + for (int x = -max; x <= max; x++) + { + for (int y = -max; y <= max; y++) + { + for (int z = -max; z <= max; z++) + { + var coords = (Coordinates3D)(new Vector3(x, y, z) + ray.Position).Round(); + if (!world.IsValidPosition(coords)) + continue; + var id = world.GetBlockID(coords); + if (id != 0) + { + var provider = repository.GetBlockProvider(id); + var box = provider.BoundingBox; + if (box != null) + { + var distance = ray.Intersects(box.Value.OffsetBy(coords)); + if (distance != null && distance.Value < min) + { + min = distance.Value; + pick = coords; + } + } + } + } + } + } + if (pick == -Coordinates3D.One) return null; - - max /= Math.Sqrt(ray.Direction.X * ray.Direction.X - + ray.Direction.Y * ray.Direction.Y - + ray.Direction.Z * ray.Direction.Z); - - while (world.IsValidPosition((Coordinates3D)origin)) - { - var provider = repository.GetBlockProvider(world.GetBlockID((Coordinates3D)origin)); - var _box = provider.BoundingBox; - if (_box != null) - { - var box = _box.Value.OffsetBy((Coordinates3D)origin); - if (ray.Intersects(box) != null) - return new Tuple((Coordinates3D)origin, face); - } - - if (tMax.X < tMax.Y) - { - if (tMax.X < tMax.Z) - { - if (tMax.X > max) - return null; - // Update which cube we are now in. - origin.X += step.X; - // Adjust tMaxX to the next X-oriented boundary crossing. - tMax.X += tDelta.X; - // Record the normal vector of the cube face we entered. - if (step.X < 0) - face = BlockFace.PositiveX; - else - face = BlockFace.NegativeX; - } - else - { - if (tMax.Z > max) - return null; - origin.Z += step.Z; - tMax.Z += tDelta.Z; - if (step.Z < 0) - face = BlockFace.PositiveZ; - else - face = BlockFace.NegativeZ; - } - } - else - { - if (tMax.Y < tMax.Z) - { - if (tMax.Y > max) - return null; - origin.Y += step.Y; - tMax.Y += tDelta.Y; - if (step.Y < 0) - face = BlockFace.PositiveY; - else - face = BlockFace.NegativeY; - } - else - { - // Identical to the second case, repeated for simplicity in - // the conditionals. - if (tMax.Z > max) - break; - origin.Z += step.Z; - tMax.Z += tDelta.Z; - if (step.Z < 0) - face = BlockFace.PositiveZ; - else - face = BlockFace.NegativeZ; - } - } - } - - return null; - } - - private static double IntBound(double s, double ds) - { - // Find the smallest positive t such that s+t*ds is an integer. - if (ds < 0) - { - return IntBound(-s, -ds); - } - else - { - s = Mod(s, 1); - // problem is now s+t*ds = 1 - return (1 - s) / ds; - } - } - - private static int SigNum(double x) - { - return x > 0 ? 1 : x < 0 ? -1 : 0; - } - - private static double Mod(double value, double modulus) - { - return (value % modulus + modulus) % modulus; + return new Tuple(pick, BlockFace.PositiveY); } } }