373{
374
375 Vector u0 = make_vector(v0.x + off.x, v0.y + off.y, v0.z + off.z);
376 Vector u1 = make_vector(v1.x + off.x, v1.y + off.y, v1.z + off.z);
377
378 OctreeDebugLog(
@"DEBUG octant: [%d] radius: %.2f vs. line: (%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f)",
379 level, rad, u0.x, u0.y, u0.z, u1.x, u1.y, u1.z);
380
381 if (octbuffer[level] == 0)
382 {
384 return NO;
385 }
386
387 if (octbuffer[level] == -1)
388 {
390 collbuffer[level] = 2;
391 hit_dist = sqrt(u0.x * u0.x + u0.y * u0.y + u0.z * u0.z);
392 return YES;
393 }
394
395 int faces = face_hit;
396 if (faces == 0)
398
399 if (faces == 0)
400 {
402 return NO;
403 }
404
405 int octantIntersected = 0;
406
407 if (faces > 0)
408 {
410
411 if (CUBE_FACE_FRONT & faces)
412 octantIntersected = ((vi.x < 0.0)? 1: 5) + ((vi.y < 0.0)? 0: 2);
413 if (CUBE_FACE_BACK & faces)
414 octantIntersected = ((vi.x < 0.0)? 0: 4) + ((vi.y < 0.0)? 0: 2);
415
416 if (CUBE_FACE_RIGHT & faces)
417 octantIntersected = ((vi.y < 0.0)? 4: 6) + ((vi.z < 0.0)? 0: 1);
418 if (CUBE_FACE_LEFT & faces)
419 octantIntersected = ((vi.y < 0.0)? 0: 2) + ((vi.z < 0.0)? 0: 1);
420
421 if (CUBE_FACE_TOP & faces)
422 octantIntersected = ((vi.x < 0.0)? 2: 6) + ((vi.z < 0.0)? 0: 1);
423 if (CUBE_FACE_BOTTOM & faces)
424 octantIntersected = ((vi.x < 0.0)? 0: 4) + ((vi.z < 0.0)? 0: 1);
425
426 OctreeDebugLog(
@"----> found intersection with face 0x%2x of cube of radius %.2f at (%.2f, %.2f, %.2f) octant:%d",
427 faces, rad, vi.x, vi.y, vi.z, octantIntersected);
428 }
429 else
430 {
431 OctreeDebugLog(
@"----> inside cube of radius %.2f octant:%d", rad, octantIntersected);
432 }
433
435
436 collbuffer[level] = 1;
437
439
440 int nextLevel = level + octbuffer[level];
441
442 GLfloat rd2 = 0.5f * rad;
443
444
445 int oct0, oct1, oct2, oct3;
446 oct0 = octantIntersected;
447 oct1 = oct0 ^ 0x01;
448 oct2 = oct0 ^ 0x02;
449 oct3 = oct0 ^ 0x04;
450
452 if (
isHitByLineSub(octbuffer, collbuffer, nextLevel, rad, rd2, u0, u1, oct0))
return YES;
453
454
455
456 OctreeDebugLog(
@"----> testing next three octants [+%d] [+%d] [+%d]", oct1, oct2, oct3);
457 if (
isHitByLineSub(octbuffer, collbuffer, nextLevel, rad, rd2, u0, u1, oct1))
return YES;
458 if (
isHitByLineSub(octbuffer, collbuffer, nextLevel, rad, rd2, u0, u1, oct2))
return YES;
459 if (
isHitByLineSub(octbuffer, collbuffer, nextLevel, rad, rd2, u0, u1, oct3))
return YES;
460
461
462
463 oct0 ^= 0x07; oct1 ^= 0x07; oct2 ^= 0x07; oct3 ^= 0x07;
464
465 OctreeDebugLog(
@"----> testing back three octants [+%d] [+%d] [+%d]", oct1, oct2, oct3);
466 if (
isHitByLineSub(octbuffer, collbuffer, nextLevel, rad, rd2, u0, u1, oct1))
return YES;
467 if (
isHitByLineSub(octbuffer, collbuffer, nextLevel, rad, rd2, u0, u1, oct2))
return YES;
468 if (
isHitByLineSub(octbuffer, collbuffer, nextLevel, rad, rd2, u0, u1, oct3))
return YES;
469
470
472 if (
isHitByLineSub(octbuffer, collbuffer, nextLevel, rad, rd2, u0, u1, oct0))
return YES;
473
474 return NO;
475}
Vector lineIntersectionWithFace(Vector p1, Vector p2, long mask, GLfloat rd)
int lineCubeIntersection(Vector v0, Vector v1, GLfloat rd)
#define OctreeDebugLog(format,...)
static BOOL isHitByLineSub(const int *octbuffer, unsigned char *collbuffer, int nextLevel, GLfloat rad, GLfloat rd2, Vector v0, Vector v1, int octantMask)