Volumes Of Fun http://www.volumesoffun.com/phpBB3/ |
|
CubicSurfaceExtractor assert in addVertex http://www.volumesoffun.com/phpBB3/viewtopic.php?f=14&t=287 |
Page 1 of 1 |
Author: | VengantMjolnir [ Fri Nov 18, 2011 6:09 pm ] | |||
Post subject: | CubicSurfaceExtractor assert in addVertex | |||
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.
|
Author: | David Williams [ Sat Nov 19, 2011 12:18 am ] |
Post subject: | Re: CubicSurfaceExtractor assert in addVertex |
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. |
Author: | David Williams [ Sat Jan 07, 2012 11:53 am ] |
Post subject: | Re: CubicSurfaceExtractor assert in addVertex |
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.
|
Page 1 of 1 | All times are UTC |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |