X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=laserbrain_demo;a=blobdiff_plain;f=src%2Fgeom.cc;h=1813eea03af3f08dd7e173489e69dcda12bbe783;hp=5fc3dce208cc6385f02f4b5cd20ee183fa1a48e7;hb=2f5ee2007d258d947f2efab3bf3460479fe34813;hpb=03085a16aa2fef785083fa3921be83015e08b290 diff --git a/src/geom.cc b/src/geom.cc index 5fc3dce..1813eea 100644 --- a/src/geom.cc +++ b/src/geom.cc @@ -1,5 +1,6 @@ -#include +#include #include +#include #include "geom.h" #include "app.h" @@ -26,6 +27,15 @@ void GeomObject::invalidate() { } +float GeomObject::distance(const Vec3 &v) const +{ + return sqrt(distance_sq(v)); +} + +float GeomObject::signed_distance(const Vec3 &v) const +{ + return sqrt(signed_distance_sq(v)); +} Sphere::Sphere() { @@ -94,14 +104,14 @@ bool Sphere::contains(const Vec3 &pt) const return length_sq(pt - center) <= radius * radius; } -float Sphere::distance(const Vec3 &v) const +float Sphere::distance_sq(const Vec3 &v) const { - return std::max(length(v - center) - radius, 0.0f); + return std::max(length_sq(v - center) - radius * radius, 0.0f); } -float Sphere::signed_distance(const Vec3 &v) const +float Sphere::signed_distance_sq(const Vec3 &v) const { - return length(v - center) - radius; + return length_sq(v - center) - radius * radius; } AABox::AABox() @@ -135,6 +145,28 @@ Vec3 AABox::get_corner(int idx) const return Vec3(v[xidx[idx]].x, v[yidx[idx]].y, v[zidx[idx]].z); } +Plane AABox::get_plane(int pidx) const +{ + switch(pidx) { + case AABOX_PLANE_PX: + return Plane(Vec3(max.x, 0, 0), Vec3(1, 0, 0)); + case AABOX_PLANE_NX: + return Plane(Vec3(min.x, 0, 0), Vec3(-1, 0, 0)); + case AABOX_PLANE_PY: + return Plane(Vec3(0, max.x, 0), Vec3(0, 1, 0)); + case AABOX_PLANE_NY: + return Plane(Vec3(0, min.x, 0), Vec3(0, -1, 0)); + case AABOX_PLANE_PZ: + return Plane(Vec3(0, 0, max.z), Vec3(0, 0, 1)); + case AABOX_PLANE_NZ: + return Plane(Vec3(0, 0, min.z), Vec3(0, 0, -1)); + default: + break; + } + abort(); + return Plane(); +} + bool AABox::intersect(const Ray &ray, HitPoint *hit) const { Vec3 param[2] = {min, max}; @@ -217,14 +249,31 @@ bool AABox::contains(const Vec3 &v) const v.x <= max.x && v.y <= max.y && v.z <= max.z; } -float AABox::distance(const Vec3 &v) const +#define SQ(x) ((x) * (x)) +float AABox::distance_sq(const Vec3 &v) const { - return 0.0; // TODO + float dsq = 0.0f; + + for(int i=0; i<3; i++) { + if(v[i] < min[i]) dsq += SQ(min[i] - v[i]); + if(v[i] > max[i]) dsq += SQ(v[i] - max[i]); + } + return dsq; } -float AABox::signed_distance(const Vec3 &v) const +float AABox::signed_distance_sq(const Vec3 &v) const { - return 0.0; // TODO + if(!contains(v)) { + return distance_sq(v); + } + + float dsq = 0.0f; + for(int i=0; i<3; i++) { + float dmin = v[i] - min[i]; + float dmax = max[i] - v[i]; + dsq -= dmin < dmax ? SQ(dmin) : SQ(dmax); + } + return dsq; } Box::Box() @@ -311,12 +360,12 @@ bool Box::contains(const Vec3 &pt) const return AABox::contains(inverse(xform) * pt); } -float Box::distance(const Vec3 &v) const +float Box::distance_sq(const Vec3 &v) const { return 0.0f; // TODO } -float Box::signed_distance(const Vec3 &v) const +float Box::signed_distance_sq(const Vec3 &v) const { return 0.0f; // TODO } @@ -382,6 +431,18 @@ float Plane::signed_distance(const Vec3 &v) const return dot(v - pt, normal); } +float Plane::distance_sq(const Vec3 &v) const +{ + float d = distance(v); + return d * d; +} + +float Plane::signed_distance_sq(const Vec3 &v) const +{ + float d = distance(v); + return dot(v, normal) >= 0.0f ? d * d : -(d * d); +} + Disc::Disc() { @@ -431,12 +492,12 @@ bool Disc::contains(const Vec3 &pt) const return length_sq(pj - this->pt) <= radius * radius; } -float Disc::distance(const Vec3 &v) const +float Disc::distance_sq(const Vec3 &v) const { return 0.0; // TODO } -float Disc::signed_distance(const Vec3 &v) const +float Disc::signed_distance_sq(const Vec3 &v) const { return 0.0; // TODO } @@ -703,3 +764,8 @@ bool intersect_aabox_aabox(AABox *res, const AABox &a, const AABox &b) } return res->min.x != res->max.x && res->min.y != res->max.y && res->min.z != res->max.z; } + +bool collision_sphere_aabox(const Sphere &s, const AABox &b) +{ + return b.distance_sq(s.center) <= s.radius * s.radius; +}