Page 1 of 1

Swapping terrain page

Posted: Wed Feb 23, 2005 11:18 pm
by DWORD
I'm trying to change TerrainSceneManager::attachPage() so that a page can be attached multiple times and just replace the old page. (Useful for updating an already loaded page in a background thread.)

I'm facing a problem, however, because when I delete the old page inside attachPage(), it looks like it's already been queued for rendering, and therefore an access violation occurs on next rendering (stack trace). The code I use right now for testing looks like this: (And yes, I know I shouldn't delete the terrain page here. I'm going to use SharedPtrs so it'll be handled automatically.)

Code: Select all

    void TerrainSceneManager::attachPage(ushort pageX, ushort pageZ, TerrainPage* page)
    {
        assert(pageX == 0 && pageZ == 0 && "Multiple pages not yet supported");

        //assert(mTerrainPages[pageX][pageZ] == 0 && "Page at that index not yet expired!");
        if (mTerrainPages[pageX][pageZ])
        {
            // Detach old page from terrain root
            mTerrainRoot->removeChild(mTerrainPages[pageX][pageZ]->pageSceneNode);
            delete mTerrainPages[pageX][pageZ];
        }
        // Insert page into list
        mTerrainPages[pageX][pageZ] = page;
        // Attach page to terrain root
        mTerrainRoot->addChild(page->pageSceneNode);

    }
Is there any special order I have to follow when removing and adding the scene node of the terrain page to avoid this error?

Posted: Fri Feb 25, 2005 4:18 pm
by DWORD
Bump? Maybe I should note that the call to attachPage() is indirectly made inside a frameStarted() or frameEnded() function - I get the same error no matter which of them I use.

Posted: Fri Feb 25, 2005 9:35 pm
by sinbad
I suspect the problem is that the SceneNode which the page was attached to still thinks it's there. Try detaching the page from the pageSceneNode before deleting it.

Posted: Sun Feb 27, 2005 12:46 am
by DWORD
After hours of debugging I think I have found the cause of this problem. The error appears only to happen, when I create a new TerrainPage before destroying the old one. This is necessary, though, to avoid lag when building the new page.

TerrainRenderable::mLevelIndex is initialised in the TerrainRenderable constructor by calling TerrainRenderable::_initLevelIndexes(), which only initialises the vector if the static member mLevelInit is false. This is ok when building the first page.

When I build the second TerrainPage, TerrainRenderable::mLevelInit is still true, so the mLevelIndex vector is left unchanged. However, when I perform the page swapping I need to delete the old TerrainPage, and in its destructor, the TerrainRenderable::mLevelIndex is cleared during the call to TerrainRenderable::_destroyLevelIndexes().

The effect of this is, that I have lots of TerrainRenderables with an uninitialised mLevelIndex. And this is what caused an access violation. I don't know how this is best fixed, though, but as far as I can see this will also block paging capability, because as soon as the first TerrainRenderable is destroyed, so is the static mLevelIndex. Maybe some reference counting is needed?

Posted: Sun Feb 27, 2005 6:48 pm
by sinbad
Given that the paging capability has not been tested (I just put the interface hooks in whilst I was doing something else), I'm not surprised there are some practicality issues.

I'm not going to have time to do any serious work on TSM for a while, you might want to consider trying PLSM2 if you don't have the time to resolve the paging issues in TSM.

Posted: Sun Feb 27, 2005 10:51 pm
by DWORD
Ok, thanks for your answer. I know you have many irons in the fire; I'll see if I can figure out something. :)