From 6fb700ae8ff28fd81b4a2393dee67b7917e5b2f7 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Wed, 23 Dec 2015 15:30:34 +1100 Subject: [PATCH] Particles now work with non 0 min and non 1 max. --- ClassicalSharp/Blocks/BlockInfo.cs | 2 +- ClassicalSharp/Entities/Entity.cs | 28 +++++++++--------- ClassicalSharp/Map/ChunkMeshBuilder.cs | 5 +--- .../Map/ChunkMeshBuilderTex2Col4.cs | 29 ++++++++++--------- .../Particles/CollidableParticle.cs | 26 +++++++++++++---- 5 files changed, 52 insertions(+), 38 deletions(-) diff --git a/ClassicalSharp/Blocks/BlockInfo.cs b/ClassicalSharp/Blocks/BlockInfo.cs index df84678e1..aca2537c6 100644 --- a/ClassicalSharp/Blocks/BlockInfo.cs +++ b/ClassicalSharp/Blocks/BlockInfo.cs @@ -37,7 +37,7 @@ namespace ClassicalSharp { public string[] Name = new string[BlocksCount]; - /// Gets the custom fog colour that should be used when the player is standing within this block. + /// Gets the custom fog colour that should be used when the player is standing within this block. /// Note that this is only used for exponential fog mode. public FastColour[] FogColour = new FastColour[BlocksCount]; diff --git a/ClassicalSharp/Entities/Entity.cs b/ClassicalSharp/Entities/Entity.cs index 1f5a413cc..8f6da6466 100644 --- a/ClassicalSharp/Entities/Entity.cs +++ b/ClassicalSharp/Entities/Entity.cs @@ -84,21 +84,19 @@ namespace ClassicalSharp { Vector3I bbMin = Vector3I.Floor( bounds.Min ); Vector3I bbMax = Vector3I.Floor( bounds.Max ); - // Order loops so that we minimise cache misses - for( int y = bbMin.Y; y <= bbMax.Y; y++ ) { - for( int z = bbMin.Z; z <= bbMax.Z; z++ ) { - for( int x = bbMin.X; x <= bbMax.X; x++ ) { - if( !game.Map.IsValidPos( x, y, z ) ) continue; - byte block = game.Map.GetBlock( x, y, z ); - - if( condition( block ) ) { - float blockHeight = info.Height[block]; - Vector3 min = new Vector3( x, y, z ) + info.MinBB[block]; - Vector3 max = new Vector3( x, y, z ) + info.MaxBB[block]; - BoundingBox blockBB = new BoundingBox( min, max ); - if( blockBB.Intersects( bounds ) ) return true; - } - } + // Order loops so that we minimise cache misses + for( int y = bbMin.Y; y <= bbMax.Y; y++ ) + for( int z = bbMin.Z; z <= bbMax.Z; z++ ) + for( int x = bbMin.X; x <= bbMax.X; x++ ) + { + if( !game.Map.IsValidPos( x, y, z ) ) continue; + byte block = game.Map.GetBlock( x, y, z ); + + if( condition( block ) ) { + Vector3 min = new Vector3( x, y, z ) + info.MinBB[block]; + Vector3 max = new Vector3( x, y, z ) + info.MaxBB[block]; + BoundingBox blockBB = new BoundingBox( min, max ); + if( blockBB.Intersects( bounds ) ) return true; } } return false; diff --git a/ClassicalSharp/Map/ChunkMeshBuilder.cs b/ClassicalSharp/Map/ChunkMeshBuilder.cs index ba2e93f69..38da282fa 100644 --- a/ClassicalSharp/Map/ChunkMeshBuilder.cs +++ b/ClassicalSharp/Map/ChunkMeshBuilder.cs @@ -126,10 +126,8 @@ namespace ClassicalSharp { if( info.IsSprite[tile] ) { fullBright = info.FullBright[tile]; int count = counts[index + TileSide.Top]; - if( count != 0 ) { - blockHeight = info.Height[tile]; + if( count != 0 ) DrawSprite( count ); - } return; } @@ -145,7 +143,6 @@ namespace ClassicalSharp { this.minBB = min; this.maxBB = max; fullBright = info.FullBright[tile]; - blockHeight = info.Height[tile]; isTranslucent = info.IsTranslucent[tile]; if( leftCount != 0 ) diff --git a/ClassicalSharp/Map/ChunkMeshBuilderTex2Col4.cs b/ClassicalSharp/Map/ChunkMeshBuilderTex2Col4.cs index 395662827..26dd6c365 100644 --- a/ClassicalSharp/Map/ChunkMeshBuilderTex2Col4.cs +++ b/ClassicalSharp/Map/ChunkMeshBuilderTex2Col4.cs @@ -117,7 +117,6 @@ namespace ClassicalSharp { } bool isTranslucent; - float blockHeight; float invVerElementSize; int elementsPerAtlas1D; @@ -273,23 +272,27 @@ namespace ClassicalSharp { } void DrawSprite( int count ) { - int texId = info.GetTextureLoc( tile, TileSide.Right ); - int i; - TextureRec rec = atlas.GetTexRec( texId, 1, out i ); - FastColour col = fullBright ? FastColour.White : (Y > map.heightmap[(Z * width) + X] ? map.Sunlight : map.Shadowlight); + int texId = info.textures[tile * TileSide.Sides + TileSide.Right]; + int i = texId / elementsPerAtlas1D; + float vOrigin = (texId % elementsPerAtlas1D) * invVerElementSize; + float blockHeight = info.Height[tile]; + + float u1 = 0, u2 = 1 * 15.99f/16f; + float v1 = vOrigin, v2 = vOrigin + invVerElementSize * 15.99f/16f; DrawInfo part = drawInfoNormal[i]; + FastColour col = fullBright ? FastColour.White : (Y > map.heightmap[(Z * width) + X] ? map.Sunlight : map.Shadowlight); // Draw Z axis - part.vertices[part.spriteIndex++] = new VertexPos3fTex2fCol4b( X + 2.50f/16, Y, Z + 2.5f/16, rec.U2, rec.V2, col ); - part.vertices[part.spriteIndex++] = new VertexPos3fTex2fCol4b( X + 2.50f/16, Y + blockHeight, Z + 2.5f/16, rec.U2, rec.V1, col ); - part.vertices[part.spriteIndex++] = new VertexPos3fTex2fCol4b( X + 13.5f/16, Y + blockHeight, Z + 13.5f/16, rec.U1, rec.V1, col ); - part.vertices[part.spriteIndex++] = new VertexPos3fTex2fCol4b( X + 13.5f/16, Y, Z + 13.5f/16, rec.U1, rec.V2, col ); + part.vertices[part.spriteIndex++] = new VertexPos3fTex2fCol4b( X + 2.50f/16, Y, Z + 2.5f/16, u2, v2, col ); + part.vertices[part.spriteIndex++] = new VertexPos3fTex2fCol4b( X + 2.50f/16, Y + blockHeight, Z + 2.5f/16, u2, v1, col ); + part.vertices[part.spriteIndex++] = new VertexPos3fTex2fCol4b( X + 13.5f/16, Y + blockHeight, Z + 13.5f/16, u1, v1, col ); + part.vertices[part.spriteIndex++] = new VertexPos3fTex2fCol4b( X + 13.5f/16, Y, Z + 13.5f/16, u1, v2, col ); // Draw X axis - part.vertices[part.spriteIndex++] = new VertexPos3fTex2fCol4b( X + 2.50f/16, Y, Z + 13.5f/16, rec.U1, rec.V2, col ); - part.vertices[part.spriteIndex++] = new VertexPos3fTex2fCol4b( X + 2.50f/16, Y + blockHeight, Z + 13.5f/16, rec.U1, rec.V1, col ); - part.vertices[part.spriteIndex++] = new VertexPos3fTex2fCol4b( X + 13.5f/16, Y + blockHeight, Z + 2.5f/16, rec.U2, rec.V1, col ); - part.vertices[part.spriteIndex++] = new VertexPos3fTex2fCol4b( X + 13.5f/16, Y, Z + 2.5f/16, rec.U2, rec.V2, col ); + part.vertices[part.spriteIndex++] = new VertexPos3fTex2fCol4b( X + 2.50f/16, Y, Z + 13.5f/16, u1, v2, col ); + part.vertices[part.spriteIndex++] = new VertexPos3fTex2fCol4b( X + 2.50f/16, Y + blockHeight, Z + 13.5f/16, u1, v1, col ); + part.vertices[part.spriteIndex++] = new VertexPos3fTex2fCol4b( X + 13.5f/16, Y + blockHeight, Z + 2.5f/16, u2, v1, col ); + part.vertices[part.spriteIndex++] = new VertexPos3fTex2fCol4b( X + 13.5f/16, Y, Z + 2.5f/16, u2, v2, col ); } } } \ No newline at end of file diff --git a/ClassicalSharp/Particles/CollidableParticle.cs b/ClassicalSharp/Particles/CollidableParticle.cs index 49aa0e3fa..e52aa4768 100644 --- a/ClassicalSharp/Particles/CollidableParticle.cs +++ b/ClassicalSharp/Particles/CollidableParticle.cs @@ -19,8 +19,11 @@ namespace ClassicalSharp.Particles { hitTerrain = false; lastPos = Position = nextPos; byte curBlock = game.Map.SafeGetBlock( (int)Position.X, (int)Position.Y, (int)Position.Z ); - float blockY = (int)Position.Y + game.BlockInfo.Height[curBlock]; - if( !CanPassThrough( curBlock ) && Position.Y < blockY ) return true; + float minY = Utils.Floor( Position.Y ) + game.BlockInfo.MinBB[curBlock].Y; + float maxY = Utils.Floor( Position.Y ) + game.BlockInfo.MaxBB[curBlock].Y; + if( !CanPassThrough( curBlock ) && Position.Y >= minY && + Position.Y < maxY && CollideHor( curBlock ) ) + return true; Velocity.Y -= gravity * (float)delta; int startY = (int)Math.Floor( Position.Y ); @@ -50,10 +53,12 @@ namespace ClassicalSharp.Particles { byte block = game.Map.SafeGetBlock( (int)Position.X, y, (int)Position.Z ); if( CanPassThrough( block ) ) return true; + Vector3 minBB = game.BlockInfo.MinBB[block]; + Vector3 maxBB = game.BlockInfo.MaxBB[block]; + float collideY = y + (topFace ? maxBB.Y : minBB.Y); + bool collideVer = topFace ? (Position.Y < collideY) : (Position.Y > collideY); - float collideY = y + (topFace ? game.BlockInfo.Height[block] : 0); - bool collide = topFace ? (Position.Y < collideY) : (Position.Y > collideY); - if( collide ) { + if( collideVer && CollideHor( block ) ) { float adjust = topFace ? Entity.Adjustment : -Entity.Adjustment; Position.Y = nextPos.Y = lastPos.Y = collideY + adjust; Velocity = Vector3.Zero; @@ -66,5 +71,16 @@ namespace ClassicalSharp.Particles { bool CanPassThrough( byte block ) { return block == 0 || game.BlockInfo.IsSprite[block] || game.BlockInfo.IsLiquid[block]; } + + bool CollideHor( byte block ) { + Vector3 min = game.BlockInfo.MinBB[block] + Floor( Position ); + Vector3 max = game.BlockInfo.MaxBB[block] + Floor( Position ); + return Position.X >= min.X && Position.Z >= min.Z && + Position.X < max.X && Position.Z < max.Z; + } + + static Vector3 Floor( Vector3 v ) { + return new Vector3( Utils.Floor( v.X ), 0, Utils.Floor( v.Z ) ); + } } }