123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- #include "ChunkFluidModel.h"
- #include <Trie.h>
- #include "Area.h"
- #include "Block.h"
- #include "Constants.h"
- #include "FactoryCraftModel.h"
- #include "Globals.h"
- ChunkFluidModel::ChunkFluidModel(FactoryCraftModel* target, Chunk* zChunk)
- : ChunkModelBuilder(target, zChunk, Chunk::CombinedModels::FLUID)
- {}
- __int64 ChunkFluidModel::calculateLight(Framework::Vec3<float> vertexPos,
- Framework::Vec3<int> blockPos,
- Direction direction)
- {
- __int64 result = 0;
- int sumCount = 1;
- short lightSum[6];
- Block* current = blocks()[Chunk::index(blockPos)];
- const unsigned char* light = current->getLightData(direction);
- for (int i = 0; i < 6; i++)
- {
- lightSum[i] = (short)light[i];
- }
- Vec3<int> vertexDirs(vertexPos.x < 0 ? -1 : 1,
- vertexPos.y < 0 ? -1 : 1,
- vertexPos.z < 0 ? -1 : 1);
- Directions dirs = getDirectionsFromVector(vertexDirs) & ~direction;
- Vec3<int> neighborDirs[3];
- int neighborIndex = 0;
- for (int i = 0; i < 6; i++)
- {
- Direction dir = getDirectionFromIndex(i);
- if ((dirs | dir) == dirs)
- {
- neighborDirs[neighborIndex++] = getDirection(dir);
- if (neighborIndex == 2) break;
- }
- }
- neighborDirs[2] = neighborDirs[0] + neighborDirs[1];
- for (int i = 0; i < 3; i++)
- {
- neighborDirs[i] += blockPos;
- if (neighborDirs[i].x >= 0 && neighborDirs[i].y >= 0
- && neighborDirs[i].z >= 0 && neighborDirs[i].x < CHUNK_SIZE
- && neighborDirs[i].y < CHUNK_SIZE
- && neighborDirs[i].z < WORLD_HEIGHT)
- {
- int neighborIndex = Chunk::index(neighborDirs[i]);
- Block* neighbor = blocks()[neighborIndex];
- if (neighbor)
- {
- const unsigned char* neighborLight
- = neighbor->getLightData(direction);
- if ((neighborLight[0] | neighborLight[1] | neighborLight[2]
- | neighborLight[3] | neighborLight[4]
- | neighborLight[5])
- != 0)
- {
- sumCount++;
- for (int j = 0; j < 6; j++)
- {
- lightSum[j] += (short)neighborLight[j];
- }
- }
- }
- }
- else
- { // TODO: get light from neighbor chunk
- }
- }
- for (int i = 0; i < 6; i++)
- {
- lightSum[i] = (lightSum[i] / sumCount) & 0xFF;
- }
- result = ((__int64)lightSum[0] << 24) | ((__int64)lightSum[1] << 16)
- | ((__int64)lightSum[2] << 8) | ((__int64)lightSum[3] << 56)
- | ((__int64)lightSum[4] << 48) | ((__int64)lightSum[5] << 40);
- return result;
- }
- bool ChunkFluidModel::isPartOfGroundModel(
- Framework::Vec3<int> location, int directionIndex)
- {
- Framework::Vec3<int> neighborLocation
- = location + getDirection(getDirectionFromIndex(directionIndex));
- bool needed = 0;
- if (neighborLocation.x < 0 || neighborLocation.y < 0
- || neighborLocation.z < 0 || neighborLocation.x >= CHUNK_SIZE
- || neighborLocation.y >= CHUNK_SIZE
- || neighborLocation.z >= WORLD_HEIGHT)
- {
- needed = 1;
- }
- else
- {
- int naighborIndex = Chunk::index(neighborLocation);
- int currIndex = Chunk::index(location);
- if (!blocks()[naighborIndex] || !isPartOfModel(blocks()[naighborIndex])
- || blocks()[currIndex]->zBlockType()
- != blocks()[naighborIndex]->zBlockType()
- || blocks()[naighborIndex]->getDistanceToSource()
- > blocks()[currIndex]->getDistanceToSource())
- {
- needed = 1;
- }
- }
- return needed;
- }
- void ChunkFluidModel::buildModel()
- {
- Model3DData* chunkModel = target->zModelData();
- // remove old model
- while (chunkModel->getPolygonAnzahl() > 0)
- {
- chunkModel->removePolygon(0);
- }
- // calculate verticies
- Trie<GroundModelPart*> groundModelBuidler;
- Array<GroundModelPart*> groundPartArray;
- Vertex3D* groundVerticies = new Vertex3D[10000];
- __int64* lightBuffer = new __int64[10000];
- int groundVertexCount = 0;
- int groundVertexArraySize = 10000;
- for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++)
- {
- if (blocks()[i])
- {
- if (isPartOfModel(blocks()[i]))
- {
- setBlockPartOfModel(blocks()[i], 1);
- int index = 0;
- for (Text* textureName :
- *blocks()[i]->zBlockType()->getModelInfo().getTexturNames())
- {
- Framework::Vec3<int> location(
- (i / WORLD_HEIGHT) / CHUNK_SIZE,
- (i / WORLD_HEIGHT) % CHUNK_SIZE,
- i % WORLD_HEIGHT);
- Framework::Vec3<int> aboveLocation
- = location
- + getDirection(Direction::TOP);
- int aboveIndex = Chunk::index(aboveLocation);
- bool sameAbove = aboveLocation.z < WORLD_HEIGHT
- && blocks()[aboveIndex]
- && blocks()[aboveIndex]->zBlockType()
- == blocks()[i]->zBlockType();
- if (isPartOfGroundModel(location, index))
- {
- if (!groundModelBuidler.get(
- *textureName, textureName->getLength()))
- {
- GroundModelPart* part = new GroundModelPart();
- part->indexList = new int[10000];
- part->indexCount = 0;
- part->indexArraySize = 10000;
- part->name = *textureName;
- groundModelBuidler.set(
- *textureName, textureName->getLength(), part);
- groundPartArray.add(part);
- }
- GroundModelPart* part = groundModelBuidler.get(
- *textureName, textureName->getLength());
- const Vertex3D* vBuffer
- = blocks()[i]->zModelData()->zVertexBuffer();
- Polygon3D* polygon
- = blocks()[i]->zModelData()->getPolygon(index);
- if (part->indexCount + polygon->indexAnz
- > part->indexArraySize)
- {
- int* tmp = new int[part->indexArraySize + 10000];
- memcpy(tmp, part->indexList, part->indexCount * 4);
- delete[] part->indexList;
- part->indexList = tmp;
- part->indexArraySize += 10000;
- }
- if (groundVertexCount + polygon->indexAnz
- > groundVertexArraySize)
- {
- Vertex3D* tmp
- = new Vertex3D[groundVertexArraySize + 10000];
- memcpy(tmp,
- groundVerticies,
- groundVertexCount * sizeof(Vertex3D));
- delete[] groundVerticies;
- groundVerticies = tmp;
- groundVertexArraySize += 10000;
- __int64* lTmp = new __int64[groundVertexArraySize];
- memcpy(lTmp,
- lightBuffer,
- groundVertexCount * sizeof(__int64));
- delete[] lightBuffer;
- lightBuffer = lTmp;
- }
- for (int vi = 0; vi < polygon->indexAnz; vi++)
- {
- lightBuffer[groundVertexCount] = calculateLight(
- vBuffer[polygon->indexList[vi]].pos,
- location,
- getDirectionFromIndex(index));
- part->indexList[part->indexCount++]
- = groundVertexCount;
- groundVerticies[groundVertexCount++]
- = vBuffer[polygon->indexList[vi]];
- if (groundVerticies[groundVertexCount - 1].pos.z > 0
- && !sameAbove)
- {
- char maxFlowDist = blocks()[i]
- ->zBlockType()
- ->getMaxFlowDistance();
- float dist = (float)(maxFlowDist + 1 - blocks()[i]
- ->getDistanceToSource()) / (float)(maxFlowDist + 1);
- groundVerticies[groundVertexCount - 1].pos.z
- -= (1 - dist);
- }
- groundVerticies[groundVertexCount - 1].pos
- += blocks()[i]->getPos()
- - Vec3<float>((float)chunkCenter().x,
- (float)chunkCenter().y,
- (float)WORLD_HEIGHT / 2.f);
- groundVerticies[groundVertexCount - 1].id
- = groundVertexCount - 1;
- }
- }
- index++;
- }
- }
- else
- {
- setBlockPartOfModel(blocks()[i], 0);
- }
- }
- }
- Model3DTextur* textur = new Model3DTextur();
- int pi = 0;
- for (GroundModelPart* part : groundPartArray)
- {
- Polygon3D* polygon = new Polygon3D();
- polygon->indexAnz = part->indexCount;
- polygon->indexList = part->indexList;
- target->zModelData()->addPolygon(polygon);
- textur->setPolygonTextur(pi,
- uiFactory.initParam.bildschirm->zGraphicsApi()->createOrGetTextur(
- part->name));
- pi++;
- delete part;
- }
- target->zModelData()->setVertecies(groundVerticies, groundVertexCount);
- target->setModelTextur(textur);
- target->setVertexLightBuffer(lightBuffer, groundVertexCount);
- }
- bool ChunkFluidModel::updateLightning()
- {
- __int64* lightBuffer = target->zLightBuffer();
- int oldVertexCount = target->getVertexAnzahl();
- int groundVertexCount = 0;
- for (int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++)
- {
- if (blocks()[i]
- && isPartOfModel(blocks()[i]))
- {
- int index = 0;
- for (Text* textureName :
- *blocks()[i]->zBlockType()->getModelInfo().getTexturNames())
- {
- Framework::Vec3<int> location(
- (i / WORLD_HEIGHT) / CHUNK_SIZE,
- (i / WORLD_HEIGHT) % CHUNK_SIZE,
- i % WORLD_HEIGHT);
- if (isPartOfGroundModel(location, index))
- {
- const Vertex3D* vBuffer
- = blocks()[i]->zModelData()->zVertexBuffer();
- Polygon3D* polygon
- = blocks()[i]->zModelData()->getPolygon(index);
- for (int vi = 0; vi < polygon->indexAnz; vi++)
- {
- if (oldVertexCount <= groundVertexCount)
- {
- std::cout << "ERROR: to many vertecies in chunk fluid model" << std::endl;
- return 0;
- }
- lightBuffer[groundVertexCount++] = calculateLight(
- vBuffer[polygon->indexList[vi]].pos,
- location,
- getDirectionFromIndex(index));
- }
- }
- index++;
- }
- }
- }
- target->copyLightToGPU();
- return 1;
- }
- bool ChunkFluidModel::isTransparent() const
- {
- return true;
- }
- bool ChunkFluidModel::isPartOfModel(Block* zBlock) const
- {
- return zBlock->zBlockType()->isFluid();
- }
|