summaryrefslogtreecommitdiff
path: root/core/math
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2014-06-11 10:41:03 -0300
committerJuan Linietsky <reduzio@gmail.com>2014-06-11 10:41:03 -0300
commit9b8696d3dd92e2ed6f310ad0f0bf3c2182c9c6ae (patch)
treeb2ed0515196bb774504b54aab0bf242992ac3d9f /core/math
parent6f0b4678e26c04abfc88c0226c803e78a108de98 (diff)
Light Baker!
-=-=-=-=-=-= -Support for lightmap baker, have fun figuring out how it works before tutorial is published.
Diffstat (limited to 'core/math')
-rw-r--r--core/math/aabb.cpp9
-rw-r--r--core/math/aabb.h61
-rw-r--r--core/math/face3.cpp2
-rw-r--r--core/math/face3.h169
4 files changed, 230 insertions, 11 deletions
diff --git a/core/math/aabb.cpp b/core/math/aabb.cpp
index 0d454cd07d..576e4fa928 100644
--- a/core/math/aabb.cpp
+++ b/core/math/aabb.cpp
@@ -335,15 +335,6 @@ AABB AABB::grow(real_t p_by) const {
aabb.grow_by(p_by);
return aabb;
}
-void AABB::grow_by(real_t p_amount) {
-
- pos.x-=p_amount;
- pos.y-=p_amount;
- pos.z-=p_amount;
- size.x+=2.0*p_amount;
- size.y+=2.0*p_amount;
- size.z+=2.0*p_amount;
-}
void AABB::get_edge(int p_edge,Vector3& r_from,Vector3& r_to) const {
diff --git a/core/math/aabb.h b/core/math/aabb.h
index 87be03cf16..089d5d15f7 100644
--- a/core/math/aabb.h
+++ b/core/math/aabb.h
@@ -73,6 +73,8 @@ public:
AABB intersection(const AABB& p_aabb) const; ///get box where two intersect, empty if no intersection occurs
bool intersects_segment(const Vector3& p_from, const Vector3& p_to,Vector3* r_clip=NULL,Vector3* r_normal=NULL) const;
bool intersects_ray(const Vector3& p_from, const Vector3& p_dir,Vector3* r_clip=NULL,Vector3* r_normal=NULL) const;
+ _FORCE_INLINE_ bool smits_intersect_ray(const Vector3 &from,const Vector3& p_dir, float t0, float t1) const;
+
_FORCE_INLINE_ bool intersects_convex_shape(const Plane *p_plane, int p_plane_count) const;
bool intersects_plane(const Plane &p_plane) const;
@@ -89,7 +91,7 @@ public:
_FORCE_INLINE_ real_t get_shortest_axis_size() const;
AABB grow(real_t p_by) const;
- void grow_by(real_t p_amount);
+ _FORCE_INLINE_ void grow_by(real_t p_amount);
void get_edge(int p_edge,Vector3& r_from,Vector3& r_to) const;
_FORCE_INLINE_ Vector3 get_endpoint(int p_point) const;
@@ -314,6 +316,63 @@ inline real_t AABB::get_shortest_axis_size() const {
return max_size;
}
+bool AABB::smits_intersect_ray(const Vector3 &from,const Vector3& dir, float t0, float t1) const {
+
+ float divx=1.0/dir.x;
+ float divy=1.0/dir.y;
+ float divz=1.0/dir.z;
+
+ Vector3 upbound=pos+size;
+ float tmin, tmax, tymin, tymax, tzmin, tzmax;
+ if (dir.x >= 0) {
+ tmin = (pos.x - from.x) * divx;
+ tmax = (upbound.x - from.x) * divx;
+ }
+ else {
+ tmin = (upbound.x - from.x) * divx;
+ tmax = (pos.x - from.x) * divx;
+ }
+ if (dir.y >= 0) {
+ tymin = (pos.y - from.y) * divy;
+ tymax = (upbound.y - from.y) * divy;
+ }
+ else {
+ tymin = (upbound.y - from.y) * divy;
+ tymax = (pos.y - from.y) * divy;
+ }
+ if ( (tmin > tymax) || (tymin > tmax) )
+ return false;
+ if (tymin > tmin)
+ tmin = tymin;
+ if (tymax < tmax)
+ tmax = tymax;
+ if (dir.z >= 0) {
+ tzmin = (pos.z - from.z) * divz;
+ tzmax = (upbound.z - from.z) * divz;
+ }
+ else {
+ tzmin = (upbound.z - from.z) * divz;
+ tzmax = (pos.z - from.z) * divz;
+ }
+ if ( (tmin > tzmax) || (tzmin > tmax) )
+ return false;
+ if (tzmin > tmin)
+ tmin = tzmin;
+ if (tzmax < tmax)
+ tmax = tzmax;
+ return ( (tmin < t1) && (tmax > t0) );
+}
+
+void AABB::grow_by(real_t p_amount) {
+
+ pos.x-=p_amount;
+ pos.y-=p_amount;
+ pos.z-=p_amount;
+ size.x+=2.0*p_amount;
+ size.y+=2.0*p_amount;
+ size.z+=2.0*p_amount;
+}
+
typedef AABB Rect3;
#endif // AABB_H
diff --git a/core/math/face3.cpp b/core/math/face3.cpp
index 9cdf31ed84..814f2d675d 100644
--- a/core/math/face3.cpp
+++ b/core/math/face3.cpp
@@ -247,7 +247,7 @@ bool Face3::intersects_aabb(const AABB& p_aabb) const {
p_aabb.get_edge(i,from,to);
Vector3 e1=from-to;
for (int j=0;j<3;j++) {
- Vector3 e2=edge_norms[i];
+ Vector3 e2=edge_norms[j];
Vector3 axis=vec3_cross( e1, e2 );
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