Browse Source

improve chunk model builder architecture

Kolja Strohm 1 year ago
parent
commit
48fd128bc1

+ 66 - 78
FactoryCraft/Chunk.cpp

@@ -37,11 +37,11 @@ Chunk::Chunk(Framework::Punkt location)
     ground->setPosition(
         (float)location.x, (float)location.y, (float)WORLD_HEIGHT / 2.f);
     ground->tick(0);
-    groundModel = new ChunkGroundModel(ground, this);
+    ChunkModelBuilder* groundModel = new ChunkGroundModel(ground, this);
+    modelBuilders.add(groundModel);
     FactoryCraftModel* transparentGround = new FactoryCraftModel();
-    chunkModel
-        = uiFactory.initParam.bildschirm->zGraphicsApi()->getModel(
-            Text("transparent_chunk_ground_") + location.x + location.y);
+    chunkModel = uiFactory.initParam.bildschirm->zGraphicsApi()->getModel(
+        Text("transparent_chunk_ground_") + location.x + location.y);
     if (!chunkModel)
     {
         chunkModel
@@ -56,8 +56,9 @@ Chunk::Chunk(Framework::Punkt location)
     transparentGround->setPosition(
         (float)location.x, (float)location.y, (float)WORLD_HEIGHT / 2.f);
     transparentGround->tick(0);
-    transparentGroundModel
+    ChunkModelBuilder* transparentGroundModel
         = new TransparentChunkGroundModel(transparentGround, this);
+    modelBuilders.add(transparentGroundModel);
     FactoryCraftModel* fluids = new FactoryCraftModel();
     chunkModel = uiFactory.initParam.bildschirm->zGraphicsApi()->getModel(
         Text("chunk_fluids_") + location.x + location.y);
@@ -75,16 +76,18 @@ Chunk::Chunk(Framework::Punkt location)
     fluids->setPosition(
         (float)location.x, (float)location.y, (float)WORLD_HEIGHT / 2.f);
     fluids->tick(0);
-    fluidModel = new ChunkFluidModel(fluids, this);
+    ChunkModelBuilder* fluidModel = new ChunkFluidModel(fluids, this);
+    modelBuilders.add(fluidModel);
 }
 
 Chunk::Chunk(Framework::Punkt location, Framework::StreamReader* zReader)
     : Chunk(location)
 {
     load(zReader);
-    buildModel(groundModel);
-    buildModel(transparentGroundModel);
-    buildModel(fluidModel);
+    for (ChunkModelBuilder* builder : modelBuilders)
+    {
+		buildModel(builder);
+	}
 }
 
 Chunk::~Chunk()
@@ -103,9 +106,6 @@ Chunk::~Chunk()
         }
     }
     delete[] blocks;
-    groundModel->release();
-    transparentGroundModel->release();
-    fluidModel->release();
 }
 
 void Chunk::appendAnimation(
@@ -331,17 +331,18 @@ void Chunk::renderSolid(std::function<void(Model3D*)> f)
     CustomDX11API* api
         = (CustomDX11API*)uiFactory.initParam.bildschirm->zGraphicsApi();
     api->setCullBack(false);
-    f(groundModel->zModel());
+    for (ChunkModelBuilder* builder : modelBuilders)
+    {
+        if (!builder->isTransparent())
+        {
+			f(builder->zModel());
+		}
+    }
     api->setCullBack(true);
     float dist = 0.f;
-    if (api->isInFrustrum(groundModel->zModel()->getPos(),
-            (CHUNK_SIZE / 2.f, CHUNK_SIZE / 2.f, WORLD_HEIGHT / 2.f),
-            &dist))
+    for (Block* b : visibleBlocks)
     {
-        for (Block* b : visibleBlocks)
-        {
-            f(b);
-        }
+        f(b);
     }
     vcs.unlock();
 }
@@ -351,8 +352,13 @@ void Chunk::renderTransparent(std::function<void(Model3D*)> f)
     CustomDX11API* api
         = (CustomDX11API*)uiFactory.initParam.bildschirm->zGraphicsApi();
     api->setCullBack(false);
