Java-Gaming.org    
Featured games (78)
games approved by the League of Dukes
Games in Showcase (426)
Games in Android Showcase (89)
games submitted by our members
Games in WIP (466)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Frustum culling question  (Read 1053 times)
0 Members and 1 Guest are viewing this topic.
zahl2001
Guest
« Posted 2004-06-18 19:14:30 »

I got the code for a frustum culling class out of a book, and there was nothing in the way of explanation, so I really don't understand how the thing does it's job.

The terrain is broken up into square blocks, and my goal is to cull the non-visible blocks.  I believe the code is good, because the demos in the book use it, and the culling works fine.

As far as I can tell, the code is testing each corner of the bounding box to see if any of them are currently visible, and if so, the block is visible.  I think the problem is that my terrain blocks are large enough so that the camera can get in a position where some of the block is still visible, yet none of the corners are. The code listed is the method used to cull the blocks.

I don't want to make the blocks smaller, so what are my options?

// x, y, z : center vertex of the block to be checked
// size    : length of one side of the block to be checked

public boolean CubeFrustumTest( float x, float y,
                                                     float z,  float size )
{
  for( int i=0; i<6; i++ )
  {
       if( m_viewFrustum
  • * ( x-size ) +
               m_viewFrustum[1] * ( y-size ) +
               m_viewFrustum[2] * ( z-size ) +
               m_viewFrustum[3] > 0 )
               continue;
               
           if( m_viewFrustum
    • * ( x+size ) +
                 m_viewFrustum[1] * ( y-size ) +
                 m_viewFrustum[2] * ( z-size ) +
                 m_viewFrustum[3] > 0 )
                 continue;
                 
             if( m_viewFrustum
      • * ( x-size ) +
                   m_viewFrustum[1] * ( y+size ) +
                   m_viewFrustum[2] * ( z-size ) +
                   m_viewFrustum[3] > 0 )
                   continue;
                   
               if( m_viewFrustum
        • * ( x+size ) +
                     m_viewFrustum[1] * ( y+size ) +
                     m_viewFrustum[2] * ( z-size ) +
                     m_viewFrustum[3] > 0 )
                     continue;
                     
                 if( m_viewFrustum
          • * ( x-size ) +
                       m_viewFrustum[1] * ( y-size ) +
                       m_viewFrustum[2] * ( z+size ) +
                       m_viewFrustum[3] > 0 )
                       continue;
                       
                   if( m_viewFrustum
            • * ( x+size ) +
                         m_viewFrustum[1] * ( y-size ) +
                         m_viewFrustum[2] * ( z+size ) +
                         m_viewFrustum[3] > 0 )
                         continue;
                         
                     if( m_viewFrustum
              • * ( x-size ) +
                           m_viewFrustum[1] * ( y+size ) +
                           m_viewFrustum[2] * ( z+size ) +
                           m_viewFrustum[3] > 0 )
                           continue;
                           
                       if( m_viewFrustum
                • * ( x+size ) +
                             m_viewFrustum[1] * ( y+size ) +
                             m_viewFrustum[2] * ( z+size ) +
                             m_viewFrustum[3] > 0 )
                             continue;

                         return false;
                     }
                       
                   return true;
                  }

                  If someone has a FrustumCuller that contains a method that would work in my case, I would be very pleased to recieve it.
                  kmyers@bardstowncable.net

                  Thanks Smiley
Offline tom
« Reply #1 - Posted 2004-06-18 21:55:29 »

Quote
As far as I can tell, the code is testing each corner of the bounding box to see if any of them are currently visible, and if so, the block is visible.

The code checks each corner of the box and if all of them is behind a plane it is not visible and returns false. The code looks correct. Try to verify that your parameters are correct. Make sure that x,y,z is in the center of the box and that size is the maximum of the box sides. If it still don't work just multiply size with 2  Tongue

zahl2001
Guest
« Reply #2 - Posted 2004-06-19 01:54:49 »

