source: libcfa/src/vec/vec.hfa @ 760c88c

ast-experimental
Last change on this file since 760c88c was dd3576b, checked in by Peter A. Buhr <pabuhr@…>, 21 months ago

update from old to new trait syntax using forall

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