TriangleMesh::TriangleMesh(domTrianglesRef triangles) { const domInputLocalOffset_Array trianglesInputArray = triangles->getInput_array(); size_t vertexOffset, normalOffset; for (size_t m = 0; m < trianglesInputArray.getCount(); m++) { const domInputLocalOffsetRef trianglesInput = trianglesInputArray[m]; const xsNMTOKEN trianglesInputSemantic = trianglesInput->getSemantic(); if (!strcmp(trianglesInputSemantic, "VERTEX")) { const domVerticesRef src = daeSafeCast<domVertices>(trianglesInput->getSource().getElement()); const domInputLocal_Array verticesInputArray = src->getInput_array(); for (size_t n = 0; n < verticesInputArray.getCount(); n++) { const domInputLocalRef verticesInput = verticesInputArray[n]; const xsNMTOKEN verticesInputSemantic = verticesInput->getSemantic(); if (!strcmp(verticesInputSemantic, "POSITION")) { const domSourceRef src = daeSafeCast<domSource>(verticesInput->getSource().getElement()); parseCoordinateSource(&posArray, src, 1.f); } } vertexOffset = trianglesInput->getOffset(); } else if (!strcmp(trianglesInputSemantic, "NORMAL")) { const domSourceRef src = daeSafeCast<domSource>(trianglesInput->getSource().getElement()); parseCoordinateSource(&normalArray, src, 0.f); normalOffset = trianglesInput->getOffset(); } } const domListOfUInts origInds = triangles->getP()->getValue(); for (int i = 0; i < 3*triangles->getCount(); i++) { inds.append(origInds[i*trianglesInputArray.getCount()+vertexOffset]); inds.append(origInds[i*trianglesInputArray.getCount()+normalOffset]); } }
TriangleMesh::TriangleMesh(domTrianglesRef triangles, const char *desiredEffect) : effect(desiredEffect) { const domInputLocalOffset_Array trianglesInputArray = triangles->getInput_array(); size_t vertexOffset, normalOffset, texcoordOffset, colorOffset; bool foundtexcoord = false, foundcolor = false; for (size_t m = 0; m < trianglesInputArray.getCount(); m++) { const domInputLocalOffsetRef trianglesInput = trianglesInputArray[m]; const xsNMTOKEN trianglesInputSemantic = trianglesInput->getSemantic(); if (!strcmp(trianglesInputSemantic, "VERTEX")) { const domVerticesRef src = daeSafeCast<domVertices>(trianglesInput->getSource().getElement()); const domInputLocal_Array verticesInputArray = src->getInput_array(); for (size_t n = 0; n < verticesInputArray.getCount(); n++) { const domInputLocalRef verticesInput = verticesInputArray[n]; const xsNMTOKEN verticesInputSemantic = verticesInput->getSemantic(); if (!strcmp(verticesInputSemantic, "POSITION")) { const domSourceRef src = daeSafeCast<domSource>(verticesInput->getSource().getElement()); parseCoordinateSource(&posArray, src); } } vertexOffset = trianglesInput->getOffset(); } else if (!strcmp(trianglesInputSemantic, "NORMAL")) { const domSourceRef src = daeSafeCast<domSource>(trianglesInput->getSource().getElement()); parseCoordinateSource(&normalArray, src); normalOffset = trianglesInput->getOffset(); } else if (!strcmp(trianglesInputSemantic, "TEXCOORD")) { const domSourceRef src = daeSafeCast<domSource>(trianglesInput->getSource().getElement()); parseTexcoordSource(&texcoordArray, src); texcoordOffset = trianglesInput->getOffset(); foundtexcoord = true; } else if (!strcmp(trianglesInputSemantic, "COLOR")) { const domSourceRef src = daeSafeCast<domSource>(trianglesInput->getSource().getElement()); parseColorSource(&colorArray, src); colorOffset = trianglesInput->getOffset(); foundcolor = true; } } if (!foundtexcoord) texcoordArray.append2(0.f, 0.f); if (!foundcolor) colorArray.append4(1.f, 1.f, 1.f, 1.f); const domListOfUInts origInds = triangles->getP()->getValue(); for (int i = 0; i < 3*triangles->getCount(); i++) { inds.append(origInds[i*trianglesInputArray.getCount()+vertexOffset]); inds.append(origInds[i*trianglesInputArray.getCount()+normalOffset]); inds.append(foundtexcoord ? origInds[i*trianglesInputArray.getCount()+texcoordOffset] : 0); inds.append(foundcolor ? origInds[i*trianglesInputArray.getCount()+colorOffset] : 0); } material = triangles->getMaterial(); }
unsigned int CScene::GetMaxOffset( domInputLocalOffset_Array &input_array ) { unsigned int maxOffset = 0; for ( unsigned int i = 0; i < input_array.getCount(); i++ ) { if ( input_array[i]->getOffset() > maxOffset ) { maxOffset = (unsigned int)input_array[i]->getOffset(); } } return maxOffset; }
//---------------------------------------------------------------------------- unsigned int SEColladaScene::GetMaxOffset( domInputLocalOffset_Array& rInputArray) { unsigned int uiMaxOffset = 0; for( int i = 0; i < (int)rInputArray.getCount(); i++ ) { if( rInputArray[i]->getOffset() > uiMaxOffset ) { uiMaxOffset = (unsigned int)rInputArray[i]->getOffset(); } } return uiMaxOffset; }
UInt32 ColladaGeometry::setupGeometry(const domInputLocal_Array &vertInputs, const domInputLocalOffset_Array &inputs, xsNCName matSymbol, IndexStore &idxStore ) { OSG_COLLADA_LOG(("ColladaGeometry::setupGeometry\n")); typedef std::vector<UInt32> UnhandledStore; typedef UnhandledStore::const_iterator UnhandledStoreConstIt; Int32 vertInputIndex = -1; // <input> with sem "VERTEX" UnhandledStore unhandledVertInputs; UnhandledStore unhandledInputs; UInt32 geoIdx = _geoStore.size(); _geoStore.push_back(GeoInfo()); if(matSymbol != NULL) { _geoStore[geoIdx]._matSymbol = matSymbol; } else { SWARNING << "ColladaGeometry::setupGeometry: " << "Found empty material symbol." << std::endl; } for(UInt32 i = 0; i < inputs.getCount(); ++i) { std::string semantic = inputs[i]->getSemantic(); UInt32 set = inputs[i]->getSet (); UInt32 offset = inputs[i]->getOffset (); std::string sourceId = inputs[i]->getSource ().id(); OSG_COLLADA_LOG(("ColladaGeometry::setupGeometry: input [%d] " "semantic [%s] set [%d] offset [%d] - source [%s]\n", i, semantic.c_str(), set, offset, sourceId.c_str())); if(semantic == "VERTEX") { // handle <input> tag with semantic "VERTEX" // by processing vertInputs, i.e. the <vertices> tag vertInputIndex = i; // all vertInputs use the same index - with the offset from the // <input> with semantic == VERTEX if(offset >= idxStore.size() || idxStore[offset] == NULL) { OSG_COLLADA_LOG(("ColladaGeometry::setupGeometry: " "new index property for offset [%d]\n", offset)); // new index idxStore.resize( osgMax<UInt32>(offset + 1, idxStore.size()), NULL); idxStore[offset] = GeoUInt32Property::create(); } for(UInt32 j = 0; j < vertInputs.getCount(); ++j) { semantic = vertInputs[j]->getSemantic(); sourceId = vertInputs[j]->getSource ().id(); OSG_COLLADA_LOG(("ColladaGeometry::setupGeometry: vertices [%d] " "semantic [%s] - source [%s]\n", j, semantic.c_str(), sourceId.c_str())); UInt32 propIdx = mapSemantic(semantic, 0, geoIdx); if(propIdx == Geometry::MaxAttribs) { unhandledVertInputs.push_back(j); } else { setupProperty(geoIdx, propIdx, semantic, set, sourceId, idxStore[offset] ); } } } else { // handle regular <input> tags if(offset >= idxStore.size() || idxStore[offset] == NULL) { OSG_COLLADA_LOG(("ColladaGeometry::setupGeometry: " "new index property for offset [%d]\n", offset)); // new index idxStore.resize(osgMax<UInt32>(offset + 1, idxStore.size()), NULL); idxStore[offset] = GeoUInt32Property::create(); } UInt32 propIdx = mapSemantic(semantic, set, geoIdx); if(propIdx == Geometry::MaxAttribs) { unhandledInputs.push_back(i); } else { setupProperty(geoIdx, propIdx, semantic, set, sourceId, idxStore[offset] ); } } } // some <inputs> could not be handled above because their // semantic was not recognized. // after everything else is set put them into free attribute // slots, starting at Geometry::TexCoordsIndex UnhandledStoreConstIt uhIt = unhandledVertInputs.begin(); UnhandledStoreConstIt uhEnd = unhandledVertInputs.end (); for(; uhIt != uhEnd; ++uhIt) { std::string semantic = vertInputs[*uhIt ]->getSemantic(); UInt32 set = inputs [vertInputIndex]->getSet (); UInt32 offset = inputs [vertInputIndex]->getOffset (); std::string sourceId = vertInputs[*uhIt ]->getSource ().id(); UInt32 propIdx = findFreePropertyIndex(geoIdx); OSG_COLLADA_LOG(("ColladaGeometry::setupGeometry: unhandled vertex " " <input> [%d] semantic [%s] set [%d] offset [%d] - " "source [%s] mapped to propIdx [%d]\n", *uhIt, semantic.c_str(), set, offset, sourceId.c_str(), propIdx)); setupProperty(geoIdx, propIdx, semantic, set, sourceId, idxStore[offset] ); } uhIt = unhandledInputs.begin(); uhEnd = unhandledInputs.end (); for(; uhIt != uhEnd; ++uhIt) { std::string semantic = inputs[*uhIt]->getSemantic(); UInt32 set = inputs[*uhIt]->getSet (); UInt32 offset = inputs[*uhIt]->getOffset (); std::string sourceId = inputs[*uhIt]->getSource ().id(); UInt32 propIdx = findFreePropertyIndex(geoIdx); OSG_COLLADA_LOG(("ColladaGeometry::setupGeometry: unhandled <input> " "[%d] semantic [%s] set [%d] offset [%d] - " "source [%s] mapped to propIdx [%d]\n", *uhIt, semantic.c_str(), set, offset, sourceId.c_str(), propIdx)); setupProperty(geoIdx, propIdx, semantic, set, sourceId, idxStore[offset] ); } #ifdef OSG_DEBUG // check for holes in idxStore - which is not supported IndexStoreConstIt idxIt = idxStore.begin(); IndexStoreConstIt idxEnd = idxStore.end (); for(UInt32 i = 0; idxIt != idxEnd; ++idxIt, ++i) { if(*idxIt == NULL) { SWARNING << "ColladaGeometry::setupGeometry: idxStore contains " << "hole at [" << i << "]" << std::endl; } } #endif _geoStore[geoIdx]._lengths = GeoUInt32Property::create(); _geoStore[geoIdx]._types = GeoUInt8Property ::create(); return geoIdx; }
//---------------------------------------------------------------------------- void SEColladaInputArray::SetInputs(domInputLocalOffset_Array& rDomInputs) { // Inputs with offsets. for( int i = 0; i < (int)rDomInputs.getCount(); i++ ) { int iCurrentOffset = (int)rDomInputs[i]->getOffset(); if( m_iMaxOffset < iCurrentOffset ) { m_iMaxOffset++; } domSource* pDomSource = (domSource*)(domElement*)rDomInputs[i]->getSource().getElement(); xsNMTOKEN strSemantic = rDomInputs[i]->getSemantic(); if( strcmp("VERTEX", strSemantic) == 0 ) { m_iPosition = iCurrentOffset; } else if( strcmp("NORMAL", strSemantic) == 0 ) { m_iNormal = iCurrentOffset; m_pDomNormalData = &pDomSource->getFloat_array()->getValue(); m_iNormalStride = (int)pDomSource->getTechnique_common( )->getAccessor()->getStride(); } else if( strcmp("TEXCOORD", strSemantic) == 0 ) { m_iTCoord = iCurrentOffset; m_pDomTCoordData = &pDomSource->getFloat_array()->getValue(); m_iTCoordStride = (int)pDomSource->getTechnique_common( )->getAccessor()->getStride(); } } m_iMaxOffset += 1; // Inputs without offsets in vertices. domMesh* pDomMesh = (domMesh*)rDomInputs[0]->getParentElement()->getParentElement(); SE_ASSERT( pDomMesh ); domVertices* pDomVertices = pDomMesh->getVertices(); domInputLocal_Array& rDomVerticesInputs = pDomVertices->getInput_array(); for( int i = 0; i < (int)rDomVerticesInputs.getCount(); i++ ) { domSource* pDomSource = (domSource*)(domElement*)rDomVerticesInputs[i]->getSource( ).getElement(); xsNMTOKEN strSemantic = rDomVerticesInputs[i]->getSemantic(); if( strcmp("POSITION", strSemantic) == 0 ) { m_pDomPositionData = &pDomSource->getFloat_array()->getValue(); m_iPositionStride = (int)pDomSource->getTechnique_common( )->getAccessor()->getStride(); } else if( strcmp("NORMAL", strSemantic) == 0 ) { m_pDomNormalData = &pDomSource->getFloat_array()->getValue(); m_iNormal = m_iPosition; m_iNormalStride = (int)pDomSource->getTechnique_common( )->getAccessor()->getStride(); } else if( strcmp("TEXCOORD", strSemantic) == 0 ) { m_pDomTCoordData = &pDomSource->getFloat_array()->getValue(); m_iTCoord = m_iPosition; m_iTCoordStride = (int)pDomSource->getTechnique_common( )->getAccessor()->getStride(); } } }