source: libcfa/src/vec/vec3.hfa @ 9ec35db

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 9ec35db was 9ec35db, checked in by Dmitry Kobets <dkobets@…>, 4 years ago

Add vec3_float tests

  • Property mode set to 100644
File size: 4.8 KB
Line 
1#pragma once
2#include <math.hfa>
3#include <iostream.hfa>
4
5trait vec3_t(otype T) {
6    void ?{}(T&, int);
7    T ?=?(T&, zero_t);
8    T ?-?(T, T);
9    T -?(T);
10    T ?+?(T, T);
11    T ?*?(T, T);
12    T ?/?(T, T);
13    int ?==?(T, T);
14    int ?<?(T, T);
15    T sqrt(T);
16};
17
18static inline {
19// int
20int ?=?(int& n, zero_t) { return n = 0.f; }
21int sqrt(int a) { return sqrt((float)a); }
22/* float */
23void ?{}(float& a, int b) { a = b; }
24float ?=?(float& n, zero_t) { return n = 0.f; }
25/* double */
26void ?{}(double& a, int b) { a = b; }
27double ?=?(double& n, zero_t) { return n = 0L; }
28// long double
29void ?{}(long double& a, int b) { a = b; }
30long double ?=?(long double& n, zero_t) { return n = 0L; }
31}
32
33forall(otype T | vec3_t(T)) {
34    struct vec3 {
35        T x, y, z;
36    };
37}
38
39/* static inline { */
40forall(otype T | vec3_t(T)) {
41    static inline {
42
43    // Constructors
44
45    void ?{}(vec3(T)& v, T x, T y, T z) {
46        v.[x, y, z] = [x, y, z];
47    }
48    void ?{}(vec3(T)& vec, zero_t) with (vec) {
49        x = y = z = 0;
50    }
51    void ?{}(vec3(T)& vec, T val) with (vec) {
52        x = y = z = val;
53    }
54    void ?{}(vec3(T)& vec, vec3(T) other) with (vec) {
55        [x,y,z] = other.[x,y,z];
56    }
57
58    // Assignment
59    void ?=?(vec3(T)& vec, vec3(T) other) with (vec) {
60        [x,y,z] = other.[x,y,z];
61    }
62    void ?=?(vec3(T)& vec, zero_t) with (vec) {
63        x = y = z = 0;
64    }
65
66    // Primitive mathematical operations
67
68    // Subtraction
69    vec3(T) ?-?(vec3(T) u, vec3(T) v) { // TODO( can't make this const ref )
70        return [u.x - v.x, u.y - v.y, u.z - v.z];
71    }
72    vec3(T)& ?-=?(vec3(T)& u, vec3(T) v) {
73        u = u - v;
74        return u;
75    }
76    vec3(T) -?(vec3(T)& v) with (v) {
77        return [-x, -y, -z];
78    }
79
80    // Addition
81    vec3(T) ?+?(vec3(T) u, vec3(T) v) { // TODO( can't make this const ref )
82        return [u.x + v.x, u.y + v.y, u.z + v.z];
83    }
84    vec3(T)& ?+=?(vec3(T)& u, vec3(T) v) {
85        u = u + v;
86        return u;
87    }
88
89    // Scalar Multiplication
90    vec3(T) ?*?(vec3(T) v, T scalar) with (v) { // TODO (can't make this const ref)
91        return [x * scalar, y * scalar, z * scalar];
92    }
93    vec3(T) ?*?(T scalar, vec3(T) v) { // TODO (can't make this const ref)
94        return v * scalar;
95    }
96    vec3(T)& ?*=?(vec3(T)& v, T scalar) {
97        v = v * scalar;
98        return v;
99    }
100
101
102    // Scalar Division
103    vec3(T) ?/?(vec3(T) v, T scalar) with (v) {
104        return [x / scalar, y / scalar, z / scalar];
105    }
106    vec3(T)& ?/=?(vec3(T)& v, T scalar) with (v) {
107        v = v / scalar;
108        return v;
109    }
110    // Relational Operators
111    bool ?==?(vec3(T) u, vec3(T) v) with (u) {
112        return x == v.x && y == v.y && z == v.z;
113    }
114    bool ?!=?(vec3(T) u, vec3(T) v) {
115        return !(u == v);
116    }
117
118    T dot(vec3(T) u, vec3(T) v) {
119        return u.x * v.x + u.y * v.y + u.z * v.z;
120    }
121
122    T length(vec3(T) v) {
123       return sqrt(dot(v, v));
124    }
125
126    T length_squared(vec3(T) v) {
127       return dot(v, v);
128    }
129
130    T distance(vec3(T) v1, vec3(T) v2) {
131        return length(v1 - v2);
132    }
133
134    vec3(T) normalize(vec3(T) v) {
135        return v / sqrt(dot(v, v));
136    }
137
138    // Project vector u onto vector v
139    vec3(T) project(vec3(T) u, vec3(T) v) {
140        vec3(T) v_norm = normalize(v);
141        return v_norm * dot(u, v_norm);
142    }
143
144    // Reflect incident vector v with respect to surface with normal n
145    vec3(T) reflect(vec3(T) v, vec3(T) n) {
146        return v - (T){2} * project(v, n);
147    }
148
149    // Refract incident vector v with respect to surface with normal n
150    // eta is the ratio of indices of refraction between starting material and
151    // entering material (i.e., from air to water, eta = 1/1.33)
152    // v and n must already be normalized
153    vec3(T) refract(vec3(T) v, vec3(T) n, T eta) {
154        T dotValue = dot(n, v);
155        T k = (T){1} - eta * eta * ((T){1} - dotValue * dotValue);
156        if (k < (T){0}) {
157            return 0;
158        }
159        return eta * v - (eta * dotValue + sqrt(k)) * n;
160    }
161
162    // Given a perturbed normal and a geometric normal,
163    // flip the perturbed normal if the geometric normal is pointing away
164    // from the observer.
165    // n is the perturbed vector that we want to align
166    // i is the incident vector
167    // ng is the geometric normal of the surface
168    vec3(T) faceforward(vec3(T) n, vec3(T) i, vec3(T) ng) {
169        return dot(ng, i) < (T){0} ? n : -n;
170    }
171
172    vec3(T) cross(vec3(T) u, vec3(T) v) {
173        return (vec3(T)){ u.y * v.z - v.y * u.z,
174                          u.z * v.x - v.z * u.x,
175                          u.x * v.y - v.x * u.y };
176    }
177    }
178}
179
180forall(dtype ostype, otype T | writeable(T, ostype) | vec3_t(T)) {
181    ostype & ?|?( ostype & os, vec3(T) v) with (v) {
182        return os | '<' | x | ',' | y | ',' | z | '>';
183    }
184    void ?|?( ostype & os, vec3(T) v ) with (v) {
185        (ostype &)(os | v); ends(os);
186    }
187}
Note: See TracBrowser for help on using the repository browser.