From 6ee9f75e293afb2b886ef3f6931f9997d879147e Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Wed, 27 Apr 2016 19:35:45 +1000 Subject: [PATCH] Initial work on new collision engine. --- ClassicalSharp/ClassicalSharp.csproj | 1 + .../Components/CollisionsComponent.cs | 12 +-- .../Components/NewCollisionsComponent.cs | 78 +++++++++++++++++++ 3 files changed, 83 insertions(+), 8 deletions(-) create mode 100644 ClassicalSharp/Entities/Components/NewCollisionsComponent.cs diff --git a/ClassicalSharp/ClassicalSharp.csproj b/ClassicalSharp/ClassicalSharp.csproj index b4e409999..615ce0d86 100644 --- a/ClassicalSharp/ClassicalSharp.csproj +++ b/ClassicalSharp/ClassicalSharp.csproj @@ -153,6 +153,7 @@ + diff --git a/ClassicalSharp/Entities/Components/CollisionsComponent.cs b/ClassicalSharp/Entities/Components/CollisionsComponent.cs index 24d950e46..9cfaa589b 100644 --- a/ClassicalSharp/Entities/Components/CollisionsComponent.cs +++ b/ClassicalSharp/Entities/Components/CollisionsComponent.cs @@ -53,18 +53,14 @@ namespace ClassicalSharp.Entities { Vector3 size = entity.CollisionSize; BoundingBox entityBB, entityExtentBB; int count = 0; - FindReachableBlocks( ref count, ref size, out entityBB, out entityExtentBB ); + FindReachableBlocks( ref count, out entityBB, out entityExtentBB ); CollideWithReachableBlocks( count, ref size, ref entityBB, ref entityExtentBB ); } - void FindReachableBlocks( ref int count, ref Vector3 size, - out BoundingBox entityBB, out BoundingBox entityExtentBB ) { + void FindReachableBlocks( ref int count, out BoundingBox entityBB, + out BoundingBox entityExtentBB ) { Vector3 vel = entity.Velocity; - Vector3 pos = entity.Position; - entityBB = new BoundingBox( - pos.X - size.X / 2, pos.Y, pos.Z - size.Z / 2, - pos.X + size.X / 2, pos.Y + size.Y, pos.Z + size.Z / 2 - ); + entityBB = entity.CollisionBounds; // Exact maximum extent the entity can reach, and the equivalent map coordinates. entityExtentBB = new BoundingBox( diff --git a/ClassicalSharp/Entities/Components/NewCollisionsComponent.cs b/ClassicalSharp/Entities/Components/NewCollisionsComponent.cs new file mode 100644 index 000000000..872a8bdcd --- /dev/null +++ b/ClassicalSharp/Entities/Components/NewCollisionsComponent.cs @@ -0,0 +1,78 @@ +// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT +using System; +using OpenTK; + +#if false +namespace ClassicalSharp.Entities { + + /// Entity component that performs collision detection. + public sealed class NewCollisionsComponent { + + Game game; + Entity entity; + BlockInfo info; + static BoundingBox bb; + static RayTracer tracerP1Y1 = new RayTracer(); + static RayTracer tracerP2Y1 = new RayTracer(); + static RayTracer tracerP1Y2 = new RayTracer(); + static RayTracer tracerP2Y2 = new RayTracer(); + + public NewCollisionsComponent( Game game, Entity entity ) { + this.game = game; + this.entity = entity; + info = game.BlockInfo; + } + + internal unsafe void MoveAndWallSlide() { + if( entity.Velocity == Vector3.Zero ) return; + int* minY = stackalloc int[4096]; + int* maxY = stackalloc int[4096]; + int* minX = stackalloc int[4096]; + int* maxX = stackalloc int[4096]; + + for( int i = 0; i < 4096; i++ ) { + minX[i] = int.MaxValue; minY[i] = int.MaxValue; + maxX[i] = int.MinValue; maxY[i] = int.MinValue; + } + bb = entity.CollisionBounds; + int count = 0; + + // First raytrace out from the origin to find approximate blocks + CalcRayDirection(); + while( true ) { + UpdateCoords( tracerP1Y1, minX, maxX, minY, maxY ); + UpdateCoords( tracerP1Y2, minX, maxX, minY, maxY ); + UpdateCoords( tracerP2Y1, minX, maxX, minY, maxY ); + UpdateCoords( tracerP2Y2, minX, maxX, minY, maxY ); + } + + // Now precisely which blocks we really intersect with + + // .. then perform collision + } + + void UpdateCoords( RayTracer tracer, int* minX, int* maxX, + int* minY, int* maxY, ref int count ) { + tracer.Step(); + minX[tracer.Z] = Math.Min( tracer.X, minX[tracer.Z] ); + minY[tracer.Z] = Math.Min( tracer.Y, minY[tracer.Z] ); + maxX[tracer.Z] = Math.Max( tracer.X, maxX[tracer.Z] ); + maxY[tracer.Z] = Math.Max( tracer.Y, maxY[tracer.Z] ); + count = Math.Max( count, tracer.Z ); + } + + void CalcRayDirection() { + Vector3 dir = entity.Velocity; + Vector3 P = new Vector3( bb.Min.X, bb.Min.Y, bb.Max.Z ); + tracerP1Y1.SetRayData( P, dir ); + P.Y = bb.Max.Y; + tracerP1Y1.SetRayData( P, dir ); + + P = new Vector3( bb.Max.X, bb.Min.Y, bb.Min.Z ); + tracerP2Y1.SetRayData( P, dir ); + P.Y = bb.Max.Y; + tracerP2Y2.SetRayData( P, dir ); + } + } +} +#endif \ No newline at end of file