Advertisement

RayCasting - sphere, plane and OBB

Started by August 19, 2017 01:07 PM
1 comment, last by ApochPiQ 7 years, 3 months ago

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;
}

 

I doubt there is some magic combination of words that someone could post here that will make sense, if all the other explanations you've read do not.

That said, maybe we can still help. But it will require some effort on your part.

Here's one way that this could proceed:

  1. Pick a test. Say it's ray-sphere.
  2. Look up three descriptions of the ray-sphere intersection test math.
  3. Post a reply here with links to all three descriptions.
  4. For each description, walk through it sentence by sentence. If you understand the sentence fully, move to the next. When you reach something you don't understand, post a quote of it here for us to read.
  5. For each quote, explain what you are missing - a piece of terminology, a leap of reasoning that seems illogical, or whatever.

This isn't a mandatory assignment or anything, just a suggested framework to help you ask more pointed questions and hopefully get more specific assistance.

It will work better in two ways. First, it will help you focus on the specific points of what you are having trouble understanding. Second, it will help us identify where you are getting tripped up, and give us something concrete to talk about.

As it stands, your post is open ended and very hard to answer, as the lack of replies may have shown you already. But that's OK. If you want to give my exercise a try I'm sure you'll get more responses. Or if there's another way you'd prefer to clarify your original question, that's cool too!

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

This topic is closed to new replies.

Advertisement