Xbox LIVE Indie Games
Sort Discussions: Previous Discussion Next Discussion
Page 1 of 1 (8 posts)

Paul Bourke's Marching Cubes Method in XNA

Last post 4/23/2012 3:41 AM by Alex Althauser. 7 replies.
  • 5/8/2011 11:57 AM

    Paul Bourke's Marching Cubes Method in XNA

    If anyone is interested the source code I produced can be found here.

    Hey,
         Earlier today I was working on converting the code in Paul Bourke's Polygonise into c# XNA (From C++) in order to create marching cube voxel terrain as an alternative to a simple height map. All went well with converting the two tables for looking up values into C#, which I have uploaded here and here in case they may be of use to anyone, although I do not believe this to be a problem, if anyone notices a mistake please point it out. The problem I face at this point is with trying to convert the if statements such as

    if (edgeTable[cubeindex] & 1)

    into C#/XNA. I believe the & sign acts as a pointer, but with my limited knowledge I am unsure how to convert this into C#/XNA. The code I currently have leading up to this point, excluding the tables is below.

                // The 3D grid of density values to be used. 
                int[, ,] density = new int[10, 10, 10]; 
                // The density values of the eight corners of the cube. 
                int[] dense = new int[8]; 
                // The storage for the points to made be made into triangles 
                List<Vector3> points = new List<Vector3>(); 
     
                int cubeIndex = 0; 
     
                // Work out where 
                if (dense[0] < isolevel) 
                    cubeIndex += 1; 
                if (dense[1] < isolevel) 
                    cubeIndex += 2; 
                if (dense[2] < isolevel) 
                    cubeIndex += 4; 
                if (dense[3] < isolevel) 
                    cubeIndex += 8; 
                if (dense[4] < isolevel) 
                    cubeIndex += 16; 
                if (dense[5] < isolevel) 
                    cubeIndex += 32; 
                if (dense[6] < isolevel) 
                    cubeIndex += 64; 
                if (dense[7] < isolevel) 
                    cubeIndex += 128; 

    Any help would be greatly appreciated, and I will try to link the code here when it is complete for anyone who might find it helpful in the future.

    Thanks in advance, Jekev.

  • 5/8/2011 12:40 PM In reply to

    Re: Paul Bourke's Marching Cubes Method in XNA

    That's a binary & operator: http://msdn.microsoft.com/en-us/library/sbf85k1c.aspx It can be used for bitwise operations: http://en.wikipedia.org/wiki/Bitwise_operation#AND
  • 5/8/2011 2:37 PM In reply to

    Re: Paul Bourke's Marching Cubes Method in XNA

    Like you've been already answered, & is a bitwise 'and'. In that case it will set every bit to 0 in edgeTable[cubeIndex] and check if the last bit is 1. so something like if ((edgeTable[cubeindex] & 1) == 1) should work
  • 5/8/2011 3:49 PM In reply to

    Re: Paul Bourke's Marching Cubes Method in XNA

    Thanks for the responses,
    I have set up a small check method to see if a bit is set based on the above code:

            bool BitSet(int b, int pos) 
            { 
                return ((b & pos) == 1); 
            } 

    as well as the method described here however, neither seem to be producing the correct results, although this may be due to factors elsewhere in the code. The one suggested by null interactive seems to return nothing in the vertlist from which triangles are constructed, while the linked method returns some vertices. (Although presumably not the correct ones)

    The function for finding the triangles for a grid square is completed with the below code, in case it can be of use:

                Vector3[] vertlist = new Vector3[12]; 
                if (IsBitSet(edgeTable[cubeIndex], 1)) 
                    vertlist[0] = VertexInterp(isolevel, grid.p[0], grid.p[1], grid.val[0], grid.val[1]); 
                if (IsBitSet(edgeTable[cubeIndex], 2)) 
                    vertlist[1] = VertexInterp(isolevel, grid.p[1], grid.p[2], grid.val[1], grid.val[2]); 
                if (IsBitSet(edgeTable[cubeIndex], 4)) 
                    vertlist[2] = VertexInterp(isolevel, grid.p[2], grid.p[3], grid.val[2], grid.val[3]); 
                if (IsBitSet(edgeTable[cubeIndex], 8)) 
                    vertlist[3] = VertexInterp(isolevel, grid.p[3], grid.p[0], grid.val[3], grid.val[0]); 
                if (IsBitSet(edgeTable[cubeIndex], 16)) 
                    vertlist[4] = VertexInterp(isolevel, grid.p[4], grid.p[5], grid.val[4], grid.val[5]); 
                if (IsBitSet(edgeTable[cubeIndex], 32)) 
                    vertlist[5] = VertexInterp(isolevel, grid.p[5], grid.p[6], grid.val[5], grid.val[6]); 
                if (IsBitSet(edgeTable[cubeIndex], 64)) 
                    vertlist[6] = VertexInterp(isolevel, grid.p[6], grid.p[7], grid.val[6], grid.val[7]); 
                if (IsBitSet(edgeTable[cubeIndex], 128)) 
                    vertlist[7] = VertexInterp(isolevel, grid.p[7], grid.p[4], grid.val[7], grid.val[4]); 
                if (IsBitSet(edgeTable[cubeIndex], 256)) 
                    vertlist[8] = VertexInterp(isolevel, grid.p[0], grid.p[4], grid.val[0], grid.val[4]); 
                if (IsBitSet(edgeTable[cubeIndex], 512)) 
                    vertlist[9] = VertexInterp(isolevel, grid.p[1], grid.p[5], grid.val[1], grid.val[5]); 
                if (IsBitSet(edgeTable[cubeIndex], 1024)) 
                    vertlist[10] = VertexInterp(isolevel, grid.p[2], grid.p[6], grid.val[2], grid.val[6]); 
                if (IsBitSet(edgeTable[cubeIndex], 2048)) 
                    vertlist[11] = VertexInterp(isolevel, grid.p[3], grid.p[7], grid.val[3], grid.val[7]); 
     
                for (int i = 0; triTable[cubeIndex][i] != -1; i += 3) 
                { 
                    returnTriangles.Add(new Triangle(vertlist[triTable[cubeIndex][i]], vertlist[triTable[cubeIndex][i + 1]], vertlist[triTable[cubeIndex][i + 2]])); 
                } 

    Where VertexInterp is a copy of the version in the article. A text file can be found here to prevent this post being full of code.

    The code is presented to work with a 10 by 10 by 10 grid (float[10, 10, 10]) where all points where y = 4 are set to 1. Isolevel is set to 0.9f and the rest of the points are not set. The method returns a lot of triangles (simply a class of 3 Vector3s) but all corners are set to '0,0,0', and nothing can be seen to be drawn on screen when sent to a renderer (this functions correctly when passed a valid triangle). Thanks in advance for any further help you can provide.
  • 5/8/2011 4:19 PM In reply to

    Re: Paul Bourke's Marching Cubes Method in XNA

    you would do something like this:

    bool BitSet(int b, int pos) 
      return ((b & pos) == pos); 


    its a way to check if the bits set in pos are also set in 'b', and that seems like what he was doing in the original code
  • 5/8/2011 6:10 PM In reply to

    Re: Paul Bourke's Marching Cubes Method in XNA

    I've tried to do a game based on marching cubes once. But I didn't have the time nor the knowledge to complete it back then. But maybe what I did can still be of use to you - no guarantees though. :) SurfaceMesh class: http://pastebin.com/aY1txh92 LevelSet class: http://pastebin.com/bcgv5Nxi Testdata xml: http://pastebin.com/VrbHjNgk
  • 5/8/2011 7:15 PM In reply to

    Re: Paul Bourke's Marching Cubes Method in XNA

    null interactive:
    you would do something like this:

    bool BitSet(int b, int pos) 
      return ((b & pos) == pos); 


    its a way to check if the bits set in pos are also set in 'b', and that seems like what he was doing in the original code


    Thanks, this did the trick perfectly!

    Suzume:
    I've tried to do a game based on marching cubes once. But I didn't have the time nor the knowledge to complete it back then. But maybe what I did can still be of use to you - no guarantees though. :) SurfaceMesh class: http://pastebin.com/aY1txh92 LevelSet class: http://pastebin.com/bcgv5Nxi Testdata xml: http://pastebin.com/VrbHjNgk


    Thanks, I will take a proper look through your code a bit later, but from a quick look it seems like it could be really helpful.

    On topic, the code is now working, although in a very basic way, I will try to improve and comment it before posting it in full here. Again, thanks for the help Suzume and Null Interactive.

    EDIT: See the first post for links to the completed code.

  • 4/23/2012 3:41 AM In reply to

    Re: Paul Bourke's Marching Cubes Method in XNA

    Hi Jekev,
    I'm trying to build a simple 3d Metaball program using the marching cubes algorithm, c# & xna. Could you tell me if your code would be helpful at all, and what would I need to change? I understand the basics of Metaballs and the marching cubes algorithm, but small important facts elude me. I have been unable to find a decent C# tutorial on them.
    Thank you for the help,
    -Alex
Page 1 of 1 (8 posts) Previous Discussion Next Discussion