Browse Source

improved algorithm for clearung unneeded generated blocks

Kolja Strohm 3 years ago
parent
commit
1145b8c9dc
4 changed files with 38 additions and 7 deletions
  1. 5 0
      FactoryCraft/Area.cpp
  2. 2 1
      FactoryCraft/Area.h
  3. 3 0
      FactoryCraft/Block.cpp
  4. 28 6
      FactoryCraft/Chunk.cpp

+ 5 - 0
FactoryCraft/Area.cpp

@@ -73,4 +73,9 @@ int getDirectionIndex( Direction dir )
         return 5;
     assert( false );
     return -1;
+}
+
+Direction getFromIndex( int index )
+{
+    return (Direction)(1 << index);
 }

+ 2 - 1
FactoryCraft/Area.h

@@ -26,4 +26,5 @@ typedef int Directions;
 Direction opposite( Direction dir );
 Directions getDirections( Framework::Vec3<float> currentPos, Framework::Vec3<float> otherPos );
 Framework::Vec3<int> getDirection( Directions dir );
-int getDirectionIndex( Direction dir );
+int getDirectionIndex( Direction dir );
+Direction getFromIndex( int index );

+ 3 - 0
FactoryCraft/Block.cpp

@@ -1,5 +1,6 @@
 #include "Block.h"
 #include "Inventory.h"
+#include "NoBlock.h"
 
 Block::Block( const BlockType* zType, ItemType* zTool, Framework::Vec3<int> pos, bool hasInventory )
     : Inventory( pos, hasInventory )
@@ -148,6 +149,8 @@ bool Block::isVisible() const
         return 1;
     for( int i = 0; i < 6; i++ )
     {
+        if( neighbourTypes[ i ] == NoBlockBlockType::ID )
+            continue;
         const Block* neighbour = CONST_BLOCK( zNeighbours[ i ], neighbourTypes[ i ] );
         if( neighbour->isPassable() || neighbour->isTransparent() )
             return 1;

+ 28 - 6
FactoryCraft/Chunk.cpp

@@ -250,20 +250,42 @@ void Chunk::save( Framework::StreamWriter* zWriter )
 
 void Chunk::removeUnusedBlocks()
 {
-    bool removed = true;
-    while( removed )
+    for( int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++ )
     {
-        removed = false;
-        for( int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++ )
+        if( blocks[ i ] )
         {
-            if( blocks[ i ] && !blocks[ i ]->isVisible() )
+            if( !blocks[ i ]->isVisible() )
             {
                 int x = (i / WORLD_HEIGHT) / CHUNK_SIZE;
                 int y = (i / WORLD_HEIGHT) % CHUNK_SIZE;
                 int z = i % WORLD_HEIGHT;
                 putBlockAt( { x,y,z }, 0 );
                 putBlockTypeAt( { x, y, z }, NoBlockBlockType::ID );
-                removed = true;
+            }
+        }
+        else if( blockIds[ i ] )
+        {
+            int x = (i / WORLD_HEIGHT) / CHUNK_SIZE;
+            int y = (i / WORLD_HEIGHT) % CHUNK_SIZE;
+            int z = i % WORLD_HEIGHT;
+            bool visible = 0;
+            if( CONST_BLOCK( 0, blockIds[ i ] )->isTransparent() || CONST_BLOCK( 0, blockIds[ i ] )->isPassable() )
+                visible = 1;
+            else
+            {
+                for( int d = 0; d < 6 && !visible; d++ )
+                {
+                    auto n = zBlockNeighbor( getDirection( (Directions)getFromIndex( d ) ) + Framework::Vec3<int>( x, y, z ) );
+                    if( n.isA() && (((Block*)n)->isPassable() || ((Block*)n)->isTransparent()) )
+                        visible = 1;
+                    if( n.isB() && n != NoBlockBlockType::ID && CONST_BLOCK( 0, n )->isTransparent() )
+                        visible = 1;
+                }
+            }
+            if( !visible )
+            {
+                putBlockAt( { x,y,z }, 0 );
+                putBlockTypeAt( { x, y, z }, NoBlockBlockType::ID );
             }
         }
     }