#include "GL_IndexedFaceSet.h" #include "X3D_IndexedFaceSet.h" #include "X3D_Normal.h" #include "X3D_Coordinate.h" #include "X3D_TextureCoordinate.h" #include "X3D_Color.h" #include "X3D_ColorRGBA.h" #include using namespace std; namespace X3DTK { namespace GL { typedef struct { SFInt32 face; unsigned short position; } faceposition; typedef struct { list faceList; SFVec3f normal; } partnormal; IndexedFaceSet::IndexedFaceSet() : X3DComposedGeometryNode() { define(Recorder::getTypeName("IndexedFaceSet", "Geometry3D")); } IndexedFaceSet::~IndexedFaceSet() { } void IndexedFaceSet::setN3F_V3F_vertexArray(const std::vector &N3F_V3F_vertexArray) { _N3F_V3F_vertexArray = N3F_V3F_vertexArray; } void IndexedFaceSet::setC4F_N3F_V3F_vertexArray(const std::vector &C4F_N3F_V3F_vertexArray) { _C4F_N3F_V3F_vertexArray = C4F_N3F_V3F_vertexArray; } void IndexedFaceSet::setT2F_N3F_V3F_vertexArray(const std::vector &T2F_N3F_V3F_vertexArray) { _T2F_N3F_V3F_vertexArray = T2F_N3F_V3F_vertexArray; } void IndexedFaceSet::setT2F_C4F_N3F_V3F_vertexArray(const std::vector &T2F_C4F_N3F_V3F_vertexArray) { _T2F_C4F_N3F_V3F_vertexArray = T2F_C4F_N3F_V3F_vertexArray; } void IndexedFaceSet::setIndexArray(const MFInt32 &indexArray) { _indexArray = indexArray; } void IndexedFaceSet::computeNormals() { switch (getVertexFormat()) { case GL_N3F_V3F: computeNoColorNoTexCoordNormals(); break; case GL_C4F_N3F_V3F: computeColorNoTexCoordNormals(); break; case GL_T2F_N3F_V3F: computeNoColorTexCoordNormals(); break; case GL_T2F_C4F_N3F_V3F: computeColorTexCoordNormals(); break; } } void IndexedFaceSet::update() { if (x3dReference == 0) return; X3D::IndexedFaceSet *I = static_cast(x3dReference); //for the moment if the node color has changed, all the attributes are computed //emptying the arrays emptyArrays(); X3D::Coordinate *CoordNode = static_cast(I->getCoord()); if (CoordNode == 0) return; const MFVec3f &vertexArray = CoordNode->getPoint(); const MFInt32 &coordIndex = I->getCoordIndex(); //IndexedFaceSet attributes if (coordIndex.empty()) return; setSolid(I->getSolid()); setCcw(I->getCcw()); setNormalPerVertex(I->getNormalPerVertex()); MFVec3f array; MFVec3f &normalArray = array; X3D::Normal *NormalNode = dynamic_cast(I->getNormal()); if (NormalNode != 0) normalArray = NormalNode->getVector(); //in the other case, normalArray remains empty, that is the test to know whether the //normals have to be assigned or not. if ((dynamic_cast(I->getColor()) != 0) && (I->getTexCoord() != 0)) { setColor(true); setTexCoord(true); setVertexFormat(GL_T2F_C4F_N3F_V3F); computeColorRGBATexCoord(vertexArray, normalArray, coordIndex); } if ((dynamic_cast(I->getColor()) != 0) && (I->getTexCoord() != 0)) { setColor(true); setTexCoord(true); setVertexFormat(GL_T2F_C4F_N3F_V3F); computeColorTexCoord(vertexArray, normalArray, coordIndex); } if ((dynamic_cast(I->getColor()) != 0) && (I->getTexCoord() == 0)) { setColor(true); setTexCoord(false); setVertexFormat(GL_C4F_N3F_V3F); computeColorRGBANoTexCoord(vertexArray, normalArray, coordIndex); } if ((dynamic_cast(I->getColor()) != 0) && (I->getTexCoord() == 0)) { setColor(true); setTexCoord(false); setVertexFormat(GL_C4F_N3F_V3F); computeColorNoTexCoord(vertexArray, normalArray, coordIndex); } if ((I->getColor() == 0) && (I->getTexCoord() != 0)) { setColor(false); setTexCoord(true); setVertexFormat(GL_T2F_N3F_V3F); computeNoColorTexCoord(vertexArray, normalArray, coordIndex); } if ((I->getColor() == 0) && (I->getTexCoord() == 0)) { setColor(false); setTexCoord(false); setVertexFormat(GL_N3F_V3F); computeNoColorNoTexCoord(vertexArray, normalArray, coordIndex); } } void IndexedFaceSet::draw() const { if (getSolid()) { glEnable(GL_CULL_FACE); if (getCcw()) glFrontFace(GL_CCW); else glFrontFace(GL_CW); glCullFace(GL_BACK); } if (getVertexFormat() == GL_N3F_V3F) { glInterleavedArrays(GL_N3F_V3F, 0, &_N3F_V3F_vertexArray.front()); glDrawElements(GL_TRIANGLES, _indexArray.size(), GL_UNSIGNED_INT, &_indexArray.front()); } if (getVertexFormat() == GL_C4F_N3F_V3F) { glEnable(GL_COLOR_MATERIAL); glInterleavedArrays(GL_C4F_N3F_V3F, 0, &_C4F_N3F_V3F_vertexArray.front()); glDrawElements(GL_TRIANGLES, _indexArray.size(), GL_UNSIGNED_INT, &_indexArray.front()); glDisable(GL_COLOR_MATERIAL); } if (getVertexFormat() == GL_T2F_N3F_V3F) { glEnable(GL_TEXTURE_2D); glInterleavedArrays(GL_T2F_N3F_V3F, 0, &_T2F_N3F_V3F_vertexArray.front()); glDrawElements(GL_TRIANGLES, _indexArray.size(), GL_UNSIGNED_INT, &_indexArray.front()); glDisable(GL_TEXTURE_2D); } if (getVertexFormat() == GL_T2F_C4F_N3F_V3F) { glEnable(GL_TEXTURE_2D); glEnable(GL_COLOR_MATERIAL); glInterleavedArrays(GL_T2F_C4F_N3F_V3F, 0, &_T2F_C4F_N3F_V3F_vertexArray.front()); glDrawElements(GL_TRIANGLES, _indexArray.size(), GL_UNSIGNED_INT, &_indexArray.front()); glDisable(GL_COLOR_MATERIAL); glDisable(GL_TEXTURE_2D); } if (getSolid()) glDisable(GL_CULL_FACE); } void IndexedFaceSet::emptyArrays() { _N3F_V3F_vertexArray.clear(); _C4F_N3F_V3F_vertexArray.clear(); _T2F_N3F_V3F_vertexArray.clear(); _T2F_C4F_N3F_V3F_vertexArray.clear(); _indexArray.clear(); _X3DtoGLIndex.clear(); } void IndexedFaceSet::computeNoColorNoTexCoord(const MFVec3f &vertexArray, const MFVec3f &normalArray, const MFInt32 &coordIndex) { _X3DtoGLIndex.resize(vertexArray.size()); X3D::IndexedFaceSet *I = static_cast(x3dReference); ////////////////// arrays ////////////////////////////////////////////////////////// bool hasNormal = !normalArray.empty(); ////////////////// indexes ///////////////////////////////////////////////////////// MFInt32 normalIndex; normalIndex = I->getNormalIndex(); bool hasNormalIndex = !normalIndex.empty(); ////////////////// iterators /////////////////////////////////////////////////////// MFInt32::const_iterator itCoordIndex = coordIndex.begin(); MFInt32::const_iterator itNormalIndex; unsigned int itFaceIndex = 0; if (hasNormalIndex) itNormalIndex = normalIndex.begin(); else itNormalIndex = coordIndex.begin(); ////////////////// loop //////////////////////////////////////////////////////////// SFBool normalPerVertex = I->getNormalPerVertex(); while (itCoordIndex != coordIndex.end()) { list > N3F_V3F_face; while ((*itCoordIndex != -1) && (itCoordIndex != coordIndex.end())) { N3F_V3F element; element.vertex = vertexArray[*itCoordIndex]; if (hasNormal) if (normalPerVertex) element.normal = normalArray[*itNormalIndex]; else element.normal = normalArray[(hasNormalIndex ? *itNormalIndex : itFaceIndex)]; N3F_V3F_face.push_back(pair(*itCoordIndex, element)); ++itCoordIndex; if (normalPerVertex) ++itNormalIndex; } ++itCoordIndex; ++itNormalIndex; ++itFaceIndex; // processing the face. tesselateNoColorNoTexCoord(N3F_V3F_face); for (list >::const_iterator itPair = _N3F_V3F_tesselatedFace.begin(); itPair != _N3F_V3F_tesselatedFace.end(); ++itPair) { bool found = false; MFInt32 &indexList = _X3DtoGLIndex[(*itPair).first]; for (MFInt32::const_iterator itIndex = indexList.begin(); itIndex != indexList.end(); ++itIndex) { N3F_V3F element = _N3F_V3F_vertexArray[*itIndex]; if (element == (*itPair).second) { _indexArray.push_back(*itIndex); found = true; break; } } if (!found) { _indexArray.push_back(_N3F_V3F_vertexArray.size()); indexList.push_back(_N3F_V3F_vertexArray.size()); _N3F_V3F_vertexArray.push_back((*itPair).second); } } } if (!hasNormal) computeNoColorNoTexCoordNormals(); } void IndexedFaceSet::computeColorRGBANoTexCoord(const MFVec3f &vertexArray, const MFVec3f &normalArray, const MFInt32 &coordIndex) { _X3DtoGLIndex.resize(vertexArray.size()); X3D::IndexedFaceSet *I = static_cast(x3dReference); ////////////////// arrays ////////////////////////////////////////////////////////// const MFColorRGBA &colorArray = static_cast(I->getColor())->getColor(); bool hasNormal = !normalArray.empty(); bool hasColor = !colorArray.empty(); ////////////////// indexes ///////////////////////////////////////////////////////// MFInt32 normalIndex; MFInt32 colorIndex; normalIndex = I->getNormalIndex(); colorIndex = I->getColorIndex(); bool hasNormalIndex = !normalIndex.empty(); bool hasColorIndex = !colorIndex.empty(); ////////////////// iterators /////////////////////////////////////////////////////// MFInt32::const_iterator itCoordIndex = coordIndex.begin(); MFInt32::const_iterator itNormalIndex; MFInt32::const_iterator itColorIndex; unsigned int itFaceIndex = 0; if (hasNormalIndex) itNormalIndex = normalIndex.begin(); else itNormalIndex = coordIndex.begin(); if (hasColorIndex) itColorIndex = colorIndex.begin(); else itColorIndex = coordIndex.begin(); ////////////////// loop //////////////////////////////////////////////////////////// SFBool normalPerVertex = I->getNormalPerVertex(); SFBool colorPerVertex = I->getColorPerVertex(); while (itCoordIndex != coordIndex.end()) { list > C4F_N3F_V3F_face; while ((*itCoordIndex != -1) && (itCoordIndex != coordIndex.end())) { C4F_N3F_V3F element; element.vertex = vertexArray[*itCoordIndex]; if (hasNormal) if (normalPerVertex) element.normal = normalArray[*itNormalIndex]; else element.normal = normalArray[(hasNormalIndex ? *itNormalIndex : itFaceIndex)]; if (hasColor) if (colorPerVertex) element.color = colorArray[*itColorIndex]; else element.color = colorArray[(hasColorIndex ? *itColorIndex : itFaceIndex)]; C4F_N3F_V3F_face.push_back(pair(*itCoordIndex, element)); ++itCoordIndex; if (normalPerVertex) ++itNormalIndex; if (colorPerVertex) ++itColorIndex; } ++itCoordIndex; ++itNormalIndex; ++itColorIndex; ++itFaceIndex; // processing the face. tesselateColorNoTexCoord(C4F_N3F_V3F_face); for (list >::const_iterator itPair = _C4F_N3F_V3F_tesselatedFace.begin(); itPair != _C4F_N3F_V3F_tesselatedFace.end(); ++itPair) { bool found = false; MFInt32 &indexList = _X3DtoGLIndex[(*itPair).first]; for (MFInt32::const_iterator itIndex = indexList.begin(); itIndex != indexList.end(); ++itIndex) { C4F_N3F_V3F element = _C4F_N3F_V3F_vertexArray[*itIndex]; if (element == (*itPair).second) { _indexArray.push_back(*itIndex); found = true; break; } } if (!found) { _indexArray.push_back(_C4F_N3F_V3F_vertexArray.size()); indexList.push_back(_C4F_N3F_V3F_vertexArray.size()); _C4F_N3F_V3F_vertexArray.push_back((*itPair).second); } } } if (!hasNormal) computeColorNoTexCoordNormals(); } void IndexedFaceSet::computeColorNoTexCoord(const MFVec3f &vertexArray, const MFVec3f &normalArray, const MFInt32 &coordIndex) { _X3DtoGLIndex.resize(vertexArray.size()); X3D::IndexedFaceSet *I = static_cast(x3dReference); ////////////////// arrays ////////////////////////////////////////////////////////// const MFColor &colorArray = static_cast(I->getColor())->getColor(); bool hasNormal = !normalArray.empty(); bool hasColor = !colorArray.empty(); ////////////////// indexes ///////////////////////////////////////////////////////// MFInt32 normalIndex; MFInt32 colorIndex; normalIndex = I->getNormalIndex(); colorIndex = I->getColorIndex(); bool hasNormalIndex = !normalIndex.empty(); bool hasColorIndex = !colorIndex.empty(); ////////////////// iterators /////////////////////////////////////////////////////// MFInt32::const_iterator itCoordIndex = coordIndex.begin(); MFInt32::const_iterator itNormalIndex; MFInt32::const_iterator itColorIndex; unsigned int itFaceIndex = 0; if (hasNormalIndex) itNormalIndex = normalIndex.begin(); else itNormalIndex = coordIndex.begin(); if (hasColorIndex) itColorIndex = colorIndex.begin(); else itColorIndex = coordIndex.begin(); ////////////////// loop //////////////////////////////////////////////////////////// SFBool normalPerVertex = I->getNormalPerVertex(); SFBool colorPerVertex = I->getColorPerVertex(); while (itCoordIndex != coordIndex.end()) { list > C4F_N3F_V3F_face; while ((*itCoordIndex != -1) && (itCoordIndex != coordIndex.end())) { C4F_N3F_V3F element; element.vertex = vertexArray[*itCoordIndex]; if (hasNormal) if (normalPerVertex) element.normal = normalArray[*itNormalIndex]; else element.normal = normalArray[(hasNormalIndex ? *itNormalIndex : itFaceIndex)]; if (hasColor) if (colorPerVertex) element.color = colorArray[*itColorIndex]; else element.color = colorArray[(hasColorIndex ? *itColorIndex : itFaceIndex)]; C4F_N3F_V3F_face.push_back(pair(*itCoordIndex, element)); ++itCoordIndex; if (normalPerVertex) ++itNormalIndex; if (colorPerVertex) ++itColorIndex; } ++itCoordIndex; ++itNormalIndex; ++itColorIndex; ++itFaceIndex; // processing the face. tesselateColorNoTexCoord(C4F_N3F_V3F_face); for (list >::const_iterator itPair = _C4F_N3F_V3F_tesselatedFace.begin(); itPair != _C4F_N3F_V3F_tesselatedFace.end(); ++itPair) { bool found = false; MFInt32 &indexList = _X3DtoGLIndex[(*itPair).first]; for (MFInt32::const_iterator itIndex = indexList.begin(); itIndex != indexList.end(); ++itIndex) { C4F_N3F_V3F element = _C4F_N3F_V3F_vertexArray[*itIndex]; if (element == (*itPair).second) { _indexArray.push_back(*itIndex); found = true; break; } } if (!found) { _indexArray.push_back(_C4F_N3F_V3F_vertexArray.size()); indexList.push_back(_C4F_N3F_V3F_vertexArray.size()); _C4F_N3F_V3F_vertexArray.push_back((*itPair).second); } } } if (!hasNormal) computeColorNoTexCoordNormals(); } void IndexedFaceSet::computeNoColorTexCoord(const MFVec3f &vertexArray, const MFVec3f &normalArray, const MFInt32 &coordIndex) { _X3DtoGLIndex.resize(vertexArray.size()); X3D::IndexedFaceSet *I = static_cast(x3dReference); ////////////////// arrays ////////////////////////////////////////////////////////// X3D::TextureCoordinate *TexCoordNode = dynamic_cast(I->getTexCoord()); if (TexCoordNode == 0) return; const MFVec2f &texCoordArray = TexCoordNode->getPoint(); bool hasNormal = !normalArray.empty(); bool hasTexCoord = !texCoordArray.empty(); ////////////////// indexes ///////////////////////////////////////////////////////// MFInt32 normalIndex; MFInt32 texCoordIndex; normalIndex = I->getNormalIndex(); texCoordIndex = I->getTexCoordIndex(); bool hasNormalIndex = !normalIndex.empty(); bool hasTexCoordIndex = !texCoordIndex.empty(); ////////////////// iterators /////////////////////////////////////////////////////// MFInt32::const_iterator itCoordIndex = coordIndex.begin(); MFInt32::const_iterator itNormalIndex; MFInt32::const_iterator itTexCoordIndex; unsigned int itFaceIndex = 0; if (hasNormalIndex) itNormalIndex = normalIndex.begin(); else itNormalIndex = coordIndex.begin(); if (hasTexCoordIndex) itTexCoordIndex = texCoordIndex.begin(); else itTexCoordIndex = coordIndex.begin(); ////////////////// loop //////////////////////////////////////////////////////////// SFBool normalPerVertex = I->getNormalPerVertex(); while (itCoordIndex != coordIndex.end()) { list > T2F_N3F_V3F_face; while ((*itCoordIndex != -1) && (itCoordIndex != coordIndex.end())) { T2F_N3F_V3F element; element.vertex = vertexArray[*itCoordIndex]; if (hasNormal) if (normalPerVertex) element.normal = normalArray[*itNormalIndex]; else element.normal = normalArray[(hasNormalIndex ? *itNormalIndex : itFaceIndex)]; if (hasTexCoord) element.texCoord = texCoordArray[*itTexCoordIndex]; T2F_N3F_V3F_face.push_back(pair(*itCoordIndex, element)); ++itCoordIndex; if (normalPerVertex) ++itNormalIndex; ++itTexCoordIndex; } ++itCoordIndex; ++itNormalIndex; ++itTexCoordIndex; ++itFaceIndex; // processing the face. tesselateNoColorTexCoord(T2F_N3F_V3F_face); for (list >::const_iterator itPair = _T2F_N3F_V3F_tesselatedFace.begin(); itPair != _T2F_N3F_V3F_tesselatedFace.end(); ++itPair) { bool found = false; MFInt32 &indexList = _X3DtoGLIndex[(*itPair).first]; for (MFInt32::const_iterator itIndex = indexList.begin(); itIndex != indexList.end(); ++itIndex) { T2F_N3F_V3F element = _T2F_N3F_V3F_vertexArray[*itIndex]; if (element == (*itPair).second) { _indexArray.push_back(*itIndex); found = true; break; } } if (!found) { _indexArray.push_back(_T2F_N3F_V3F_vertexArray.size()); indexList.push_back(_T2F_N3F_V3F_vertexArray.size()); _T2F_N3F_V3F_vertexArray.push_back((*itPair).second); } } } if (!hasNormal) computeNoColorTexCoordNormals(); } void IndexedFaceSet::computeColorRGBATexCoord(const MFVec3f &vertexArray, const MFVec3f &normalArray, const MFInt32 &coordIndex) { _X3DtoGLIndex.resize(vertexArray.size()); X3D::IndexedFaceSet *I = static_cast(x3dReference); ////////////////// arrays ////////////////////////////////////////////////////////// const MFColorRGBA &colorArray = static_cast(I->getColor())->getColor(); X3D::TextureCoordinate *TexCoordNode = dynamic_cast(I->getTexCoord()); if (TexCoordNode == 0) return; const MFVec2f &texCoordArray = TexCoordNode->getPoint(); bool hasNormal = !normalArray.empty(); bool hasColor = !colorArray.empty(); bool hasTexCoord = !texCoordArray.empty(); ////////////////// indexes ///////////////////////////////////////////////////////// MFInt32 normalIndex; MFInt32 colorIndex; MFInt32 texCoordIndex; normalIndex = I->getNormalIndex(); colorIndex = I->getColorIndex(); texCoordIndex = I->getTexCoordIndex(); bool hasNormalIndex = !normalIndex.empty(); bool hasColorIndex = !colorIndex.empty(); bool hasTexCoordIndex = !texCoordIndex.empty(); ////////////////// iterators /////////////////////////////////////////////////////// MFInt32::const_iterator itCoordIndex = coordIndex.begin(); MFInt32::const_iterator itNormalIndex; MFInt32::const_iterator itColorIndex; MFInt32::const_iterator itTexCoordIndex; unsigned int itFaceIndex = 0; if (hasNormalIndex) itNormalIndex = normalIndex.begin(); else itNormalIndex = coordIndex.begin(); if (hasColorIndex) itColorIndex = colorIndex.begin(); else itColorIndex = coordIndex.begin(); if (hasTexCoordIndex) itTexCoordIndex = texCoordIndex.begin(); else itTexCoordIndex = coordIndex.begin(); ////////////////// loop //////////////////////////////////////////////////////////// SFBool normalPerVertex = I->getNormalPerVertex(); SFBool colorPerVertex = I->getColorPerVertex(); while (itCoordIndex != coordIndex.end()) { list > T2F_C4F_N3F_V3F_face; while ((*itCoordIndex != -1) && (itCoordIndex != coordIndex.end())) { T2F_C4F_N3F_V3F element; element.vertex = vertexArray[*itCoordIndex]; if (hasNormal) if (normalPerVertex) element.normal = normalArray[*itNormalIndex]; else element.normal = normalArray[(hasNormalIndex ? *itNormalIndex : itFaceIndex)]; if (hasColor) if (colorPerVertex) element.color = colorArray[*itColorIndex]; else element.color = colorArray[(hasColorIndex ? *itColorIndex : itFaceIndex)]; if (hasTexCoord) element.texCoord = texCoordArray[*itTexCoordIndex]; T2F_C4F_N3F_V3F_face.push_back(pair(*itCoordIndex, element)); ++itCoordIndex; if (normalPerVertex) ++itNormalIndex; if (colorPerVertex) ++itColorIndex; ++itTexCoordIndex; } ++itCoordIndex; ++itNormalIndex; ++itColorIndex; ++itTexCoordIndex; ++itFaceIndex; // processing the face. tesselateColorTexCoord(T2F_C4F_N3F_V3F_face); for (list >::const_iterator itPair = _T2F_C4F_N3F_V3F_tesselatedFace.begin(); itPair != _T2F_C4F_N3F_V3F_tesselatedFace.end(); ++itPair) { bool found = false; MFInt32 &indexList = _X3DtoGLIndex[(*itPair).first]; for (MFInt32::const_iterator itIndex = indexList.begin(); itIndex != indexList.end(); ++itIndex) { T2F_C4F_N3F_V3F element = _T2F_C4F_N3F_V3F_vertexArray[*itIndex]; if (element == (*itPair).second) { _indexArray.push_back(*itIndex); found = true; break; } } if (!found) { _indexArray.push_back(_T2F_C4F_N3F_V3F_vertexArray.size()); indexList.push_back(_T2F_C4F_N3F_V3F_vertexArray.size()); _T2F_C4F_N3F_V3F_vertexArray.push_back((*itPair).second); } } } if (!hasNormal) computeColorTexCoordNormals(); } void IndexedFaceSet::computeColorTexCoord(const MFVec3f &vertexArray, const MFVec3f &normalArray, const MFInt32 &coordIndex) { _X3DtoGLIndex.resize(vertexArray.size()); X3D::IndexedFaceSet *I = static_cast(x3dReference); ////////////////// arrays ////////////////////////////////////////////////////////// const MFColor &colorArray = static_cast(I->getColor())->getColor(); X3D::TextureCoordinate *TexCoordNode = dynamic_cast(I->getTexCoord()); if (TexCoordNode == 0) return; const MFVec2f &texCoordArray = TexCoordNode->getPoint(); bool hasNormal = !normalArray.empty(); bool hasColor = !colorArray.empty(); bool hasTexCoord = !texCoordArray.empty(); ////////////////// indexes ///////////////////////////////////////////////////////// MFInt32 normalIndex; MFInt32 colorIndex; MFInt32 texCoordIndex; normalIndex = I->getNormalIndex(); colorIndex = I->getColorIndex(); texCoordIndex = I->getTexCoordIndex(); bool hasNormalIndex = !normalIndex.empty(); bool hasColorIndex = !colorIndex.empty(); bool hasTexCoordIndex = !texCoordIndex.empty(); ////////////////// iterators /////////////////////////////////////////////////////// MFInt32::const_iterator itCoordIndex = coordIndex.begin(); MFInt32::const_iterator itNormalIndex; MFInt32::const_iterator itColorIndex; MFInt32::const_iterator itTexCoordIndex; unsigned int itFaceIndex = 0; if (hasNormalIndex) itNormalIndex = normalIndex.begin(); else itNormalIndex = coordIndex.begin(); if (hasColorIndex) itColorIndex = colorIndex.begin(); else itColorIndex = coordIndex.begin(); if (hasTexCoordIndex) itTexCoordIndex = texCoordIndex.begin(); else itTexCoordIndex = coordIndex.begin(); ////////////////// loop //////////////////////////////////////////////////////////// SFBool normalPerVertex = I->getNormalPerVertex(); SFBool colorPerVertex = I->getColorPerVertex(); while (itCoordIndex != coordIndex.end()) { list > T2F_C4F_N3F_V3F_face; while ((*itCoordIndex != -1) && (itCoordIndex != coordIndex.end())) { T2F_C4F_N3F_V3F element; element.vertex = vertexArray[*itCoordIndex]; if (hasNormal) if (normalPerVertex) element.normal = normalArray[*itNormalIndex]; else element.normal = normalArray[(hasNormalIndex ? *itNormalIndex : itFaceIndex)]; if (hasColor) if (colorPerVertex) element.color = colorArray[*itColorIndex]; else element.color = colorArray[(hasColorIndex ? *itColorIndex : itFaceIndex)]; if (hasTexCoord) element.texCoord = texCoordArray[*itTexCoordIndex]; T2F_C4F_N3F_V3F_face.push_back(pair(*itCoordIndex, element)); ++itCoordIndex; if (normalPerVertex) ++itNormalIndex; if (colorPerVertex) ++itColorIndex; ++itTexCoordIndex; } ++itCoordIndex; ++itNormalIndex; ++itColorIndex; ++itTexCoordIndex; ++itFaceIndex; // processing the face. tesselateColorTexCoord(T2F_C4F_N3F_V3F_face); for (list >::const_iterator itPair = _T2F_C4F_N3F_V3F_tesselatedFace.begin(); itPair != _T2F_C4F_N3F_V3F_tesselatedFace.end(); ++itPair) { bool found = false; MFInt32 &indexList = _X3DtoGLIndex[(*itPair).first]; for (MFInt32::const_iterator itIndex = indexList.begin(); itIndex != indexList.end(); ++itIndex) { T2F_C4F_N3F_V3F element = _T2F_C4F_N3F_V3F_vertexArray[*itIndex]; if (element == (*itPair).second) { _indexArray.push_back(*itIndex); found = true; break; } } if (!found) { _indexArray.push_back(_T2F_C4F_N3F_V3F_vertexArray.size()); indexList.push_back(_T2F_C4F_N3F_V3F_vertexArray.size()); _T2F_C4F_N3F_V3F_vertexArray.push_back((*itPair).second); } } } if (!hasNormal) computeColorTexCoordNormals(); } void IndexedFaceSet::tesselateNoColorNoTexCoord(const list > &N3F_V3F_face) { _N3F_V3F_tesselatedFace.clear(); list >::const_iterator itPair = N3F_V3F_face.begin(); pair first, a; if (itPair == N3F_V3F_face.end()) {return;}; first = *itPair; ++itPair; if (itPair == N3F_V3F_face.end()) {return;}; a = *itPair; ++itPair; while (itPair != N3F_V3F_face.end()) { pair b = *itPair; _N3F_V3F_tesselatedFace.push_back(first); _N3F_V3F_tesselatedFace.push_back(a); _N3F_V3F_tesselatedFace.push_back(b); a = b; ++itPair; } } void IndexedFaceSet::tesselateColorNoTexCoord(const list > &C4F_N3F_V3F_face) { _C4F_N3F_V3F_tesselatedFace.clear(); list >::const_iterator itPair = C4F_N3F_V3F_face.begin(); pair first, a; if (itPair == C4F_N3F_V3F_face.end()) {return;}; first = *itPair; ++itPair; if (itPair == C4F_N3F_V3F_face.end()) {return;}; a = *itPair; ++itPair; while (itPair != C4F_N3F_V3F_face.end()) { pair b = *itPair; _C4F_N3F_V3F_tesselatedFace.push_back(first); _C4F_N3F_V3F_tesselatedFace.push_back(a); _C4F_N3F_V3F_tesselatedFace.push_back(b); a = b; ++itPair; } } void IndexedFaceSet::tesselateNoColorTexCoord(const list > &T2F_N3F_V3F_face) { _T2F_N3F_V3F_tesselatedFace.clear(); list >::const_iterator itPair = T2F_N3F_V3F_face.begin(); pair first, a; if (itPair == T2F_N3F_V3F_face.end()) {return;}; first = *itPair; ++itPair; if (itPair == T2F_N3F_V3F_face.end()) {return;}; a = *itPair; ++itPair; while (itPair != T2F_N3F_V3F_face.end()) { pair b = *itPair; _T2F_N3F_V3F_tesselatedFace.push_back(first); _T2F_N3F_V3F_tesselatedFace.push_back(a); _T2F_N3F_V3F_tesselatedFace.push_back(b); a = b; ++itPair; } } void IndexedFaceSet::tesselateColorTexCoord(const std::list > &T2F_C4F_N3F_V3F_face) { _T2F_C4F_N3F_V3F_tesselatedFace.clear(); list >::const_iterator itPair = T2F_C4F_N3F_V3F_face.begin(); pair first, a; if (itPair == T2F_C4F_N3F_V3F_face.end()) {return;}; first = *itPair; ++itPair; if (itPair == T2F_C4F_N3F_V3F_face.end()) {return;}; a = *itPair; ++itPair; while (itPair != T2F_C4F_N3F_V3F_face.end()) { pair b = *itPair; _T2F_C4F_N3F_V3F_tesselatedFace.push_back(first); _T2F_C4F_N3F_V3F_tesselatedFace.push_back(a); _T2F_C4F_N3F_V3F_tesselatedFace.push_back(b); a = b; ++itPair; } } void IndexedFaceSet::computeNoColorNoTexCoordNormals() { X3D::IndexedFaceSet *I = static_cast(x3dReference); MFInt32::const_iterator itIndex = _indexArray.begin(); // computing the normals per face. while (itIndex != _indexArray.end()) { N3F_V3F &A = _N3F_V3F_vertexArray[*itIndex]; ++itIndex; N3F_V3F &B = _N3F_V3F_vertexArray[*itIndex]; ++itIndex; N3F_V3F &C = _N3F_V3F_vertexArray[*itIndex]; ++itIndex; SFVec3f AB = (B.vertex - A.vertex).normalize(); SFVec3f AC = (C.vertex - A.vertex).normalize(); SFVec3f N; if (getCcw()) N = crossprod(AB, AC); else N = crossprod(AC, AB); A.normal += N; B.normal += N; C.normal += N; } if (I->getNormalPerVertex()) { // adding the different faces for a vertex. for (vector::const_iterator itIndexList = _X3DtoGLIndex.begin(); itIndexList != _X3DtoGLIndex.end(); ++itIndexList) { SFVec3f N(0.0f, 0.0f, 0.0f); for (MFInt32::const_iterator i = (*itIndexList).begin(); i != (*itIndexList).end(); ++i) N += _N3F_V3F_vertexArray[*i].normal; N.normalize(); for (MFInt32::const_iterator j = (*itIndexList).begin(); j != (*itIndexList).end(); ++j) _N3F_V3F_vertexArray[*j].normal = N; } } } void IndexedFaceSet::computeColorNoTexCoordNormals() { X3D::IndexedFaceSet *I = static_cast(x3dReference); MFInt32::const_iterator itIndex = _indexArray.begin(); // computing the normals per face. while (itIndex != _indexArray.end()) { C4F_N3F_V3F &A = _C4F_N3F_V3F_vertexArray[*itIndex]; ++itIndex; C4F_N3F_V3F &B = _C4F_N3F_V3F_vertexArray[*itIndex]; ++itIndex; C4F_N3F_V3F &C = _C4F_N3F_V3F_vertexArray[*itIndex]; ++itIndex; SFVec3f AB = (B.vertex - A.vertex).normalize(); SFVec3f AC = (C.vertex - A.vertex).normalize(); SFVec3f N; if (getCcw()) N = crossprod(AB, AC); else N = crossprod(AC, AB); A.normal += N; B.normal += N; C.normal += N; } if (I->getNormalPerVertex()) { // adding the different faces for a vertex. for (vector::const_iterator itIndexList = _X3DtoGLIndex.begin(); itIndexList != _X3DtoGLIndex.end(); ++itIndexList) { SFVec3f N(0.0f, 0.0f, 0.0f); for (MFInt32::const_iterator i = (*itIndexList).begin(); i != (*itIndexList).end(); ++i) N += _C4F_N3F_V3F_vertexArray[*i].normal; N.normalize(); for (MFInt32::const_iterator j = (*itIndexList).begin(); j != (*itIndexList).end(); ++j) _C4F_N3F_V3F_vertexArray[*j].normal = N; } } } void IndexedFaceSet::computeNoColorTexCoordNormals() { X3D::IndexedFaceSet *I = static_cast(x3dReference); MFInt32::const_iterator itIndex = _indexArray.begin(); // computing the normals per face. while (itIndex != _indexArray.end()) { T2F_N3F_V3F &A = _T2F_N3F_V3F_vertexArray[*itIndex]; ++itIndex; T2F_N3F_V3F &B = _T2F_N3F_V3F_vertexArray[*itIndex]; ++itIndex; T2F_N3F_V3F &C = _T2F_N3F_V3F_vertexArray[*itIndex]; ++itIndex; SFVec3f AB = (B.vertex - A.vertex).normalize(); SFVec3f AC = (C.vertex - A.vertex).normalize(); SFVec3f N; if (getCcw()) N = crossprod(AB, AC); else N = crossprod(AC, AB); A.normal += N; B.normal += N; C.normal += N; } if (I->getNormalPerVertex()) { // adding the different faces for a vertex. for (vector::const_iterator itIndexList = _X3DtoGLIndex.begin(); itIndexList != _X3DtoGLIndex.end(); ++itIndexList) { SFVec3f N(0.0f, 0.0f, 0.0f); for (MFInt32::const_iterator i = (*itIndexList).begin(); i != (*itIndexList).end(); ++i) N += _T2F_N3F_V3F_vertexArray[*i].normal; N.normalize(); for (MFInt32::const_iterator j = (*itIndexList).begin(); j != (*itIndexList).end(); ++j) _T2F_N3F_V3F_vertexArray[*j].normal = N; } } } void IndexedFaceSet::computeColorTexCoordNormals() { X3D::IndexedFaceSet *I = static_cast(x3dReference); MFInt32::const_iterator itIndex = _indexArray.begin(); // computing the normals per face. while (itIndex != _indexArray.end()) { T2F_C4F_N3F_V3F &A = _T2F_C4F_N3F_V3F_vertexArray[*itIndex]; ++itIndex; T2F_C4F_N3F_V3F &B = _T2F_C4F_N3F_V3F_vertexArray[*itIndex]; ++itIndex; T2F_C4F_N3F_V3F &C = _T2F_C4F_N3F_V3F_vertexArray[*itIndex]; ++itIndex; SFVec3f AB = (B.vertex - A.vertex).normalize(); SFVec3f AC = (C.vertex - A.vertex).normalize(); SFVec3f N; if (getCcw()) N = crossprod(AB, AC); else N = crossprod(AC, AB); A.normal += N; B.normal += N; C.normal += N; } if (I->getNormalPerVertex()) { // adding the different faces for a vertex. for (vector::const_iterator itIndexList = _X3DtoGLIndex.begin(); itIndexList != _X3DtoGLIndex.end(); ++itIndexList) { SFVec3f N(0.0f, 0.0f, 0.0f); for (MFInt32::const_iterator i = (*itIndexList).begin(); i != (*itIndexList).end(); ++i) N += _T2F_C4F_N3F_V3F_vertexArray[*i].normal; N.normalize(); for (MFInt32::const_iterator j = (*itIndexList).begin(); j != (*itIndexList).end(); ++j) _T2F_C4F_N3F_V3F_vertexArray[*j].normal = N; } } } } }