0
\$\begingroup\$

This one is kinda specific. If I'm to implement frustum culling in my game, that means each one of my cubes would need a bounding sphere. My first question is can I make the sphere so close to the edge of the cube that its still easily clickable for destroying and building? Frustum culling is easily done in XNA as I've recently learned, I just need to figure out where to place the code for the culling. I'm guessing in my method that draws all my cubes but I could be wrong. My camera class currently implements a bounding frustum which is in the update method like so

   frustum.Matrix = (view * proj);

Simple enough, as I can call that when I have a camera object in my class. This works for now, as I only have a camera in my main game class. The problem comes when I decide to move my camera to my player class, but I can worry about that later.

    ContainmentType CurrentContainmentType = ContainmentType.Disjoint;
    CurrentContainmentType = CamerasFrustrum.Contains(cubes.CollisionSphere);

Can it really be as easy as adding those two lines to my foreach loop in my draw method? Or am I missing something bigger here?

UPDATE: I have added the lines to my draw methods and it works great!! So great infact that just moving a little bit removes the whole map. Many factors could of caused this, so I'll try to break it down.

    cubeBoundingSphere = new BoundingSphere(cubePosition, 0.5f);

This is in my cube constructor. cubePosition is stored in an array, The vertices that define my cube are factors of 1 ie: (1,0,1) so the radius should be .5. I least I think it should. The spheres are created every time a cube is created of course.

    ContainmentType CurrentContainmentType = ContainmentType.Disjoint;

        foreach (Cube block in cube.cubes)
        {
            CurrentContainmentType = cam.frustum.Contains(cube.cubeBoundingSphere);

    ///more code here

     if (CurrentContainmentType != ContainmentType.Disjoint)
            {
                cube.Draw(effect);
            }

Within my draw method. Now I know this works because the map disappears, its just working wrong. Any idea on what I'm doing wrong?

\$\endgroup\$
1
\$\begingroup\$

answer:

A bounding sphere for a cube will not have a radius of 0.5. If the furthest point on a cube (a corner) has a model-local position of +/-(0.5,0.5,0.5) then the radius of the sphere must be equal to the length of that vector, or sqrt(0.5*0.5 + 0.5*0.5 + 0.5*0.5)=0.86602540378. A radius of 0.5 will make a sphere that touches the midpoints of the cube's faces but which does not include the corners (a midpoint along the X axis would be at (+/-X,0,0) for instance putting it at radius sqrt(0.5*0.5 + 0*0 + 0*0)=0.5, which is too small to contain the whole cube).

unsolicited advice:

Really, though, bounding spheres are not ideal here. You have cubes. Why not use an AABB? They will more tightly fit your objects (perfectly fit them, in fact) and you can easily enough do an AABB-Frustrum collision test.

Furthermore, if you're doing the Minecrafty type of rendering, don't render individual cubes. You'll spend more time culling little cubes than you will rendering the actually visible ones. Precompute a full mesh for each "chunk" of the world and simply recompute this mesh whenever you add or remove a block. Now you can cull whole chunks, which will be relatively efficient, and rendering a whole chunk in a single draw call will be cheap and the built-in triangle clipping will be more than sufficient when only a part of a chunk is visible (most likely much quicker than culling each block).

To generate the mesh, do something like:

modify(chunk):
  clear chunk.mesh
  for each block in chunk.blocks:
    for each face in block.faces:
      if face is not adjacent to another block:
        add face to mesh

All your blocks' textures will need to be in a single atlas, of course.

\$\endgroup\$
  • \$\begingroup\$ Even better, XNA has BoundingBox as well as BoundingSphere. But you're quite right, he's been told repeatedly to do one mesh per chunk by several people (including yourself and myself). \$\endgroup\$ – Andrew Russell Jul 2 '13 at 6:28
  • \$\begingroup\$ Each block will only have one texture so that'll be easy. I know people keep giving me this advice, I just don't know how to implement it properly \$\endgroup\$ – Christian Frantz Jul 2 '13 at 7:16
  • \$\begingroup\$ I thought that Contains() only worked with a bounding sphere. At least that's what the box that pops up says \$\endgroup\$ – Christian Frantz Jul 2 '13 at 7:18
  • \$\begingroup\$ I don't know Contains(), but you can always do the math yourself instead of relying on libraries. :) \$\endgroup\$ – Sean Middleditch Jul 2 '13 at 7:38
  • \$\begingroup\$ Thats very true lol. But before I work on that, I want to get my fps up above 7 and now that you've shown me how to do that, can you explain a little more in detail about how I might create meshes for my chunks of cubes? Andrew showed me a good example, but I'm having a hard time implementing into my code. All this advanced stuff is new to me. I thought just storing 2500 cubes in a single vertex buffer would be fine but I guess I'm wrong haha \$\endgroup\$ – Christian Frantz Jul 2 '13 at 7:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.