aboutsummaryrefslogtreecommitdiff
path: root/src/intersect/normals.cpp
blob: f9b0ea116f7593caabde4438ebe8404ad3c101a5 (plain)
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
//
// Created by Michael Foiani on 11/4/23.
//

#include <iostream>
#include "raytracer/raytracer.h"

glm::vec4 getConeNormal(
    glm::vec4 intersectPointObject)
{
    if (RayTracer::floatEquals(intersectPointObject.y, -.5f)) // normal for y base
    {
        return {0.f, -1.f, 0.f, 0.f};
    }
    if (RayTracer::floatEquals(intersectPointObject.w, -.5f)) // normal for w base
    {
        return {0.f, 0.f, 0.f, -1.f};
    }
    if (RayTracer::floatEquals(intersectPointObject.y, .5f)) // normal for y top
    {
        return {0.f, 1.f, 0.f, 0.f};
    }
    if (RayTracer::floatEquals(intersectPointObject.w, .5f)) // normal for w top
    {
        return {0.f, 0.f, 0.f, 1.f};
    }

    // gradient in object space for cone top is 2x, r^2 - .5*y, 2z, r^2 - .5*w
    return glm::vec4{
        2.f * intersectPointObject.x,
        .25f - .5f * intersectPointObject.y,
        2.f * intersectPointObject.z,
        .25f - .5f * intersectPointObject[3]
    };
}

glm::vec4  getCylinderNormal(
    glm::vec4 intersectPointObject)
{
    if (RayTracer::floatEquals(intersectPointObject.y + intersectPointObject[3], -.5f)) // normal for base
    {
        return {0.f, -1.f, 0.f, -1.f};
    }
    if (RayTracer::floatEquals(intersectPointObject.y + intersectPointObject[3], .5f)) // normal for top
    {
        return {0.f, 1.f, 0.f, 1.f};
    }

    // gradient in object space for cylinder top is 2x, 0, 2z
    return glm::vec4{
        2.f * intersectPointObject.x,
        0.f,
        2.f * intersectPointObject.z,
        0.f
    };
}

glm::vec4 getCubeNormal(
    glm::vec4 intersectPointObject)
{
    if (RayTracer::floatEquals(intersectPointObject.y, -.5f)) // neg y
    {
        return {0.f, -1.f, 0.f, 0.f};
    }
    if (RayTracer::floatEquals(intersectPointObject.y, .5f)) // pos y
    {
        return {0.f, 1.f, 0.f, 0.f};
    }
    if (RayTracer::floatEquals(intersectPointObject.x, -.5f)) // neg x
    {
        return {-1.f, 0.f, 0.f, 0.f};
    }
    if (RayTracer::floatEquals(intersectPointObject.x, .5f)) // pos x
    {
        return {1.f, 0.f, 0.f, 0.f};
    }
    if (RayTracer::floatEquals(intersectPointObject.z, -.5f)) // neg z
    {
        return {0.f, 0.f, -1.f, 0.f};
    }
    if (RayTracer::floatEquals(intersectPointObject.z, .5f)) // pos z
    {
        return {0.f, 0.f, 1.f, 0.f};
    }
    if (RayTracer::floatEquals(intersectPointObject.w, -.5f)) // neg w
    {
        return {0.f, 0.f, 0.f, -1.f};
    }
    if (RayTracer::floatEquals(intersectPointObject.w, .5f)) // pos w
    {
        return {0.f, 0.f, 0.f, 1.f};
    }
    return glm::vec4(0.f);
}

glm::vec4 getSphereNormal(
    glm::vec4 intersectPointObject)
{
    return {2.f * intersectPointObject.x,
            2.f * intersectPointObject.y,
            2.f * intersectPointObject.z,
            2.f * intersectPointObject.w};
}

glm::vec4 RayTracer::getNormal(
    glm::vec4 intersectPointObject,
    const RenderShapeData& shape,
    const RayTraceScene &scene)
{
    switch(shape.primitive.type)
    {
    case PrimitiveType::PRIMITIVE_SPHERE:
        // gradient in object space for sphere is 2x, 2y, 2z
        // return 2.f * intersectPointObject;
        return getSphereNormal(intersectPointObject);
    case PrimitiveType::PRIMITIVE_CONE:
        return getConeNormal(intersectPointObject);
    case PrimitiveType::PRIMITIVE_CYLINDER:
        return getCylinderNormal(intersectPointObject);
    case PrimitiveType::PRIMITIVE_CUBE:
        return getCubeNormal(intersectPointObject);
    case PrimitiveType::PRIMITIVE_MESH:
        break;
    }
    return glm::vec4(0.f);
}