17 #include <GameObject.h> 22 #define EPSILON 0.00001f 26 bool rayTriangle(chag::float3 r_o, chag::float3 r_d,
27 chag::float3 v1, chag::float3 v2,
28 chag::float3 v3,
float *ins) {
29 chag::float3 e2 = v3 - v1;
30 chag::float3 e1 = v2 - v1;
33 chag::float3 r = chag::cross(r_d, e2);
36 chag::float3 s = r_o - v1;
40 chag::float3 q = chag::cross(s, e1);
41 float u = chag::dot(s, r);
45 if ((u < 0) || (u > a))
return false;
46 float v = chag::dot(r_d, q);
47 if ((v < 0) || (u + v > a))
return false;
50 if ((u > 0) || (u < a))
return false;
51 float v = chag::dot(r_d, q);
52 if ((v > 0) || (u + v < a))
return false;
55 float t = f * chag::dot(e2, q);
63 #define ISECT(VV0,VV1,VV2,D0,D1,D2,isect0,isect1) \ 64 isect0=VV0+(VV1-VV0)*D0/(D0-D1); \ 65 isect1=VV0+(VV2-VV0)*D0/(D0-D2); 68 #define EDGE_EDGE_TEST(V0,U0,U1) \ 75 if((f>0 && d>=0 && d<=f) || (f<0 && d<=0 && d>=f)) \ 80 if(e>=0 && e<=f) return 1; \ 84 if(e<=0 && e>=f) return 1; \ 89 #define EDGE_AGAINST_TRI_EDGES(V0,V1,U0,U1,U2) \ 91 float Ax,Ay,Bx,By,Cx,Cy,e,d,f; \ 95 EDGE_EDGE_TEST(V0,U0,U1); \ 97 EDGE_EDGE_TEST(V0,U1,U2); \ 99 EDGE_EDGE_TEST(V0,U2,U0); \ 102 #define POINT_IN_TRI(V0,U0,U1,U2) \ 104 float a,b,c,d0,d1,d2; \ 108 b=-(U1[i0]-U0[i0]); \ 109 c=-a*U0[i0]-b*U0[i1]; \ 110 d0=a*V0[i0]+b*V0[i1]+c; \ 113 b=-(U2[i0]-U1[i0]); \ 114 c=-a*U1[i0]-b*U1[i1]; \ 115 d1=a*V0[i0]+b*V0[i1]+c; \ 118 b=-(U0[i0]-U2[i0]); \ 119 c=-a*U2[i0]-b*U2[i1]; \ 120 d2=a*V0[i0]+b*V0[i1]+c; \ 123 if(d0*d2>0.0) return 1; \ 127 bool coplanar_tri_tri(float3 N,float3 V0,float3 V1,float3 V2,
128 float3 U0,float3 U1,float3 U2)
165 EDGE_AGAINST_TRI_EDGES(V0,V1,U0,U1,U2);
166 EDGE_AGAINST_TRI_EDGES(V1,V2,U0,U1,U2);
167 EDGE_AGAINST_TRI_EDGES(V2,V0,U0,U1,U2);
170 POINT_IN_TRI(V0,U0,U1,U2);
171 POINT_IN_TRI(U0,V0,V1,V2);
176 #define COMPUTE_INTERVALS(VV0,VV1,VV2,D0,D1,D2,D0D1,D0D2,isect0,isect1) \ 181 ISECT(VV2,VV0,VV1,D2,D0,D1,isect0,isect1); \ 186 ISECT(VV1,VV0,VV2,D1,D0,D2,isect0,isect1); \ 188 else if(D1*D2>0.0f || D0!=0.0f) \ 191 ISECT(VV0,VV1,VV2,D0,D1,D2,isect0,isect1); \ 195 ISECT(VV1,VV0,VV2,D1,D0,D2,isect0,isect1); \ 199 ISECT(VV2,VV0,VV1,D2,D0,D1,isect0,isect1); \ 204 return coplanar_tri_tri(N1,V0,V1,V2,U0,U1,U2); \ 231 float du0,du1,du2,dv0,dv1,dv2;
233 float isect1[2], isect2[2];
234 float du0du1,du0du2,dv0dv1,dv0dv2;
253 if(fabs(du0)<EPSILON) du0=0.0;
254 if(fabs(du1)<EPSILON) du1=0.0;
255 if(fabs(du2)<EPSILON) du2=0.0;
259 if(du0du1>0.0f && du0du2>0.0f)
274 if(fabs(dv0)<EPSILON) dv0=0.0;
275 if(fabs(dv1)<EPSILON) dv1=0.0;
276 if(fabs(dv2)<EPSILON) dv2=0.0;
281 if(dv0dv1>0.0f && dv0dv2>0.0f)
292 if(b>max) max=b,index=1;
293 if(c>max) max=c,index=2;
305 COMPUTE_INTERVALS(vp0,vp1,vp2,dv0,dv1,dv2,dv0dv1,dv0dv2,isect1[0],isect1[1]);
308 COMPUTE_INTERVALS(up0,up1,up2,du0,du1,du2,du0du1,du0du2,isect2[0],isect2[1]);
310 SORT(isect1[0],isect1[1]);
311 SORT(isect2[0],isect2[1]);
313 if(isect1[1]<isect2[0] || isect2[1]<isect1[0]) {
return false;}
317 bool AabbAabbintersection(
AABB *aabb1,
AABB *aabb2) {
318 if (aabb1->maxV.x < aabb2->minV.x) {
return false; }
319 if (aabb1->maxV.y < aabb2->minV.y) {
return false; }
320 if (aabb1->maxV.z < aabb2->minV.z) {
return false; }
322 if (aabb2->maxV.x < aabb1->minV.x) {
return false; }
323 if (aabb2->maxV.y < aabb1->minV.y) {
return false; }
324 if (aabb2->maxV.z < aabb1->minV.z) {
return false; }
330 return length(sphere1.getPosition()-sphere2.getPosition()) < sphere1.getRadius()+sphere2.getRadius();
334 bool raySphereIntersection(
Sphere sphere, float3 rayOrigin, float3 rayDirection){
335 float3 l = sphere.getPosition() - rayOrigin;
336 float projOflOnRayDir = dot(l,rayDirection);
338 float r2 = sphere.getRadius()*sphere.getRadius();
339 if(projOflOnRayDir < 0 && l2 > r2)
return false;
340 float m2 = l2 - projOflOnRayDir*projOflOnRayDir;
341 if(m2 > r2)
return false;
349 Triangle multiplyTriangleWithModelMatrix(
Triangle *triangle, float4x4 *modelMatrix) {
350 float4 p1 = make_vector(triangle->p1.x, triangle->p1.y, triangle->p1.z, 1.0f);
351 float4 p2 = make_vector(triangle->p2.x, triangle->p2.y, triangle->p2.z, 1.0f);
352 float4 p3 = make_vector(triangle->p3.x, triangle->p3.y, triangle->p3.z, 1.0f);
354 float4 convertedP1 = *modelMatrix * p1;
355 float4 convertedP2 = *modelMatrix * p2;
356 float4 convertedP3 = *modelMatrix * p3;
358 float3 p1f3 = make_vector(convertedP1.x, convertedP1.y, convertedP1.z);
359 float3 p2f3 = make_vector(convertedP2.x, convertedP2.y, convertedP2.z);
360 float3 p3f3 = make_vector(convertedP3.x, convertedP3.y, convertedP3.z);
365 void calculateAndUpdateMinMax(float3 point, float4x4* modelMatrix, float3 *minV, float3 *maxV) {
366 float4 convertedValue = *modelMatrix * make_vector(point.x, point.y, point.z, 1.0f);
368 if( maxV->x < convertedValue.x) { maxV->x = convertedValue.x;}
369 if( maxV->y < convertedValue.y) { maxV->y = convertedValue.y;}
370 if( maxV->z < convertedValue.z) { maxV->z = convertedValue.z;}
372 if( minV->x > convertedValue.x) { minV->x = convertedValue.x;}
373 if( minV->y > convertedValue.y) { minV->y = convertedValue.y;}
374 if( minV->z > convertedValue.z) { minV->z = convertedValue.z;}
378 AABB multiplyAABBWithModelMatrix(
AABB *aabb, float4x4 modelMat) {
379 float4x4* modelMatrix = &modelMat;
382 calculateAndUpdateMinMax(make_vector(aabb->maxV.x,aabb->maxV.y,aabb->maxV.z), modelMatrix, &convertedAabb.minV, &convertedAabb.maxV);
383 calculateAndUpdateMinMax(make_vector(aabb->maxV.x,aabb->maxV.y,aabb->minV.z), modelMatrix, &convertedAabb.minV, &convertedAabb.maxV);
384 calculateAndUpdateMinMax(make_vector(aabb->maxV.x,aabb->minV.y,aabb->maxV.z), modelMatrix, &convertedAabb.minV, &convertedAabb.maxV);
385 calculateAndUpdateMinMax(make_vector(aabb->maxV.x,aabb->minV.y,aabb->minV.z), modelMatrix, &convertedAabb.minV, &convertedAabb.maxV);
387 calculateAndUpdateMinMax(make_vector(aabb->minV.x,aabb->maxV.y,aabb->maxV.z), modelMatrix, &convertedAabb.minV, &convertedAabb.maxV);
388 calculateAndUpdateMinMax(make_vector(aabb->minV.x,aabb->maxV.y,aabb->minV.z), modelMatrix, &convertedAabb.minV, &convertedAabb.maxV);
389 calculateAndUpdateMinMax(make_vector(aabb->minV.x,aabb->minV.y,aabb->maxV.z), modelMatrix, &convertedAabb.minV, &convertedAabb.maxV);
390 calculateAndUpdateMinMax(make_vector(aabb->minV.x,aabb->minV.y,aabb->minV.z), modelMatrix, &convertedAabb.minV, &convertedAabb.maxV);
392 return convertedAabb;
395 bool octreeOctreeIntersection(
Octree *object1Octree, float4x4 *object1ModelMatrix,
Octree *object2Octree,
396 float4x4 *object2ModelMatrix) {
397 AABB object1Aabb = multiplyAABBWithModelMatrix(object1Octree->
getAABB(), *object1ModelMatrix);
398 AABB object2Aabb = multiplyAABBWithModelMatrix(object2Octree->
getAABB(), *object2ModelMatrix);
400 if (!AabbAabbintersection(&object1Aabb, &object2Aabb)) {
405 return isTrianglesIntersecting(object1Octree, object1ModelMatrix, object2Octree, object2ModelMatrix);
407 if(isTrianglesIntersecting(object1Octree, object1ModelMatrix, object2Octree, object2ModelMatrix)) {
411 std::vector<Octree *> object1Children;
414 for (
auto it = object1Children.begin(); it != object1Children.end(); it++) {
415 if (octreeOctreeIntersection(*it, object1ModelMatrix, object2Octree, object2ModelMatrix)) {
420 std::vector<Octree *> object2Children;
423 for (
auto it = object2Children.begin(); it != object2Children.end(); it++) {
424 if (octreeOctreeIntersection(object1Octree, object1ModelMatrix, *it, object2ModelMatrix)) {
429 if(isTrianglesIntersecting(object1Octree, object1ModelMatrix, object2Octree, object2ModelMatrix)) {
433 std::vector<Octree *> object2Children;
436 for (
auto it = object2Children.begin(); it != object2Children.end(); it++) {
437 if(octreeOctreeIntersection(object1Octree, object1ModelMatrix, *it, object2ModelMatrix)) {
444 if(isTrianglesIntersecting(object1Octree, object1ModelMatrix, object2Octree, object2ModelMatrix)) {
448 std::vector<Octree *> object1Children;
451 for (
auto it = object1Children.begin(); it != object1Children.end(); it++) {
452 if(octreeOctreeIntersection(*it, object1ModelMatrix, object2Octree, object2ModelMatrix)) {
462 bool isTrianglesIntersecting(
Octree *object1Octree, float4x4 *object1ModelMatrix,
Octree *object2Octree,
463 float4x4 *object2ModelMatrix) {
464 std::vector<Triangle *> *triangles1 = object1Octree->
getTriangles();
465 std::vector<Triangle *> *triangles2 = object2Octree->
getTriangles();
467 if(triangles1->size() == 0 || triangles2->size() == 0) {
471 for (
auto t1 = triangles1->begin(); t1 != triangles1->end(); t1++) {
472 Triangle triangle1 = multiplyTriangleWithModelMatrix(*t1, object1ModelMatrix);
473 for (
auto t2 = triangles2->begin(); t2 != triangles2->end(); t2++) {
474 Triangle triangle2 = multiplyTriangleWithModelMatrix(*t2, object2ModelMatrix);
476 if (triangleTriangleIntersection(&triangle1, &triangle2)) {
std::vector< Triangle * > * getTriangles()
void getChildren(std::vector< Octree * > *octs)