diff --git a/src/coders/vcm.cpp b/src/coders/vcm.cpp index b7d93b578..c797d8566 100644 --- a/src/coders/vcm.cpp +++ b/src/coders/vcm.cpp @@ -71,6 +71,39 @@ static void perform_rect(const xmlelement& root, model::Model& model) { ); } +static void perform_triangle(const xmlelement& root, model::Model& model) { + auto pointA = root.attr("a").asVec3(); + auto pointB = root.attr("b").asVec3(); + auto pointC = root.attr("c").asVec3(); + + float uvs[6] {0, 0, 1, 0, 1, 1}; + + bool shading = true; + if (root.has("shading")) { + shading = to_boolean(root.attr("shading")); + } + if (root.has("uv")) { + root.attr("uv").asNumbers(uvs, sizeof(uvs) / sizeof(float)); + } + + glm::vec3 ba = pointB - pointA; + glm::vec3 ca = pointC - pointA; + glm::vec3 normal = glm::normalize(glm::cross(ba, ca)); + + std::string texture = root.attr("texture", "$0").getText(); + auto& mesh = model.addMesh(texture, shading); + + mesh.addTriangle( + pointA, + pointB, + pointC, + normal, + {uvs[0], uvs[1]}, + {uvs[2], uvs[3]}, + {uvs[4], uvs[5]} + ); +} + static void perform_box(const xmlelement& root, model::Model& model) { auto from = root.attr("from").asVec3(); auto to = root.attr("to").asVec3(); @@ -181,6 +214,8 @@ static std::unique_ptr load_model(const xmlelement& root) { perform_rect(*elem, model); } else if (tag == "box") { perform_box(*elem, model); + } else if (tag == "tri") { + perform_triangle(*elem, model); } } diff --git a/src/coders/xml.cpp b/src/coders/xml.cpp index 0763fa430..4efabc959 100644 --- a/src/coders/xml.cpp +++ b/src/coders/xml.cpp @@ -105,6 +105,19 @@ glm::vec4 Attribute::asColor() const { } } +int Attribute::asNumbers(float* dst, size_t dstSize) const { + size_t pos = 0; + size_t count = 0; + while (pos < text.length() && count < dstSize) { + size_t end = text.find(',', pos); + dst[count++] = util::parse_double( + text, pos, std::min(end - pos, text.length() - pos) + ); + pos = end + 1; + } + return count; +} + Node::Node(std::string tag) : tag(std::move(tag)) { } diff --git a/src/coders/xml.hpp b/src/coders/xml.hpp index 24cf0fbdc..4954caa17 100644 --- a/src/coders/xml.hpp +++ b/src/coders/xml.hpp @@ -29,6 +29,7 @@ namespace xml { glm::vec3 asVec3() const; glm::vec4 asVec4() const; glm::vec4 asColor() const; + int asNumbers(float* dst, size_t dstSize) const; }; /// @brief XML element class. Text element has tag 'text' and attribute diff --git a/src/graphics/commons/Model.cpp b/src/graphics/commons/Model.cpp index 386ae1cce..e7c247868 100644 --- a/src/graphics/commons/Model.cpp +++ b/src/graphics/commons/Model.cpp @@ -41,6 +41,20 @@ void Mesh::addPlane( ); } +void Mesh::addTriangle( + const glm::vec3& a, + const glm::vec3& b, + const glm::vec3& c, + const glm::vec3& norm, + const glm::vec2& uvA, + const glm::vec2& uvB, + const glm::vec2& uvC +) { + vertices.push_back({a, uvA, norm}); + vertices.push_back({b, uvB, norm}); + vertices.push_back({c, uvC, norm}); +} + void Mesh::addRect( const glm::vec3& pos, const glm::vec3& right, diff --git a/src/graphics/commons/Model.hpp b/src/graphics/commons/Model.hpp index bbb0d398f..67618ed38 100644 --- a/src/graphics/commons/Model.hpp +++ b/src/graphics/commons/Model.hpp @@ -39,6 +39,15 @@ namespace model { const glm::vec3& up, const glm::vec3& norm, const UVRegion& region + ); + void addTriangle( + const glm::vec3& a, + const glm::vec3& b, + const glm::vec3& c, + const glm::vec3& norm, + const glm::vec2& uvA, + const glm::vec2& uvB, + const glm::vec2& uvC ); void addBox(const glm::vec3& pos, const glm::vec3& size); void addBox(