/* * Triangle.cpp * * Copyright (C) 2008 Matthias Schiffer * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "Triangle.h" #include #include namespace ZoomEdit { namespace Data { vmml::vec3f Triangle::loadVector(xmlpp::Element *node) const { vmml::vec3f v; v.x() = std::atof(node->get_attribute_value("x").c_str()); v.y() = std::atof(node->get_attribute_value("y").c_str()); v.z() = std::atof(node->get_attribute_value("z").c_str()); return v; } TexCoords Triangle::loadTexCoords(xmlpp::Element *node) const { TexCoords t(1); xmlpp::Attribute *attr; t.setS(std::atof(node->get_attribute_value("s").c_str())); attr = node->get_attribute("t"); if(attr) { t.setT(std::atof(attr->get_value().c_str())); t.setCoordCount(2); } attr = node->get_attribute("r"); if(attr) { t.setR(std::atof(attr->get_value().c_str())); t.setCoordCount(3); } attr = node->get_attribute("q"); if(attr) { t.setQ(std::atof(attr->get_value().c_str())); t.setCoordCount(4); } return t; } Triangle::Triangle(xmlpp::Element *node) : triangleNode(node) { xmlpp::Node::NodeList nodeList = node->get_children(); int i = -1; std::memset(vertexNodes, 0, sizeof(vertexNodes)); for(xmlpp::Node::NodeList::iterator n = nodeList.begin(); n != nodeList.end(); ++n) { xmlpp::Element *e = dynamic_cast(*n); if(!e) continue; if(i >= 0) { if(e->get_name() == "normal") { normalNodes[i] = e; normals[i] = loadVector(e); continue; } else if(e->get_name() == "texcoords") { texCoordsNodes[i] = e; texCoords[i] = loadTexCoords(e); continue; } } if(e->get_name() == "vertex") { vertexNodes[++i] = e; vertices[i] = loadVector(e); normalNodes[i] = 0; texCoordsNodes[i] = 0; } } visible = (node->get_attribute_value("visible").lowercase() != "false"); texture = node->get_attribute_value("texture"); } void Triangle::setVertex(unsigned int i, const vmml::vec3f &v) { vertices[i] = v; vertexNodes[i]->set_attribute("x", Glib::ustring::format(v.x())); vertexNodes[i]->set_attribute("y", Glib::ustring::format(v.y())); vertexNodes[i]->set_attribute("z", Glib::ustring::format(v.z())); } void Triangle::setNormal(unsigned int i, const vmml::vec3f &n) { normals[i] = n; if(!normalNodes[i]) normalNodes[i] = triangleNode->add_child(vertexNodes[i], "normal"); normalNodes[i]->set_attribute("x", Glib::ustring::format(n.x())); normalNodes[i]->set_attribute("y", Glib::ustring::format(n.y())); normalNodes[i]->set_attribute("z", Glib::ustring::format(n.z())); } void Triangle::setTexCoords(unsigned int i, const TexCoords &t) { texCoords[i] = t; if(!texCoordsNodes[i]) { if(normalNodes[i]) texCoordsNodes[i] = triangleNode->add_child(normalNodes[i], "texcoords"); else texCoordsNodes[i] = triangleNode->add_child(vertexNodes[i], "texcoords"); } texCoordsNodes[i]->set_attribute("s", Glib::ustring::format(t.getS())); if(t.getCoordCount() >= 2) texCoordsNodes[i]->set_attribute("t", Glib::ustring::format(t.getT())); else texCoordsNodes[i]->remove_attribute("t"); if(t.getCoordCount() >= 3) texCoordsNodes[i]->set_attribute("r", Glib::ustring::format(t.getR())); else texCoordsNodes[i]->remove_attribute("r"); if(t.getCoordCount() >= 4) texCoordsNodes[i]->set_attribute("q", Glib::ustring::format(t.getQ())); else texCoordsNodes[i]->remove_attribute("q"); } } }