//-------------------------------------------------------------------------------------------------- /// Transforms all vertices in this drawable geometry using the specified matrix /// /// \warning Calling this function will create a new internal vertex array. /// \warning Normals may have to be recomputed after this function has been called. //-------------------------------------------------------------------------------------------------- void DrawableGeo::transform(const Mat4d& transformation) { size_t numVertices = m_vertexBundle->vertexCount(); if (numVertices == 0) { return; } cref<Vec3fArray> sourceVertexArray = m_vertexBundle->vertexArray(); CVF_ASSERT(sourceVertexArray.notNull()); ref<Vec3fArray> newVertexArr = new Vec3fArray(numVertices); size_t i; for (i = 0; i < numVertices; i++) { // Transform to double vector to be able to do a transform using a double matrix Vec3d tmpVertex(sourceVertexArray->get(i)); tmpVertex.transformPoint(transformation); newVertexArr->set(i, Vec3f(tmpVertex)); } m_vertexBundle->setVertexArray(newVertexArr.p()); recomputeBoundingBox(); }
//-------------------------------------------------------------------------------------------------- /// Setup geometry with quads from an array of vertices (4 vertices per quad). /// /// This method sets the vertices to the passed vertexArray, and then creates one PrimitiveSet with /// two triangles for every four vertices in vertexArray. //-------------------------------------------------------------------------------------------------- void DrawableGeo::setFromQuadVertexArray(Vec3fArray* vertexArray) { CVF_ASSERT(vertexArray); m_vertexBundle->setVertexArray(vertexArray); m_primitiveSets.clear(); size_t numVertices = vertexArray->size(); size_t numQuads = numVertices/4; CVF_ASSERT(numVertices%4 == 0); // Two triangles per quad ref<UIntArray> indices = new UIntArray; indices->resize(numQuads*2*3); size_t index = 0; uint i; for (i = 0; i < numQuads; i++) { indices->set(index++, i*4); indices->set(index++, i*4 + 1); indices->set(index++, i*4 + 2); indices->set(index++, i*4); indices->set(index++, i*4 + 2); indices->set(index++, i*4 + 3); } ref<PrimitiveSetIndexedUInt> prim = new PrimitiveSetIndexedUInt(PT_TRIANGLES); prim->setIndices(indices.p()); m_primitiveSets.push_back(prim.p()); recomputeBoundingBox(); }
//-------------------------------------------------------------------------------------------------- /// Setup a geometry with triangles from an array of vertices (3 vertices per triangle). /// /// This method sets the vertices to the passed vertexArray, and then creates one PrimitiveSet with /// one triangle for every three vertices in vertexArray. //-------------------------------------------------------------------------------------------------- void DrawableGeo::setFromTriangleVertexArray(Vec3fArray* vertexArray) { CVF_ASSERT(vertexArray); m_vertexBundle->setVertexArray(vertexArray); m_primitiveSets.clear(); size_t numVertices = vertexArray->size(); ref<UIntArray> indices = new UIntArray; indices->resize(numVertices); size_t i; for (i = 0; i < numVertices; i++) { indices->set(i, static_cast<uint>(i)); } ref<PrimitiveSetIndexedUInt> prim = new PrimitiveSetIndexedUInt(PT_TRIANGLES); prim->setIndices(indices.p()); m_primitiveSets.push_back(prim.p()); recomputeBoundingBox(); }
void CylinderNode::initialize() { recomputeBoundingBox(); #ifdef SUPPORT_OPENGL recomputeDisplayList(); #endif }
//-------------------------------------------------------------------------------------------------- /// Weld vertices based on vertex distance /// /// \warning Calling this function will delete all vertex related data except the vertex positions //-------------------------------------------------------------------------------------------------- void DrawableGeo::weldVertices(double weldDistance) { size_t numVertices = m_vertexBundle->vertexCount(); size_t numPrimSets = m_primitiveSets.size(); if (numVertices == 0 || numPrimSets == 0) { return; } cref<Vec3fArray> sourceVertexArray = m_vertexBundle->vertexArray(); CVF_ASSERT(sourceVertexArray.notNull()); // Try and use bounding box to guess cell size // Probably needs more experimenting here double cellSize = m_boundingBox.radius()/100; VertexWelder welder; welder.initialize(weldDistance, cellSize, static_cast<uint>(numVertices)); welder.reserveVertices(static_cast<uint>(numVertices)); Collection<PrimitiveSet> newPrimSets; size_t ip; for (ip = 0; ip < numPrimSets; ip++) { const PrimitiveSet* srcPrimSet = m_primitiveSets.at(ip); PrimitiveType primType = srcPrimSet->primitiveType(); size_t numIndices = srcPrimSet->indexCount(); ref<UIntArray> newIndices = new UIntArray; newIndices->reserve(numIndices); size_t i; for (i = 0; i < numIndices; i++) { uint idx = srcPrimSet->index(i); Vec3f v = sourceVertexArray->get(idx); uint newIndexOfVertex = welder.weldVertex(v, NULL); newIndices->add(newIndexOfVertex); } ref<PrimitiveSetIndexedUInt> primSet = new PrimitiveSetIndexedUInt(primType); primSet->setIndices(newIndices.p()); newPrimSets.push_back(primSet.p()); } releaseBufferObjectsGPU(); m_vertexBundle->clear(); m_vertexBundle->setVertexArray(welder.createVertexArray().p()); m_primitiveSets = newPrimSets; recomputeBoundingBox(); }
void siptlp_GlRect::sipProtectVirt_recomputeBoundingBox(bool sipSelfWasArg) { (sipSelfWasArg ? tlp::GlAbstractPolygon::recomputeBoundingBox() : recomputeBoundingBox()); }
void TransformNode::initialize() { recomputeBoundingBox(); }
//-------------------------------------------------------------------------------------------------- /// Merge a drawable geometry object with this drawable possibly with transformation. /// /// \param drawableGeo Drawable geometries to be merged /// \param transformation Transformation matrix used to modify vertices /// /// Vertices are converted if a transformation matrix is given. /// Vertex arrays are appended to the merged vertex array. Primitives are copied and indices updated. /// /// \warning All other vertex attribute data such as normals, texture coordinates etc will be set to NULL //-------------------------------------------------------------------------------------------------- void DrawableGeo::mergeInto(const DrawableGeo& drawableGeo, const Mat4d* transformation) { size_t totalVertexCount = m_vertexBundle->vertexCount(); totalVertexCount += drawableGeo.vertexCount(); // Nothing to do if no existing vertices and no new vertices if (totalVertexCount == 0) { return; } // Create a new vertex array and copy data from our array cref<Vec3fArray> oldVertexArray = m_vertexBundle->vertexArray(); ref<Vec3fArray> newVertexArr = new Vec3fArray(totalVertexCount); size_t currentVertexIndex = 0; if (oldVertexArray.notNull() && oldVertexArray->size() > 0) { newVertexArr->copyData(*oldVertexArray, oldVertexArray->size(), 0, 0); currentVertexIndex = oldVertexArray->size(); } // Do the primitive set size_t i = 0; for (i = 0; i < drawableGeo.primitiveSetCount(); i++) { const PrimitiveSet* primSet = drawableGeo.primitiveSet(i); CVF_ASSERT(primSet); ref<UIntArray> indices = new UIntArray; indices->resize(primSet->indexCount()); uint k; for (k = 0; k < primSet->indexCount(); k++) { uint val = primSet->index(k); val += static_cast<uint>(currentVertexIndex); indices->set(k, val); } ref<PrimitiveSetIndexedUInt> prim = new PrimitiveSetIndexedUInt(primSet->primitiveType()); prim->setIndices(indices.p()); m_primitiveSets.push_back(prim.p()); } const Vec3fArray* srcVertices = drawableGeo.vertexArray(); CVF_ASSERT(srcVertices); if (transformation) { size_t j; for (j = 0; j < srcVertices->size(); j++) { // Transform to double vector to be able to do a transform using a double matrix Vec3d tmpDoubleVec(srcVertices->get(j)); tmpDoubleVec.transformPoint(*transformation); newVertexArr->set(currentVertexIndex, Vec3f(tmpDoubleVec)); currentVertexIndex++; } } else { // Append other drawable vertices vertex array and update vertex index newVertexArr->copyData(*srcVertices, srcVertices->size(), currentVertexIndex, 0); } // Clear all vertex attributes and set new vertex array m_vertexBundle->clear(); m_vertexBundle->setVertexArray(newVertexArr.p()); recomputeBoundingBox(); }
//-------------------------------------------------------------------------------------------------- /// Merge a collection of drawable geometry objects into this drawable /// /// \param drawableGeos Collection of drawable geometries to be merged /// /// A new vertex array is created with the incoming vertex arrays appended to the existing contents. /// Primitives are copied and indices updated. /// /// \warning All other vertex attribute data such as normals, texture coordinates etc will be set to NULL //-------------------------------------------------------------------------------------------------- void DrawableGeo::mergeInto(const Collection<DrawableGeo>& drawableGeos) { size_t totalVertexCount = m_vertexBundle->vertexCount(); size_t i; for (i = 0; i < drawableGeos.size(); i++) { const DrawableGeo* geo = drawableGeos[i].p(); totalVertexCount += geo->vertexCount(); } // Nothing to do if no existing vertices and no new vertices if (totalVertexCount == 0) { return; } // Create a new vertex array and copy data from our array cref<Vec3fArray> oldVertexArray = m_vertexBundle->vertexArray(); ref<Vec3fArray> newVertexArr = new Vec3fArray(totalVertexCount); size_t currentVertexIndex = 0; if (oldVertexArray.notNull() && oldVertexArray->size() > 0) { newVertexArr->copyData(*oldVertexArray, oldVertexArray->size(), 0, 0); currentVertexIndex = oldVertexArray->size(); } // Then copy from the other drawable geos for (i = 0; i < drawableGeos.size(); i++) { const DrawableGeo* otherDrawable = drawableGeos[i].p(); size_t j = 0; for (j = 0; j < otherDrawable->primitiveSetCount(); j++) { const PrimitiveSet* primSet = otherDrawable->primitiveSet(j); CVF_ASSERT(primSet); ref<UIntArray> indices = new UIntArray; indices->resize(primSet->indexCount()); uint k; for (k = 0; k < primSet->indexCount(); k++) { uint val = primSet->index(k); val += static_cast<uint>(currentVertexIndex); indices->set(k, val); } ref<PrimitiveSetIndexedUInt> prim = new PrimitiveSetIndexedUInt(primSet->primitiveType()); prim->setIndices(indices.p()); m_primitiveSets.push_back(prim.p()); } const Vec3fArray* otherVertices = otherDrawable->vertexArray(); CVF_ASSERT(otherVertices); // Append other drawable vertices vertex array and update vertex index newVertexArr->copyData(otherVertices->ptr(), otherVertices->size(), currentVertexIndex); currentVertexIndex += otherVertices->size(); } // Clear all vertex attributes and set new vertex array m_vertexBundle->clear(); m_vertexBundle->setVertexArray(newVertexArr.p()); recomputeBoundingBox(); }
//-------------------------------------------------------------------------------------------------- /// Set the vertices (node coordinates) of this geometry. //-------------------------------------------------------------------------------------------------- void DrawableGeo::setVertexArray(Vec3fArray* vertexArray) { m_vertexBundle->setVertexArray(vertexArray); recomputeBoundingBox(); }
void AnchorNode::initialize() { recomputeBoundingBox(); }
void SceneGraph::initialize(void (*callbackFn)(int nNode, void *info), void *callbackFnInfo) { Node *node; int nNode = 0; for (node = Parser::getNodes(); node; node = node->nextTraversal()) { node->setSceneGraph(this); if (node->isInstanceNode() == false) node->initialize(); nNode++; if (callbackFn) callbackFn(nNode, callbackFnInfo); } // Convert from InstanceNode into DEFNode node = Parser::getNodes(); while(node != NULL) { Node *nextNode = node->nextTraversal(); if (node->isInstanceNode() == true && node->isDEFNode() == false) { Node *referenceNode = node->getReferenceNode(); Node *parentNode = node->getParentNode(); Node *defNode; defNode = referenceNode->createDEFNode(); if (parentNode != NULL) parentNode->addChildNode(defNode, false); else addNode(defNode, false); node->remove(); delete node; nextNode = defNode->nextTraversal(); } node = nextNode; } // Convert from DEFNode into InstanceNode node = Parser::getNodes(); while(node != NULL) { Node *nextNode = node->nextTraversal(); if (node->isDEFNode() == true) { Node *defNode = findNode(node->getName()); assert(defNode); if (defNode) { Node *instanceNode = defNode->createInstanceNode(); Node *parentNode = node->getParentNode(); if (parentNode != NULL) parentNode->moveChildNode(instanceNode); else moveNode(instanceNode); node->remove(); delete node; } } node = nextNode; } recomputeBoundingBox(); for (Route *route = Parser::getRoutes(); route; route = route->next()) route->initialize(); }