Пример #1
0
    void World::buildQuadTree(QuadTreeNode *node, std::vector<QuadTreeNode*>& leafs)
    {
        float halfSize = node->getSize()/2.f;

        if (node->getSize() <= mMinBatchSize)
        {
            // We arrived at a leaf
            float minZ,maxZ;
            Ogre::Vector2 center = node->getCenter();
            float cellWorldSize = getStorage()->getCellWorldSize();
            if (mStorage->getMinMaxHeights(node->getSize(), center, minZ, maxZ))
            {
                Ogre::AxisAlignedBox bounds(Ogre::Vector3(-halfSize*cellWorldSize, -halfSize*cellWorldSize, minZ),
                                    Ogre::Vector3(halfSize*cellWorldSize, halfSize*cellWorldSize, maxZ));
                convertBounds(bounds);
                node->setBoundingBox(bounds);
                leafs.push_back(node);
            }
            else
                node->markAsDummy(); // no data available for this node, skip it
            return;
        }

        if (node->getCenter().x - halfSize > mMaxX
                || node->getCenter().x + halfSize < mMinX
                || node->getCenter().y - halfSize > mMaxY
                || node->getCenter().y + halfSize < mMinY )
            // Out of bounds of the actual terrain - this will happen because
            // we rounded the size up to the next power of two
        {
            node->markAsDummy();
            return;
        }

        // Not a leaf, create its children
        node->createChild(SW, halfSize, node->getCenter() - halfSize/2.f);
        node->createChild(SE, halfSize, node->getCenter() + Ogre::Vector2(halfSize/2.f, -halfSize/2.f));
        node->createChild(NW, halfSize, node->getCenter() + Ogre::Vector2(-halfSize/2.f, halfSize/2.f));
        node->createChild(NE, halfSize, node->getCenter() + halfSize/2.f);
        buildQuadTree(node->getChild(SW), leafs);
        buildQuadTree(node->getChild(SE), leafs);
        buildQuadTree(node->getChild(NW), leafs);
        buildQuadTree(node->getChild(NE), leafs);

        // if all children are dummy, we are also dummy
        for (int i=0; i<4; ++i)
        {
            if (!node->getChild((ChildDirection)i)->isDummy())
                return;
        }
        node->markAsDummy();
    }
Пример #2
0
bool ElTerrain::create(unsigned int size, bool lod /* = true */, float tileSizeLength /* = 1.0f */)
{
	assert(size >= 1);

	mNumTilePerSide		= (unsigned int)pow((long double)2, (int)size);
	mSideLengthScalar	= tileSizeLength;
	mLod				= lod;
	mTopLod				= size - 1;

	// setup variables and data
	calculateVariables();
	preAllocMemory();
	createVertexDel();

	// build vertices
	buildVertices();

	// build structure for organization of indices
	if (mLod)
	{
		buildQuadTree();
		buildQuadTreeBound();
	}
	else
		buildPatchList();

	// create shader
	if (!createShader())
		return false;

	return true;
}
Пример #3
0
    World::World(Ogre::SceneManager* sceneMgr,
                     Storage* storage, int visibilityFlags, bool distantLand, bool shaders, Alignment align, float minBatchSize, float maxBatchSize)
        : mStorage(storage)
        , mMinBatchSize(minBatchSize)
        , mMaxBatchSize(maxBatchSize)
        , mSceneMgr(sceneMgr)
        , mVisibilityFlags(visibilityFlags)
        , mDistantLand(distantLand)
        , mShaders(shaders)
        , mVisible(true)
        , mAlign(align)
        , mMaxX(0)
        , mMinX(0)
        , mMaxY(0)
        , mMinY(0)
        , mChunksLoading(0)
        , mWorkQueueChannel(0)
        , mCache(storage->getCellVertices())
        , mLayerLoadPending(true)
    {
#if TERRAIN_USE_SHADER == 0
        if (mShaders)
            std::cerr << "Compiled Terrain without shader support, disabling..." << std::endl;
        mShaders = false;
#endif

        mCompositeMapSceneMgr = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC);

        /// \todo make composite map size configurable
        Ogre::Camera* compositeMapCam = mCompositeMapSceneMgr->createCamera("a");
        mCompositeMapRenderTexture = Ogre::TextureManager::getSingleton().createManual(
                    "terrain/comp/rt", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
            Ogre::TEX_TYPE_2D, 128, 128, 0, Ogre::PF_A8B8G8R8, Ogre::TU_RENDERTARGET);
        mCompositeMapRenderTarget = mCompositeMapRenderTexture->getBuffer()->getRenderTarget();
        mCompositeMapRenderTarget->setAutoUpdated(false);
        mCompositeMapRenderTarget->addViewport(compositeMapCam);

        storage->getBounds(mMinX, mMaxX, mMinY, mMaxY);

        int origSizeX = mMaxX-mMinX;
        int origSizeY = mMaxY-mMinY;

        // Dividing a quad tree only works well for powers of two, so round up to the nearest one
        int size = nextPowerOfTwo(std::max(origSizeX, origSizeY));

        // Adjust the center according to the new size
        float centerX = (mMinX+mMaxX)/2.f + (size-origSizeX)/2.f;
        float centerY = (mMinY+mMaxY)/2.f + (size-origSizeY)/2.f;

        mRootSceneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();

        // While building the quadtree, remember leaf nodes since we need to load their layers
        LayersRequestData data;
        data.mPack = getShadersEnabled();

        mRootNode = new QuadTreeNode(this, Root, size, Ogre::Vector2(centerX, centerY), NULL);
        buildQuadTree(mRootNode, data.mNodes);
        //loadingListener->indicateProgress();
        mRootNode->initAabb();
        //loadingListener->indicateProgress();
        mRootNode->initNeighbours();
        //loadingListener->indicateProgress();

        Ogre::WorkQueue* wq = Ogre::Root::getSingleton().getWorkQueue();
        mWorkQueueChannel = wq->getChannel("LargeTerrain");
        wq->addRequestHandler(mWorkQueueChannel, this);
        wq->addResponseHandler(mWorkQueueChannel, this);

        // Start loading layers in the background (for leaf nodes)
        wq->addRequest(mWorkQueueChannel, REQ_ID_LAYERS, Ogre::Any(data));
    }