source: libcfa/src/vec/vec3.hfa@ 2444324

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 2444324 was 9ec35db, checked in by Dmitry Kobets <dkobets@…>, 6 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.