// recursively build a table of geometry instances with ID and transform // to be accessed when geometries are read in the second pass bool OgreCollada::MeshWriter::createSceneDFS(const COLLADAFW::Node* cn, // node to instantiate Ogre::Matrix4 xn) // accumulated transform { // apply this node's transformation matrix to the one inherited from its parent const COLLADAFW::TransformationPointerArray& tarr = cn->getTransformations(); // COLLADA spec says multiple transformations are "postmultiplied in the order in which // they are specified", which I think means like this: for (size_t i = 0; i < tarr.getCount(); ++i) { xn = xn * computeTransformation(tarr[i]); } // record any geometry instances present in this node, along with their attached materials // and cumulative transform const COLLADAFW::InstanceGeometryPointerArray& ginodes = cn->getInstanceGeometries(); for (int i = 0, count = ginodes.getCount(); i < count; ++i) { COLLADAFW::InstanceGeometry* gi = ginodes[i]; if (m_geometryUsage.find(gi->getInstanciatedObjectId()) == m_geometryUsage.end()) { // create empty usage list for this geometry m_geometryUsage.insert(std::make_pair(gi->getInstanciatedObjectId(), GeoInstUsageList())); } m_geometryUsage[gi->getInstanciatedObjectId()].push_back(std::make_pair(&(gi->getMaterialBindings()), xn)); } // recursively follow child nodes and library instances const COLLADAFW::NodePointerArray& cnodes = cn->getChildNodes(); for (int i = 0, count = cnodes.getCount(); i < count; ++i) { if (!createSceneDFS(cnodes[i], xn)) return false; } const COLLADAFW::InstanceNodePointerArray& inodes = cn->getInstanceNodes(); for (int i = 0, count = inodes.getCount(); i < count; ++i) { LibNodesIterator lit = m_libNodes.find(inodes[i]->getInstanciatedObjectId()); if (lit == m_libNodes.end()) { LOG_DEBUG("COLLADA WARNING: could not find library node with unique ID " + boost::lexical_cast<Ogre::String>(inodes[i]->getInstanciatedObjectId())); continue; } if (!createSceneDFS(lit->second, xn)) return false; } return true; }
//------------------------------ void SceneGraphWriter::storeInstanceGeometries( const COLLADAFW::InstanceGeometryPointerArray& instanceGeometries, const COLLADABU::Math::Matrix4& worldMatrix ) { for ( size_t i = 0, count = instanceGeometries.getCount(); i < count; ++i) { COLLADAFW::InstanceGeometry* instanceGeometry = instanceGeometries[i]; OgreWriter::InstanceGeometryInfo instanceGeometryInfo( instanceGeometry, worldMatrix ); addGeometryUniqueIdInstanceGeometryInfoPair(instanceGeometry->getInstanciatedObjectId(), instanceGeometryInfo); } }