mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-14 18:15:28 -04:00
Initial block in hand model. No left/right click animations yet though.
This commit is contained in:
parent
fe2353c11d
commit
83af1b5a2d
@ -196,6 +196,7 @@
|
||||
<Compile Include="Physics\Picking.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Rendering\BlockHandRenderer.cs" />
|
||||
<Compile Include="Rendering\EnvRenderer.cs" />
|
||||
<Compile Include="Rendering\MapRenderer.Occlusion.cs" />
|
||||
<Compile Include="Rendering\MapRenderer.Rendering.cs" />
|
||||
|
@ -56,6 +56,7 @@ namespace ClassicalSharp {
|
||||
public Events Events = new Events();
|
||||
public InputHandler InputHandler;
|
||||
public ChatLog Chat;
|
||||
public BlockHandRenderer BlockHandRenderer;
|
||||
|
||||
public IPAddress IPAddress;
|
||||
public string Username;
|
||||
@ -172,6 +173,8 @@ namespace ClassicalSharp {
|
||||
ParticleManager = new ParticleManager( this );
|
||||
WeatherRenderer = new WeatherRenderer( this );
|
||||
WeatherRenderer.Init();
|
||||
BlockHandRenderer = new BlockHandRenderer( this );
|
||||
BlockHandRenderer.Init();
|
||||
|
||||
bool vsync = Options.GetBool( OptionsKey.VSync, true );
|
||||
Graphics.SetVSync( this, vsync );
|
||||
@ -257,10 +260,12 @@ namespace ClassicalSharp {
|
||||
bool middle = IsMousePressed( MouseButton.Middle );
|
||||
bool right = IsMousePressed( MouseButton.Right );
|
||||
InputHandler.PickBlocks( true, left, middle, right );
|
||||
BlockHandRenderer.Render( e.Time );
|
||||
} else {
|
||||
SelectedPos.SetAsInvalid();
|
||||
}
|
||||
|
||||
|
||||
Graphics.Mode2D( Width, Height, EnvRenderer is StandardEnvRenderer );
|
||||
fpsScreen.Render( e.Time );
|
||||
if( activeScreen == null || !activeScreen.HidesHud )
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using ClassicalSharp.GraphicsAPI;
|
||||
using ClassicalSharp.Renderers;
|
||||
using OpenTK;
|
||||
|
||||
namespace ClassicalSharp.Model {
|
||||
@ -25,11 +26,18 @@ namespace ClassicalSharp.Model {
|
||||
}
|
||||
|
||||
public override BoundingBox PickingBounds {
|
||||
get { return new BoundingBox( -0.5f, 0f, -0.5f, 0.5f, blockHeight, 0.5f ); }
|
||||
get { return new BoundingBox( -scale, 0f, -scale, scale, blockHeight, scale ); }
|
||||
}
|
||||
|
||||
protected override void DrawPlayerModel( Player p ) {
|
||||
block = Byte.Parse( p.ModelName );
|
||||
// TODO: using 'is' is ugly, but means we can avoid creating
|
||||
// a string every single time held block changes.
|
||||
if( p is FakePlayer ) {
|
||||
col = FastColour.Scale( FastColour.White, 0.8f );
|
||||
block = ((FakePlayer)p).Block;
|
||||
} else {
|
||||
block = Byte.Parse( p.ModelName );
|
||||
}
|
||||
if( block == 0 ) {
|
||||
blockHeight = 1;
|
||||
return;
|
||||
@ -41,21 +49,28 @@ namespace ClassicalSharp.Model {
|
||||
BlockInfo = game.BlockInfo;
|
||||
|
||||
if( BlockInfo.IsSprite[block] ) {
|
||||
XQuad( 0f, TileSide.Right, false );
|
||||
ZQuad( 0f, TileSide.Back, false );
|
||||
float offset = TerrainAtlas2D.invElementSize / 2;
|
||||
XQuad( 0f, TileSide.Right, -scale, 0, 0, -offset, false );
|
||||
ZQuad( 0f, TileSide.Back, 0, scale, offset, 0, false );
|
||||
|
||||
XQuad( 0f, TileSide.Right, 0, scale, offset, 0, false );
|
||||
ZQuad( 0f, TileSide.Back, -scale, 0, 0, -offset, false );
|
||||
} else {
|
||||
YQuad( blockHeight, TileSide.Top );
|
||||
XQuad( -0.5f, TileSide.Right, false );
|
||||
XQuad( 0.5f, TileSide.Left, true );
|
||||
ZQuad( -0.5f, TileSide.Front, true );
|
||||
ZQuad( 0.5f, TileSide.Back, false );
|
||||
YQuad( 0f, TileSide.Bottom );
|
||||
XQuad( scale, TileSide.Left, -scale, scale, 0, 0, true );
|
||||
ZQuad( -scale, TileSide.Front, -scale, scale, 0, 0, true );
|
||||
|
||||
ZQuad( scale, TileSide.Back, -scale, scale, 0, 0, true );
|
||||
YQuad( blockHeight, TileSide.Top );
|
||||
XQuad( -scale, TileSide.Right, -scale, scale, 0, 0, true );
|
||||
|
||||
}
|
||||
graphics.UpdateDynamicIndexedVb( DrawMode.Triangles, cache.vb, cache.vertices, index, index * 6 / 4 );
|
||||
}
|
||||
float blockHeight;
|
||||
TerrainAtlas2D atlas;
|
||||
BlockInfo BlockInfo;
|
||||
float scale = 0.5f;
|
||||
|
||||
public override void Dispose() {
|
||||
}
|
||||
@ -64,36 +79,45 @@ namespace ClassicalSharp.Model {
|
||||
int texId = BlockInfo.GetTextureLoc( block, side );
|
||||
TextureRec rec = atlas.GetAdjTexRec( texId );
|
||||
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + -0.5f, pos.Y + y, pos.Z + -0.5f, rec.U1, rec.V1, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + 0.5f, pos.Y + y, pos.Z + -0.5f, rec.U2, rec.V1, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + 0.5f, pos.Y + y, pos.Z + 0.5f, rec.U2, rec.V2, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + -0.5f, pos.Y + y, pos.Z + 0.5f, rec.U1, rec.V2, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X - scale, pos.Y + y, pos.Z - scale, rec.U1, rec.V1, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + scale, pos.Y + y, pos.Z - scale, rec.U2, rec.V1, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + scale, pos.Y + y, pos.Z + scale, rec.U2, rec.V2, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X - scale, pos.Y + y, pos.Z + scale, rec.U1, rec.V2, col );
|
||||
}
|
||||
|
||||
void ZQuad( float z, int side, bool swapU ) {
|
||||
void ZQuad( float z, int side, float x1, float x2,
|
||||
float u1Offset, float u2Offset, bool swapU ) {
|
||||
int texId = BlockInfo.GetTextureLoc( block, side );
|
||||
TextureRec rec = atlas.GetAdjTexRec( texId );
|
||||
if( blockHeight != 1 )
|
||||
rec.V2 = rec.V1 + blockHeight * TerrainAtlas2D.invElementSize * (15.99f/16f);
|
||||
if( swapU ) rec.SwapU();
|
||||
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + -0.5f, pos.Y + 0f, pos.Z + z, rec.U1, rec.V2, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + -0.5f, pos.Y + blockHeight, pos.Z + z, rec.U1, rec.V1, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + 0.5f, pos.Y + blockHeight, pos.Z + z, rec.U2, rec.V1, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + 0.5f, pos.Y + 0f, pos.Z + z, rec.U2, rec.V2, col );
|
||||
// need to break into two quads when drawing a sprite model in hand.
|
||||
if( swapU ) rec.SwapU();
|
||||
rec.U1 += u1Offset;
|
||||
rec.U2 += u2Offset;
|
||||
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x1, pos.Y + 0f, pos.Z + z, rec.U1, rec.V2, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x1, pos.Y + blockHeight, pos.Z + z, rec.U1, rec.V1, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x2, pos.Y + blockHeight, pos.Z + z, rec.U2, rec.V1, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x2, pos.Y + 0f, pos.Z + z, rec.U2, rec.V2, col );
|
||||
}
|
||||
|
||||
void XQuad( float x, int side, bool swapU ) {
|
||||
void XQuad( float x, int side, float z1, float z2,
|
||||
float u1Offset, float u2Offset, bool swapU ) {
|
||||
int texId = BlockInfo.GetTextureLoc( block, side );
|
||||
TextureRec rec = atlas.GetAdjTexRec( texId );
|
||||
if( blockHeight != 1 )
|
||||
rec.V2 = rec.V1 + blockHeight * TerrainAtlas2D.invElementSize * (15.99f/16f);
|
||||
if( swapU ) rec.SwapU();
|
||||
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x, pos.Y + 0f, pos.Z + -0.5f, rec.U1, rec.V2, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x, pos.Y + blockHeight, pos.Z + -0.5f, rec.U1, rec.V1, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x, pos.Y + blockHeight, pos.Z + 0.5f, rec.U2, rec.V1, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x, pos.Y + 0f, pos.Z + 0.5f, rec.U2, rec.V2, col );
|
||||
if( swapU ) rec.SwapU();
|
||||
rec.U1 += u1Offset;
|
||||
rec.U2 += u2Offset;
|
||||
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x, pos.Y + 0f, pos.Z + z1, rec.U1, rec.V2, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x, pos.Y + blockHeight, pos.Z + z1, rec.U1, rec.V1, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x, pos.Y + blockHeight, pos.Z + z2, rec.U2, rec.V1, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x, pos.Y + 0f, pos.Z + z2, rec.U2, rec.V2, col );
|
||||
}
|
||||
}
|
||||
}
|
71
ClassicalSharp/Rendering/BlockHandRenderer.cs
Normal file
71
ClassicalSharp/Rendering/BlockHandRenderer.cs
Normal file
@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using ClassicalSharp.Model;
|
||||
using OpenTK;
|
||||
|
||||
namespace ClassicalSharp.Renderers {
|
||||
|
||||
public class BlockHandRenderer : IDisposable {
|
||||
|
||||
Game game;
|
||||
BlockModel block;
|
||||
FakePlayer fakePlayer;
|
||||
|
||||
public BlockHandRenderer( Game window ) {
|
||||
this.game = window;
|
||||
}
|
||||
|
||||
public void Init() {
|
||||
block = new BlockModel( game );
|
||||
fakePlayer = new FakePlayer( game );
|
||||
SetupMatrices();
|
||||
}
|
||||
|
||||
public void Render( double delta ) {
|
||||
game.Graphics.Texturing = true;
|
||||
game.Graphics.DepthTest = false;
|
||||
game.Graphics.AlphaTest = true;
|
||||
|
||||
byte type = (byte)game.Inventory.HeldBlock;
|
||||
if( game.BlockInfo.IsSprite[type] )
|
||||
game.Graphics.LoadMatrix( ref spriteMat );
|
||||
else
|
||||
game.Graphics.LoadMatrix( ref normalMat );
|
||||
fakePlayer.Block = type;
|
||||
block.RenderModel( fakePlayer );
|
||||
|
||||
game.Graphics.LoadMatrix( ref game.View );
|
||||
game.Graphics.Texturing = false;
|
||||
game.Graphics.DepthTest = true;
|
||||
game.Graphics.AlphaTest = false;
|
||||
}
|
||||
|
||||
|
||||
Matrix4 normalMat, spriteMat;
|
||||
void SetupMatrices() {
|
||||
Matrix4 m = Matrix4.Identity;
|
||||
m = m * Matrix4.Scale( 0.6f );
|
||||
m = m * Matrix4.RotateY( 45 * Utils.Deg2Rad );
|
||||
|
||||
normalMat = m * Matrix4.Translate( 0.85f, -1.35f, -1.5f );
|
||||
spriteMat = m * Matrix4.Translate( 0.85f, -1.05f, -1.5f );
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
}
|
||||
}
|
||||
|
||||
internal class FakePlayer : Player {
|
||||
|
||||
public FakePlayer( Game game ) : base( game ) {
|
||||
}
|
||||
public byte Block;
|
||||
|
||||
public override void SetLocation( LocationUpdate update, bool interpolate ) { }
|
||||
|
||||
public override void Tick( double delta ) { }
|
||||
|
||||
public override void RenderModel( double deltaTime, float t ) { }
|
||||
|
||||
public override void RenderName() { }
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ using OpenTK;
|
||||
|
||||
namespace ClassicalSharp.Renderers {
|
||||
|
||||
public class PickingRenderer {
|
||||
public class PickingRenderer : IDisposable {
|
||||
|
||||
IGraphicsApi graphics;
|
||||
BlockInfo info;
|
||||
|
@ -1,4 +1,4 @@
|
||||
ClassicalSharp is a custom Minecraft Classic client written in C# that works on both Windows, Linux and OSX.
|
||||
ClassicalSharp is a custom Minecraft Classic client written in C# that works on Windows, Linux and OSX.
|
||||
**It is not affiliated with (or supported by) Mojang AB, Minecraft, or Microsoft in any way.**
|
||||
|
||||

|
||||
|
Loading…
x
Reference in New Issue
Block a user