I hate to ask anybody to dig through this, but if it can be verified that this code is correct, then I'm really doing something wrong, because even expanding the 'size' argument to the culling method call didn't help :(

Note: mx is the modelview matrix, and px is the projection matrix.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
/* combine the two matrices by multiplying them */
                      clip[0]  = mx[0]*px[0]  + mx[1]*px[4]  + mx[2]*px[8]   + mx[3]*px[12];
                      clip[1]  = mx[0]*px[1]  + mx[1]*px[5]  + mx[2]*px[9]   + mx[3]*px[13];
                      clip[2]  = mx[0]*px[2]  + mx[1]*px[6]  + mx[2]*px[10]  + mx[3]*px[14];
                      clip[3]  = mx[0]*px[3]  + mx[1]*px[7]  + mx[2]*px[11]  + mx[3]*px[15];
                      
                      clip[4]  = mx[4]*px[0]  + mx[5]*px[4]  + mx[6]*px[8]   + mx[7]*px[12];
                      clip[5]  = mx[4]*px[1]  + mx[5]*px[5]  + mx[6]*px[9]   + mx[7]*px[13];
                      clip[6]  = mx[4]*px[2]  + mx[5]*px[6]  + mx[6]*px[10]  + mx[7]*px[14];
                      clip[7]  = mx[4]*px[3]  + mx[5]*px[7]  + mx[6]*px[11]  + mx[7]*px[15];
                      
                      clip[8]  = mx[8]*px[0]  + mx[9]*px[4]  + mx[10]*px[8]  + mx[11]*px[12];
                      clip[9]  = mx[8]*px[1]  + mx[9]*px[5]  + mx[10]*px[9]  + mx[11]*px[13];
                      clip[10] = mx[8]*px[2]  + mx[9]*px[6]  + mx[10]*px[10] + mx[11]*px[14];
                      clip[11] = mx[8]*px[3]  + mx[9]*px[7]  + mx[10]*px[11] + mx[11]*px[15];
                      
                      clip[12] = mx[12]*px[0] + mx[13]*px[4] + mx[14]*px[8]  + mx[15]*px[12];
                      clip[13] = mx[12]*px[1] + mx[13]*px[5] + mx[14]*px[9]  + mx[15]*px[13];
                      clip[14] = mx[12]*px[2] + mx[13]*px[6] + mx[14]*px[10] + mx[15]*px[14];
                      clip[15] = mx[12]*px[3] + mx[13]*px[7] + mx[14]*px[11] + mx[15]*px[15];
                      
                      //--------------------
                     
                      /* Extract the numbers for the RIGHT plane */
                      viewFrustum[FRUSTUM_RIGHT][0] = clip[3]  - clip[0];
                      viewFrustum[FRUSTUM_RIGHT][1] = clip[7]  - clip[4];
                      viewFrustum[FRUSTUM_RIGHT][2] = clip[11] - clip[8];
                      viewFrustum[FRUSTUM_RIGHT][3] = clip[15] - clip[12];
                      
                      /* Normalize the RIGHT plane */
                      norm = (float)Math.sqrt(
                              (viewFrustum[FRUSTUM_RIGHT][0] * viewFrustum[FRUSTUM_RIGHT][0]) +
                         (viewFrustum[FRUSTUM_RIGHT][1] * viewFrustum[FRUSTUM_RIGHT][1]) +
                         (viewFrustum[FRUSTUM_RIGHT][2] * viewFrustum[FRUSTUM_RIGHT][2])   );
                        
                      viewFrustum[FRUSTUM_RIGHT][0] /= norm;
                      viewFrustum[FRUSTUM_RIGHT][1] /= norm;
                      viewFrustum[FRUSTUM_RIGHT][2] /= norm;
                      viewFrustum[FRUSTUM_RIGHT][3] /= norm;
                      
                      //--------------------
                     
                      /* Extract the numbers for the LEFT plane */
                      viewFrustum[FRUSTUM_LEFT][0] = clip[3]  + clip[0];
                      viewFrustum[FRUSTUM_LEFT][1] = clip[7]  + clip[4];
                      viewFrustum[FRUSTUM_LEFT][2] = clip[11] + clip[8];
                      viewFrustum[FRUSTUM_LEFT][3] = clip[15] + clip[12];
                      
                      /* Normalize the LEFT plane */
                      norm = (float)Math.sqrt(
                              (viewFrustum[FRUSTUM_LEFT][0] * viewFrustum[FRUSTUM_LEFT][0]) +
                         (viewFrustum[FRUSTUM_LEFT][1] * viewFrustum[FRUSTUM_LEFT][1]) +
                         (viewFrustum[FRUSTUM_LEFT][2] * viewFrustum[FRUSTUM_LEFT][2])   );
                        
                      viewFrustum[FRUSTUM_LEFT][0] /= norm;
                      viewFrustum[FRUSTUM_LEFT][1] /= norm;
                      viewFrustum[FRUSTUM_LEFT][2] /= norm;
                      viewFrustum[FRUSTUM_LEFT][3] /= norm;
                      
                      //--------------------
                     
                      /* Extract the numbers for the BOTTOM plane */
                      viewFrustum[FRUSTUM_BOTTOM][0] = clip[3]  + clip[1];
                      viewFrustum[FRUSTUM_BOTTOM][1] = clip[7]  + clip[5];
                      viewFrustum[FRUSTUM_BOTTOM][2] = clip[11] + clip[9];
                      viewFrustum[FRUSTUM_BOTTOM][3] = clip[15] + clip[13];
                      
                      /* Normalize the BOTTOM plane */
                      norm = (float)Math.sqrt(
                              (viewFrustum[FRUSTUM_BOTTOM][0] * viewFrustum[FRUSTUM_BOTTOM][0]) +
                         (viewFrustum[FRUSTUM_BOTTOM][1] * viewFrustum[FRUSTUM_BOTTOM][1]) +
                         (viewFrustum[FRUSTUM_BOTTOM][2] * viewFrustum[FRUSTUM_BOTTOM][2])   );
                        
                      viewFrustum[FRUSTUM_BOTTOM][0] /= norm;
                      viewFrustum[FRUSTUM_BOTTOM][1] /= norm;
                      viewFrustum[FRUSTUM_BOTTOM][2] /= norm;
                      viewFrustum[FRUSTUM_BOTTOM][3] /= norm;
                      
                      //--------------------
                     
                      /* Extract the numbers for the TOP plane */
                      viewFrustum[FRUSTUM_TOP][0] = clip[3]  - clip[1];
                      viewFrustum[FRUSTUM_TOP][1] = clip[7]  - clip[5];
                      viewFrustum[FRUSTUM_TOP][2] = clip[11] - clip[9];
                      viewFrustum[FRUSTUM_TOP][3] = clip[15] - clip[13];
                      
                      /* Normalize the TOP plane */
                      norm = (float)Math.sqrt(
                              (viewFrustum[FRUSTUM_TOP][0] * viewFrustum[FRUSTUM_TOP][0]) +
                         (viewFrustum[FRUSTUM_TOP][1] * viewFrustum[FRUSTUM_TOP][1]) +
                         (viewFrustum[FRUSTUM_TOP][2] * viewFrustum[FRUSTUM_TOP][2])   );
                        
                      viewFrustum[FRUSTUM_TOP][0] /= norm;
                      viewFrustum[FRUSTUM_TOP][1] /= norm;
                      viewFrustum[FRUSTUM_TOP][2] /= norm;
                      viewFrustum[FRUSTUM_TOP][3] /= norm;
                      
                      //--------------------
                     
                      /* Extract the numbers for the FAR plane */
                      viewFrustum[FRUSTUM_FAR][0] = clip[3]  - clip[2];
                      viewFrustum[FRUSTUM_FAR][1] = clip[7]  - clip[6];
                      viewFrustum[FRUSTUM_FAR][2] = clip[11] - clip[10];
                      viewFrustum[FRUSTUM_FAR][3] = clip[15] - clip[14];
                      
                      /* Normalize the FAR plane */
                      norm = (float)Math.sqrt(
                              (viewFrustum[FRUSTUM_FAR][0] * viewFrustum[FRUSTUM_FAR][0]) +
                         (viewFrustum[FRUSTUM_FAR][1] * viewFrustum[FRUSTUM_FAR][1]) +
                         (viewFrustum[FRUSTUM_FAR][2] * viewFrustum[FRUSTUM_FAR][2])   );
                        
                      viewFrustum[FRUSTUM_FAR][0] /= norm;
                      viewFrustum[FRUSTUM_FAR][1] /= norm;
                      viewFrustum[FRUSTUM_FAR][2] /= norm;
                      viewFrustum[FRUSTUM_FAR][3] /= norm;
                      
                      //--------------------
                     
                      /* Extract the numbers for the NEAR plane */
                      viewFrustum[FRUSTUM_NEAR][0] = clip[3]  + clip[2];
                      viewFrustum[FRUSTUM_NEAR][1] = clip[7]  + clip[6];
                      viewFrustum[FRUSTUM_NEAR][2] = clip[11] + clip[10];
                      viewFrustum[FRUSTUM_NEAR][3] = clip[15] + clip[14];
                      
                      /* Normalize the NEAR plane */
                      norm = (float)Math.sqrt(
                              (viewFrustum[FRUSTUM_NEAR][0] * viewFrustum[FRUSTUM_NEAR][0]) +
                         (viewFrustum[FRUSTUM_NEAR][1] * viewFrustum[FRUSTUM_NEAR][1]) +
                         (viewFrustum[FRUSTUM_NEAR][2] * viewFrustum[FRUSTUM_NEAR][2])   );
                        
                      viewFrustum[FRUSTUM_NEAR][0] /= norm;
                      viewFrustum[FRUSTUM_NEAR][1] /= norm;
                      viewFrustum[FRUSTUM_NEAR][2] /= norm;
                      viewFrustum[FRUSTUM_NEAR][3] /= norm;
                   }
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
zahl2001
Guest
« Reply #3 - Posted 2004-06-20 00:34:32 »

