RayCasting - sphere, plane and OBB

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 fully works. I'm kinda in desperate need of help right now.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
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;
}
Last edited on
Topic archived. No new replies allowed.