diff options
Diffstat (limited to 'core/math/face3.h')
-rw-r--r-- | core/math/face3.h | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/core/math/face3.h b/core/math/face3.h index 3a62f7f812..630c408de3 100644 --- a/core/math/face3.h +++ b/core/math/face3.h @@ -86,6 +86,7 @@ public: } bool intersects_aabb(const AABB& p_aabb) const; + _FORCE_INLINE_ bool intersects_aabb2(const AABB& p_aabb) const; operator String() const; inline Face3() {} @@ -94,4 +95,172 @@ public: }; +bool Face3::intersects_aabb2(const AABB& p_aabb) const { + + Vector3 perp = (vertex[0]-vertex[2]).cross(vertex[0]-vertex[1]); + + Vector3 half_extents = p_aabb.size * 0.5; + Vector3 ofs = p_aabb.pos + half_extents; + + Vector3 sup =Vector3( + (perp.x>0) ? -half_extents.x : half_extents.x, + (perp.y>0) ? -half_extents.y : half_extents.y, + (perp.z>0) ? -half_extents.z : half_extents.z + ); + + float d = perp.dot(vertex[0]); + float dist_a = perp.dot(ofs+sup)-d; + float dist_b = perp.dot(ofs-sup)-d; + + if (dist_a*dist_b > 0) + return false; //does not intersect the plane + + +#define TEST_AXIS(m_ax)\ + {\ + float aabb_min=p_aabb.pos.m_ax;\ + float aabb_max=p_aabb.pos.m_ax+p_aabb.size.m_ax;\ + float tri_min,tri_max;\ + for (int i=0;i<3;i++) {\ + if (i==0 || vertex[i].m_ax > tri_max)\ + tri_max=vertex[i].m_ax;\ + if (i==0 || vertex[i].m_ax < tri_min)\ + tri_min=vertex[i].m_ax;\ + }\ +\ + if (tri_max<aabb_min || aabb_max<tri_min)\ + return false;\ + } + + TEST_AXIS(x); + TEST_AXIS(y); + TEST_AXIS(z); + +#undef TEST_AXIS + + + Vector3 edge_norms[3]={ + vertex[0]-vertex[1], + vertex[1]-vertex[2], + vertex[2]-vertex[0], + }; + + for (int i=0;i<12;i++) { + + Vector3 from,to; + switch(i) { + + case 0:{ + + from=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y , p_aabb.pos.z ); + to=Vector3( p_aabb.pos.x , p_aabb.pos.y , p_aabb.pos.z ); + } break; + case 1:{ + + from=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y , p_aabb.pos.z+p_aabb.size.z ); + to=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y , p_aabb.pos.z ); + } break; + case 2:{ + from=Vector3( p_aabb.pos.x , p_aabb.pos.y , p_aabb.pos.z+p_aabb.size.z ); + to=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y , p_aabb.pos.z+p_aabb.size.z ); + + } break; + case 3:{ + + from=Vector3( p_aabb.pos.x , p_aabb.pos.y , p_aabb.pos.z ); + to=Vector3( p_aabb.pos.x , p_aabb.pos.y , p_aabb.pos.z+p_aabb.size.z ); + + } break; + case 4:{ + + from=Vector3( p_aabb.pos.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z ); + to=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z ); + } break; + case 5:{ + + from=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z ); + to=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z+p_aabb.size.z ); + } break; + case 6:{ + from=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z+p_aabb.size.z ); + to=Vector3( p_aabb.pos.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z+p_aabb.size.z ); + + } break; + case 7:{ + + from=Vector3( p_aabb.pos.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z+p_aabb.size.z ); + to=Vector3( p_aabb.pos.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z ); + + } break; + case 8:{ + + from=Vector3( p_aabb.pos.x , p_aabb.pos.y , p_aabb.pos.z+p_aabb.size.z ); + to=Vector3( p_aabb.pos.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z+p_aabb.size.z ); + + } break; + case 9:{ + + from=Vector3( p_aabb.pos.x , p_aabb.pos.y , p_aabb.pos.z ); + to=Vector3( p_aabb.pos.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z ); + + } break; + case 10:{ + + from=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y , p_aabb.pos.z ); + to=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z ); + + } break; + case 11:{ + + from=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y , p_aabb.pos.z+p_aabb.size.z ); + to=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z+p_aabb.size.z ); + + } break; + + } + + Vector3 e1=from-to; + for (int j=0;j<3;j++) { + Vector3 e2=edge_norms[j]; + + Vector3 axis=vec3_cross( e1, e2 ); + + if (axis.length_squared()<0.0001) + continue; // coplanar + //axis.normalize(); + + Vector3 sup2 =Vector3( + (axis.x>0) ? -half_extents.x : half_extents.x, + (axis.y>0) ? -half_extents.y : half_extents.y, + (axis.z>0) ? -half_extents.z : half_extents.z + ); + + float maxB = axis.dot(ofs+sup2); + float minB = axis.dot(ofs-sup2); + if (minB>maxB) { + SWAP(maxB,minB); + } + + float minT=1e20,maxT=-1e20; + for (int k=0;k<3;k++) { + + float d=axis.dot(vertex[k]); + + if (d > maxT) + maxT=d; + + if (d < minT) + minT=d; + } + + if (maxB<minT || maxT<minB) + return false; + } + } + return true; + + +} + + #endif // FACE3_H |