I found a frustum culling tutorial on the web, and it agrees with the code I posted, so apparantly the frustum culling class I have is fine.

I can't imagine what's wrong with my program...maybe it has something to do with the fact that I use gluLookAt() for my camera...I'm at total loss.

Well, anyway, no need to bother validating the above code.
zahl2001
Guest
« Reply #4 - Posted 2004-06-20 01:47:31 »

Tom,

If you happen to read this, you were right...I was NOT sending the arguments correctly due to a "this.x = x" type error which I totally overlooked in the constructor. That mistake cost me a quite a few hours...

Anway, it works great now, and I'm quite happy about it:)
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

xsi3rr4x (75 views)
2014-04-15 18:08:23

BurntPizza (68 views)
2014-04-15 03:46:01

UprightPath (80 views)
2014-04-14 17:39:50

UprightPath (65 views)
2014-04-14 17:35:47

Porlus (81 views)
2014-04-14 15:48:38

tom_mai78101 (105 views)
2014-04-10 04:04:31

BurntPizza (165 views)
2014-04-08 23:06:04

tom_mai78101 (261 views)
2014-04-05 13:34:39

trollwarrior1 (210 views)
2014-04-04 12:06:45

CJLetsGame (220 views)
2014-04-01 02:16:10
List of Learning Resources
by SHC
2014-04-18 03:17:39

List of Learning Resources
by Longarmx
2014-04-08 03:14:44

Good Examples
by matheus23
2014-04-05 13:51:37

Good Examples
by Grunnt
2014-04-03 15:48:46

Good Examples
by Grunnt
2014-04-03 15:48:37

Good Examples
by matheus23
2014-04-01 18:40:51

Good Examples
by matheus23
2014-04-01 18:40:34

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-11 15:22:30
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!