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

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

Fix issue in vec2.hfa from splitting up trait

  • Property mode set to 100644
File size: 5.4 KB
RevLine 
[9ec35db]1#pragma once
2#include <math.hfa>
3#include <iostream.hfa>
4
[1dd929e]5trait zeroassn(otype T) {
6    T ?=?(T&, zero_t);
7};
8trait fromint(otype T) {
[9ec35db]9    void ?{}(T&, int);
[1dd929e]10};
11trait zero_assign(otype T) {
[9ec35db]12    T ?=?(T&, zero_t);
[1dd929e]13};
14trait subtract(otype T) {
[9ec35db]15    T ?-?(T, T);
16    T -?(T);
[1dd929e]17};
18trait add(otype T) {
[9ec35db]19    T ?+?(T, T);
[1dd929e]20};
21trait multiply(otype T) {
[9ec35db]22    T ?*?(T, T);
[1dd929e]23};
24trait divide(otype T) {
[9ec35db]25    T ?/?(T, T);
[1dd929e]26};
27trait lessthan(otype T) {
[9ec35db]28    int ?<?(T, T);
[1dd929e]29};
30trait equality(otype T) {
31    int ?==?(T, T);
32};
33trait sqrt(otype T) {
[9ec35db]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
[1dd929e]51forall(otype T) {
[9ec35db]52    struct vec2 {
53        T x, y;
54    };
55}
56
[1dd929e]57forall(otype T) {
[9ec35db]58    static inline {
59
60    // Constructors
61
62    void ?{}(vec2(T)& v, T x, T y) {
63        v.[x, y] = [x, y];
64    }
[1dd929e]65
66    forall(| zero_assign(T))
[9ec35db]67    void ?{}(vec2(T)& vec, zero_t) with (vec) {
68        x = y = 0;
69    }
[1dd929e]70
[9ec35db]71    void ?{}(vec2(T)& vec, T val) with (vec) {
72        x = y = val;
73    }
[1dd929e]74
[9ec35db]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    }
[1dd929e]83    forall(| zero_assign(T))
[9ec35db]84    void ?=?(vec2(T)& vec, zero_t) with (vec) {
85        x = y = 0;
86    }
87
88    // Primitive mathematical operations
89
90    // Subtraction
[1dd929e]91
92    forall(| subtract(T)) {
[9ec35db]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    }
[1dd929e]103    }
[9ec35db]104
105    // Addition
[1dd929e]106    forall(| add(T)) {
[9ec35db]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    }
[1dd929e]114    }
[9ec35db]115
116    // Scalar Multiplication
[1dd929e]117    forall(| multiply(T)) {
[9ec35db]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    }
[1dd929e]128    }
[9ec35db]129
130    // Scalar Division
[1dd929e]131    forall(| divide(T)) {
[9ec35db]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    }
[1dd929e]139    }
140
[9ec35db]141    // Relational Operators
[1dd929e]142    forall(| equality(T)) {
[9ec35db]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    }
[1dd929e]149    }
[9ec35db]150
[1dd929e]151    forall(| add(T) | multiply(T))
[9ec35db]152    T dot(vec2(T) u, vec2(T) v) {
153        return u.x * v.x + u.y * v.y;
154    }
155
[1dd929e]156    forall(| sqrt(T) | add(T) | multiply(T))
[9ec35db]157    T length(vec2(T) v) {
158       return sqrt(dot(v, v));
159    }
160
[1dd929e]161    forall(| add(T) | multiply(T))
[9ec35db]162    T length_squared(vec2(T) v) {
163       return dot(v, v);
164    }
165
[1dd929e]166    forall(| subtract(T) | sqrt(T) | add(T) | multiply(T))
[9ec35db]167    T distance(vec2(T) v1, vec2(T) v2) {
168        return length(v1 - v2);
169    }
170
[1dd929e]171    forall(| sqrt(T) | divide(T) | add(T) | multiply(T))
[9ec35db]172    vec2(T) normalize(vec2(T) v) {
173        return v / sqrt(dot(v, v));
174    }
175
176    // Project vector u onto vector v
[1dd929e]177    forall(| sqrt(T) | divide(T) | add(T) | multiply(T))
[9ec35db]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
[1dd929e]184    forall(| sqrt(T) | divide(T) | add(T) | multiply(T) | subtract(T) | fromint(T))
[9ec35db]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
[1dd929e]193    forall(| sqrt(T) | add(T) | multiply(T) | subtract(T) | fromint(T) | lessthan(T) | zeroassn(T))
[9ec35db]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
[1dd929e]209    forall(| add(T) | multiply(T) | lessthan(T) | fromint(T) | subtract(T))
[9ec35db]210    vec2(T) faceforward(vec2(T) n, vec2(T) i, vec2(T) ng) {
211        return dot(ng, i) < (T){0} ? n : -n;
212    }
[1dd929e]213
[9ec35db]214    }
215}
216
[d131480]217forall(dtype ostype, otype T | writeable(T, ostype)) {
[9ec35db]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.