infinite terrain experiments
[shady.git] / transform.cpp
blob390d93dad3693c8fc83f12feef5877f7c6243f9e
2 #include "transform.hpp"
4 #include <cmath>
5 #include <cstdlib>
7 using std::sin;
8 using std::cos;
9 using std::rand;
11 float randVal() {
12 return ((float)std::rand()) / RAND_MAX;
15 float randVar(float val, float var) {
17 if(var == 0.0) {
18 return val;
21 return val + (((randVal() * 2) - 1) * var);
24 int randNextInt(float val) {
26 float proportion = val - floor(val);
28 if(randVal() < proportion) {
29 return floor(val);
30 } else {
31 return ceil(val);
36 float randVal(float min, float max) {
37 return (randVal() * (max - min)) + min;
40 /** Matrix */
42 #define T(r,t,i) ((r[i][0] * t.x) + (r[i][1] * t.y) + (r[i][2] * t.z))
44 #define TI(r,t,i) ((r[0][i] * t.x) + (r[1][i] * t.y) + (r[2][i] * t.z))
47 #define S(i,j,k) (d[i][k] * b.d[k][j])
48 #define M(i,j) (S(i,j,0) + S(i,j,1) + S(i,j,2))
50 mat::mat(const mat & o) {
51 d[0][0] = o.d[0][0]; d[0][1] = o.d[0][1]; d[0][2] = o.d[0][2];
52 d[1][0] = o.d[1][0]; d[1][1] = o.d[1][1]; d[1][2] = o.d[1][2];
53 d[2][0] = o.d[2][0]; d[2][1] = o.d[2][1]; d[2][2] = o.d[2][2];
56 vec mat::operator()(const vec & v) const {
57 return vec(T(d,v,0), T(d,v,1), T(d,v,2));
60 vec mat::operator[](const vec & v) const {
61 return vec(TI(d,v,0), TI(d,v,1), TI(d,v,2));
64 mat mat::operator*(const mat & b) const {
65 return mat(M(0,0), M(0,1), M(0,2),
66 M(1,0), M(1,1), M(1,2),
67 M(2,0), M(2,1), M(2,2));
70 mat mat::operator-() const {
71 return mat(d[0][0], d[1][0], d[2][0],
72 d[0][1], d[1][1], d[2][1],
73 d[0][2], d[1][2], d[2][2]);
76 mat m_null() { return mat(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); }
77 mat m_id() { return mat(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0); }
80 /** Affine Transformation */
82 transform::transform(const mat & rot, const vec & trans) : r(rot), t(trans) { }
84 transform::transform(const transform & other) : r(other.r), t(other.t) { }
86 transform::transform() : r(m_id()), t(v_null()) { }
88 transform::transform(const mat & rot) : r(rot), t(v_null()) { }
90 transform::transform(const vec & trans): r(m_id()), t(trans) { }
93 inline void swap(float d[3][3], int i1, int j1, int i2, int j2) {
94 register float t = d[i1][j1];
95 d[i1][j1] = d[i2][j2];
96 d[i2][j2] = t;
97 // TODO use std::swap
100 transform & transform::invert() {
101 swap(r.d, 0, 1, 1, 0);
102 swap(r.d, 0, 2, 2, 0);
103 swap(r.d, 1, 2, 2, 1);
104 t = -r(t);
105 return *this;
108 transform t_rotateX(float theta) {
109 float s = sin(theta);
110 float c = cos(theta);
111 return transform(mat(1.0, 0.0, 0.0,
112 0.0, c, -s,
113 0.0, s, c));
116 transform t_rotateY(float theta) {
117 float s = sin(theta);
118 float c = cos(theta);
119 return transform(mat( c, 0.0, s,
120 0.0, 1.0, 0.0,
121 -s, 0.0, c));
124 transform t_rotateZ(float theta) {
125 float s = sin(theta);
126 float c = cos(theta);
127 return transform(mat( c, -s, 0.0,
128 s, c, 0.0,
129 0.0, 0.0, 1.0));
132 transform t_rotate(const vec & axis, float theta) {
133 float s = sin(theta);
134 float c = cos(theta);
135 float x = axis.x;
136 float y = axis.y;
137 float z = axis.z;
138 return transform(mat((x*x) + ((1 - (x*x))*c), (x*y*(1 - c)) - (z*s) , (x*z*(1 - c)) + (y*s),
139 (x*y*(1 - c)) + (z*s) , (y*y) + ((1 - (y*y))*c), (y*z*(1 - c)) - (x*s),
140 (x*z*(1 - c)) + (y*s) , (y*z*(1 - c)) + (x*s) , (z*z) + ((1 - (z*z))*c)));
143 vec calculateTriangleNormal(const vec p[3]) {
145 vec u = p[1] - p[0];
146 vec v = p[2] - p[0];
148 vec normal;
150 normal.x = (u.y * v.z) - (u.z * v.y);
151 normal.y = (u.z * v.x) - (u.x * v.z);
152 normal.z = (u.x * v.y) - (u.y * v.x);
154 normal /= normal.det();
156 return normal;
159 vec calculateNormal(const vec * p, int n) {
161 vec normal(0.0, 0.0, 0.0);
163 for(int i = 0; i < n; i++) {
165 vec current = p[i];
166 vec next = p[(i + 1) % n];
168 normal.x += (current.y - next.y) * (current.z + next.z);
169 normal.y += (current.z - next.z) * (current.x + next.x);
170 normal.z += (current.x - next.x) * (current.y + next.y);
174 // normalize
175 normal /= normal.det();
177 return normal;