#include "DX12BLASModel.h" #include "DX12CommandQueue.h" #include "Model3D.h" Framework::DX12BLASModel::DX12BLASModel(Model3DData* zModelData, ID3D12Device5* zDevice, DX12DirectCommandQueue* zDirectQueue) : ReferenceCounter(), zModelData(zModelData), zDevice(zDevice), zDirectQueue(zDirectQueue), vertexBuffers(0), vertexDataBuffers(0), indexBuffers(0), polygonSizeBuffers(0), blasList(0) {} Framework::DX12BLASModel::~DX12BLASModel() { if (vertexBuffers) { vertexBuffers->release(); } if (vertexDataBuffers) { vertexDataBuffers->release(); } if (indexBuffers) { indexBuffers->release(); } if (polygonSizeBuffers) { polygonSizeBuffers->release(); } if (blasList) { blasList->release(); } } void Framework::DX12BLASModel::calculateBuffers() { if (!zModelData->wasIndexBufferChanged() && !zModelData->wasVertexBufferChanged()) { return; } zModelData->lock(); Skeleton* skeleton = zModelData->zSkeleton(); const Vertex3D* vertexBuffer = zModelData->zVertexBuffer(); const int* indexBuffer = zModelData->getIndexBuffer(); int vertexCount = zModelData->getVertexCount(); int indexCount = zModelData->getIndexCount(); int maxBoneId = skeleton ? skeleton->getNextBoneId() : 0; int** boneIndexMapping = new int*[maxBoneId + 1]; memset(boneIndexMapping, 0, sizeof(int*) * (maxBoneId + 1)); Vec3** boneVertexBuffers = new Vec3*[maxBoneId + 1]; memset(boneVertexBuffers, 0, sizeof(Vec3*) * (maxBoneId + 1)); int* boneVertexCount = new int[maxBoneId + 1]; memset(boneVertexCount, 0, sizeof(int) * (maxBoneId + 1)); int** boneIndexBuffers = new int*[maxBoneId + 1]; memset(boneIndexBuffers, 0, sizeof(int*) * (maxBoneId + 1)); int* boneIndexCount = new int[maxBoneId + 1]; memset(boneIndexCount, 0, sizeof(int) * (maxBoneId + 1)); DX2VertexData** boneVertexDatabuffers = new DX2VertexData*[maxBoneId + 1]; memset(boneVertexDatabuffers, 0, sizeof(DX2VertexData*) * (maxBoneId + 1)); int** bonePolygonSize = new int*[maxBoneId + 1]; memset(bonePolygonSize, 0, sizeof(int*) * (maxBoneId + 1)); ArrayIterator polygonIterator = zModelData->getPolygons(); int polygonSize = polygonIterator->indexAnz; int polygonIndex = 0; for (int i = 0; i < indexCount; i += 3) { // for each triangle int b1 = -1; int b2 = -1; for (int b = 0; b < 3; b++) { // for each bone of the model that is touched by the triangle int bone = vertexBuffer[indexBuffer[i + b]].knochenId; if (b1 != bone && b2 != bone) { // check if the bone is the same as the other two bones of the // triangle that were already processed if (b1 < 0) { b1 = bone; } else if (b2 < 0) { b2 = bone; } if (!boneIndexMapping[bone]) { boneIndexMapping[bone] = new int[vertexCount]; memset( boneIndexMapping[bone], -1, sizeof(int) * vertexCount); } if (!boneVertexBuffers[bone]) { boneVertexBuffers[bone] = new Vec3[vertexCount]; } if (!boneVertexDatabuffers[bone]) { boneVertexDatabuffers[bone] = new DX2VertexData[vertexCount]; } if (!boneIndexBuffers[bone]) { boneIndexBuffers[bone] = new int[indexCount]; } if (!bonePolygonSize[bone]) { bonePolygonSize[bone] = new int[zModelData->getPolygonCount()]; memset(bonePolygonSize[bone], 0, sizeof(int) * zModelData->getPolygonCount()); } for (int j = 0; j < 3; j++) { // add the vertecies and indices of the triangle to the // buffers of the bone if (boneIndexMapping[bone][indexBuffer[i + j]] < 0) { boneIndexMapping[bone][indexBuffer[i + j]] = boneVertexCount[bone]; boneVertexBuffers[bone][boneVertexCount[bone]] = vertexBuffer[indexBuffer[i + j]].pos; boneVertexDatabuffers[bone][boneVertexCount[bone]] .texcoord = vertexBuffer[indexBuffer[i + j]].tPos; boneVertexDatabuffers[bone][boneVertexCount[bone]] .normal = vertexBuffer[indexBuffer[i + j]].normal; boneVertexCount[bone]++; } boneIndexBuffers[bone][boneIndexCount[bone]] = boneIndexMapping[bone][indexBuffer[i + j]]; boneIndexCount[bone]++; } bonePolygonSize[bone][polygonIndex]++; } } polygonSize -= 3; if (polygonSize <= 0) { polygonIndex++; polygonIterator++; if (polygonIterator) { polygonSize = polygonIterator->indexAnz; } } } zModelData->setIndexBufferChanged(0); zModelData->setVertexBufferChanged(0); if (!vertexBuffers) { vertexBuffers = new RCArray(); } if (!vertexDataBuffers) { vertexDataBuffers = new RCArray(); } if (!indexBuffers) { indexBuffers = new RCArray(); } if (!polygonSizeBuffers) { polygonSizeBuffers = new RCArray(); } if (!blasList) { blasList = new RCArray(); } vertexBuffers->clear(); vertexDataBuffers->clear(); indexBuffers->clear(); polygonSizeBuffers->clear(); blasList->clear(); boneIds.clear(); for (int i = 0; i <= maxBoneId; i++) { if (boneVertexCount[i] > 0 && boneIndexCount[i] > 0) { DX12Buffer* vertexBuffer = new DX12Buffer(sizeof(Vec3), zDevice, dynamic_cast(zDirectQueue->getThis()), 0); vertexBuffer->setData(boneVertexBuffers[i], true); vertexBuffer->setLength(boneVertexCount[i] * sizeof(Vec3)); vertexBuffer->copyToGPU(); vertexBuffers->add(vertexBuffer); DX12Buffer* vertexDataBuffer = new DX12Buffer(sizeof(DX2VertexData), zDevice, dynamic_cast(zDirectQueue->getThis()), 0); vertexDataBuffer->setData(boneVertexDatabuffers[i], true); vertexDataBuffer->setLength( boneVertexCount[i] * sizeof(DX2VertexData)); vertexDataBuffer->copyToGPU(); vertexDataBuffers->add(vertexDataBuffer); DX12Buffer* indexBuffer = new DX12Buffer(sizeof(int), zDevice, dynamic_cast(zDirectQueue->getThis()), 0); indexBuffer->setData(boneIndexBuffers[i], true); indexBuffer->setLength(boneIndexCount[i] * sizeof(int)); indexBuffer->copyToGPU(); indexBuffers->add(indexBuffer); DX12Buffer* polygonSizeBuffer = new DX12Buffer(sizeof(int), zDevice, dynamic_cast(zDirectQueue->getThis()), 0); polygonSizeBuffer->setData(bonePolygonSize[i], true); polygonSizeBuffer->setLength( zModelData->getPolygonCount() * sizeof(int)); polygonSizeBuffer->copyToGPU(); polygonSizeBuffers->add(polygonSizeBuffer); DX12BLAS* blas = new DX12BLAS(zDevice, zDirectQueue); blas->build(vertexBuffer, dynamic_cast(vertexDataBuffer->getThis()), dynamic_cast(indexBuffer->getThis()), dynamic_cast(polygonSizeBuffer->getThis())); blasList->add(blas); boneIds.add(i); } delete[] boneIndexMapping[i]; delete[] boneVertexBuffers[i]; delete[] boneIndexBuffers[i]; delete[] boneVertexDatabuffers[i]; delete[] bonePolygonSize[i]; } delete[] boneIndexMapping; delete[] boneVertexBuffers; delete[] boneVertexCount; delete[] boneIndexBuffers; delete[] boneIndexCount; delete[] boneVertexDatabuffers; delete[] bonePolygonSize; zModelData->unlock(); } int Framework::DX12BLASModel::getBufferCount() const { return vertexBuffers ? vertexBuffers->getEntryCount() : 0; } const Framework::RCArray* Framework::DX12BLASModel::zBLAS() const { return blasList; } const Framework::Array* Framework::DX12BLASModel::zBoneIds() const { return &boneIds; }