source: libcfa/src/vec/vec.hfa @ 746157e

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

make vector an interface, allowing for shared code between dimensions

  • Property mode set to 100644
File size: 2.9 KB
Line 
1#pragma once
2
3#include <math.hfa>
4
5trait fromint(otype T) {
6    void ?{}(T&, int);
7};
8trait zeroinit(otype T) {
9    void ?{}(T&, zero_t);
10};
11trait zero_assign(otype T) {
12    T ?=?(T&, zero_t);
13};
14trait subtract(otype T) {
15    T ?-?(T, T);
16};
17trait negate(otype T) {
18    T -?(T);
19};
20trait add(otype T) {
21    T ?+?(T, T);
22};
23trait multiply(otype T) {
24    T ?*?(T, T);
25};
26trait divide(otype T) {
27    T ?/?(T, T);
28};
29trait lessthan(otype T) {
30    int ?<?(T, T);
31};
32trait equality(otype T) {
33    int ?==?(T, T);
34};
35trait sqrt(otype T) {
36    T sqrt(T);
37};
38
39static inline {
40// int
41int ?=?(int& n, zero_t) { return n = 0.f; }
42/* float */
43void ?{}(float& a, int b) { a = b; }
44float ?=?(float& n, zero_t) { return n = 0.f; }
45/* double */
46void ?{}(double& a, int b) { a = b; }
47double ?=?(double& n, zero_t) { return n = 0L; }
48// long double
49void ?{}(long double& a, int b) { a = b; }
50long double ?=?(long double& n, zero_t) { return n = 0L; }
51}
52
53trait dottable(otype V, otype T) {
54    T dot(V, V);
55};
56
57static inline {
58
59forall(otype T | sqrt(T), otype V | dottable(V, T))
60T length(V v) {
61   return sqrt(dot(v, v));
62}
63
64forall(otype T, otype V | dottable(V, T))
65T length_squared(V v) {
66   return dot(v, v);
67}
68
69forall(otype T, otype V | { T length(V); } | subtract(V))
70T distance(V v1, V v2) {
71    return length(v1 - v2);
72}
73
74
75forall(otype T, otype V | { T length(V); V ?/?(V, T); })
76V normalize(V v) {
77    return v / length(v);
78}
79
80// Project vector u onto vector v
81forall(otype T, otype V | dottable(V, T) | { V normalize(V); V ?*?(V, T); })
82V project(V u, V v) {
83    V v_norm = normalize(v);
84    return v_norm * dot(u, v_norm);
85}
86
87// Reflect incident vector v with respect to surface with normal n
88forall(otype T | fromint(T), otype V | { V project(V, V); V ?*?(T, V); V ?-?(V,V); })
89V reflect(V v, V n) {
90    return v - (T){2} * project(v, n);
91}
92
93// Refract incident vector v with respect to surface with normal n
94// eta is the ratio of indices of refraction between starting material and
95// entering material (i.e., from air to water, eta = 1/1.33)
96// v and n must already be normalized
97forall(otype T | fromint(T) | subtract(T) | multiply(T) | add(T) | lessthan(T) | sqrt(T),
98       otype V | dottable(V, T) | { V ?*?(T, V); V ?-?(V,V); void ?{}(V&, zero_t); })
99V refract(V v, V n, T eta) {
100    T dotValue = dot(n, v);
101    T k = (T){1} - eta * eta * ((T){1} - dotValue * dotValue);
102    if (k < (T){0}) {
103        return 0;
104    }
105    return eta * v - (eta * dotValue + sqrt(k)) * n;
106}
107
108// Given a perturbed normal and a geometric normal,
109// flip the perturbed normal if the geometric normal is pointing away
110// from the observer.
111// n is the perturbed vector that we want to align
112// i is the incident vector
113// ng is the geometric normal of the surface
114/* forall(| add(T) | multiply(T) | lessthan(T) | fromint(T) | subtract(T)) */
115forall(otype T | lessthan(T) | zeroinit(T), otype V | dottable(V, T) | negate(V))
116V faceforward(V n, V i, V ng) {
117    return dot(ng, i) < (T){0} ? n : -n;
118}
119
120} // inline
Note: See TracBrowser for help on using the repository browser.