diff options
author | Juan Linietsky <reduzio@gmail.com> | 2014-06-11 10:41:03 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2014-06-11 10:41:03 -0300 |
commit | 9b8696d3dd92e2ed6f310ad0f0bf3c2182c9c6ae (patch) | |
tree | b2ed0515196bb774504b54aab0bf242992ac3d9f /core/math | |
parent | 6f0b4678e26c04abfc88c0226c803e78a108de98 (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.cpp | 9 | ||||
-rw-r--r-- | core/math/aabb.h | 61 | ||||
-rw-r--r-- | core/math/face3.cpp | 2 | ||||
-rw-r--r-- | core/math/face3.h | 169 |
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 |