-    f(transparentGroundModel->zModel());
-    f(fluidModel->zModel());
+    for (ChunkModelBuilder* builder : modelBuilders)
+    {
+        if (builder->isTransparent())
+        {
+            f(builder->zModel());
+        }
+    }
     api->setCullBack(true);
 }
 
@@ -360,21 +366,21 @@ bool Chunk::tick(std::function<void(Model3D*)> f, double time)
 {
     acs.lock();
     vcs.lock(); // TODO: enshure no dead lock occures
-    if ((modelChanged | CombinedModels::GROUND) == modelChanged)
-        buildModel(groundModel);
-    if ((modelChanged | CombinedModels::TRANSPARENT_GROUND) == modelChanged)
-        buildModel(transparentGroundModel);
-    if ((modelChanged | CombinedModels::FLUID) == modelChanged)
-        buildModel(fluidModel);
-    if ((lightChanged | CombinedModels::GROUND) == lightChanged)
-        updateLight(groundModel);
-    if ((lightChanged | CombinedModels::TRANSPARENT_GROUND) == lightChanged)
-        updateLight(transparentGroundModel);
-    if ((lightChanged | CombinedModels::FLUID) == lightChanged)
-        updateLight(fluidModel);
-    bool res = groundModel->zModel()->tick(time);
-    res |= transparentGroundModel->zModel()->tick(time);
-    res |= fluidModel->zModel()->tick(time);
+    for (ChunkModelBuilder* builder : modelBuilders)
+    {
+        if ((modelChanged | builder->getType()) == modelChanged)
+			buildModel(builder);
+    }
+    for (ChunkModelBuilder* builder : modelBuilders)
+    {
+        if ((lightChanged | builder->getType()) == modelChanged)
+            updateLight(builder);
+    }
+    bool res = 0;
+    for (ChunkModelBuilder* builder : modelBuilders)
+    {
+        res |= builder->zModel()->tick(time);
+    }
     auto iterator = animations.begin();
     while (iterator)
     {
@@ -401,27 +407,16 @@ bool Chunk::tick(std::function<void(Model3D*)> f, double time)
 
 void Chunk::destroy()
 {
-    Model3DData* chunkModel = groundModel->zModel()->zModelData();
-    // remove old model
-    while (chunkModel->getPolygonAnzahl() > 0)
+    for (ChunkModelBuilder* builder : modelBuilders)
     {
-        chunkModel->removePolygon(0);
-    }
-    chunkModel->setVertecies(0, 0);
-    chunkModel = transparentGroundModel->zModel()->zModelData();
-    // remove old model
-    while (chunkModel->getPolygonAnzahl() > 0)
-    {
-        chunkModel->removePolygon(0);
-    }
-    chunkModel->setVertecies(0, 0);
-    chunkModel = fluidModel->zModel()->zModelData();
-    // remove old model
-    while (chunkModel->getPolygonAnzahl() > 0)
-    {
-        chunkModel->removePolygon(0);
+        Model3DData* chunkModel = builder->zModel()->zModelData();
+        // remove old model
+        while (chunkModel->getPolygonAnzahl() > 0)
+        {
+            chunkModel->removePolygon(0);
+        }
+        chunkModel->setVertecies(0, 0);
     }
-    chunkModel->setVertecies(0, 0);
 }
 
 void Chunk::api(char* message)
@@ -494,20 +489,19 @@ void Chunk::setBlock(Block* block)
     if (pos.x < 0) pos.x += CHUNK_SIZE;
     if (pos.y < 0) pos.y += CHUNK_SIZE;
     int index = (pos.x * CHUNK_SIZE + pos.y) * WORLD_HEIGHT + pos.z;
-    bool newAffectsGround
-        = block
-       && (block->zBlockType()->getModelInfo().getModelName().istGleich("cube")
-           || block->zBlockType()->getModelInfo().getModelName().istGleich(
-               "grass"));
-    bool affectsGround
-        = blocks[index]
-       && (blocks[index]->zBlockType()->getModelInfo().getModelName().istGleich(
-               "cube")
-           || blocks[index]
-                  ->zBlockType()
-                  ->getModelInfo()
-                  .getModelName()
-                  .istGleich("grass"));
+    int affectsGround = 0;
+    int newAffectsGround = 0;
+    for (ChunkModelBuilder* builder : modelBuilders)
+    {
+        if (block && builder->isPartOfModel(block))
+        {
+            newAffectsGround |= builder->getType();
+		}
+        if (blocks[index] && builder->isPartOfModel(blocks[index]))
+        {
+			affectsGround |= builder->getType();
+        }
+    }
     if (blocks[index])
     {
         vcs.lock();
@@ -525,10 +519,7 @@ void Chunk::setBlock(Block* block)
         blocks[index] = block;
         cs.unlock();
         vcs.lock();
-        if (affectsGround || newAffectsGround)
-        {
-            modelChanged = 1;
-        }
+        modelChanged |= affectsGround | newAffectsGround;
         if (block && block->isVisible() && !newAffectsGround)
         {
             block->tick(0);
@@ -540,10 +531,7 @@ void Chunk::setBlock(Block* block)
     blocks[index] = block;
     cs.unlock();
     vcs.lock();
-    if (affectsGround || newAffectsGround)
-    {
-        modelChanged = 1;
-    }
+    modelChanged |= affectsGround | newAffectsGround;
     if (block && block->isVisible() && !newAffectsGround)
     {
         block->tick(0);

+ 1 - 3
FactoryCraft/Chunk.h

@@ -30,9 +30,7 @@ private:
     // TODO: use native array for bedder performance?
     Block** blocks;
     Framework::Array<Block*> visibleBlocks;
-    ChunkModelBuilder* groundModel;
-    ChunkModelBuilder* transparentGroundModel;
-    ChunkModelBuilder* fluidModel;
+    Framework::RCArray<ChunkModelBuilder> modelBuilders;
     bool isLoading;
     Framework::Critical cs;
     Framework::Critical vcs;

+ 15 - 5
FactoryCraft/ChunkFluidModel.cpp

@@ -128,8 +128,7 @@ void ChunkFluidModel::buildModel()
     {
         if (blocks()[i])
         {
-            if (blocks()[i]
-                    ->zBlockType()->isFluid())
+            if (isPartOfModel(blocks()[i]))
             {
                 setBlockPartOfModel(blocks()[i], 1);
                 int index = 0;
@@ -197,7 +196,7 @@ void ChunkFluidModel::buildModel()
                                 = groundVertexCount;
                             groundVerticies[groundVertexCount++]
                                 = vBuffer[polygon->indexList[vi]];
-                            if (getDirectionFromIndex(index) & TOP)
+                            if (groundVerticies[groundVertexCount - 1].pos.z > 0)
                             {
                                 char maxFlowDist = blocks()[i]
                                                        ->zBlockType()
@@ -251,7 +250,8 @@ bool ChunkFluidModel::updateLightning()
     int groundVertexCount = 0;
     for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++)
     {
-        if (blocks()[i] && (blocks()[i]->getPartOfModels() | getType()) )
+        if (blocks()[i]
+            && isPartOfModel(blocks()[i]))
         {
             int index = 0;
             for (Text* textureName :
@@ -286,4 +286,14 @@ bool ChunkFluidModel::updateLightning()
     }
     target->copyLightToGPU();
     return 1;
-}
+}
+
+bool ChunkFluidModel::isTransparent() const
+{
+    return true;
+}
+
+bool ChunkFluidModel::isPartOfModel(Block* zBlock) const
+{
+    return zBlock->zBlockType()->isFluid();
+}

+ 2 - 0
FactoryCraft/ChunkFluidModel.h

@@ -15,4 +15,6 @@ public:
     ChunkFluidModel(FactoryCraftModel* target, Chunk* zChunk);
     void buildModel() override;
     bool updateLightning() override;
+    bool isTransparent() const override;
+    bool isPartOfModel(Block* zBlock) const override;
 };

+ 15 - 12
FactoryCraft/ChunkGroundModel.cpp

@@ -14,7 +14,6 @@ ChunkGroundModel::ChunkGroundModel(FactoryCraftModel* target, Chunk* zChunk)
     : ChunkModelBuilder(target, zChunk, Chunk::CombinedModels::GROUND)
 {}
 
-
 __int64 ChunkGroundModel::calculateLight(Framework::Vec3<float> vertexPos,
     Framework::Vec3<int> blockPos,
     Direction direction)
@@ -133,11 +132,7 @@ void ChunkGroundModel::buildModel()
     {
         if (blocks()[i])
         {
-            if (blocks()[i]
-                    ->zBlockType()
-                    ->getModelInfo()
-                    .getModelName()
-                    .istGleich("cube"))
+            if (isPartOfModel(blocks()[i]))
             {
                 setBlockPartOfModel(blocks()[i], 1);
                 int index = 0;
@@ -242,18 +237,15 @@ void ChunkGroundModel::buildModel()
     target->setVertexLightBuffer(lightBuffer, groundVertexCount);
 }
 
-bool ChunkGroundModel::updateLightning() {
+bool ChunkGroundModel::updateLightning()
+{
     __int64* lightBuffer = target->zLightBuffer();
     int groundVertexCount = 0;
     for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++)
     {
         if (blocks()[i])
         {
-            if (blocks()[i]
-                    ->zBlockType()
-                    ->getModelInfo()
-                    .getModelName()
-                    .istGleich("cube"))
+            if (isPartOfModel(blocks()[i]))
             {
                 int index = 0;
                 for (Text* textureName :
@@ -285,3 +277,14 @@ bool ChunkGroundModel::updateLightning() {
     target->copyLightToGPU();
     return 1;
 }
+
+bool ChunkGroundModel::isTransparent() const
+{
+    return false;
+}
+
+bool ChunkGroundModel::isPartOfModel(Block* zBlock) const
+{
+    return zBlock->zBlockType()->getModelInfo().getModelName().istGleich(
+        "cube");
+}

+ 2 - 0
FactoryCraft/ChunkGroundModel.h

@@ -14,4 +14,6 @@ public:
     ChunkGroundModel(FactoryCraftModel* target, Chunk* zChunk);
     void buildModel() override;
     bool updateLightning() override;
+    bool isTransparent() const override;
+    bool isPartOfModel(Block* zBlock) const override;
 };

+ 2 - 0
FactoryCraft/ChunkModelBuilder.h

@@ -35,4 +35,6 @@ public:
     virtual bool updateLightning() = 0;
     FactoryCraftModel* zModel() const;
     int getType() const;
+    virtual bool isTransparent() const = 0;
+    virtual bool isPartOfModel(Block* zBlock) const = 0;
 };

+ 14 - 11
FactoryCraft/TransparentChunkGroundModel.cpp

@@ -104,11 +104,7 @@ void TransparentChunkGroundModel::buildModel()
     {
         if (blocks()[i])
         {
-            if (blocks()[i]
-                         ->zBlockType()
-                         ->getModelInfo()
-                         .getModelName()
-                         .istGleich("grass"))
+            if (isPartOfModel(blocks()[i]))
             {
                 setBlockPartOfModel(blocks()[i], 1);
                 __int64 light = blocks()[i]->getMaxLight();
@@ -211,11 +207,7 @@ bool TransparentChunkGroundModel::updateLightning()
     {
         if (blocks()[i])
         {
-            if (blocks()[i]
-                         ->zBlockType()
-                         ->getModelInfo()
-                         .getModelName()
-                         .istGleich("grass"))
+            if (isPartOfModel(blocks()[i]))
             {
                 __int64 light = blocks()[i]->getMaxLight();
                 int index = 0;
@@ -236,4 +228,15 @@ bool TransparentChunkGroundModel::updateLightning()
     }
     target->copyLightToGPU();
     return 1;
-}
+}
+
+bool TransparentChunkGroundModel::isTransparent() const
+{
+    return true;
+}
+
+bool TransparentChunkGroundModel::isPartOfModel(Block* zBlock) const
+{
+    return zBlock->zBlockType()->getModelInfo().getModelName().istGleich(
+        "grass");
+}

+ 2 - 0
FactoryCraft/TransparentChunkGroundModel.h

@@ -13,4 +13,6 @@ public:
     TransparentChunkGroundModel(FactoryCraftModel* target, Chunk* zChunk);
     void buildModel() override;
     bool updateLightning() override;
+    bool isTransparent() const override;
+    bool isPartOfModel(Block* zBlock) const override;
 };