Fixup rain particles outside the map and rain rendering in liquids.

This commit is contained in:
UnknownShadow200 2016-01-19 23:05:51 +11:00
parent 1278b8276b
commit 2c30831c53
5 changed files with 31 additions and 18 deletions

View File

@ -223,7 +223,6 @@ namespace ClassicalSharp {
Picking.Render( e.Time, SelectedPos ); Picking.Render( e.Time, SelectedPos );
MapRenderer.Render( e.Time ); MapRenderer.Render( e.Time );
SelectionManager.Render( e.Time ); SelectionManager.Render( e.Time );
WeatherRenderer.Render( e.Time );
Players.RenderHoveredNames( Graphics, e.Time, t ); Players.RenderHoveredNames( Graphics, e.Time, t );
bool left = IsMousePressed( MouseButton.Left ); bool left = IsMousePressed( MouseButton.Left );

View File

@ -5,7 +5,7 @@ namespace ClassicalSharp.Particles {
public abstract class CollidableParticle : Particle { public abstract class CollidableParticle : Particle {
protected bool hitTerrain = false; protected bool hitTerrain = false, throughLiquids = true;
public CollidableParticle( Game game ) : base( game) { } public CollidableParticle( Game game ) : base( game) { }
public void ResetState( Vector3 pos, Vector3 velocity, double lifetime ) { public void ResetState( Vector3 pos, Vector3 velocity, double lifetime ) {
@ -18,7 +18,7 @@ namespace ClassicalSharp.Particles {
protected bool Tick( float gravity, double delta ) { protected bool Tick( float gravity, double delta ) {
hitTerrain = false; hitTerrain = false;
lastPos = Position = nextPos; lastPos = Position = nextPos;
byte curBlock = game.Map.SafeGetBlock( (int)Position.X, (int)Position.Y, (int)Position.Z ); byte curBlock = GetBlock( (int)Position.X, (int)Position.Y, (int)Position.Z );
float minY = Utils.Floor( Position.Y ) + game.BlockInfo.MinBB[curBlock].Y; float minY = Utils.Floor( Position.Y ) + game.BlockInfo.MinBB[curBlock].Y;
float maxY = Utils.Floor( Position.Y ) + game.BlockInfo.MaxBB[curBlock].Y; float maxY = Utils.Floor( Position.Y ) + game.BlockInfo.MaxBB[curBlock].Y;
if( !CanPassThrough( curBlock ) && Position.Y >= minY && if( !CanPassThrough( curBlock ) && Position.Y >= minY &&
@ -29,8 +29,6 @@ namespace ClassicalSharp.Particles {
int startY = (int)Math.Floor( Position.Y ); int startY = (int)Math.Floor( Position.Y );
Position += Velocity * (float)delta * 3; Position += Velocity * (float)delta * 3;
int endY = (int)Math.Floor( Position.Y ); int endY = (int)Math.Floor( Position.Y );
Utils.Clamp( ref Position.X, 0, game.Map.Width - 0.01f );
Utils.Clamp( ref Position.Z, 0, game.Map.Length - 0.01f );
if( Velocity.Y > 0 ) { if( Velocity.Y > 0 ) {
// don't test block we are already in // don't test block we are already in
@ -51,7 +49,7 @@ namespace ClassicalSharp.Particles {
return false; return false;
} }
byte block = game.Map.SafeGetBlock( (int)Position.X, y, (int)Position.Z ); byte block = GetBlock( (int)Position.X, y, (int)Position.Z );
if( CanPassThrough( block ) ) return true; if( CanPassThrough( block ) ) return true;
Vector3 minBB = game.BlockInfo.MinBB[block]; Vector3 minBB = game.BlockInfo.MinBB[block];
Vector3 maxBB = game.BlockInfo.MaxBB[block]; Vector3 maxBB = game.BlockInfo.MaxBB[block];
@ -69,7 +67,8 @@ namespace ClassicalSharp.Particles {
} }
bool CanPassThrough( byte block ) { bool CanPassThrough( byte block ) {
return block == 0 || game.BlockInfo.IsSprite[block] || game.BlockInfo.IsLiquid[block]; return game.BlockInfo.IsAir[block] || game.BlockInfo.IsSprite[block]
|| (throughLiquids && game.BlockInfo.IsLiquid[block]);
} }
bool CollideHor( byte block ) { bool CollideHor( byte block ) {
@ -82,5 +81,14 @@ namespace ClassicalSharp.Particles {
static Vector3 Floor( Vector3 v ) { static Vector3 Floor( Vector3 v ) {
return new Vector3( Utils.Floor( v.X ), 0, Utils.Floor( v.Z ) ); return new Vector3( Utils.Floor( v.X ), 0, Utils.Floor( v.Z ) );
} }
byte GetBlock( int x, int y, int z ) {
if( game.Map.IsValidPos( x, y, z ) )
return game.Map.GetBlock( x, y, z );
if( y >= game.Map.EdgeHeight ) return (byte)Block.Air;
if( y >= game.Map.SidesHeight ) return (byte)game.Map.EdgeBlock;
return (byte)game.Map.SidesBlock;
}
} }
} }

View File

@ -10,7 +10,9 @@ namespace ClassicalSharp.Particles {
static Vector2 tinySize = new Vector2( 0.5f/16f, 0.5f/16f ); static Vector2 tinySize = new Vector2( 0.5f/16f, 0.5f/16f );
static TextureRec rec = new TextureRec( 2/128f, 14/128f, 3/128f, 2/128f ); static TextureRec rec = new TextureRec( 2/128f, 14/128f, 3/128f, 2/128f );
public RainParticle( Game game ) : base( game ) { } public RainParticle( Game game ) : base( game ) {
throughLiquids = false;
}
public bool Big, Tiny; public bool Big, Tiny;

View File

@ -51,16 +51,22 @@ namespace ClassicalSharp {
graphics.DrawIndexedVb_TrisT2fC4b( sidesVertices * 6 / 4, 0 ); graphics.DrawIndexedVb_TrisT2fC4b( sidesVertices * 6 / 4, 0 );
} }
Vector3 camPos = game.CurrentCameraPos;
bool underWater = camPos.Y < game.Map.EdgeHeight;
graphics.AlphaBlending = true; graphics.AlphaBlending = true;
if( underWater )
game.WeatherRenderer.Render( deltaTime );
graphics.BindTexture( edgeTexId ); graphics.BindTexture( edgeTexId );
graphics.BindVb( edgesVb ); graphics.BindVb( edgesVb );
// Do not draw water when we cannot see it. // Do not draw water when we cannot see it.
// Fixes some 'depth bleeding through' issues with 16 bit depth buffers on large maps. // Fixes some 'depth bleeding through' issues with 16 bit depth buffers on large maps.
float yVisible = Math.Min( 0, map.SidesHeight ); float yVisible = Math.Min( 0, map.SidesHeight );
if( game.Map.EdgeBlock != Block.Air && game.CurrentCameraPos.Y >= yVisible ) { if( game.Map.EdgeBlock != Block.Air && camPos.Y >= yVisible )
graphics.DrawIndexedVb_TrisT2fC4b( edgesVertices * 6 / 4, 0 ); graphics.DrawIndexedVb_TrisT2fC4b( edgesVertices * 6 / 4, 0 );
}
if( !underWater )
game.WeatherRenderer.Render( deltaTime );
graphics.AlphaBlending = false; graphics.AlphaBlending = false;
graphics.Texturing = false; graphics.Texturing = false;
graphics.AlphaTest = false; graphics.AlphaTest = false;

View File

@ -31,7 +31,6 @@ namespace ClassicalSharp {
if( weather == Weather.Sunny ) return; if( weather == Weather.Sunny ) return;
if( heightmap == null ) InitHeightmap(); if( heightmap == null ) InitHeightmap();
graphics.Texturing = true;
graphics.BindTexture( weather == Weather.Rainy ? game.RainTexId : game.SnowTexId ); graphics.BindTexture( weather == Weather.Rainy ? game.RainTexId : game.SnowTexId );
Vector3 camPos = game.CurrentCameraPos; Vector3 camPos = game.CurrentCameraPos;
Vector3I pos = Vector3I.Floor( camPos ); Vector3I pos = Vector3I.Floor( camPos );
@ -44,7 +43,7 @@ namespace ClassicalSharp {
bool particles = weather == Weather.Rainy; bool particles = weather == Weather.Rainy;
int index = 0; int index = 0;
graphics.AlphaBlending = true; graphics.AlphaTest = false;
graphics.DepthWrite = false; graphics.DepthWrite = false;
FastColour col = game.Map.Sunlight; FastColour col = game.Map.Sunlight;
for( int dx = -extent; dx <= extent; dx++ ) { for( int dx = -extent; dx <= extent; dx++ ) {
@ -66,14 +65,13 @@ namespace ClassicalSharp {
graphics.SetBatchFormat( VertexFormat.Pos3fTex2fCol4b ); graphics.SetBatchFormat( VertexFormat.Pos3fTex2fCol4b );
graphics.UpdateDynamicIndexedVb( DrawMode.Triangles, weatherVb, vertices, index, index * 6 / 4 ); graphics.UpdateDynamicIndexedVb( DrawMode.Triangles, weatherVb, vertices, index, index * 6 / 4 );
} }
graphics.AlphaBlending = false; graphics.AlphaTest = true;
graphics.Texturing = false;
graphics.DepthWrite = true; graphics.DepthWrite = true;
} }
float AlphaAt( float x ) { float AlphaAt( float x ) {
// Wolfram Alpha: fit {0,178},{1,169},{4,147},{9,114},{16,59},{25,9} // Wolfram Alpha: fit {0,178},{1,169},{4,147},{9,114},{16,59},{25,9}
return 0.05f * x * x - 6.5f * x + 178; return 0.05f * x * x - 7 * x + 178;
} }
void MakeRainForSquare( int x, float y, float height, int z, FastColour col, ref int index ) { void MakeRainForSquare( int x, float y, float height, int z, FastColour col, ref int index ) {
@ -147,7 +145,7 @@ namespace ClassicalSharp {
} }
bool BlocksRain( byte block ) { bool BlocksRain( byte block ) {
return !(info.IsAir[block] || info.IsSprite[block] || info.IsLiquid[block]); return !(info.IsAir[block] || info.IsSprite[block]);
} }
internal void UpdateHeight( int x, int y, int z, byte oldBlock, byte newBlock ) { internal void UpdateHeight( int x, int y, int z, byte oldBlock, byte newBlock ) {