source: libcfa/src/vec/vec2.hfa @ d131480

arm-ehjacob/cs343-translationnew-ast-unique-expr
Last change on this file since d131480 was d131480, checked in by Dmitry Kobets <dkobets@…>, 2 years ago

Fix issue in vec2.hfa from splitting up trait

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