Move model size functionality to model classes. Add separate bounding boxes for collision and picking. Add function to rotate points around Y axis.

This commit is contained in:
UnknownShadow200 2015-07-03 09:20:46 +10:00
parent ae1105d5d9
commit e23b5aeda5
18 changed files with 122 additions and 28 deletions

View File

@ -1,4 +1,5 @@
using System; using System;
using ClassicalSharp.Model;
using OpenTK; using OpenTK;
namespace ClassicalSharp { namespace ClassicalSharp {
@ -8,6 +9,7 @@ namespace ClassicalSharp {
public Vector3 Position; public Vector3 Position;
public Vector3 Velocity; public Vector3 Velocity;
public float YawDegrees, PitchDegrees; public float YawDegrees, PitchDegrees;
public IModel Model;
public float YawRadians { public float YawRadians {
get { return (float)Utils.DegreesToRadians( YawDegrees ); } get { return (float)Utils.DegreesToRadians( YawDegrees ); }
@ -25,17 +27,38 @@ namespace ClassicalSharp {
} }
public abstract float StepSize { get; } public abstract float StepSize { get; }
public abstract Vector3 Size { get; } public virtual Vector3 CollisionSize {
get { return new Vector3( 8 / 16f, 30 / 16f, 8 / 16f );
//Model.CollisionSize; TODO: for non humanoid models, we also need to offset eye position.
}
}
public virtual BoundingBox Bounds { public virtual BoundingBox CollisionBounds {
get { get {
Vector3 pos = Position; Vector3 pos = Position;
Vector3 size = Size; Vector3 size = Model.CollisionSize;
return new BoundingBox( pos.X - size.X / 2, pos.Y, pos.Z - size.Z / 2, return 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 ); pos.X + size.X / 2, pos.Y + size.Y, pos.Z + size.Z / 2 );
} }
} }
public virtual BoundingBox PickingBounds {
get {
BoundingBox bb = Model.PickingBounds;
float angle = YawRadians;
// TODO: This would be a lot simpler and more accurate if we just did ray-oobb intersection.
Vector3 x1z1 = Utils.RotateY( bb.Min.X, 0, bb.Min.Z, angle );
Vector3 x1z2 = Utils.RotateY( bb.Min.X, 0, bb.Max.Z, angle );
Vector3 x2z1 = Utils.RotateY( bb.Max.X, 0, bb.Min.Z, angle );
Vector3 x2z2 = Utils.RotateY( bb.Max.X, 0, bb.Max.Z, angle );
float minX = Math.Min( x1z1.X, Math.Min( x1z2.X, Math.Min( x2z2.X, x2z1.X ) ) );
float maxX = Math.Max( x1z1.X, Math.Max( x1z2.X, Math.Max( x2z2.X, x2z1.X ) ) );
float minZ = Math.Min( x1z1.Z, Math.Min( x1z2.Z, Math.Min( x2z2.Z, x2z1.Z ) ) );
float maxZ = Math.Max( x1z1.Z, Math.Max( x1z2.Z, Math.Max( x2z2.Z, x2z1.Z ) ) );
return new BoundingBox( minX, bb.Min.Y, minZ, maxX, bb.Max.Y, maxZ ).Offset( Position );
}
}
public abstract void Despawn(); public abstract void Despawn();
public abstract void Render( double deltaTime, float t ); public abstract void Render( double deltaTime, float t );
@ -52,15 +75,15 @@ namespace ClassicalSharp {
return TouchesAny( b => b == (byte)Block.Water || b == (byte)Block.StillWater ); return TouchesAny( b => b == (byte)Block.Water || b == (byte)Block.StillWater );
} }
public bool TouchesAnyOf( byte blockType ) { public bool TouchesAnyOf( byte blockType ) {
return TouchesAny( b => b == blockType ); return TouchesAny( b => b == blockType );
} }
public bool TouchesAny( Predicate<byte> condition ) { public bool TouchesAny( Predicate<byte> condition ) {
BoundingBox bounds = Bounds; BoundingBox bounds = CollisionBounds;
Vector3I bbMin = Vector3I.Floor( bounds.Min ); Vector3I bbMin = Vector3I.Floor( bounds.Min );
Vector3I bbMax = Vector3I.Floor( bounds.Max ); Vector3I bbMax = Vector3I.Floor( bounds.Max );
for( int x = bbMin.X; x <= bbMax.X; x++ ) { for( int x = bbMin.X; x <= bbMax.X; x++ ) {
for( int y = bbMin.Y; y <= bbMax.Y; y++ ) { for( int y = bbMin.Y; y <= bbMax.Y; y++ ) {
for( int z = bbMin.Z; z <= bbMax.Z; z++ ) { for( int z = bbMin.Z; z <= bbMax.Z; z++ ) {
@ -74,7 +97,7 @@ namespace ClassicalSharp {
if( blockBB.Intersects( bounds ) ) return true; if( blockBB.Intersects( bounds ) ) return true;
} }
} }
} }
} }
return false; return false;
} }

View File

@ -39,8 +39,7 @@ namespace ClassicalSharp {
for( int i = 0; i < Players.Length - 1; i++ ) { // -1 because we don't want to pick against local player for( int i = 0; i < Players.Length - 1; i++ ) { // -1 because we don't want to pick against local player
Player p = Players[i]; Player p = Players[i];
if( p == null ) continue; if( p == null ) continue;
BoundingBox bounds = p.Bounds; BoundingBox bounds = p.PickingBounds;
float t0, t1; float t0, t1;
if( IntersectionUtils.RayIntersectsBox( eyePos, dir, bounds.Min, bounds.Max, out t0, out t1 ) ) { if( IntersectionUtils.RayIntersectsBox( eyePos, dir, bounds.Min, bounds.Max, out t0, out t1 ) ) {
dist = t0; dist = t0;

View File

@ -174,12 +174,7 @@ namespace ClassicalSharp {
if( dist < 1 ) dist = 1; if( dist < 1 ) dist = 1;
float multiply = factor / dist; float multiply = factor / dist;
x *= multiply; Velocity += Utils.RotateY( x * multiply, 0, z * multiply, YawRadians );
z *= multiply;
float cosA = (float)Math.Cos( YawRadians );
float sinA = (float)Math.Sin( YawRadians );
Velocity.X += x * cosA - z * sinA;
Velocity.Z += x * sinA + z * cosA;
} }
void Move( float xMoving, float zMoving, float factor, Vector3 drag, float gravity, float yMul ) { void Move( float xMoving, float zMoving, float factor, Vector3 drag, float gravity, float yMul ) {

View File

@ -9,14 +9,7 @@ namespace ClassicalSharp {
public abstract class Player : Entity { public abstract class Player : Entity {
public const float Width = 0.6f;
public const float EyeHeight = 1.625f; public const float EyeHeight = 1.625f;
public const float Height = 1.8f;
public const float Depth = 0.6f;
public override Vector3 Size {
get { return new Vector3( Width, Height, Depth ); }
}
/// <summary> Gets the position of the player's eye in the world. </summary> /// <summary> Gets the position of the player's eye in the world. </summary>
public Vector3 EyePosition { public Vector3 EyePosition {
@ -31,7 +24,6 @@ namespace ClassicalSharp {
public byte ID; public byte ID;
public string DisplayName, SkinName; public string DisplayName, SkinName;
public string ModelName; public string ModelName;
public IModel Model;
protected PlayerRenderer renderer; protected PlayerRenderer renderer;
public SkinType SkinType; public SkinType SkinType;

View File

@ -18,6 +18,15 @@ namespace ClassicalSharp.Model {
get { return blockHeight + 0.075f; } get { return blockHeight + 0.075f; }
} }
const float adjust = 0.1f;
public override Vector3 CollisionSize {
get { return new Vector3( 1 - adjust, blockHeight - adjust, 1 - adjust ); }
}
public override BoundingBox PickingBounds {
get { return new BoundingBox( -0.5f, 0f, -0.5f, 0.5f, blockHeight, 0.5f ); }
}
protected override void DrawPlayerModel( Player player, PlayerRenderer renderer ) { protected override void DrawPlayerModel( Player player, PlayerRenderer renderer ) {
graphics.Texturing = true; graphics.Texturing = true;
graphics.AlphaTest = true; graphics.AlphaTest = true;

View File

@ -58,6 +58,14 @@ namespace ClassicalSharp.Model {
get { return 1.0125f; } get { return 1.0125f; }
} }
public override Vector3 CollisionSize {
get { return new Vector3( 8 / 16f, 12 / 16f, 8 / 16f ); }
}
public override BoundingBox PickingBounds {
get { return new BoundingBox( -4 / 16f, 0, -8 / 16f, 4 / 16f, 15 / 16f, 4 / 16f ); }
}
protected override void DrawPlayerModel( Player player, PlayerRenderer renderer ) { protected override void DrawPlayerModel( Player player, PlayerRenderer renderer ) {
graphics.Texturing = true; graphics.Texturing = true;
int texId = renderer.MobTextureId <= 0 ? DefaultTexId : renderer.MobTextureId; int texId = renderer.MobTextureId <= 0 ? DefaultTexId : renderer.MobTextureId;

View File

@ -1,6 +1,7 @@
using System; using System;
using ClassicalSharp.GraphicsAPI; using ClassicalSharp.GraphicsAPI;
using ClassicalSharp.Renderers; using ClassicalSharp.Renderers;
using OpenTK;
namespace ClassicalSharp.Model { namespace ClassicalSharp.Model {
@ -39,6 +40,14 @@ namespace ClassicalSharp.Model {
get { return 1.7f; } get { return 1.7f; }
} }
public override Vector3 CollisionSize {
get { return new Vector3( 8 / 16f, 26 / 16f, 8 / 16f ); }
}
public override BoundingBox PickingBounds {
get { return new BoundingBox( -4 / 16f, 0, -6 / 16f, 4 / 16f, 26 / 16f, 6 / 16f ); }
}
protected override void DrawPlayerModel( Player player, PlayerRenderer renderer ) { protected override void DrawPlayerModel( Player player, PlayerRenderer renderer ) {
graphics.Texturing = true; graphics.Texturing = true;
int texId = renderer.MobTextureId <= 0 ? DefaultTexId : renderer.MobTextureId; int texId = renderer.MobTextureId <= 0 ? DefaultTexId : renderer.MobTextureId;

View File

@ -19,6 +19,10 @@ namespace ClassicalSharp.Model {
public abstract float NameYOffset { get; } public abstract float NameYOffset { get; }
public abstract Vector3 CollisionSize { get; }
public abstract BoundingBox PickingBounds { get; }
protected Vector3 pos; protected Vector3 pos;
protected float yaw, pitch; protected float yaw, pitch;
protected float rightLegXRot, rightArmXRot, rightArmZRot; protected float rightLegXRot, rightArmXRot, rightArmZRot;

View File

@ -41,6 +41,14 @@ namespace ClassicalSharp.Model {
get { return 1.075f; } get { return 1.075f; }
} }
public override Vector3 CollisionSize {
get { return new Vector3( 14 / 16f, 14 / 16f, 14 / 16f ); }
}
public override BoundingBox PickingBounds {
get { return new BoundingBox( -5 / 16f, 0, -14 / 16f, 5 / 16f, 16 / 16f, 9 / 16f ); }
}
protected override void DrawPlayerModel( Player player, PlayerRenderer renderer ) { protected override void DrawPlayerModel( Player player, PlayerRenderer renderer ) {
graphics.Texturing = true; graphics.Texturing = true;
int texId = renderer.MobTextureId <= 0 ? DefaultTexId : renderer.MobTextureId; int texId = renderer.MobTextureId <= 0 ? DefaultTexId : renderer.MobTextureId;

View File

@ -2,6 +2,7 @@
using System.Drawing; using System.Drawing;
using ClassicalSharp.GraphicsAPI; using ClassicalSharp.GraphicsAPI;
using ClassicalSharp.Renderers; using ClassicalSharp.Renderers;
using OpenTK;
namespace ClassicalSharp.Model { namespace ClassicalSharp.Model {
@ -81,6 +82,14 @@ namespace ClassicalSharp.Model {
get { return 2.1375f; } get { return 2.1375f; }
} }
public override Vector3 CollisionSize {
get { return new Vector3( 8 / 16f, 30 / 16f, 8 / 16f ); }
}
public override BoundingBox PickingBounds {
get { return new BoundingBox( -8 / 16f, 0, -4 / 16f, 8 / 16f, 32 / 16f, 4 / 16f ); }
}
ModelSet model; ModelSet model;
protected override void DrawPlayerModel( Player player, PlayerRenderer renderer ) { protected override void DrawPlayerModel( Player player, PlayerRenderer renderer ) {
graphics.Texturing = true; graphics.Texturing = true;

View File

@ -65,6 +65,14 @@ namespace ClassicalSharp.Model {
get { return Fur ? 1.48125f: 1.075f; } get { return Fur ? 1.48125f: 1.075f; }
} }
public override Vector3 CollisionSize {
get { return new Vector3( 14 / 16f, 20 / 16f, 14 / 16f ); }
}
public override BoundingBox PickingBounds {
get { return new BoundingBox( -6 / 16f, 0, -13 / 16f, 6 / 16f, 23 / 16f, 10 / 16f ); }
}
protected override void DrawPlayerModel( Player player, PlayerRenderer renderer ) { protected override void DrawPlayerModel( Player player, PlayerRenderer renderer ) {
graphics.Texturing = true; graphics.Texturing = true;
int texId = renderer.MobTextureId <= 0 ? DefaultTexId : renderer.MobTextureId; int texId = renderer.MobTextureId <= 0 ? DefaultTexId : renderer.MobTextureId;

View File

@ -53,6 +53,14 @@ namespace ClassicalSharp.Model {
get { return 2.075f; } get { return 2.075f; }
} }
public override Vector3 CollisionSize {
get { return new Vector3( 8 / 16f, 30 / 16f, 8 / 16f ); }
}
public override BoundingBox PickingBounds {
get { return new BoundingBox( -4 / 16f, 0, -4 / 16f, 4 / 16f, 32 / 16f, 4 / 16f ); }
}
protected override void DrawPlayerModel( Player player, PlayerRenderer renderer ) { protected override void DrawPlayerModel( Player player, PlayerRenderer renderer ) {
graphics.Texturing = true; graphics.Texturing = true;
graphics.AlphaTest = true; graphics.AlphaTest = true;

View File

@ -44,6 +44,14 @@ namespace ClassicalSharp.Model {
get { return 1.0125f; } get { return 1.0125f; }
} }
public override Vector3 CollisionSize {
get { return new Vector3( 15 / 16f, 12 / 16f, 15 / 16f ); }
}
public override BoundingBox PickingBounds {
get { return new BoundingBox( -5 / 16f, 0, -11 / 16f, 5 / 16f, 12 / 16f, 15 / 16f ); }
}
const float quarterPi = (float)( Math.PI / 4 ); const float quarterPi = (float)( Math.PI / 4 );
const float eighthPi = (float)( Math.PI / 8 ); const float eighthPi = (float)( Math.PI / 8 );
protected override void DrawPlayerModel( Player player, PlayerRenderer renderer ) { protected override void DrawPlayerModel( Player player, PlayerRenderer renderer ) {

View File

@ -53,6 +53,14 @@ namespace ClassicalSharp.Model {
get { return 2.075f; } get { return 2.075f; }
} }
public override Vector3 CollisionSize {
get { return new Vector3( 8 / 16f, 30 / 16f, 8 / 16f ); }
}
public override BoundingBox PickingBounds {
get { return new BoundingBox( -4 / 16f, 0, -4 / 16f, 4 / 16f, 32 / 16f, 4 / 16f ); }
}
protected override void DrawPlayerModel( Player player, PlayerRenderer renderer ) { protected override void DrawPlayerModel( Player player, PlayerRenderer renderer ) {
graphics.Texturing = true; graphics.Texturing = true;
int texId = renderer.MobTextureId <= 0 ? DefaultTexId : renderer.MobTextureId; int texId = renderer.MobTextureId <= 0 ? DefaultTexId : renderer.MobTextureId;

View File

@ -182,7 +182,7 @@ namespace ClassicalSharp {
} }
private static void MakePlayerClick( byte button, bool buttonDown, float yaw, float pitch, byte targetEntity, private static void MakePlayerClick( byte button, bool buttonDown, float yaw, float pitch, byte targetEntity,
Vector3I targetPos, CpeBlockFace targetFace ) { Vector3I targetPos, CpeBlockFace targetFace ) {
WriteUInt8( (byte)PacketId.CpePlayerClick ); WriteUInt8( (byte)PacketId.CpePlayerClick );
WriteUInt8( button ); WriteUInt8( button );
WriteUInt8( buttonDown ? (byte)0 : (byte)1 ); WriteUInt8( buttonDown ? (byte)0 : (byte)1 );
@ -226,7 +226,7 @@ namespace ClassicalSharp {
void SendPacket() { void SendPacket() {
int packetLength = outIndex; int packetLength = outIndex;
outIndex = 0; outIndex = 0;
if( Disconnected ) return; if( Disconnected ) return;
try { try {
stream.Write( outBuffer, 0, packetLength ); stream.Write( outBuffer, 0, packetLength );

View File

@ -61,7 +61,7 @@ namespace ClassicalSharp {
protected void MoveAndWallSlide() { protected void MoveAndWallSlide() {
if( Velocity == Vector3.Zero ) if( Velocity == Vector3.Zero )
return; return;
Vector3 size = Size; Vector3 size = CollisionSize;
BoundingBox entityBB, entityExtentBB; BoundingBox entityBB, entityExtentBB;
int count = 0; int count = 0;
FindReachableBlocks( ref count, ref size, out entityBB, out entityExtentBB ); FindReachableBlocks( ref count, ref size, out entityBB, out entityExtentBB );

View File

@ -25,7 +25,7 @@ namespace ClassicalSharp.Renderers {
using( Font font = new Font( "Arial", 14 ) ) { using( Font font = new Font( "Arial", 14 ) ) {
List<DrawTextArgs> parts = Utils2D.SplitText( Graphics, player.DisplayName, true ); List<DrawTextArgs> parts = Utils2D.SplitText( Graphics, player.DisplayName, true );
Size size = Utils2D.MeasureSize( parts, font, true ); Size size = Utils2D.MeasureSize( parts, font, true );
nameTexture = Utils2D.MakeTextTexture( parts, font, size, 0, 0 ); nameTexture = Utils2D.MakeTextTexture( parts, font, size, 0, 0 );
nameWidth = size.Width; nameWidth = size.Width;
nameHeight = size.Height; nameHeight = size.Height;
nameTextureId = nameTexture.ID; nameTextureId = nameTexture.ID;

View File

@ -111,6 +111,12 @@ namespace ClassicalSharp {
return packed * 360.0 / 256.0; return packed * 360.0 / 256.0;
} }
public static Vector3 RotateY( float x, float y, float z, float angle ) {
float cosA = (float)Math.Cos( angle );
float sinA = (float)Math.Sin( angle );
return new Vector3( cosA * x - sinA * z, y, sinA * x + cosA * z );
}
public static float DistanceSquared( Vector3 p1, Vector3 p2 ) { public static float DistanceSquared( Vector3 p1, Vector3 p2 ) {
float dx = p2.X - p1.X; float dx = p2.X - p1.X;
float dy = p2.Y - p1.Y; float dy = p2.Y - p1.Y;