Пример #1
0
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");
}
Пример #3
0
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);
        }
    }
}
Пример #4
0
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;
}