int DecalManager::addTerrainSplineDecal(Ogre::SimpleSpline *spline, float width, Ogre::Vector2 numSeg, Ogre::Vector2 uvSeg, Ogre::String materialname, float ground_offset, Ogre::String export_fn, bool debug) { #if 0 Ogre::ManualObject *mo = gEnv->ogreSceneManager->createManualObject(); String oname = mo->getName(); SceneNode *mo_node = terrain_decals_snode->createChildSceneNode(); mo->begin(materialname, Ogre::RenderOperation::OT_TRIANGLE_LIST); AxisAlignedBox *aab=new AxisAlignedBox(); int offset = 0; // how width is the road? float delta_width = width / numSeg.x; float steps_len = 1.0f / numSeg.x; for (int l = 0; l<=numSeg.x; l++) { // get current position on that spline Vector3 pos_cur = spline->interpolate(steps_len * (float)l); Vector3 pos_next = spline->interpolate(steps_len * (float)(l + 1)); Ogre::Vector3 direction = (pos_next - pos_cur); if (l == numSeg.x) { // last segment uses previous position pos_next = spline->interpolate(steps_len * (float)(l - 1)); direction = (pos_cur - pos_next); } for (int w = 0; w<=numSeg.y; w++) { // build vector for the width Vector3 wn = direction.normalisedCopy().crossProduct(Vector3::UNIT_Y); // calculate the offset, spline in the middle Vector3 offset = (-0.5 * wn * width) + (w/numSeg.y) * wn * width; // push everything together Ogre::Vector3 pos = pos_cur + offset; // get ground height there pos.y = hfinder->getHeightAt(pos.x, pos.z) + ground_offset; // add the position to the mesh mo->position(pos); aab->merge(pos); mo->textureCoord(l/(Ogre::Real)numSeg.x*uvSeg.x, w/(Ogre::Real)numSeg.y*uvSeg.y); mo->normal(Vector3::UNIT_Y); } } bool reverse = false; for (int n1 = 0; n1<numSeg.x; n1++) { for (int n2 = 0; n2<numSeg.y; n2++) { if (reverse) { mo->index(offset+0); mo->index(offset+(numSeg.y+1)); mo->index(offset+1); mo->index(offset+1); mo->index(offset+(numSeg.y+1)); mo->index(offset+(numSeg.y+1)+1); } else { mo->index(offset+0); mo->index(offset+1); mo->index(offset+(numSeg.y+1)); mo->index(offset+1); mo->index(offset+(numSeg.y+1)+1); mo->index(offset+(numSeg.y+1)); } offset++; } offset++; } offset+=numSeg.y+1; mo->end(); mo->setBoundingBox(*aab); // some optimizations mo->setCastShadows(false); mo->setDynamic(false); delete(aab); MeshPtr mesh = mo->convertToMesh(oname+"_mesh"); // build edgelist mesh->buildEdgeList(); // remove the manualobject again, since we dont need it anymore gEnv->ogreSceneManager->destroyManualObject(mo); unsigned short src, dest; if (!mesh->suggestTangentVectorBuildParams(VES_TANGENT, src, dest)) { mesh->buildTangentVectors(VES_TANGENT, src, dest); } Entity *ent = gEnv->ogreSceneManager->createEntity(oname+"_ent", oname+"_mesh"); mo_node->attachObject(ent); mo_node->setVisible(true); //mo_node->showBoundingBox(true); mo_node->setPosition(Vector3::ZERO); //(position.x, 0, position.z)); if (!export_fn.empty()) { MeshSerializer *ms = new MeshSerializer(); ms->exportMesh(mesh.get(), export_fn); LOG("spline mesh exported as " + export_fn); delete(ms); } // TBD: RTSS //Ogre::RTShader::ShaderGenerator::getSingleton().createShaderBasedTechnique(materialname, Ogre::MaterialManager::DEFAULT_SCHEME_NAME, Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); //Ogre::RTShader::ShaderGenerator::getSingleton().invalidateMaterial(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, materialname); RTSSgenerateShadersForMaterial(materialname, ""); #endif return 0; }
int DecalManager::addTerrainDecal(Ogre::Vector3 position, Ogre::Vector2 size, Ogre::Vector2 numSeg, Ogre::Real rotation, Ogre::String materialname, Ogre::String normalname) { #if 0 Ogre::ManualObject *mo = gEnv->ogreSceneManager->createManualObject(); String oname = mo->getName(); SceneNode *mo_node = terrain_decals_snode->createChildSceneNode(); mo->begin(materialname, Ogre::RenderOperation::OT_TRIANGLE_LIST); AxisAlignedBox *aab=new AxisAlignedBox(); float uTile = 1, vTile = 1; Vector3 normal = Vector3(0,1,0); // UP int offset = 0; float ground_dist = 0.001f; Ogre::Vector3 vX = normal.perpendicular(); Ogre::Vector3 vY = normal.crossProduct(vX); Ogre::Vector3 delta1 = size.x / numSeg.x * vX; Ogre::Vector3 delta2 = size.y / numSeg.y * vY; // build one corner of the square Ogre::Vector3 orig = -0.5*size.x*vX - 0.5*size.y*vY; for (int i1 = 0; i1<=numSeg.x; i1++) for (int i2 = 0; i2<=numSeg.y; i2++) { Vector3 pos = orig+i1*delta1+i2*delta2 + position; pos.y = hfinder->getHeightAt(pos.x, pos.z) + ground_dist; mo->position(pos); aab->merge(pos); mo->textureCoord(i1/(Ogre::Real)numSeg.x*uTile, i2/(Ogre::Real)numSeg.y*vTile); mo->normal(normal); } bool reverse = false; if (delta1.crossProduct(delta2).dotProduct(normal)>0) reverse= true; for (int n1 = 0; n1<numSeg.x; n1++) { for (int n2 = 0; n2<numSeg.y; n2++) { if (reverse) { mo->index(offset+0); mo->index(offset+(numSeg.y+1)); mo->index(offset+1); mo->index(offset+1); mo->index(offset+(numSeg.y+1)); mo->index(offset+(numSeg.y+1)+1); } else { mo->index(offset+0); mo->index(offset+1); mo->index(offset+(numSeg.y+1)); mo->index(offset+1); mo->index(offset+(numSeg.y+1)+1); mo->index(offset+(numSeg.y+1)); } offset++; } offset++; } offset+=numSeg.y+1; mo->end(); mo->setBoundingBox(*aab); // some optimizations mo->setCastShadows(false); mo->setDynamic(false); delete(aab); MeshPtr mesh = mo->convertToMesh(oname+"_mesh"); // build edgelist mesh->buildEdgeList(); // remove the manualobject again, since we dont need it anymore gEnv->ogreSceneManager->destroyManualObject(mo); unsigned short src, dest; if (!mesh->suggestTangentVectorBuildParams(VES_TANGENT, src, dest)) { mesh->buildTangentVectors(VES_TANGENT, src, dest); } Entity *ent = gEnv->ogreSceneManager->createEntity(oname+"_ent", oname+"_mesh"); mo_node->attachObject(ent); mo_node->setVisible(true); //mo_node->showBoundingBox(true); mo_node->setPosition(Vector3::ZERO); //(position.x, 0, position.z)); // RTSS //Ogre::RTShader::ShaderGenerator::getSingleton().createShaderBasedTechnique(materialname, Ogre::MaterialManager::DEFAULT_SCHEME_NAME, Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); //Ogre::RTShader::ShaderGenerator::getSingleton().invalidateMaterial(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, materialname); RTSSgenerateShadersForMaterial(materialname, normalname); #endif return 0; }
void OgreRecast::update() { // Fully rebuild static geometry after a reset (when tiles should be removed) if(m_rebuildSg) { m_sg->reset(); // Add navmesh tiles (polys) to static geometry Ogre::SceneManager::MovableObjectIterator iterator = m_pSceneMgr->getMovableObjectIterator("Entity"); while(iterator.hasMoreElements()) { Ogre::Entity* ent = static_cast<Ogre::Entity*>(iterator.getNext()); // Add all navmesh poly debug entities if(Ogre::StringUtil::startsWith(ent->getName(), "ent_recastmowalk_")) m_sg->addEntity(ent, Ogre::Vector3::ZERO); } m_sg->build(); // Batch all lines together in one single manualObject (since we cannot use staticGeometry for lines) if(m_pSceneMgr->hasManualObject("AllNeighbourLines")) { m_pRecastSN->detachObject("AllNeighbourLines") ; m_pSceneMgr->destroyManualObject("AllNeighbourLines"); } if(m_pSceneMgr->hasManualObject("AllBoundaryLines")) { m_pRecastSN->detachObject("AllBoundaryLines") ; m_pSceneMgr->destroyManualObject("AllBoundaryLines"); } Ogre::ManualObject *allNeighbourLines = m_pSceneMgr->createManualObject("AllNeighbourLines"); allNeighbourLines->begin("recastdebug", Ogre::RenderOperation::OT_LINE_LIST); allNeighbourLines->colour(m_navmeshNeighbourEdgeCol); Ogre::ManualObject *allBoundaryLines = m_pSceneMgr->createManualObject("AllBoundaryLines"); allBoundaryLines->begin("recastdebug", Ogre::RenderOperation::OT_LINE_LIST); allBoundaryLines->colour(m_navmeshOuterEdgeCol); iterator = m_pSceneMgr->getMovableObjectIterator("ManualObject"); while(iterator.hasMoreElements()) { Ogre::ManualObject* man = static_cast<Ogre::ManualObject*>(iterator.getNext()); if(Ogre::StringUtil::startsWith(man->getName(), "recastmoneighbour_")) { std::vector<Ogre::Vector3> verts = getManualObjectVertices(man); for(std::vector<Ogre::Vector3>::iterator iter = verts.begin(); iter != verts.end(); iter++) { allNeighbourLines->position(*iter); } } else if(Ogre::StringUtil::startsWith(man->getName(), "recastmoboundary_")) { std::vector<Ogre::Vector3> verts = getManualObjectVertices(man); for(std::vector<Ogre::Vector3>::iterator iter = verts.begin(); iter != verts.end(); iter++) { allBoundaryLines->position(*iter); } } } allNeighbourLines->end(); allBoundaryLines->end(); m_pRecastSN->attachObject(allNeighbourLines); m_pRecastSN->attachObject(allBoundaryLines); m_rebuildSg = false; } }