void ProjectManager::initializeSceneManager() { assert(QThread::currentThread() == thread()); Ogre::Root& root = Ogre::Root::getSingleton(); Ogre::SceneManager* mgr = NULL; if(root.hasSceneManager(Application::sSceneManagerName)) { mgr = root.getSceneManager(Application::sSceneManagerName); root.destroySceneManager(mgr); } mgr = root.createSceneManager(Ogre::ST_GENERIC, Application::sSceneManagerName); mgr->setShadowTechnique(Ogre::SHADOWTYPE_NONE); mgr->setAmbientLight(Ogre::ColourValue(1, 1, 1)); mgr->setShadowCasterRenderBackFaces(false); mgr->setCameraRelativeRendering(true); mgr->setShowDebugShadows(true); // This fixes some issues with ray casting when using shallow terrain. Ogre::AxisAlignedBox box; Ogre::Vector3 max(100000, 100000, 100000); box.setExtents(-max, max); mgr->setOption("Size", &box); }
/* ******************************************************************************* | implement of CGrassSticks ******************************************************************************* */ void CGrassSticks::createGrassMesh() { MeshPtr mesh = MeshManager::getSingleton().createManual(GRASS_MESH_NAME, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); // create a submesh with the grass material SubMesh* sm = mesh->createSubMesh(); sm->setMaterialName("Examples/GrassBlades"); sm->useSharedVertices = false; sm->vertexData = OGRE_NEW VertexData(); sm->vertexData->vertexStart = 0; sm->vertexData->vertexCount = 12; sm->indexData->indexCount = 18; // specify a vertex format declaration for our mesh: 3 floats for position, 3 floats for normal, 2 floats for UV VertexDeclaration* decl = sm->vertexData->vertexDeclaration; decl->addElement(0, 0, VET_FLOAT3, VES_POSITION); decl->addElement(0, sizeof(float) * 3, VET_FLOAT3, VES_NORMAL); decl->addElement(0, sizeof(float) * 6, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); // create a vertex buffer HardwareVertexBufferSharedPtr vb = HardwareBufferManager::getSingleton().createVertexBuffer (decl->getVertexSize(0), sm->vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); GrassVertex* verts = (GrassVertex*)vb->lock(HardwareBuffer::HBL_DISCARD); // start filling in vertex data for (unsigned int i = 0; i < 3; i++) // each grass mesh consists of 3 planes { // planes intersect along the Y axis with 60 degrees between them Real x = Math::Cos(Degree(i * 60)) * GRASS_WIDTH / 2; Real z = Math::Sin(Degree(i * 60)) * GRASS_WIDTH / 2; for (unsigned int j = 0; j < 4; j++) // each plane has 4 vertices { GrassVertex& vert = verts[i * 4 + j]; vert.x = j < 2 ? -x : x; vert.y = j % 2 ? 0 : GRASS_HEIGHT; vert.z = j < 2 ? -z : z; // all normals point straight up vert.nx = 0; vert.ny = 1; vert.nz = 0; vert.u = j < 2 ? 0 : 1; vert.v = j % 2; } } vb->unlock(); // commit vertex changes sm->vertexData->vertexBufferBinding->setBinding(0, vb); // bind vertex buffer to our submesh // create an index buffer sm->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer (HardwareIndexBuffer::IT_16BIT, sm->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); // start filling in index data Ogre::uint16* indices = (Ogre::uint16*)sm->indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD); for (unsigned int i = 0; i < 3; i++) // each grass mesh consists of 3 planes { unsigned int off = i * 4; // each plane consists of 2 triangles *indices++ = 0 + off; *indices++ = 3 + off; *indices++ = 1 + off; *indices++ = 0 + off; *indices++ = 2 + off; *indices++ = 3 + off; } sm->indexData->indexBuffer->unlock(); // commit index changes // update mesh AABB Ogre::AxisAlignedBox aabb; aabb.setExtents(-1,-1,-1,1,1,1); mesh->_setBounds(aabb); // Ogre::MeshSerializer serial; // serial.exportMesh(mesh.getPointer(), "grass.mesh"); }
void Terrain::buildGeometry(Ogre::SceneNode* parent, bool editable) { clearGeometry(); assert(parent); // NB: We must adjust world geometry bounding box, especially for OctreeSceneManager Ogre::AxisAlignedBox aabb = mData->getBoundBox(); Ogre::Vector3 centre = aabb.getCenter(); const Ogre::Vector3 adjust(2000, 10000, 2000); const Ogre::Real scale = 1.5f; aabb.setExtents( (aabb.getMinimum() - centre) * scale + centre - adjust, (aabb.getMaximum() - centre) * scale + centre + adjust); parent->getCreator()->setOption("Size", &aabb); mEditable = editable; if (!mData->mXSize || !mData->mZSize) { // Do nothing if it's empty terrain. return; } // Prepare atlas texture for (size_t pixmapId = 0, numPixmap = mData->mPixmaps.size(); pixmapId < numPixmap; ++pixmapId) { _getPixmapAtlasId(pixmapId); } prepareLightmapTexture(); int depth = mData->mZSize; int width = mData->mXSize; int tileSize = mData->mTileSize; int numTilePerX = mData->mNumTilePerX; int numTilePerZ = mData->mNumTilePerZ; if (mEditable) { mGridTypeInfos.resize(2); mGridTypeInfos[0].material.setNull(); mGridTypeInfos[1].material = Ogre::MaterialManager::getSingleton().getByName( "FairyEditor/GridType"); } else { _initIndexBuffer(tileSize * tileSize); } mTiles.reserve(numTilePerX * numTilePerZ); for (int z = 0; z < numTilePerZ; ++z) { for (int x = 0; x < numTilePerX; ++x) { // Create the tile int tileX = x * tileSize; int tileZ = z * tileSize; int tileWidth = std::min(width - tileX, tileSize); int tileDepth = std::min(depth - tileZ, tileSize); TerrainTile* tile; if (mEditable) tile = new TerrainTileEditable(parent, this, tileX, tileZ, tileWidth, tileDepth); else tile = new TerrainTileOptimized(parent, this, tileX, tileZ, tileWidth, tileDepth); // Use the render queue that the world geometry associated with. tile->setRenderQueueGroup(parent->getCreator()->getWorldGeometryRenderQueue()); // Attach it to the aux data mTiles.push_back(tile); } } }
BOOL CCamera_Scene::_GetInterPatch( const Fairy::TerrainData* pTerrainData, //地形数据 const fVector3& fvEyePos, //眼睛的投影位置 CAMERA_INTER_GRIDS& theInterPatch) //地形数据 { theInterPatch.m_fvGrid.clear(); //是否在地形外面 if(!pTerrainData || !(pTerrainData->isValidCoord(fvEyePos.x, fvEyePos.z))) return FALSE; //取得最近的Grid交点 std::pair<INT, INT> pJunction = pTerrainData->getJunction(fvEyePos.x, fvEyePos.z); //最多四个个Grid theInterPatch.m_fvGrid.reserve(4); FLOAT fPatchX = pTerrainData->mScale.x*1.0f; FLOAT fPatchZ = pTerrainData->mScale.z*1.0f; //取得附近的八个三角形 for(INT i=-1; i<=0; i++) { for(INT j=-1; j<=0; j++) { INT nGridX = pJunction.first + i; INT nGridZ = pJunction.second + j; if(pTerrainData->isValidGrid(nGridX, nGridZ)) { Ogre::AxisAlignedBox newGridBox; const Fairy::TerrainData::GridInfo& grid = pTerrainData->getGridInfo(nGridX, nGridZ); //转化为一个绑定盒 FLOAT fMaxY = -std::numeric_limits<FLOAT>::max(); FLOAT fTemp; fTemp = pTerrainData->getHeight(nGridX, nGridZ); if(fTemp > fMaxY) fMaxY = fTemp; fTemp = pTerrainData->getHeight(nGridX+1, nGridZ); if(fTemp > fMaxY) fMaxY = fTemp; fTemp = pTerrainData->getHeight(nGridX, nGridZ+1); if(fTemp > fMaxY) fMaxY = fTemp; fTemp = pTerrainData->getHeight(nGridX+1, nGridZ+1); if(fTemp > fMaxY) fMaxY = fTemp; newGridBox.setExtents( nGridX*(pTerrainData->mScale.x) + pTerrainData->mPosition.x, -std::numeric_limits<FLOAT>::max(), nGridZ*(pTerrainData->mScale.z) + pTerrainData->mPosition.z, (nGridX+1)*(pTerrainData->mScale.x) + pTerrainData->mPosition.x, fMaxY, (nGridZ+1)*(pTerrainData->mScale.z) + pTerrainData->mPosition.z); theInterPatch.m_fvGrid.push_back(newGridBox); } } } if(theInterPatch.m_fvGrid.size() == 2 || theInterPatch.m_fvGrid.size() == 4) return TRUE; return FALSE; }