//! Sets a new mesh void CInstancedMeshSceneNode::setMesh(IMesh* mesh) { video::IVideoDriver* driver = SceneManager->getVideoDriver(); if (baseMesh) { baseMesh->drop(); baseMesh = NULL; } if (mesh) { mesh->grab(); baseMesh = mesh; IMeshBuffer* renderBuffer = baseMesh->getMeshBuffer(0); while (renderBuffer->getVertexBufferCount() > 1) renderBuffer->removeVertexBuffer(1); // TODO add getter and so that the smaller value isnt erased // maybe the func isnt longer needed so delete it driver->setMinHardwareBufferVertexCount(renderBuffer->getVertexBuffer()->getVertexCount()); renderBuffer->setHardwareMappingHint(scene::EHM_STATIC); video::IVertexDescriptor* index = SceneManager->getVideoDriver()->getVertexDescriptor("BaseInstanceIndex"); if (!index) { video::IVertexDescriptor* stdv = SceneManager->getVideoDriver()->getVertexDescriptor(0); index = SceneManager->getVideoDriver()->addVertexDescriptor("BaseInstanceIndex"); for (u32 i = 0; i < stdv->getAttributeCount(); ++i) { index->addAttribute(stdv->getAttribute(i)->getName(), stdv->getAttribute(i)->getElementCount(), stdv->getAttribute(i)->getSemantic(), stdv->getAttribute(i)->getType(), stdv->getAttribute(i)->getBufferID()); } index->addAttribute("InstancingMatrix1", 4, video::EVAS_TEXCOORD1, video::EVAT_FLOAT, 1); index->addAttribute("InstancingMatrix2", 4, video::EVAS_TEXCOORD2, video::EVAT_FLOAT, 1); index->addAttribute("InstancingMatrix3", 4, video::EVAS_TEXCOORD3, video::EVAT_FLOAT, 1); index->addAttribute("InstancingMatrix4", 4, video::EVAS_TEXCOORD4, video::EVAT_FLOAT, 1); index->setInstanceDataStepRate(video::EIDSR_PER_INSTANCE, 1); } IVertexBuffer* instanceBuffer = new CVertexBuffer<core::matrix4>(); renderBuffer->setVertexDescriptor(index); renderBuffer->addVertexBuffer(instanceBuffer); renderBuffer->getVertexBuffer(0)->setHardwareMappingHint(scene::EHM_STATIC); renderBuffer->getVertexBuffer(1)->setHardwareMappingHint(scene::EHM_STATIC); renderBuffer->getIndexBuffer()->setHardwareMappingHint(scene::EHM_STATIC); instanceBuffer->drop(); } }
/* This method has a lot of duplication and overhead. Moreover, the tangents mesh conversion does not really work. I think we need a a proper mesh implementation for octrees, which handle all vertex types internally. Converting all structures to just one vertex type is always problematic. Thanks to Auria for fixing major parts of this method. */ bool COctreeSceneNode::createTree(IMesh* mesh) { if (!mesh) return false; MeshName = SceneManager->getMeshCache()->getMeshName(mesh); mesh->grab(); deleteTree(); Mesh = mesh; const u32 beginTime = os::Timer::getRealTime(); u32 nodeCount = 0; u32 polyCount = 0; u32 i; Box = mesh->getBoundingBox(); if (mesh->getMeshBufferCount()) { // check for "larger" buffer types u32 meshReserve = StdMeshes.size(); Materials.reallocate(Materials.size()+meshReserve); StdMeshesMatID.reallocate(meshReserve); for ( i=0; i < mesh->getMeshBufferCount(); ++i) { const scene::IMeshManipulator* meshManipulator = SceneManager->getMeshManipulator(); IMeshBuffer* meshBuffer = mesh->getMeshBuffer(i); IMeshBuffer* nchunk = StdMeshes[i]; // copy vertices video::IVertexDescriptor* srcDescriptor = meshBuffer->getVertexDescriptor(); video::IVertexDescriptor* dstDescriptor = nchunk->getVertexDescriptor(); const u32 vbCount = meshBuffer->getVertexBufferCount(); for (u32 j = 0; j < vbCount; ++j) meshManipulator->copyVertices(meshBuffer->getVertexBuffer(j), j, srcDescriptor, nchunk->getVertexBuffer(j), j, dstDescriptor, true); // copy indices scene::IIndexBuffer* srcIndexBuffer = meshBuffer->getIndexBuffer(); scene::IIndexBuffer* dstIndexBuffer = nchunk->getIndexBuffer(); meshManipulator->copyIndices(srcIndexBuffer, dstIndexBuffer); // copy material Materials.push_back(meshBuffer->getMaterial()); StdMeshesMatID.push_back(Materials.size() - 1); // others polyCount += dstIndexBuffer->getIndexCount(); if (UseVBOs) { if (UseVisibilityAndVBOs) { nchunk->setHardwareMappingHint(scene::EHM_STATIC, scene::EBT_VERTEX); nchunk->setHardwareMappingHint(scene::EHM_DYNAMIC, scene::EBT_INDEX); } else nchunk->setHardwareMappingHint(scene::EHM_STATIC); } else { nchunk->setHardwareMappingHint(scene::EHM_NEVER); } } StdOctree = new Octree(StdMeshes, StdMeshesMatID, MinimalPolysPerNode); nodeCount = StdOctree->getNodeCount(); } const u32 endTime = os::Timer::getRealTime(); c8 tmp[255]; sprintf(tmp, "Needed %ums to create Octree SceneNode.(%u nodes, %u polys)", endTime - beginTime, nodeCount, polyCount/3); os::Printer::log(tmp, ELL_INFORMATION); return true; }