204- (void) drawOctreeFromLocation:(uint32_t)loc :(GLfloat)scale :(Vector)offset
206 if (_octree[loc] == 0)
213 if (_octree[loc] == -1)
247 else if (_octree[loc] > 0)
249 GLfloat sc = 0.5f * scale;
251 [
self drawOctreeFromLocation:loc + _octree[
loc] + 0 :sc :make_vector(offset.x - sc, offset.y - sc, offset.z - sc)];
253 [
self drawOctreeFromLocation:loc + _octree[
loc] + 1 :sc :make_vector(offset.x - sc, offset.y - sc, offset.z + sc)];
255 [
self drawOctreeFromLocation:loc + _octree[
loc] + 2 :sc :make_vector(offset.x - sc, offset.y + sc, offset.z - sc)];
257 [
self drawOctreeFromLocation:loc + _octree[
loc] + 3 :sc :make_vector(offset.x - sc, offset.y + sc, offset.z + sc)];
259 [
self drawOctreeFromLocation:loc + _octree[
loc] + 4 :sc :make_vector(offset.x + sc, offset.y - sc, offset.z - sc)];
261 [
self drawOctreeFromLocation:loc + _octree[
loc] + 5 :sc :make_vector(offset.x + sc, offset.y - sc, offset.z + sc)];
263 [
self drawOctreeFromLocation:loc + _octree[
loc] + 6 :sc :make_vector(offset.x + sc, offset.y + sc, offset.z - sc)];
265 [
self drawOctreeFromLocation:loc + _octree[
loc] + 7 :sc :make_vector(offset.x + sc, offset.y + sc, offset.z + sc)];
289- (void) drawOctreeCollisionFromLocation:(uint32_t)loc :(GLfloat)scale :(Vector)offset
291 if (_octree[loc] == 0)
296 if ((_octree[loc] != 0)&&(_collisionOctree[loc] != (
unsigned char)0))
300 GLfloat red = (GLfloat)(_collisionOctree[loc])/255.0;
301 glColor4f(1.0, 0.0, 0.0, red);
304 _collisionOctree[
loc]--;
307 OOGL(glDisable(GL_CULL_FACE));
309 OOGL(glDisable(GL_TEXTURE_2D));
341 OOGL(glEnable(GL_CULL_FACE));
343 if (_octree[loc] > 0)
345 GLfloat sc = 0.5f * scale;
346 [
self drawOctreeCollisionFromLocation:loc + _octree[
loc] + 0 :sc :make_vector(offset.x - sc, offset.y - sc, offset.z - sc)];
347 [
self drawOctreeCollisionFromLocation:loc + _octree[
loc] + 1 :sc :make_vector(offset.x - sc, offset.y - sc, offset.z + sc)];
348 [
self drawOctreeCollisionFromLocation:loc + _octree[
loc] + 2 :sc :make_vector(offset.x - sc, offset.y + sc, offset.z - sc)];
349 [
self drawOctreeCollisionFromLocation:loc + _octree[
loc] + 3 :sc :make_vector(offset.x - sc, offset.y + sc, offset.z + sc)];
350 [
self drawOctreeCollisionFromLocation:loc + _octree[
loc] + 4 :sc :make_vector(offset.x + sc, offset.y - sc, offset.z - sc)];
351 [
self drawOctreeCollisionFromLocation:loc + _octree[
loc] + 5 :sc :make_vector(offset.x + sc, offset.y - sc, offset.z + sc)];
352 [
self drawOctreeCollisionFromLocation:loc + _octree[
loc] + 6 :sc :make_vector(offset.x + sc, offset.y + sc, offset.z - sc)];
353 [
self drawOctreeCollisionFromLocation:loc + _octree[
loc] + 7 :sc :make_vector(offset.x + sc, offset.y + sc, offset.z + sc)];
372static BOOL
isHitByLine(
const int *octbuffer,
unsigned char *collbuffer,
int level, GLfloat rad, Vector v0, Vector v1, Vector off,
int face_hit)
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);
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);
381 if (octbuffer[level] == 0)
387 if (octbuffer[level] == -1)
390 collbuffer[
level] = 2;
391 hit_dist = sqrt(u0.x * u0.x + u0.y * u0.y + u0.z * u0.z);
395 int faces = face_hit;
405 int octantIntersected = 0;
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);
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);
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);
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);
431 OctreeDebugLog(
@"----> inside cube of radius %.2f octant:%d", rad, octantIntersected);
436 collbuffer[
level] = 1;
440 int nextLevel = level + octbuffer[
level];
442 GLfloat rd2 = 0.5f * rad;
445 int oct0, oct1, oct2, oct3;
446 oct0 = octantIntersected;
452 if (
isHitByLineSub(octbuffer, collbuffer, nextLevel, rad, rd2, u0, u1, oct0))
return YES;
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;
463 oct0 ^= 0x07; oct1 ^= 0x07; oct2 ^= 0x07; oct3 ^= 0x07;
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;
472 if (
isHitByLineSub(octbuffer, collbuffer, nextLevel, rad, rd2, u0, u1, oct0))
return YES;
498 Octree_details otherDetails, Vector otherPosition, Triangle other_ijk)
500 const int *axialBuffer = axialDetails.
octree;
501 const int *otherBuffer = otherDetails.
octree;
503 if (axialBuffer[0] == 0)
515 if (otherBuffer[0] == 0)
521 GLfloat axialRadius = axialDetails.
radius;
522 GLfloat otherRadius = otherDetails.
radius;
524 if (otherRadius < axialRadius)
527 if ((otherPosition.x + otherRadius < -axialRadius)||(otherPosition.x - otherRadius > axialRadius)||
528 (otherPosition.y + otherRadius < -axialRadius)||(otherPosition.y - otherRadius > axialRadius)||
529 (otherPosition.z + otherRadius < -axialRadius)||(otherPosition.z - otherRadius > axialRadius))
531 OctreeDebugLog(
@"%@",
@"----> Other sphere does not intersect axial cube");
537 Vector d2 = vector_flip(otherPosition);
538 Vector axialPosition = resolveVectorInIJK(d2, other_ijk);
539 if ((axialPosition.x + axialRadius < -otherRadius)||(axialPosition.x - axialRadius > otherRadius)||
540 (axialPosition.y + axialRadius < -otherRadius)||(axialPosition.y - axialRadius > otherRadius)||
541 (axialPosition.z + axialRadius < -otherRadius)||(axialPosition.z - axialRadius > otherRadius))
543 OctreeDebugLog(
@"%@",
@"----> Axial sphere does not intersect other cube");
551 if (axialBuffer[0] == -1)
554 if (otherBuffer[0] == -1)
557 axialCollisionBuffer[0] = (
unsigned char)255;
558 otherCollisionBuffer[0] = (
unsigned char)255;
571 int nearest_oct = ((otherPosition.x > 0.0)? 0:4)|((otherPosition.y > 0.0)? 0:2)|((otherPosition.z > 0.0)? 0:1);
573 int nextLevel = otherBuffer[0];
574 const int *nextBuffer = &otherBuffer[
nextLevel];
575 unsigned char *nextCollisionBuffer = &otherCollisionBuffer[
nextLevel];
577 Vector voff, nextPosition;
580 nextDetails.
radius = 0.5f * otherRadius;
581 for (i = 0; i < 8; i++)
589 voff = resolveVectorInIJK(
offsetForOctant(oct, otherRadius), other_ijk);
590 nextPosition = vector_subtract(otherPosition, voff);
591 if (
isHitByOctree(axialDetails, nextDetails, nextPosition, other_ijk))
607 int nearest_oct = ((otherPosition.x > 0.0)? 4:0)|((otherPosition.y > 0.0)? 2:0)|((otherPosition.z > 0.0)? 1:0);
609 int nextLevel = axialBuffer[0];
610 const int *nextBuffer = &axialBuffer[
nextLevel];
611 unsigned char *nextCollisionBuffer = &axialCollisionBuffer[
nextLevel];
616 nextDetails.
radius = 0.5f * axialRadius;
617 for (i = 0; i < 8; i++)
625 nextPosition = vector_add(otherPosition,
offsetForOctant(oct, axialRadius));
626 if (
isHitByOctree(nextDetails, otherDetails, nextPosition, other_ijk))
static BOOL isHitByLine(const int *octbuffer, unsigned char *collbuffer, int level, GLfloat rad, Vector v0, Vector v1, Vector off, int face_hit)