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

#include "raytracer/raytracer.h"

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

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

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

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

glm::vec3 getCubeNormal(
        glm::vec4 intersectPointObject)
{
    if (RayTracer::floatEquals(intersectPointObject.y, -.5f)) // neg y
    {
        return {0.f, -1.f, 0.f};
    }
    if (RayTracer::floatEquals(intersectPointObject.y, .5f)) // pos y
    {
        return {0.f, 1.f, 0.f};
    }
    if (RayTracer::floatEquals(intersectPointObject.x, -.5f)) // neg x
    {
        return {-1.f, 0.f, 0.f};
    }
    if (RayTracer::floatEquals(intersectPointObject.x, .5f)) // pos x
    {
        return {1.f, 0.f, 0.f};
    }
    if (RayTracer::floatEquals(intersectPointObject.z, -.5f)) // neg z
    {
        return {0.f, 0.f, -1.f};
    }
    if (RayTracer::floatEquals(intersectPointObject.z, .5f)) // pos z
    {
        return {0.f, 0.f, 1.f};
    }
    return glm::vec3(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::vec3 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::vec3(0.f);
}