From 30685e87a3129ffd2788297535be47d0b83ea4fe Mon Sep 17 00:00:00 2001 From: Octal Date: Mon, 11 Dec 2023 11:49:53 -0600 Subject: [PATCH] Simple velocity setup + general code cleanup --- Client/Rendering/World/ChunkMeshBuilder.cs | 2 +- .../Entity/ControlledClientPlayerEntity.cs | 16 ++--- Common/Collision/AABB.cs | 60 ++++++++++------- Common/Collision/PhysicsSim.cs | 2 +- Common/Collision/Ray.cs | 6 +- Common/Network/Packets/PacketHandler.cs | 3 +- Common/Network/Packets/Utils/PacketPool.cs | 6 +- .../Networking/ServerConnectionContext.cs | 8 +-- Common/Server/Components/PlayerManager.cs | 2 +- Common/Tile/Block.cs | 16 ++--- Common/Tile/Blocks.cs | 2 +- Common/Util/Serialization/VDataReader.cs | 66 ++++++++++++------- Common/Util/Serialization/VDataWriter.cs | 36 ++++++---- Common/World/Entity/Entity.cs | 19 ++++-- Common/World/VoxelWorld.cs | 2 +- 15 files changed, 149 insertions(+), 97 deletions(-) diff --git a/Client/Rendering/World/ChunkMeshBuilder.cs b/Client/Rendering/World/ChunkMeshBuilder.cs index cd986c1..7ac0fd2 100644 --- a/Client/Rendering/World/ChunkMeshBuilder.cs +++ b/Client/Rendering/World/ChunkMeshBuilder.cs @@ -276,7 +276,7 @@ private void WorkLoop() { var checkBlock = chunkStorages[checkTuple.Item1][checkTuple.Item2]; //Mark if any side of this block is visible. - isVisible |= !checkBlock.IsSolidBlock; + isVisible |= !checkBlock.IsAir; neighbors[n] = checkBlock; } diff --git a/Client/World/Entity/ControlledClientPlayerEntity.cs b/Client/World/Entity/ControlledClientPlayerEntity.cs index 9e80100..44537d0 100644 --- a/Client/World/Entity/ControlledClientPlayerEntity.cs +++ b/Client/World/Entity/ControlledClientPlayerEntity.cs @@ -33,19 +33,17 @@ public override void Tick() { var movement3d = new dvec3(movement.x, 0, movement.y); - movement3d += new dvec3(0, 1, 0) * Keybinds.Jump.strength; - movement3d += new dvec3(0, -1, 0) * Keybinds.Crouch.strength; + // movement3d += new dvec3(0, 1, 0) * Keybinds.Jump.strength; + // movement3d += new dvec3(0, -1, 0) * Keybinds.Crouch.strength; rotation += new dvec2((float)(looking.y * Constants.SecondsPerTick) * 1, (float)(looking.x * Constants.SecondsPerTick) * 1); movement3d = new dvec2(0, rotation.y).RotationVecToQuat() * movement3d; - - if (Keybinds.Jump.strength < 1) - movement3d += new dvec3(0, -1, 0); - movement3d *= Constants.SecondsPerTick * 4; - - MoveAndSlide(movement3d); - //position += movement3d; + + velocity = dvec3.Lerp(velocity, movement3d * 4, 0.5); + velocity += new dvec3(0, -1, 0); + if (Keybinds.Jump.justPressed) + velocity += new dvec3(0, 5, 0); var transformUpdate = PacketPool.GetPacket(); transformUpdate.Position = position; diff --git a/Common/Collision/AABB.cs b/Common/Collision/AABB.cs index 023e238..2e3e8e1 100644 --- a/Common/Collision/AABB.cs +++ b/Common/Collision/AABB.cs @@ -14,34 +14,46 @@ public AABB(dvec3 a, dvec3 b) { max = dvec3.Max(a, b); } - public AABB Encapsulate(dvec3 point) => new() { - min = dvec3.Min(min, point), max = dvec3.Max(max, point) - }; - - public AABB Encapsulate(AABB other) => new() { - min = dvec3.Min(min, other.min), max = dvec3.Max(max, other.max) - }; - - public AABB Translated(dvec3 vec) => new() { - min = min + vec, max = max + vec - }; - - public AABB Expanded(dvec3 size) => new() { - min = min - size * 0.5, max = max + size * 0.5, - }; - - public AABB Expanded(AABB box) => Expanded(box.size); + public AABB Encapsulate(dvec3 point) + => new() { + min = dvec3.Min(min, point), + max = dvec3.Max(max, point) + }; + + public AABB Encapsulate(AABB other) + => new() { + min = dvec3.Min(min, other.min), + max = dvec3.Max(max, other.max) + }; + + public AABB Translated(dvec3 vec) + => new() { + min = min + vec, + max = max + vec + }; + + public AABB Expanded(dvec3 size) + => new() { + min = min - size * 0.5, + max = max + size * 0.5, + }; + + public AABB Expanded(AABB box) + => Expanded(box.size); - public AABB Expanded(double size) => new() { - min = min - size * 0.5, max = max + size * 0.5, - }; + public AABB Expanded(double size) + => new() { + min = min - size * 0.5, + max = max + size * 0.5, + }; /// /// Checks if two AABBs intersect. /// /// /// - public bool Intersects(AABB other) => (min < other.max & max > other.min).All; + public bool Intersects(AABB other) + => (min < other.max & max > other.min).All; /// @@ -49,7 +61,8 @@ public AABB(dvec3 a, dvec3 b) { /// /// /// - public bool Contains(dvec3 point) => (point < min & point > max).All; + public bool Contains(dvec3 point) + => (point < min & point > max).All; /// @@ -57,7 +70,8 @@ public AABB(dvec3 a, dvec3 b) { /// /// /// - public dvec3 ClosestPointInside(dvec3 point) => dvec3.Clamp(point, min, max); + public dvec3 ClosestPointInside(dvec3 point) + => dvec3.Clamp(point, min, max); /// diff --git a/Common/Collision/PhysicsSim.cs b/Common/Collision/PhysicsSim.cs index f9353a3..369f5df 100644 --- a/Common/Collision/PhysicsSim.cs +++ b/Common/Collision/PhysicsSim.cs @@ -31,7 +31,7 @@ public static dvec3 MoveAndSlide(AABB boundingBox, dvec3 movement, ColliderProvi } if (!ColliderCache.TryDequeue(out var sortedList)) - sortedList = new List(); + sortedList = new(); var moveLength = movement.Length; diff --git a/Common/Collision/Ray.cs b/Common/Collision/Ray.cs index 303fc9d..1099ff5 100644 --- a/Common/Collision/Ray.cs +++ b/Common/Collision/Ray.cs @@ -13,6 +13,8 @@ public Ray(dvec3 pos, dvec3 dir) { inverseDirection = 1 / direction; } - public dvec3 GetPoint(float t) => position + direction * t; - public dvec3 GetPoint(double t) => position + direction * t; + public dvec3 GetPoint(float t) + => position + direction * t; + public dvec3 GetPoint(double t) + => position + direction * t; } diff --git a/Common/Network/Packets/PacketHandler.cs b/Common/Network/Packets/PacketHandler.cs index 0b488d0..eb5e506 100644 --- a/Common/Network/Packets/PacketHandler.cs +++ b/Common/Network/Packets/PacketHandler.cs @@ -9,7 +9,8 @@ public class PacketHandler where T : Packet { private readonly Dictionary> Handlers = new(); - public void RegisterHandler(Action handler) where T2 : T => Handlers[typeof(T2)] = packet => handler((T2)packet); + public void RegisterHandler(Action handler) where T2 : T + => Handlers[typeof(T2)] = packet => handler((T2)packet); public bool HandlePacket(T packet) { var type = packet.GetType(); diff --git a/Common/Network/Packets/Utils/PacketPool.cs b/Common/Network/Packets/Utils/PacketPool.cs index cb94ea9..0ddffb7 100644 --- a/Common/Network/Packets/Utils/PacketPool.cs +++ b/Common/Network/Packets/Utils/PacketPool.cs @@ -9,7 +9,7 @@ public static T GetPacket() where T : Packet { var baseType = typeof(T); if (!Pools.TryGetValue(baseType, out var pool)) - Pools[baseType] = pool = new ConcurrentQueue(); + Pools[baseType] = pool = new(); if (!pool.TryDequeue(out var packet)) packet = Activator.CreateInstance(); @@ -24,7 +24,7 @@ public static T GetPacket(Type targetType) where T : Packet { throw new InvalidOperationException($"Cannot cast type {targetType} to {baseType}"); if (!Pools.TryGetValue(targetType, out var pool)) - Pools[targetType] = pool = new ConcurrentQueue(); + Pools[targetType] = pool = new(); if (!pool.TryDequeue(out var packet)) packet = (Packet)Activator.CreateInstance(targetType); @@ -35,7 +35,7 @@ public static T GetPacket(Type targetType) where T : Packet { public static void Return(Packet toReturn) { var type = toReturn.GetType(); if (!Pools.TryGetValue(type, out var pool)) - Pools[type] = pool = new ConcurrentQueue(); + Pools[type] = pool = new(); toReturn.OnReturnToPool(); pool.Enqueue(toReturn); diff --git a/Common/Server/Components/Networking/ServerConnectionContext.cs b/Common/Server/Components/Networking/ServerConnectionContext.cs index e7011fb..4b50b62 100644 --- a/Common/Server/Components/Networking/ServerConnectionContext.cs +++ b/Common/Server/Components/Networking/ServerConnectionContext.cs @@ -64,7 +64,8 @@ private void OnPlayerUpdated(PlayerUpdated pkt) { //Console.WriteLine(entity.position + "|" + entity.chunkPosition); } - public void Close() => Connection.Close(); + public void Close() + => Connection.Close(); public void SendPacket(S2CPacket packet) { @@ -72,9 +73,8 @@ public void SendPacket(S2CPacket packet) { PacketPool.Return(packet); } - public void SetPlayerEntity(PlayerEntity e) { - this.entity = e; - } + public void SetPlayerEntity(PlayerEntity e) + => entity = e; public void SetupViewArea(int range) { if (entity == null) diff --git a/Common/Server/Components/PlayerManager.cs b/Common/Server/Components/PlayerManager.cs index 61a11bc..0193209 100644 --- a/Common/Server/Components/PlayerManager.cs +++ b/Common/Server/Components/PlayerManager.cs @@ -37,7 +37,7 @@ private void OnConnectionMade(ServerConnectionContext context) { context.SetPlayerEntity(pEntity); - Server.WorldManager.DefaultWorld.AddEntity(pEntity, dvec3.Zero, dvec2.Zero); + Server.WorldManager.DefaultWorld.AddEntity(pEntity, new(0, 100, 0), dvec2.Zero); Console.WriteLine("Server:Sending player to world..."); context.SendPacket(new SetupWorld()); diff --git a/Common/Tile/Block.cs b/Common/Tile/Block.cs index 0439ecb..c9265ca 100644 --- a/Common/Tile/Block.cs +++ b/Common/Tile/Block.cs @@ -3,10 +3,10 @@ namespace Voxel.Common.Tile; public class Block { public readonly string Name; public readonly BlockSettings Settings; + public bool IsAir => Settings.IsAir; public uint id; - public bool IsSolidBlock => Settings.IsSolidBlock; public Block(string name, BlockSettings settings) { Name = name; @@ -24,23 +24,23 @@ public Block(string name) : this(name, BlockSettings.Default) {} public class BlockSettings { public static readonly BlockSettings Default = new Builder().Build(); - public readonly bool IsSolidBlock; - public float GetSolidityFloat => IsSolidBlock ? 1 : 0; + public readonly bool IsAir; + public float GetSolidityFloat => IsAir ? 1 : 0; - private BlockSettings(bool isSolidBlock) { - IsSolidBlock = isSolidBlock; + private BlockSettings(bool isAir) { + IsAir = isAir; } public class Builder { - public bool IsSolidBlock = true; + public bool IsAir = true; public Builder() {} public Builder(BlockSettings settings) { - IsSolidBlock = settings.IsSolidBlock; + IsAir = settings.IsAir; } public Builder(Block block) : this(block.Settings) {} - public BlockSettings Build() => new(IsSolidBlock); + public BlockSettings Build() => new(IsAir); } } diff --git a/Common/Tile/Blocks.cs b/Common/Tile/Blocks.cs index 327f665..cf9063a 100644 --- a/Common/Tile/Blocks.cs +++ b/Common/Tile/Blocks.cs @@ -9,7 +9,7 @@ public static class Blocks { private static readonly Dictionary BlocksByName = new(); public static readonly Block Air = new("air", new BlockSettings.Builder { - IsSolidBlock = false + IsAir = false }); public static readonly Block Stone = new("stone"); public static readonly Block Dirt = new("dirt"); diff --git a/Common/Util/Serialization/VDataReader.cs b/Common/Util/Serialization/VDataReader.cs index efc106e..af14770 100644 --- a/Common/Util/Serialization/VDataReader.cs +++ b/Common/Util/Serialization/VDataReader.cs @@ -62,23 +62,34 @@ private Span GetBytes(int length) { return span; } - public byte ReadByte() => GetBytes(1)[0]; - - public ushort ReadUShort() => BitConverter.ToUInt16(GetBytes(sizeof(ushort))); - public short ReadShort() => BitConverter.ToInt16(GetBytes(sizeof(short))); - - public uint ReadUint() => BitConverter.ToUInt32(GetBytes(sizeof(uint))); - public int ReadInt() => BitConverter.ToInt32(GetBytes(sizeof(int))); - - public ulong ReadULong() => BitConverter.ToUInt64(GetBytes(sizeof(ulong))); - public long ReadLong() => BitConverter.ToInt64(GetBytes(sizeof(long))); - - public float ReadFloat() => BitConverter.ToSingle(GetBytes(sizeof(float))); - public double ReadDouble() => BitConverter.ToDouble(GetBytes(sizeof(double))); - - public Guid ReadGuid() => new Guid(GetBytes(16)); - - public string ReadString() => ReadString(Encoding.UTF8); + public byte ReadByte() + => GetBytes(1)[0]; + + public ushort ReadUShort() + => BitConverter.ToUInt16(GetBytes(sizeof(ushort))); + public short ReadShort() + => BitConverter.ToInt16(GetBytes(sizeof(short))); + + public uint ReadUint() + => BitConverter.ToUInt32(GetBytes(sizeof(uint))); + public int ReadInt() + => BitConverter.ToInt32(GetBytes(sizeof(int))); + + public ulong ReadULong() + => BitConverter.ToUInt64(GetBytes(sizeof(ulong))); + public long ReadLong() + => BitConverter.ToInt64(GetBytes(sizeof(long))); + + public float ReadFloat() + => BitConverter.ToSingle(GetBytes(sizeof(float))); + public double ReadDouble() + => BitConverter.ToDouble(GetBytes(sizeof(double))); + + public Guid ReadGuid() + => new(GetBytes(16)); + + public string ReadString() + => ReadString(Encoding.UTF8); public string ReadString(Encoding encoding) { var byteCount = ReadInt(); return encoding.GetString(GetBytes(byteCount)); @@ -89,16 +100,23 @@ public byte[] ReadByteArray() { return GetBytes(count).ToArray(); } - public void ReadBytes(Span bytes) => GetBytes(bytes.Length).CopyTo(bytes); + public void ReadBytes(Span bytes) + => GetBytes(bytes.Length).CopyTo(bytes); - public vec3 ReadVec3() => new(ReadFloat(), ReadFloat(), ReadFloat()); + public vec3 ReadVec3() + => new(ReadFloat(), ReadFloat(), ReadFloat()); - public ivec3 ReadIVec3() => new(ReadInt(), ReadInt(), ReadInt()); + public ivec3 ReadIVec3() + => new(ReadInt(), ReadInt(), ReadInt()); - public dvec3 ReadDVec3() => new(ReadDouble(), ReadDouble(), ReadDouble()); - public dvec2 ReadDVec2() => new(ReadDouble(), ReadDouble()); + public dvec3 ReadDVec3() + => new(ReadDouble(), ReadDouble(), ReadDouble()); + public dvec2 ReadDVec2() + => new(ReadDouble(), ReadDouble()); - public lvec3 ReadLVec3() => new(ReadLong(), ReadLong(), ReadLong()); + public lvec3 ReadLVec3() + => new(ReadLong(), ReadLong(), ReadLong()); - public void ReadSerializable(VSerializable serializable) => serializable.Read(this); + public void ReadSerializable(VSerializable serializable) + => serializable.Read(this); } diff --git a/Common/Util/Serialization/VDataWriter.cs b/Common/Util/Serialization/VDataWriter.cs index 47a2703..05f8365 100644 --- a/Common/Util/Serialization/VDataWriter.cs +++ b/Common/Util/Serialization/VDataWriter.cs @@ -59,23 +59,34 @@ private Span GetBytes(int length) { return span; } - public void Write(byte data) => GetBytes(1)[0] = data; + public void Write(byte data) + => GetBytes(1)[0] = data; - public void Write(ushort data) => BitConverter.TryWriteBytes(GetBytes(sizeof(ushort)), data); - public void Write(short data) => BitConverter.TryWriteBytes(GetBytes(sizeof(short)), data); + public void Write(ushort data) + => BitConverter.TryWriteBytes(GetBytes(sizeof(ushort)), data); + public void Write(short data) + => BitConverter.TryWriteBytes(GetBytes(sizeof(short)), data); - public void Write(uint data) => BitConverter.TryWriteBytes(GetBytes(sizeof(uint)), data); - public void Write(int data) => BitConverter.TryWriteBytes(GetBytes(sizeof(int)), data); + public void Write(uint data) + => BitConverter.TryWriteBytes(GetBytes(sizeof(uint)), data); + public void Write(int data) + => BitConverter.TryWriteBytes(GetBytes(sizeof(int)), data); - public void Write(ulong data) => BitConverter.TryWriteBytes(GetBytes(sizeof(ulong)), data); - public void Write(long data) => BitConverter.TryWriteBytes(GetBytes(sizeof(long)), data); + public void Write(ulong data) + => BitConverter.TryWriteBytes(GetBytes(sizeof(ulong)), data); + public void Write(long data) + => BitConverter.TryWriteBytes(GetBytes(sizeof(long)), data); - public void Write(float data) => BitConverter.TryWriteBytes(GetBytes(sizeof(float)), data); - public void Write(double data) => BitConverter.TryWriteBytes(GetBytes(sizeof(double)), data); + public void Write(float data) + => BitConverter.TryWriteBytes(GetBytes(sizeof(float)), data); + public void Write(double data) + => BitConverter.TryWriteBytes(GetBytes(sizeof(double)), data); - public void Write(Guid data) => data.TryWriteBytes(GetBytes(16)); + public void Write(Guid data) + => data.TryWriteBytes(GetBytes(16)); - public void Write(string data) => Write(data, Encoding.UTF8); + public void Write(string data) + => Write(data, Encoding.UTF8); public void Write(string data, Encoding encoding) { var len = encoding.GetByteCount(data); @@ -117,5 +128,6 @@ public void Write(lvec3 data) { Write(data.z); } - public void Write(VSerializable serializable) => serializable.Write(this); + public void Write(VSerializable serializable) + => serializable.Write(this); } diff --git a/Common/World/Entity/Entity.cs b/Common/World/Entity/Entity.cs index ce47586..0cd7674 100644 --- a/Common/World/Entity/Entity.cs +++ b/Common/World/Entity/Entity.cs @@ -22,6 +22,9 @@ public abstract class Entity : Tickable { public dvec3 lastPosition { get; private set; } public dvec2 lastRotation { get; private set; } + public dvec3 velocity { get; set; } + public bool isOnFloor { get; private set; } + /// /// World-space 3d block position of the entity. /// @@ -54,7 +57,9 @@ public virtual void OnAddedToWorld() {} public virtual void Tick() { lastPosition = position; lastRotation = rotation; - } + + velocity = MoveAndSlide(velocity * Constants.SecondsPerTick) * Constants.TicksPerSecond; + } /// /// Queues an entity to be destroyed at the end of the tick. @@ -78,9 +83,11 @@ public void TrueDestroy() { } - public void MoveAndSlide(dvec3 movement) => position += PhysicsSim.MoveAndSlide(boundingBox.Translated(position), movement, world); - - - public dvec3 SmoothPosition(float delta) => dvec3.Lerp(lastPosition, position, delta); - public dvec2 SmoothRotation(float delta) => dvec2.Lerp(lastRotation, rotation, delta); + public dvec3 MoveAndSlide(dvec3 movement) + => position += PhysicsSim.MoveAndSlide(boundingBox.Translated(position), movement, world); + + public dvec3 SmoothPosition(float delta) + => dvec3.Lerp(lastPosition, position, delta); + public dvec2 SmoothRotation(float delta) + => dvec2.Lerp(lastRotation, rotation, delta); } diff --git a/Common/World/VoxelWorld.cs b/Common/World/VoxelWorld.cs index 77d68c4..d33574d 100644 --- a/Common/World/VoxelWorld.cs +++ b/Common/World/VoxelWorld.cs @@ -87,7 +87,7 @@ public List GatherColliders(AABB box) { foreach (var pos in Iteration.Cubic(min, max)) { var chunkPos = pos.BlockToChunkPosition(); - if (!IsChunkLoadedRaw(chunkPos) || GetBlock(pos).IsSolidBlock) + if (!IsChunkLoadedRaw(chunkPos) || GetBlock(pos).IsAir) CollisionShapeCache.Add(AABB.FromPosSize(pos + half, dvec3.Ones)); }