I have a problem understanding how excatly the intersection test when testing ray against plane, sphere and OBB. I have a presentation of an assignment and I need to be able to explain how the code I have written works. But I dont really understand it, even though I have searched over the internet and read through a lot of sites telling how it works. I still dont really understand it, im hoping that someone can give me a dummy explaination of it that is easy to understand. I'll provide the code in question down below, all help is appreciated. I just really wanna understand how this stuff works fully.
void GiantSphere::test(Ray & ray, HitData & hit)
{
float b = ray.d.Dot(ray.o - this->center);
float j = (ray.o - this->center).Dot(ray.o - this->center) - pow(this->radius,2);
float intersectCalc = b*b - j;
if (intersectCalc >= 0)
{
float t = -b - sqrt(intersectCalc);
if (hit.t == -1 || hit.t > t)
{
hit.t = t;
hit.lastShape = this;
hit.color = this->c;
hit.lastNormal = this->normal(ray.o+ray.d*t);
}
}
}
Vec GiantSphere::normal(Vec & point)
{
Vec temp = point - this->center;
temp.Normalize();
return temp;
}
GiantSphere::GiantSphere(Vec _center, float _radius, Color _color)
{
this->center = _center;
this->radius = _radius;
this->c = _color;
}
void GiantPlane::test(Ray & ray, HitData & hit)
{
float d = this->n.Dot(this->point);
float t = (d - this->n.Dot(ray.o)) / this->n.Dot(ray.d);
if (t > 0.0001f)
{
if (hit.t == -1 || hit.t > t)
{
hit.t = t;
hit.lastShape = this;
hit.color = this->c;
hit.lastNormal = this->n;
}
}
}
Vec GiantPlane::normal(Vec & point)
{
point = n;
return point;
}
GiantPlane::GiantPlane(Vec normal, float _d, Color color)
{
this->n = normal;
//this->d = _d;
this->point = this->n*_d;
this->c = color;
}
void GiantOBB::test(Ray & ray, HitData & hit)
{
float tMin = -INFINITY;
float tMax = +INFINITY;
Vec p = Bcenter - ray.o; // Bcenter is the center of the OBB. Ray.o is the origin of the ray.
Vec arr[3] = { Bu,Bv,Bw }; // Direction/base vectors. (1,0,0), (0,1,0), (0,0,1)
for (auto& i : arr)
{
float e = i.Dot(p);
float f = i.Dot(ray.d);
float q = -e - halfBu; // The distance between the center and each side. 100.
float w = -e + halfBu;
if (abs(f) > 1e-20f)
{
float t1 = ((e + halfBu) / f);
float t2 = ((e - halfBu) / f);
if (t1 > t2) { std::swap(t1, t2); }
if (t1 > tMin) { tMin = t1; }
if (t2 < tMax) { tMax = t2; }
if (tMin > tMax) { return; }
if (tMax < 0) { return; }
}
else if (q > 0 || w < 0) { return; }
}
if (tMin > 0)
{
if (hit.t == -1)
{
hit.t = tMin;
hit.lastShape = this;
hit.color = c;
}
else if (tMin < hit.t)
{
hit.t = tMin;
hit.lastShape = this;
hit.color = c;
}
}
else if (tMax <= 0)
{
if (hit.t == -1)
{
hit.t = tMax;
hit.lastShape = this;
hit.color = c;
}
else if (tMax < hit.t)
{
hit.t = tMax;
hit.lastShape = this;
hit.color = c;
}
}
}
Vec GiantOBB::normal(Vec & point)
{
Vec arr[3] = { this->Bu,this->Bv,this->Bw };
float halfArr[3] = { this->halfBu,this->halfBv,this->halfBw };
Vec returnValue = Vec();
for (int i = 0; i < 3; i++)
{
Vec sPlus = this->Bcenter + (arr[i] * halfArr[i]);
Vec sMinus = this->Bcenter - (arr[i] * halfArr[i]);
if ((point - sPlus).Dot(arr[i]) < 0.0001f && (point - sPlus).Dot(arr[i]) > -0.0001f)
{
float dot = (point - sPlus).Dot(arr[i]);
returnValue = arr[i];
}
else if ((point - sMinus).Dot(arr[i] * -1) < 0.0001f && (point - sMinus).Dot(arr[i] * -1) > -0.0001f)
{
float dot2 = (point - sMinus).Dot(arr[i]);
returnValue = arr[i] * -1;
}
}
return returnValue;
}
GiantOBB::GiantOBB(Vec b, Vec b1, Vec b2, Vec b3, float Hu, float Hv, float Hw, Color _color)
{
this->Bcenter = b;
this->Bu = b1;
this->Bv = b2;
this->Bw = b3;
this->c = _color;
this->halfBu = Hu;
this->halfBv = Hv;
this->halfBw = Hw;
}
GiantOBB::GiantOBB(Vec b, float Hu, float Hv, float Hw, Color _color)
{
this->Bcenter = b;
this->halfBu = Hu;
this->halfBv = Hv;
this->halfBw = Hw;
this->c = _color;
}