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

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since d131480 was d131480, checked in by Dmitry Kobets <dkobets@…>, 6 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.