3 #ifndef RENDERER_DETAIL_TRACE_H
4 #define RENDERER_DETAIL_TRACE_H
15 #include <boost/math/special_functions.hpp>
50 template<
int t_ColorFormat,
int t_Platform >
52 uint8_t*
const colorDestination,
53 float*
const depthDestination,
54 typename Synchronized::TextureHeap< t_ColorFormat, t_Platform >::Pointer
const& texture,
58 unsigned int const origin
61 static unsigned int const maskTable[] = { 0, 3, 12, 15, 48, 51, 60, 63 };
63 unsigned int const mask = maskTable[ origin ];
64 unsigned int index = 0;
66 remainingMaximum /= 2;
67 if ( remaining[ 0 ] >= remainingMaximum[ 0 ] ) {
70 remaining[ 0 ] -= remainingMaximum[ 0 ];
72 if ( remaining[ 1 ] >= remainingMaximum[ 1 ] ) {
75 remaining[ 1 ] -= remainingMaximum[ 1 ];
77 if ( remaining[ 2 ] >= remainingMaximum[ 2 ] ) {
80 remaining[ 2 ] -= remainingMaximum[ 2 ];
83 remainingMaximum /= 2;
84 if ( remaining[ 0 ] >= remainingMaximum[ 0 ] ) {
87 remaining[ 0 ] -= remainingMaximum[ 0 ];
89 if ( remaining[ 1 ] >= remainingMaximum[ 1 ] ) {
92 remaining[ 1 ] -= remainingMaximum[ 1 ];
94 if ( remaining[ 2 ] >= remainingMaximum[ 2 ] ) {
97 remaining[ 2 ] -= remainingMaximum[ 2 ];
100 int comparisons = -1;
101 while ( comparisons < 0 ) {
103 assert( ( index ^ mask ) < 64 );
104 Color< t_ColorFormat >
const& color = texture[ index ^ mask ];
105 if ( color.Packed() != 0 ) {
108 colorDestination[ 0 ] = color.Blue();
109 colorDestination[ 1 ] = color.Green();
110 colorDestination[ 2 ] = color.Red();
111 colorDestination[ 3 ] = 0xff;
113 *depthDestination = lambda;
120 ( ( remaining[ 0 ] < remaining[ 1 ] ) ? 1 : 0 ) |
121 ( ( remaining[ 1 ] < remaining[ 2 ] ) ? 2 : 0 ) |
122 ( ( remaining[ 2 ] < remaining[ 0 ] ) ? 4 : 0 )
124 switch( comparisons ) {
129 if ( ( index & 3 ) != 0 ) {
133 lambda += remaining[ 0 ];
134 remaining[ 1 ] -= remaining[ 0 ];
135 remaining[ 2 ] -= remaining[ 0 ];
136 remaining[ 0 ] = remainingMaximum[ 0 ];
146 if ( ( index & 12 ) != 0 ) {
150 lambda += remaining[ 1 ];
151 remaining[ 0 ] -= remaining[ 1 ];
152 remaining[ 2 ] -= remaining[ 1 ];
153 remaining[ 1 ] = remainingMaximum[ 1 ];
163 if ( ( index & 48 ) != 0 ) {
167 lambda += remaining[ 2 ];
168 remaining[ 0 ] -= remaining[ 2 ];
169 remaining[ 1 ] -= remaining[ 2 ];
170 remaining[ 2 ] = remainingMaximum[ 2 ];
191 template<
int t_ColorFormat,
int t_Platform >
193 uint8_t*
const colorDestination,
194 float*
const depthDestination,
201 double const epsilon = std::numeric_limits< double >::epsilon();
204 double lambda = Project( projected, ray );
205 if ( ! boost::math::isfinite( lambda ) )
208 unsigned int origin = 7;
211 if ( delta[ 0 ] < 0 ) {
214 remaining[ 0 ] = projected[ 0 ];
215 delta[ 0 ] = -delta[ 0 ];
217 if ( delta[ 1 ] < 0 ) {
220 remaining[ 1 ] = projected[ 1 ];
221 delta[ 1 ] = -delta[ 1 ];
223 if ( delta[ 2 ] < 0 ) {
226 remaining[ 2 ] = projected[ 2 ];
227 delta[ 2 ] = -delta[ 2 ];
231 delta = std::max( delta, epsilon );
233 #if ( SETTING_MIPMAP != 0 )
236 double sideLength = 1;
237 double distanceThresholds[ SETTING_TRACE_STACK_SIZE ];
238 distanceThresholds[ 0 ] = 0.125 / spread;
239 for (
unsigned int ii = 1; ii <
ARRAYLENGTH( distanceThresholds ); ++ii )
240 distanceThresholds[ ii ] = distanceThresholds[ ii - 1 ] / 2;
241 #endif // SETTING_MIPMAP
244 remaining *= remainingMaximum;
247 unsigned int indexStack[ SETTING_TRACE_STACK_SIZE ];
248 unsigned int depth = 0;
251 unsigned int index = 0;
256 while ( children[ index ].children ) {
258 #if ( SETTING_MIPMAP != 0 )
259 if ( ( distance[ 0 ] > distanceThresholds[ depth ] ) || ( distance[ 1 ] > distanceThresholds[ depth ] ) || ( distance[ 2 ] > distanceThresholds[ depth ] ) )
261 #endif // SETTING_MIPMAP
265 childrenStack[ depth ] = children;
266 indexStack[ depth ] = index;
269 children = children[ index ].children.get();
272 #if ( SETTING_MIPMAP != 0 )
274 #endif // SETTING_MIPMAP
275 remainingMaximum /= 2;
277 if ( remaining[ 0 ] >= remainingMaximum[ 0 ] ) {
279 remaining[ 0 ] -= remainingMaximum[ 0 ];
282 #if ( SETTING_MIPMAP != 0 )
284 distance[ 0 ] += sideLength;
285 #endif // SETTING_MIPMAP
287 if ( remaining[ 1 ] >= remainingMaximum[ 1 ] ) {
289 remaining[ 1 ] -= remainingMaximum[ 1 ];
292 #if ( SETTING_MIPMAP != 0 )
294 distance[ 1 ] += sideLength;
295 #endif // SETTING_MIPMAP
297 if ( remaining[ 2 ] >= remainingMaximum[ 2 ] ) {
299 remaining[ 2 ] -= remainingMaximum[ 2 ];
302 #if ( SETTING_MIPMAP != 0 )
304 distance[ 2 ] += sideLength;
305 #endif // SETTING_MIPMAP
312 int comparisons = -1;
313 if ( children[ index ].texture ) {
315 comparisons = TraceTexture< t_ColorFormat, t_Platform >(
318 children[ index ].texture,
325 if ( comparisons < 0 )
331 ( ( remaining[ 0 ] < remaining[ 1 ] ) ? 1 : 0 ) |
332 ( ( remaining[ 1 ] < remaining[ 2 ] ) ? 2 : 0 ) |
333 ( ( remaining[ 2 ] < remaining[ 0 ] ) ? 4 : 0 )
339 switch( comparisons ) {
344 #if ( SETTING_MIPMAP != 0 )
345 distance[ 0 ] += sideLength;
346 #endif // SETTING_MIPMAP
348 lambda += remaining[ 0 ];
349 remaining[ 1 ] -= remaining[ 0 ];
350 remaining[ 2 ] -= remaining[ 0 ];
354 unsigned int const indexOrigin = ( index ^ origin );
355 if ( indexOrigin & 1 ) {
362 if ( indexOrigin & 2 )
363 remaining[ 1 ] += remainingMaximum[ 1 ];
364 #if ( SETTING_MIPMAP != 0 )
366 distance[ 1 ] -= sideLength;
367 #endif // SETTING_MIPMAP
369 if ( indexOrigin & 4 )
370 remaining[ 2 ] += remainingMaximum[ 2 ];
371 #if ( SETTING_MIPMAP != 0 )
373 distance[ 2 ] -= sideLength;
374 #endif // SETTING_MIPMAP
376 #if ( SETTING_MIPMAP != 0 )
378 #endif // SETTING_MIPMAP
379 remainingMaximum *= 2;
383 children = childrenStack[ depth ];
384 index = indexStack[ depth ];
387 }
while ( depth > 0 );
389 remaining[ 0 ] = remainingMaximum[ 0 ];
396 #if ( SETTING_MIPMAP != 0 )
397 distance[ 1 ] += sideLength;
398 #endif // SETTING_MIPMAP
400 lambda += remaining[ 1 ];
401 remaining[ 0 ] -= remaining[ 1 ];
402 remaining[ 2 ] -= remaining[ 1 ];
406 unsigned int const indexOrigin = ( index ^ origin );
407 if ( indexOrigin & 2 ) {
414 if ( indexOrigin & 1 )
415 remaining[ 0 ] += remainingMaximum[ 0 ];
416 #if ( SETTING_MIPMAP != 0 )
418 distance[ 0 ] -= sideLength;
419 #endif // SETTING_MIPMAP
421 if ( indexOrigin & 4 )
422 remaining[ 2 ] += remainingMaximum[ 2 ];
423 #if ( SETTING_MIPMAP != 0 )
425 distance[ 2 ] -= sideLength;
426 #endif // SETTING_MIPMAP
428 #if ( SETTING_MIPMAP != 0 )
430 #endif // SETTING_MIPMAP
431 remainingMaximum *= 2;
435 children = childrenStack[ depth ];
436 index = indexStack[ depth ];
439 }
while ( depth > 0 );
441 remaining[ 1 ] = remainingMaximum[ 1 ];
448 #if ( SETTING_MIPMAP != 0 )
449 distance[ 2 ] += sideLength;
450 #endif // SETTING_MIPMAP
452 lambda += remaining[ 2 ];
453 remaining[ 0 ] -= remaining[ 2 ];
454 remaining[ 1 ] -= remaining[ 2 ];
458 unsigned int const indexOrigin = ( index ^ origin );
459 if ( indexOrigin & 4 ) {
466 if ( indexOrigin & 1 )
467 remaining[ 0 ] += remainingMaximum[ 0 ];
468 #if ( SETTING_MIPMAP != 0 )
470 distance[ 0 ] -= sideLength;
471 #endif // SETTING_MIPMAP
473 if ( indexOrigin & 2 )
474 remaining[ 1 ] += remainingMaximum[ 1 ];
475 #if ( SETTING_MIPMAP != 0 )
477 distance[ 1 ] -= sideLength;
478 #endif // SETTING_MIPMAP
480 #if ( SETTING_MIPMAP != 0 )
482 #endif // SETTING_MIPMAP
483 remainingMaximum *= 2;
487 children = childrenStack[ depth ];
488 index = indexStack[ depth ];
491 }
while ( depth > 0 );
493 remaining[ 2 ] = remainingMaximum[ 2 ];
499 }
while ( depth > 0 );
513 #endif // RENDERER_DETAIL_TRACE_H