// // Created by Epagris on 2020. 03. 16.. // #include "Geometry.h" namespace eg3d { int ImportAdapters::IAD_Default(XMFLOAT3& vertex) { return 0; } int ImportAdapters::IAD_SwapYZ_RH(XMFLOAT3& vertex) { float y = vertex.y; vertex.y = vertex.z; vertex.z = -y; //vertex.x = vertex.x; return 0; } // ------------------- Geometry::Geometry(ComPtr device) : device(device) { // topológia beállítása setTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); } Geometry::Geometry(const Geometry &other) : device(other.device) { setTopology(other.getTopology()); setVertices(other.getVertices()); setIndices(other.getIndices()); } void Geometry::setVertices(const std::vector &vertices) { mVertices = vertices; size_t bufferSize = mVertices.size() * sizeof(Vertex); // buffer mérete mVertexBuffer.Reset(); // buffer törlése mVertexBuffer = createBuffer_UH(device, bufferSize); // buffer létrehozása bufferMapCopy(mVertexBuffer, (void *) mVertices.data(), bufferSize); // buffer feltöltése // vertex buffer view beállítása mVertexBufferView.BufferLocation = mVertexBuffer->GetGPUVirtualAddress(); mVertexBufferView.StrideInBytes = sizeof(Vertex); mVertexBufferView.SizeInBytes = bufferSize; } std::vector Geometry::getVertices() const { return mVertices; } void Geometry::setIndices(const std::vector &indices) { mIndices = indices; size_t bufferSize = mIndices.size() * sizeof(uint32_t); // buffer mérete mIndexBuffer.Reset(); // buffer törlése mIndexBuffer = createBuffer_UH(device, bufferSize); // buffer létrehozása bufferMapCopy(mIndexBuffer, (void *) mIndices.data(), bufferSize); // buffer feltöltése // index buffer view beállítása mIndexBufferView.Format = /*(sizeof(IT) == 2) ? DXGI_FORMAT_R16_UINT :*/ DXGI_FORMAT_R32_UINT; mIndexBufferView.BufferLocation = mIndexBuffer->GetGPUVirtualAddress(); mIndexBufferView.SizeInBytes = bufferSize; } std::vector Geometry::getIndices() const { return mIndices; } void Geometry::setTopology(D3D_PRIMITIVE_TOPOLOGY topology) { mTopology = topology; } D3D_PRIMITIVE_TOPOLOGY Geometry::getTopology() const { return mTopology; } void Geometry::setupInputAssembler(ComPtr commandList) const { commandList->IASetVertexBuffers(0, 1, &mVertexBufferView); commandList->IASetIndexBuffer(&mIndexBufferView); commandList->IASetPrimitiveTopology(mTopology); } void Geometry::draw(ComPtr commandList) const { setupInputAssembler(commandList); // input assembler beállítása commandList->DrawIndexedInstanced(mIndices.size(), 1, 0, 0, 0); // rajzolás } void Geometry::merge(const Geometry &other) { std::vector vertices = mVertices; vertices.insert(vertices.end(), other.mVertices.begin(), other.mVertices.end()); uint32_t offset = mIndices.size(); std::vector indices = mIndices; indices.insert(indices.end(), other.mIndices.begin(), other.mIndices.end()); // indexek megváltozatása offsettel for (uint32_t i = offset; i < indices.size(); i++) { indices[i] += offset; } // bufferek újrafoglalása a videokártyán setVertices(vertices); setIndices(indices); } Geometry &Geometry::operator+=(const Geometry &other) { merge(other); return *this; } void Geometry::loadBinarySTL(const std::string &fileName, ImportAdapter_fn * pIAD) { auto inFile = std::ifstream(fileName, std::ios::in | std::ios::binary); // bináris fájl megnyitása olvasásra if (!inFile.is_open()) { // megnézzük, hogy sikerült-e megnyitni a fájlt LOG("Failed to open file: '" + fileName + "'! STL geometry loading failed!"); return; } // vertexek és indexek std::vector vertices; std::vector indices; uint32_t triN; // háromszögek száma inFile.seekg(80, std::ios::beg); // fejléc átugrása inFile.read((char *) &triN, sizeof(triN)); // háromszögek számának kiolvasása LOG(std::to_string(sizeof(Vertex))); // vertexek kiolvasása for (uint32_t i = 0; i < triN; i++) { STLTriangle triangle; inFile.read(reinterpret_cast(&triangle), 50); // egy háromszög betöltése for (auto& stlVertex : triangle.vertices) { if (pIAD != nullptr) { pIAD(stlVertex); } // koordináták másolása Vertex vertex = stlVertex; // normálvektorok hozzárendelése TODO szebben! vertex.nx = triangle.normal.x; vertex.ny = triangle.normal.y; vertex.nz = triangle.normal.z; vertices.emplace_back(vertex); } // indexek vektorának feltöltése uint32_t firstIndex = 3 * i; indices.push_back(firstIndex); indices.push_back(firstIndex + 2); indices.push_back(firstIndex + 1); } inFile.close(); setVertices(vertices); setIndices(indices); LOG("Successful geometry loading from file '" + fileName + "' of " + std::to_string(triN) + " triangles."); } ComPtr Geometry::getDevice() const { return device; } }