Fix highlighted block, add crosshairs
This commit is contained in:
parent
6066db0bd7
commit
02146108ba
@ -79,6 +79,14 @@ namespace TrueCraft.API
|
||||
return new Vector3(Math.Floor(X), Math.Floor(Y), Math.Floor(Z));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rounds the decimal component of each part of this Vector3.
|
||||
/// </summary>
|
||||
public Vector3 Round()
|
||||
{
|
||||
return new Vector3(Math.Round(X), Math.Round(Y), Math.Round(Z));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clamps the vector to within the specified value.
|
||||
/// </summary>
|
||||
|
BIN
TrueCraft.Client/Content/icons.png
Normal file
BIN
TrueCraft.Client/Content/icons.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
38
TrueCraft.Client/Modules/HUDModule.cs
Normal file
38
TrueCraft.Client/Modules/HUDModule.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace TrueCraft.Client.Modules
|
||||
{
|
||||
public class HUDModule : IGraphicalModule
|
||||
{
|
||||
private TrueCraftGame Game { get; set; }
|
||||
private SpriteBatch SpriteBatch { get; set; }
|
||||
private Texture2D GUI { get; set; }
|
||||
private Texture2D Icons { get; set; }
|
||||
|
||||
public HUDModule(TrueCraftGame game)
|
||||
{
|
||||
Game = game;
|
||||
SpriteBatch = new SpriteBatch(game.GraphicsDevice);
|
||||
GUI = game.TextureMapper.GetTexture("gui/gui.png");
|
||||
Icons = game.TextureMapper.GetTexture("gui/icons.png");
|
||||
}
|
||||
|
||||
public void Update(GameTime gameTime)
|
||||
{
|
||||
}
|
||||
|
||||
static readonly Color CrosshairColor = new Color(255, 255, 255, 70);
|
||||
|
||||
public void Draw(GameTime gameTime)
|
||||
{
|
||||
SpriteBatch.Begin(samplerState: SamplerState.PointClamp);
|
||||
SpriteBatch.Draw(Icons, new Vector2(
|
||||
Game.GraphicsDevice.Viewport.Width / 2 - (8 * Game.ScaleFactor * 2),
|
||||
Game.GraphicsDevice.Viewport.Height / 2 - (8 * Game.ScaleFactor * 2)),
|
||||
new Rectangle(0, 0, 16, 16), CrosshairColor,
|
||||
0, Vector2.Zero, Game.ScaleFactor * 2, SpriteEffects.None, 1);
|
||||
SpriteBatch.End();
|
||||
}
|
||||
}
|
||||
}
|
@ -3,6 +3,9 @@ using Microsoft.Xna.Framework.Graphics;
|
||||
using TrueCraft.API;
|
||||
using TrueCraft.Client.Rendering;
|
||||
using Microsoft.Xna.Framework;
|
||||
using XVector3 = Microsoft.Xna.Framework.Vector3;
|
||||
using TVector3 = TrueCraft.API.Vector3;
|
||||
using TRay = TrueCraft.API.Ray;
|
||||
|
||||
namespace TrueCraft.Client.Modules
|
||||
{
|
||||
@ -10,51 +13,37 @@ namespace TrueCraft.Client.Modules
|
||||
{
|
||||
public TrueCraftGame Game { get; set; }
|
||||
|
||||
private Texture2D HighlightTexture { get; set; }
|
||||
private Coordinates3D HighlightedBlock { get; set; }
|
||||
private Mesh HighlightMesh { get; set; }
|
||||
private BasicEffect HighlightEffect { get; set; }
|
||||
private static readonly VertexPositionColor[] CubeVerticies;
|
||||
private static readonly short[] CubeIndicies;
|
||||
|
||||
static HighlightModule()
|
||||
{
|
||||
var color = Color.Black;
|
||||
CubeVerticies = new[]
|
||||
{
|
||||
new VertexPositionColor(new XVector3(0, 0, 1), color),
|
||||
new VertexPositionColor(new XVector3(1, 0, 1), color),
|
||||
new VertexPositionColor(new XVector3(1, 1, 1), color),
|
||||
new VertexPositionColor(new XVector3(0, 1, 1), color),
|
||||
new VertexPositionColor(new XVector3(0, 0, 0), color),
|
||||
new VertexPositionColor(new XVector3(1, 0, 0), color),
|
||||
new VertexPositionColor(new XVector3(1, 1, 0), color),
|
||||
new VertexPositionColor(new XVector3(0, 1, 0), color)
|
||||
};
|
||||
CubeIndicies = new short[]
|
||||
{
|
||||
0, 1, 1, 2, 2, 3, 3, 0,
|
||||
0, 4, 4, 7, 7, 6, 6, 2,
|
||||
1, 5, 5, 4, 3, 7, 6, 5
|
||||
};
|
||||
}
|
||||
|
||||
public HighlightModule(TrueCraftGame game)
|
||||
{
|
||||
Game = game;
|
||||
|
||||
const int size = 64;
|
||||
HighlightedBlock = -Coordinates3D.One;
|
||||
HighlightTexture = new Texture2D(Game.GraphicsDevice, size, size);
|
||||
|
||||
var colors = new Color[size * size];
|
||||
for (int i = 0; i < colors.Length; i++)
|
||||
colors[i] = Color.Transparent;
|
||||
for (int x = 0; x < size; x++)
|
||||
colors[x] = Color.Black; // Top
|
||||
for (int x = 0; x < size; x++)
|
||||
colors[x + (size - 1) * size] = Color.Black; // Bottom
|
||||
for (int y = 0; y < size; y++)
|
||||
colors[y * size] = Color.Black; // Left
|
||||
for (int y = 0; y < size; y++)
|
||||
colors[y * size + (size - 1)] = Color.Black; // Right
|
||||
|
||||
HighlightTexture.SetData<Color>(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<VertexPositionColor>(
|
||||
PrimitiveType.LineList, CubeVerticies, 0,
|
||||
CubeVerticies.Length, CubeIndicies, 0, CubeIndicies.Length / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -27,17 +27,13 @@ namespace TrueCraft.Client.Rendering.Blocks
|
||||
public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset,
|
||||
VisibleFaces faces, Tuple<int, int> 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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -132,6 +132,7 @@
|
||||
<Compile Include="Modules\HighlightModule.cs" />
|
||||
<Compile Include="Modules\PlayerControlModule.cs" />
|
||||
<Compile Include="Modules\DebugInfoModule.cs" />
|
||||
<Compile Include="Modules\HUDModule.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ItemGroup>
|
||||
@ -230,8 +231,11 @@
|
||||
<Content Include="Content\gui.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Content\icons.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Modules\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
@ -28,6 +28,7 @@ namespace TrueCraft.Client
|
||||
public ConcurrentBag<Action> PendingMainThreadActions { get; set; }
|
||||
public double Bobbing { get; set; }
|
||||
public ChunkModule ChunkModule { get; set; }
|
||||
public float ScaleFactor { get; set; }
|
||||
|
||||
private List<IGameplayModule> 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<IGameplayModule>();
|
||||
@ -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;
|
||||
|
@ -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<Coordinates3D, BlockFace> 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, BlockFace>((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<Coordinates3D, BlockFace>(pick, BlockFace.PositiveY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user