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 ClassicalSharp.Model;
using OpenTK;
namespace ClassicalSharp {
@ -8,6 +9,7 @@ namespace ClassicalSharp {
public Vector3 Position;
public Vector3 Velocity;
public float YawDegrees, PitchDegrees;
public IModel Model;
public float YawRadians {
get { return (float)Utils.DegreesToRadians( YawDegrees ); }
@ -25,17 +27,38 @@ namespace ClassicalSharp {
}
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 {
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,
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 Render( double deltaTime, float t );
@ -57,7 +80,7 @@ namespace ClassicalSharp {
}
public bool TouchesAny( Predicate<byte> condition ) {
BoundingBox bounds = Bounds;
BoundingBox bounds = CollisionBounds;
Vector3I bbMin = Vector3I.Floor( bounds.Min );
Vector3I bbMax = Vector3I.Floor( bounds.Max );

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
Player p = Players[i];
if( p == null ) continue;
BoundingBox bounds = p.Bounds;
BoundingBox bounds = p.PickingBounds;
float t0, t1;
if( IntersectionUtils.RayIntersectsBox( eyePos, dir, bounds.Min, bounds.Max, out t0, out t1 ) ) {
dist = t0;

View File

@ -174,12 +174,7 @@ namespace ClassicalSharp {
if( dist < 1 ) dist = 1;
float multiply = factor / dist;
x *= multiply;
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;
Velocity += Utils.RotateY( x * multiply, 0, z * multiply, YawRadians );
}
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 const float Width = 0.6f;
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>
public Vector3 EyePosition {
@ -31,7 +24,6 @@ namespace ClassicalSharp {
public byte ID;
public string DisplayName, SkinName;
public string ModelName;
public IModel Model;
protected PlayerRenderer renderer;
public SkinType SkinType;

View File

@ -18,6 +18,15 @@ namespace ClassicalSharp.Model {
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 ) {
graphics.Texturing = true;
graphics.AlphaTest = true;

View File

@ -58,6 +58,14 @@ namespace ClassicalSharp.Model {
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 ) {
graphics.Texturing = true;
int texId = renderer.MobTextureId <= 0 ? DefaultTexId : renderer.MobTextureId;

View File

@ -1,6 +1,7 @@
using System;
using ClassicalSharp.GraphicsAPI;
using ClassicalSharp.Renderers;
using OpenTK;
namespace ClassicalSharp.Model {
@ -39,6 +40,14 @@ namespace ClassicalSharp.Model {
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 ) {
graphics.Texturing = true;
int texId = renderer.MobTextureId <= 0 ? DefaultTexId : renderer.MobTextureId;

View File

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

View File

@ -41,6 +41,14 @@ namespace ClassicalSharp.Model {
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 ) {
graphics.Texturing = true;
int texId = renderer.MobTextureId <= 0 ? DefaultTexId : renderer.MobTextureId;

View File

@ -2,6 +2,7 @@
using System.Drawing;
using ClassicalSharp.GraphicsAPI;
using ClassicalSharp.Renderers;
using OpenTK;
namespace ClassicalSharp.Model {
@ -81,6 +82,14 @@ namespace ClassicalSharp.Model {
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;
protected override void DrawPlayerModel( Player player, PlayerRenderer renderer ) {
graphics.Texturing = true;

View File

@ -65,6 +65,14 @@ namespace ClassicalSharp.Model {
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 ) {
graphics.Texturing = true;
int texId = renderer.MobTextureId <= 0 ? DefaultTexId : renderer.MobTextureId;

View File

@ -53,6 +53,14 @@ namespace ClassicalSharp.Model {
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 ) {
graphics.Texturing = true;
graphics.AlphaTest = true;

View File

@ -44,6 +44,14 @@ namespace ClassicalSharp.Model {
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 eighthPi = (float)( Math.PI / 8 );
protected override void DrawPlayerModel( Player player, PlayerRenderer renderer ) {

View File

@ -53,6 +53,14 @@ namespace ClassicalSharp.Model {
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 ) {
graphics.Texturing = true;
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,
Vector3I targetPos, CpeBlockFace targetFace ) {
Vector3I targetPos, CpeBlockFace targetFace ) {
WriteUInt8( (byte)PacketId.CpePlayerClick );
WriteUInt8( button );
WriteUInt8( buttonDown ? (byte)0 : (byte)1 );

View File

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

View File

@ -111,6 +111,12 @@ namespace ClassicalSharp {
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 ) {
float dx = p2.X - p1.X;
float dy = p2.Y - p1.Y;