mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-10-06 04:25:05 -04:00
145 lines
6.9 KiB
C#
145 lines
6.9 KiB
C#
using System;
|
|
using ClassicalSharp.GraphicsAPI;
|
|
using ClassicalSharp.Renderers;
|
|
using OpenTK;
|
|
|
|
namespace ClassicalSharp.Model {
|
|
|
|
public abstract class IModel : IDisposable {
|
|
|
|
protected Game game;
|
|
protected ModelCache cache;
|
|
protected IGraphicsApi graphics;
|
|
protected const int planeVertices = 4;
|
|
protected const int partVertices = 6 * planeVertices;
|
|
|
|
public IModel( Game game ) {
|
|
this.game = game;
|
|
graphics = game.Graphics;
|
|
cache = game.ModelCache;
|
|
}
|
|
|
|
public abstract float NameYOffset { get; }
|
|
|
|
public abstract Vector3 CollisionSize { get; }
|
|
|
|
public abstract BoundingBox PickingBounds { get; }
|
|
|
|
protected Vector3 pos;
|
|
protected float cosA, sinA;
|
|
public void RenderModel( Player p ) {
|
|
index = 0;
|
|
pos = p.Position;
|
|
cosA = (float)Math.Cos( p.YawRadians );
|
|
sinA = (float)Math.Sin( p.YawRadians );
|
|
Map map = game.Map;
|
|
col = game.Map.IsLit( Vector3I.Floor( p.EyePosition ) ) ? map.Sunlight : map.Shadowlight;
|
|
|
|
graphics.BeginVbBatch( VertexFormat.Pos3fTex2fCol4b );
|
|
DrawPlayerModel( p );
|
|
graphics.DrawDynamicIndexedVb( DrawMode.Triangles, cache.vb, cache.vertices, index, index * 6 / 4 );
|
|
}
|
|
|
|
protected abstract void DrawPlayerModel( Player p );
|
|
|
|
public abstract void Dispose();
|
|
|
|
public int DefaultTexId;
|
|
|
|
protected FastColour col;
|
|
protected VertexPos3fTex2fCol4b[] vertices;
|
|
protected int index;
|
|
|
|
protected ModelPart MakePart( int x, int y, int sidesW, int sidesH, int endsW, int endsH, int bodyW, int bodyH,
|
|
float x1, float x2, float y1, float y2, float z1, float z2, bool _64x64 ) {
|
|
YPlane( x + sidesW, y, endsW, endsH, x2, x1, z2, z1, y2, _64x64 ); // top
|
|
YPlane( x + sidesW + bodyW, y, endsW, endsH, x2, x1, z1, z2, y1, _64x64 ); // bottom
|
|
ZPlane( x + sidesW, y + endsH, bodyW, bodyH, x2, x1, y1, y2, z1, _64x64 ); // front
|
|
ZPlane( x + sidesW + bodyW + sidesW, y + endsH, bodyW, bodyH, x1, x2, y1, y2, z2, _64x64 ); // back
|
|
XPlane( x, y + endsH, sidesW, sidesH, z2, z1, y1, y2, x2, _64x64 ); // left
|
|
XPlane( x + sidesW + bodyW, y + endsH, sidesW, sidesH, z1, z2, y1, y2, x1, _64x64 ); // right
|
|
return new ModelPart( index - 6 * 4, 6 * 4 );
|
|
}
|
|
|
|
protected ModelPart MakeRotatedPart( int x, int y, int sidesW, int sidesH, int endsW, int endsH, int bodyW, int bodyH,
|
|
float x1, float x2, float y1, float y2, float z1, float z2, bool _64x64 ) {
|
|
YPlane( x + sidesW + bodyW + sidesW, y + endsH, bodyW, bodyH, x1, x2, z1, z2, y2, _64x64 ); // top
|
|
YPlane( x + sidesW, y + endsH, bodyW, bodyH, x2, x1, z1, z2, y1, _64x64 ); // bottom
|
|
ZPlane( x + sidesW, y, endsW, endsH, x2, x1, y1, y2, z1, _64x64 ); // front
|
|
ZPlane( x + sidesW + bodyW, y, endsW, endsH, x2, x1, y2, y1, z2, _64x64 ); // back
|
|
XPlane( x, y + endsH, sidesW, sidesH, y2, y1, z2, z1, x2, _64x64 ); // left
|
|
XPlane( x + sidesW + bodyW, y + endsH, sidesW, sidesH, y1, y2, z2, z1, x1, _64x64 ); // right
|
|
// rotate left and right 90 degrees
|
|
for( int i = index - 8; i < index; i++ ) {
|
|
VertexPos3fTex2fCol4b vertex = vertices[i];
|
|
float z = vertex.Z;
|
|
vertex.Z = vertex.Y;
|
|
vertex.Y = z;
|
|
vertices[i] = vertex;
|
|
}
|
|
return new ModelPart( index - 6 * 4, 6 * 4 );
|
|
}
|
|
|
|
protected static TextureRectangle SkinTexCoords( int x, int y, int width, int height, float skinWidth, float skinHeight ) {
|
|
return new TextureRectangle( x / skinWidth, y / skinHeight, width / skinWidth, height / skinHeight );
|
|
}
|
|
|
|
protected void XPlane( int texX, int texY, int texWidth, int texHeight,
|
|
float z1, float z2, float y1, float y2, float x, bool _64x64 ) {
|
|
TextureRectangle rec = SkinTexCoords( texX, texY, texWidth, texHeight, 64, _64x64 ? 64 : 32 );
|
|
vertices[index++] = new VertexPos3fTex2fCol4b( x, y1, z1, rec.U1, rec.V2, FastColour.White );
|
|
vertices[index++] = new VertexPos3fTex2fCol4b( x, y2, z1, rec.U1, rec.V1, FastColour.White );
|
|
vertices[index++] = new VertexPos3fTex2fCol4b( x, y2, z2, rec.U2, rec.V1, FastColour.White );
|
|
vertices[index++] = new VertexPos3fTex2fCol4b( x, y1, z2, rec.U2, rec.V2, FastColour.White );
|
|
}
|
|
|
|
protected void YPlane( int texX, int texY, int texWidth, int texHeight,
|
|
float x1, float x2, float z1, float z2, float y, bool _64x64 ) {
|
|
TextureRectangle rec = SkinTexCoords( texX, texY, texWidth, texHeight, 64, _64x64 ? 64 : 32 );
|
|
vertices[index++] = new VertexPos3fTex2fCol4b( x1, y, z1, rec.U1, rec.V1, FastColour.White );
|
|
vertices[index++] = new VertexPos3fTex2fCol4b( x2, y, z1, rec.U2, rec.V1, FastColour.White );
|
|
vertices[index++] = new VertexPos3fTex2fCol4b( x2, y, z2, rec.U2, rec.V2, FastColour.White );
|
|
vertices[index++] = new VertexPos3fTex2fCol4b( x1, y, z2, rec.U1, rec.V2, FastColour.White );
|
|
}
|
|
|
|
protected void ZPlane( int texX, int texY, int texWidth, int texHeight,
|
|
float x1, float x2, float y1, float y2, float z, bool _64x64 ) {
|
|
TextureRectangle rec = SkinTexCoords( texX, texY, texWidth, texHeight, 64, _64x64 ? 64 : 32 );
|
|
vertices[index++] = new VertexPos3fTex2fCol4b( x1, y1, z, rec.U1, rec.V2, FastColour.White );
|
|
vertices[index++] = new VertexPos3fTex2fCol4b( x2, y1, z, rec.U2, rec.V2, FastColour.White );
|
|
vertices[index++] = new VertexPos3fTex2fCol4b( x2, y2, z, rec.U2, rec.V1, FastColour.White );
|
|
vertices[index++] = new VertexPos3fTex2fCol4b( x1, y2, z, rec.U1, rec.V1, FastColour.White );
|
|
}
|
|
|
|
protected void DrawPart( ModelPart part ) {
|
|
for( int i = 0; i < part.Count; i++ ) {
|
|
VertexPos3fTex2fCol4b vertex = vertices[part.Offset + i];
|
|
Vector3 newPos = Utils.RotateY( vertex.X, vertex.Y, vertex.Z, cosA, sinA ) + pos;
|
|
vertex.X = newPos.X; vertex.Y = newPos.Y; vertex.Z = newPos.Z;
|
|
vertex.R = col.R; vertex.G = col.G; vertex.B = col.B;
|
|
cache.vertices[index++] = vertex;
|
|
}
|
|
}
|
|
|
|
protected void DrawRotate( float x, float y, float z, float angleX, float angleY, float angleZ, ModelPart part ) {
|
|
Matrix4 mat = Matrix4.Translate( x, y, z );
|
|
float cosX = (float)Math.Cos( -angleX ), sinX = (float)Math.Sin( -angleX );
|
|
float cosY = (float)Math.Cos( -angleY ), sinY = (float)Math.Sin( -angleY );
|
|
float cosZ = (float)Math.Cos( -angleZ ), sinZ = (float)Math.Sin( -angleZ );
|
|
Vector3 offset = new Vector3( x, y, z ) + pos;
|
|
|
|
for( int i = 0; i < part.Count; i++ ) {
|
|
VertexPos3fTex2fCol4b vertex = vertices[part.Offset + i];
|
|
Vector3 loc = new Vector3( vertex.X - x, vertex.Y - y, vertex.Z - z );
|
|
loc = Utils.RotateZ( loc.X, loc.Y, loc.Z, cosZ, sinZ );
|
|
loc = Utils.RotateY( loc.X, loc.Y, loc.Z, cosY, sinY );
|
|
loc = Utils.RotateX( loc.X, loc.Y, loc.Z, cosX, sinX );
|
|
|
|
Vector3 newPos = Utils.RotateY( loc.X, loc.Y, loc.Z, cosA, sinA ) + offset;
|
|
vertex.X = newPos.X; vertex.Y = newPos.Y; vertex.Z = newPos.Z;
|
|
vertex.R = col.R; vertex.G = col.G; vertex.B = col.B;
|
|
cache.vertices[index++] = vertex;
|
|
}
|
|
}
|
|
}
|
|
} |