diff --git a/radiantcore/model/StaticModelSurface.cpp b/radiantcore/model/StaticModelSurface.cpp index e2a5023324..a73023a706 100644 --- a/radiantcore/model/StaticModelSurface.cpp +++ b/radiantcore/model/StaticModelSurface.cpp @@ -13,53 +13,21 @@ namespace model { -// Constructor. Copy the provided picoSurface_t structure into this object -StaticModelSurface::StaticModelSurface(picoSurface_t* surf) -: _defaultMaterial(""), - _dlRegular(0), - _dlProgramVcol(0), - _dlProgramNoVCol(0) +StaticModelSurface::StaticModelSurface(std::vector&& vertices, std::vector&& indices) : + _vertices(vertices), + _indices(indices), + _dlRegular(0), + _dlProgramVcol(0), + _dlProgramNoVCol(0) { - // Capturing the shader happens later on when we have a RenderSystem reference - - // Get the number of vertices and indices, and reserve capacity in our - // vectors in advance by populating them with empty structs. - int nVerts = PicoGetSurfaceNumVertexes(surf); - _nIndices = PicoGetSurfaceNumIndexes(surf); - _vertices.resize(nVerts); - _indices.resize(_nIndices); - - // Stream in the vertex data from the raw struct, expanding the local AABB - // to include each vertex. - for (int vNum = 0; vNum < nVerts; ++vNum) { - - // Get the vertex position and colour - Vertex3f vertex(PicoGetSurfaceXYZ(surf, vNum)); - - Normal3f normal = PicoGetSurfaceNormal(surf, vNum); - - // Expand the AABB to include this new vertex - _localAABB.includePoint(vertex); - - _vertices[vNum].vertex = vertex; - _vertices[vNum].normal = normal; - _vertices[vNum].texcoord = TexCoord2f(PicoGetSurfaceST(surf, 0, vNum)); - _vertices[vNum].colour = - getColourVector(PicoGetSurfaceColor(surf, 0, vNum)); - } - - // Stream in the index data - picoIndex_t* ind = PicoGetSurfaceIndexes(surf, 0); - for (unsigned int i = 0; i < _nIndices; i++) + // Expand the local AABB to include all vertices + for (const auto& vertex : _vertices) { - _indices[i] = ind[i]; + _localAABB.includePoint(vertex.vertex); } - // Calculate the tangent and bitangent vectors - calculateTangents(); - - // Construct the DLs - createDisplayLists(); + calculateTangents(); + createDisplayLists(); } StaticModelSurface::StaticModelSurface(const StaticModelSurface& other) : @@ -83,19 +51,9 @@ StaticModelSurface::~StaticModelSurface() glDeleteLists(_dlProgramVcol, 1); } -// Convert byte pointers to colour vector -Vector3 StaticModelSurface::getColourVector(unsigned char* array) { - if (array) { - return Vector3(array[0] / 255.0f, array[1] / 255.0f, array[2] / 255.0f); - } - else { - return Vector3(1.0f, 1.0f, 1.0f); // white - } -} - // Tangent calculation -void StaticModelSurface::calculateTangents() { - +void StaticModelSurface::calculateTangents() +{ // Calculate the tangents and bitangents using the indices into the vertex // array. for (Indices::iterator i = _indices.begin(); diff --git a/radiantcore/model/StaticModelSurface.h b/radiantcore/model/StaticModelSurface.h index ace0cc9989..b32b3de49f 100644 --- a/radiantcore/model/StaticModelSurface.h +++ b/radiantcore/model/StaticModelSurface.h @@ -1,7 +1,6 @@ #pragma once #include "GLProgramAttributes.h" -#include "picomodel/lib/picomodel.h" #include "render.h" #include "math/AABB.h" @@ -31,6 +30,7 @@ class StaticModelSurface : public IIndexedModelSurface, public OpenGLRenderable { +private: // Name of the material this surface is using by default (without any skins) std::string _defaultMaterial; @@ -74,7 +74,8 @@ class StaticModelSurface : std::string cleanupShaderName(const std::string& mapName); public: - StaticModelSurface(picoSurface_t* surf); + // Move-construct this static model surface from the given vertex- and index array + StaticModelSurface(std::vector&& vertices, std::vector&& indices); // Copy-constructor. StaticModelSurface(const StaticModelSurface& other); diff --git a/radiantcore/model/import/AseModel.cpp b/radiantcore/model/import/AseModel.cpp index 54903c2f9d..f1e6478445 100644 --- a/radiantcore/model/import/AseModel.cpp +++ b/radiantcore/model/import/AseModel.cpp @@ -548,14 +548,12 @@ static void shadername_convert(char* shaderName) namespace model { -#if 0 -StaticModelSurface& AseModel::addSurface() +AseModel::Surface& AseModel::addSurface() { - return *_surfaces.emplace_back(std::make_shared()); + return _surfaces.emplace_back(); } -#endif -const std::vector& AseModel::getSurfaces() const +std::vector& AseModel::getSurfaces() { return _surfaces; } diff --git a/radiantcore/model/import/AseModel.h b/radiantcore/model/import/AseModel.h index e93b3cfc86..2e0d27fed9 100644 --- a/radiantcore/model/import/AseModel.h +++ b/radiantcore/model/import/AseModel.h @@ -8,13 +8,23 @@ namespace model class AseModel { +public: + struct Surface + { + std::string material; + + std::vector vertices; + std::vector indices; + }; + private: - std::vector _surfaces; + std::vector _surfaces; public: - StaticModelSurface& addSurface(); + Surface& addSurface(); - const std::vector& getSurfaces() const; + // Read/Write access + std::vector& getSurfaces(); static std::shared_ptr CreateFromStream(std::istream& stream); }; diff --git a/radiantcore/model/import/AseModelLoader.cpp b/radiantcore/model/import/AseModelLoader.cpp index c4e3dc37c2..445733b520 100644 --- a/radiantcore/model/import/AseModelLoader.cpp +++ b/radiantcore/model/import/AseModelLoader.cpp @@ -28,10 +28,23 @@ IModelPtr AseModelLoader::loadModelFromPath(const std::string& path) return IModelPtr(); } + // Parse the ASE model data from the given stream std::istream stream(&(file->getInputStream())); auto model = AseModel::CreateFromStream(stream); - auto staticModel = std::make_shared(model->getSurfaces()); + // Convert the AseModel to StaticModelSurfaces, destructing it during the process + std::vector staticSurfaces; + + for (auto& aseSurface : model->getSurfaces()) + { + // Move the vertex and index data to construct the StaticModelSurface + auto& staticSurface = staticSurfaces.emplace_back(std::make_shared( + std::move(aseSurface.vertices), std::move(aseSurface.indices))); + + staticSurface->setDefaultMaterial(aseSurface.material); + } + + auto staticModel = std::make_shared(staticSurfaces); // Set the filename staticModel->setFilename(os::getFilename(file->getName())); diff --git a/radiantcore/model/picomodel/PicoModelLoader.cpp b/radiantcore/model/picomodel/PicoModelLoader.cpp index 1746bbf201..94d6c9bd28 100644 --- a/radiantcore/model/picomodel/PicoModelLoader.cpp +++ b/radiantcore/model/picomodel/PicoModelLoader.cpp @@ -19,9 +19,21 @@ namespace model { namespace { - size_t picoInputStreamReam(void* inputStream, unsigned char* buffer, size_t length) { + size_t picoInputStreamReam(void* inputStream, unsigned char* buffer, size_t length) + { return reinterpret_cast(inputStream)->read(buffer, length); } + + // Convert byte pointers to colour vector + inline Vector3 getColourVector(unsigned char* array) + { + if (array) + { + return Vector3(array[0] / 255.0f, array[1] / 255.0f, array[2] / 255.0f); + } + + return Vector3(1.0f, 1.0f, 1.0f); // white + } } // namespace PicoModelLoader::PicoModelLoader(const picoModule_t* module, const std::string& extension) : @@ -197,8 +209,45 @@ StaticModelSurfacePtr PicoModelLoader::CreateSurface(picoSurface_t* picoSurface, // Fix the normals of the surface (?) PicoFixSurfaceNormals(picoSurface); - // Create the StaticModelSurface object and add it to the vector - auto staticSurface = std::make_shared(picoSurface); + // Convert the pico vertex data to the types we need to construct a StaticModelSurface + + // Get the number of vertices and indices, and reserve capacity in our + // vectors in advance by populating them with empty structs. + auto numVertices = PicoGetSurfaceNumVertexes(picoSurface); + unsigned int numIndices = PicoGetSurfaceNumIndexes(picoSurface); + + std::shared_ptr staticSurface; + + { + // Allocate the vectors that will be moved to the surface at end of scope + std::vector vertices(numVertices); + std::vector indices(numIndices); + + // Stream in the vertex data from the raw struct, expanding the local AABB + // to include each vertex. + for (int vNum = 0; vNum < numVertices; ++vNum) { + + // Get the vertex position and colour + Vertex3f vertex(PicoGetSurfaceXYZ(picoSurface, vNum)); + + Normal3f normal = PicoGetSurfaceNormal(picoSurface, vNum); + + vertices[vNum].vertex = vertex; + vertices[vNum].normal = normal; + vertices[vNum].texcoord = TexCoord2f(PicoGetSurfaceST(picoSurface, 0, vNum)); + vertices[vNum].colour = getColourVector(PicoGetSurfaceColor(picoSurface, 0, vNum)); + } + + // Stream in the index data + picoIndex_t* ind = PicoGetSurfaceIndexes(picoSurface, 0); + + for (unsigned int i = 0; i < numIndices; i++) + { + indices[i] = ind[i]; + } + + staticSurface = std::make_shared(std::move(vertices), std::move(indices)); + } staticSurface->setDefaultMaterial(DetermineDefaultMaterial(picoSurface, extension));