It is currently Sat Aug 22, 2020 3:33 pm


All times are UTC




Post new topic Reply to topic  [ 3 posts ] 
Author Message
 Post subject: CubicSurfaceExtractor assert in addVertex
PostPosted: Fri Nov 18, 2011 6:09 pm 

Joined: Thu Nov 17, 2011 1:33 am
Posts: 2
Hey everyone, this is addressed mostly to the Williams but if someone else has run into this before feel free to jump in.

First I'll describe my setup and then I'll go into the problem.

I have built Polyvox on windows and used it successfully in an Ogre project for the last week. I initially just had a volume class being setup that was capable of filling a set of dynamic buffers of a SimpleRenderable. This volume class contained the surface extractor, Polyvox volume and wrapper methods to interact with it. Four of these wrapper methods let you add or delete single voxels, or add or delete a sphere of a variable size. At first I set up the class to use CubicSurfaceExtractorWithNormals and everything was great. Materials were rendered by attaching a vertex color to the buffer, looked up from a color palette indexed by the material.

I wanted to try to take advantage of the improvements made to the CubicSurfaceExtractor as well as lower the vertex bandwidth by removing the normals. So, I switched the class to use a CubicSurfaceExtractor instead and just calculated the normals in the pixel shader. This was also done because I was switching to a per-pixel lighting and I thought it would just make sense to offload a bit of work to the GPU. However, here is where my problems start.

Adding voxels seems to work just fine, the volume is updated and the extractor runs over it correctly. Removing single voxels also works, but removing them in a sphere causes a runtime assert when processing a voxelof the last z loop( z == m_regSizeInVoxels.getUpperCorner().getZ() )

Its not the first voxel in either the x or y direction... so I'm not sure why its failing. The comment specifically says

//If we exit the loop here then apparently all the slots were full but none of
//them matched. I don't think this can happen so let's put an assert to make sure.

The code I am using to remove voxels is pretty simple, but I'll post it just in case I'm doing something odd.
Code:
void VoxelVolume::RemoveVoxel( Ogre::Vector3 voxelPosition )
{
    if( PositionIsValid( voxelPosition ) == false )
    {
        return;
    }

    //Our new density value
   uint8_t uDensity = 0;

   //Get the old voxel
    MaterialDensityPair44 voxel = mVolData->getVoxelAt(voxelPosition.x,voxelPosition.y,voxelPosition.z);

   //Modify the density
   voxel.setDensity(uDensity);

    uint8_t uMaterial = 0;

   //Wrte the voxel value into the volume   
   mVolData->setVoxelAt(voxelPosition.x, voxelPosition.y, voxelPosition.z, voxel);

    mDirty = true;
}

void VoxelVolume::RemoveSphereFromVolume( Ogre::Vector3 position, int radius )
{
    //This vector hold the position of the center of the sphere to remove
   Vector3DFloat v3dVolCenter( position.x, position.y, position.z );
    float fRadius = (float)radius;

   //This three-level for loop iterates over every voxel in the region to be removed
   for (int z = position.z - radius; z < position.z + radius; z++)
   {
      for (int y = position.y - radius; y < position.y + radius; y++)
      {
         for (int x = position.x - radius; x < position.x + radius; x++)
         {
            //Store our current position as a vector...
            Vector3DFloat v3dCurrentPos(x,y,z);   
            //And compute how far the current position is from the center of the intended sphere
            float fDistToCenter = (v3dCurrentPos - v3dVolCenter).length();

            //If the current voxel is less than 'radius' units from the center then we make it solid.
            if(fDistToCenter <= fRadius)
            {
                RemoveVoxel( Vector3(x, y, z) );
                }
         }
      }
   }
}


To be clear the assert is in the CubicSurfaceExtractor::addVertex() method, line 265( using latest Git source. ) Also, with a danger of stating the obvious, the assert does not happen until the surface extractor is run after modifying the volume.

EDIT -
After running in release mode to skip past the asserts I produced the following screenshots. I hope those help to illustrate the problem a bit better.


Attachments:
File comment: Rendering as a wireframe
Wireframe.png
Wireframe.png [ 92.18 KiB | Viewed 2306 times ]
File comment: Rendering as a solid
Solid.png
Solid.png [ 96.24 KiB | Viewed 2306 times ]
Top
Offline Profile  
Reply with quote  
 Post subject: Re: CubicSurfaceExtractor assert in addVertex
PostPosted: Sat Nov 19, 2011 12:18 am 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
I've made a commit which might have fixed this.

The mesh was being cleared in the constructor of the surface extractor, rather than at the start of the execute() function. I suspect most people are creating a new surface extractor each time they want to get a surface, but you are reusing the same one? Hence the old mesh is never being cleared?

Let me know if the new commit makes a difference.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: CubicSurfaceExtractor assert in addVertex
PostPosted: Sat Jan 07, 2012 11:53 am 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
I've just found and fixed another bug which was almost certainly the cause of this. I had assumed that a single vertex could be shared by no more than four quads, whereas I now believe the correct maximum is six. From the newly added comment:

Quote:
As far as I can tell, it is possible to have at most six vertices with the same position but different materials. This worst-case scenario happens when we have a 2x2x2 group of voxels (all with different materials) and then we delete two voxels from opposing corners. The vertex position at the center of this group is then going to be used by six quads all with different materials.


Top
Offline Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Theme created StylerBB.net