goat3d

annotate libs/vmath/vector.cc @ 38:60f2037680ee

split the exporter into two files to make it more readable (and maybe make an importer too at some point?)
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 07 Oct 2013 20:02:57 +0300
parents
children
rev   line source
nuclear@27 1 #include "vector.h"
nuclear@27 2 #include "vmath.h"
nuclear@27 3
nuclear@27 4 // ---------- Vector2 -----------
nuclear@27 5
nuclear@27 6 Vector2::Vector2(scalar_t x, scalar_t y)
nuclear@27 7 {
nuclear@27 8 this->x = x;
nuclear@27 9 this->y = y;
nuclear@27 10 }
nuclear@27 11
nuclear@27 12 Vector2::Vector2(const vec2_t &vec)
nuclear@27 13 {
nuclear@27 14 x = vec.x;
nuclear@27 15 y = vec.y;
nuclear@27 16 }
nuclear@27 17
nuclear@27 18 Vector2::Vector2(const Vector3 &vec)
nuclear@27 19 {
nuclear@27 20 x = vec.x;
nuclear@27 21 y = vec.y;
nuclear@27 22 }
nuclear@27 23
nuclear@27 24 Vector2::Vector2(const Vector4 &vec)
nuclear@27 25 {
nuclear@27 26 x = vec.x;
nuclear@27 27 y = vec.y;
nuclear@27 28 }
nuclear@27 29
nuclear@27 30 void Vector2::normalize()
nuclear@27 31 {
nuclear@27 32 scalar_t len = length();
nuclear@27 33 x /= len;
nuclear@27 34 y /= len;
nuclear@27 35 }
nuclear@27 36
nuclear@27 37 Vector2 Vector2::normalized() const
nuclear@27 38 {
nuclear@27 39 scalar_t len = length();
nuclear@27 40 return Vector2(x / len, y / len);
nuclear@27 41 }
nuclear@27 42
nuclear@27 43 void Vector2::transform(const Matrix3x3 &mat)
nuclear@27 44 {
nuclear@27 45 scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2];
nuclear@27 46 y = mat[1][0] * x + mat[1][1] * y + mat[1][2];
nuclear@27 47 x = nx;
nuclear@27 48 }
nuclear@27 49
nuclear@27 50 Vector2 Vector2::transformed(const Matrix3x3 &mat) const
nuclear@27 51 {
nuclear@27 52 Vector2 vec;
nuclear@27 53 vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2];
nuclear@27 54 vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2];
nuclear@27 55 return vec;
nuclear@27 56 }
nuclear@27 57
nuclear@27 58 void Vector2::rotate(scalar_t angle)
nuclear@27 59 {
nuclear@27 60 *this = Vector2(cos(angle) * x - sin(angle) * y, sin(angle) * x + cos(angle) * y);
nuclear@27 61 }
nuclear@27 62
nuclear@27 63 Vector2 Vector2::rotated(scalar_t angle) const
nuclear@27 64 {
nuclear@27 65 return Vector2(cos(angle) * x - sin(angle) * y, sin(angle) * x + cos(angle) * y);
nuclear@27 66 }
nuclear@27 67
nuclear@27 68 Vector2 Vector2::reflection(const Vector2 &normal) const
nuclear@27 69 {
nuclear@27 70 return 2.0 * dot_product(*this, normal) * normal - *this;
nuclear@27 71 }
nuclear@27 72
nuclear@27 73 Vector2 Vector2::refraction(const Vector2 &normal, scalar_t src_ior, scalar_t dst_ior) const
nuclear@27 74 {
nuclear@27 75 // quick and dirty implementation :)
nuclear@27 76 Vector3 v3refr = Vector3(this->x, this->y, 1.0).refraction(Vector3(this->x, this->y, 1), src_ior, dst_ior);
nuclear@27 77 return Vector2(v3refr.x, v3refr.y);
nuclear@27 78 }
nuclear@27 79
nuclear@27 80 std::ostream &operator <<(std::ostream &out, const Vector2 &vec)
nuclear@27 81 {
nuclear@27 82 out << "[" << vec.x << " " << vec.y << "]";
nuclear@27 83 return out;
nuclear@27 84 }
nuclear@27 85
nuclear@27 86
nuclear@27 87
nuclear@27 88 // --------- Vector3 ----------
nuclear@27 89
nuclear@27 90 Vector3::Vector3(scalar_t x, scalar_t y, scalar_t z)
nuclear@27 91 {
nuclear@27 92 this->x = x;
nuclear@27 93 this->y = y;
nuclear@27 94 this->z = z;
nuclear@27 95 }
nuclear@27 96
nuclear@27 97 Vector3::Vector3(const vec3_t &vec)
nuclear@27 98 {
nuclear@27 99 x = vec.x;
nuclear@27 100 y = vec.y;
nuclear@27 101 z = vec.z;
nuclear@27 102 }
nuclear@27 103
nuclear@27 104 Vector3::Vector3(const Vector2 &vec)
nuclear@27 105 {
nuclear@27 106 x = vec.x;
nuclear@27 107 y = vec.y;
nuclear@27 108 z = 1;
nuclear@27 109 }
nuclear@27 110
nuclear@27 111 Vector3::Vector3(const Vector4 &vec)
nuclear@27 112 {
nuclear@27 113 x = vec.x;
nuclear@27 114 y = vec.y;
nuclear@27 115 z = vec.z;
nuclear@27 116 }
nuclear@27 117
nuclear@27 118 Vector3::Vector3(const SphVector &sph)
nuclear@27 119 {
nuclear@27 120 *this = sph;
nuclear@27 121 }
nuclear@27 122
nuclear@27 123 Vector3 &Vector3::operator =(const SphVector &sph)
nuclear@27 124 {
nuclear@27 125 x = sph.r * cos(sph.theta) * sin(sph.phi);
nuclear@27 126 z = sph.r * sin(sph.theta) * sin(sph.phi);
nuclear@27 127 y = sph.r * cos(sph.phi);
nuclear@27 128 return *this;
nuclear@27 129 }
nuclear@27 130
nuclear@27 131 void Vector3::normalize()
nuclear@27 132 {
nuclear@27 133 scalar_t len = length();
nuclear@27 134 x /= len;
nuclear@27 135 y /= len;
nuclear@27 136 z /= len;
nuclear@27 137 }
nuclear@27 138
nuclear@27 139 Vector3 Vector3::normalized() const
nuclear@27 140 {
nuclear@27 141 scalar_t len = length();
nuclear@27 142 return Vector3(x / len, y / len, z / len);
nuclear@27 143 }
nuclear@27 144
nuclear@27 145 Vector3 Vector3::reflection(const Vector3 &normal) const
nuclear@27 146 {
nuclear@27 147 return 2.0 * dot_product(*this, normal) * normal - *this;
nuclear@27 148 }
nuclear@27 149
nuclear@27 150 Vector3 Vector3::refraction(const Vector3 &normal, scalar_t src_ior, scalar_t dst_ior) const
nuclear@27 151 {
nuclear@27 152 return refraction(normal, src_ior / dst_ior);
nuclear@27 153 }
nuclear@27 154
nuclear@27 155 Vector3 Vector3::refraction(const Vector3 &normal, scalar_t ior) const
nuclear@27 156 {
nuclear@27 157 scalar_t cos_inc = dot_product(*this, -normal);
nuclear@27 158
nuclear@27 159 scalar_t radical = 1.0 + SQ(ior) * (SQ(cos_inc) - 1.0);
nuclear@27 160
nuclear@27 161 if(radical < 0.0) { // total internal reflection
nuclear@27 162 return -reflection(normal);
nuclear@27 163 }
nuclear@27 164
nuclear@27 165 scalar_t beta = ior * cos_inc - sqrt(radical);
nuclear@27 166
nuclear@27 167 return *this * ior + normal * beta;
nuclear@27 168 }
nuclear@27 169
nuclear@27 170 void Vector3::transform(const Matrix3x3 &mat)
nuclear@27 171 {
nuclear@27 172 scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z;
nuclear@27 173 scalar_t ny = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z;
nuclear@27 174 z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z;
nuclear@27 175 x = nx;
nuclear@27 176 y = ny;
nuclear@27 177 }
nuclear@27 178
nuclear@27 179 Vector3 Vector3::transformed(const Matrix3x3 &mat) const
nuclear@27 180 {
nuclear@27 181 Vector3 vec;
nuclear@27 182 vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z;
nuclear@27 183 vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z;
nuclear@27 184 vec.z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z;
nuclear@27 185 return vec;
nuclear@27 186 }
nuclear@27 187
nuclear@27 188 void Vector3::transform(const Matrix4x4 &mat)
nuclear@27 189 {
nuclear@27 190 scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3];
nuclear@27 191 scalar_t ny = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3];
nuclear@27 192 z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3];
nuclear@27 193 x = nx;
nuclear@27 194 y = ny;
nuclear@27 195 }
nuclear@27 196
nuclear@27 197 Vector3 Vector3::transformed(const Matrix4x4 &mat) const
nuclear@27 198 {
nuclear@27 199 Vector3 vec;
nuclear@27 200 vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3];
nuclear@27 201 vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3];
nuclear@27 202 vec.z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3];
nuclear@27 203 return vec;
nuclear@27 204 }
nuclear@27 205
nuclear@27 206 void Vector3::transform(const Quaternion &quat)
nuclear@27 207 {
nuclear@27 208 Quaternion vq(0.0f, *this);
nuclear@27 209 vq = quat * vq * quat.inverse();
nuclear@27 210 *this = vq.v;
nuclear@27 211 }
nuclear@27 212
nuclear@27 213 Vector3 Vector3::transformed(const Quaternion &quat) const
nuclear@27 214 {
nuclear@27 215 Quaternion vq(0.0f, *this);
nuclear@27 216 vq = quat * vq * quat.inverse();
nuclear@27 217 return vq.v;
nuclear@27 218 }
nuclear@27 219
nuclear@27 220 void Vector3::rotate(const Vector3 &euler)
nuclear@27 221 {
nuclear@27 222 Matrix4x4 rot;
nuclear@27 223 rot.set_rotation(euler);
nuclear@27 224 transform(rot);
nuclear@27 225 }
nuclear@27 226
nuclear@27 227 Vector3 Vector3::rotated(const Vector3 &euler) const
nuclear@27 228 {
nuclear@27 229 Matrix4x4 rot;
nuclear@27 230 rot.set_rotation(euler);
nuclear@27 231 return transformed(rot);
nuclear@27 232 }
nuclear@27 233
nuclear@27 234 std::ostream &operator <<(std::ostream &out, const Vector3 &vec)
nuclear@27 235 {
nuclear@27 236 out << "[" << vec.x << " " << vec.y << " " << vec.z << "]";
nuclear@27 237 return out;
nuclear@27 238 }
nuclear@27 239
nuclear@27 240
nuclear@27 241 // -------------- Vector4 --------------
nuclear@27 242 Vector4::Vector4(scalar_t x, scalar_t y, scalar_t z, scalar_t w)
nuclear@27 243 {
nuclear@27 244 this->x = x;
nuclear@27 245 this->y = y;
nuclear@27 246 this->z = z;
nuclear@27 247 this->w = w;
nuclear@27 248 }
nuclear@27 249
nuclear@27 250 Vector4::Vector4(const vec4_t &vec)
nuclear@27 251 {
nuclear@27 252 x = vec.x;
nuclear@27 253 y = vec.y;
nuclear@27 254 z = vec.z;
nuclear@27 255 w = vec.w;
nuclear@27 256 }
nuclear@27 257
nuclear@27 258 Vector4::Vector4(const Vector2 &vec)
nuclear@27 259 {
nuclear@27 260 x = vec.x;
nuclear@27 261 y = vec.y;
nuclear@27 262 z = 1;
nuclear@27 263 w = 1;
nuclear@27 264 }
nuclear@27 265
nuclear@27 266 Vector4::Vector4(const Vector3 &vec)
nuclear@27 267 {
nuclear@27 268 x = vec.x;
nuclear@27 269 y = vec.y;
nuclear@27 270 z = vec.z;
nuclear@27 271 w = 1;
nuclear@27 272 }
nuclear@27 273
nuclear@27 274 void Vector4::normalize()
nuclear@27 275 {
nuclear@27 276 scalar_t len = (scalar_t)sqrt(x*x + y*y + z*z + w*w);
nuclear@27 277 x /= len;
nuclear@27 278 y /= len;
nuclear@27 279 z /= len;
nuclear@27 280 w /= len;
nuclear@27 281 }
nuclear@27 282
nuclear@27 283 Vector4 Vector4::normalized() const
nuclear@27 284 {
nuclear@27 285 scalar_t len = (scalar_t)sqrt(x*x + y*y + z*z + w*w);
nuclear@27 286 return Vector4(x / len, y / len, z / len, w / len);
nuclear@27 287 }
nuclear@27 288
nuclear@27 289 void Vector4::transform(const Matrix4x4 &mat)
nuclear@27 290 {
nuclear@27 291 scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3] * w;
nuclear@27 292 scalar_t ny = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3] * w;
nuclear@27 293 scalar_t nz = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3] * w;
nuclear@27 294 w = mat[3][0] * x + mat[3][1] * y + mat[3][2] * z + mat[3][3] * w;
nuclear@27 295 x = nx;
nuclear@27 296 y = ny;
nuclear@27 297 z = nz;
nuclear@27 298 }
nuclear@27 299
nuclear@27 300 Vector4 Vector4::transformed(const Matrix4x4 &mat) const
nuclear@27 301 {
nuclear@27 302 Vector4 vec;
nuclear@27 303 vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3] * w;
nuclear@27 304 vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3] * w;
nuclear@27 305 vec.z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3] * w;
nuclear@27 306 vec.w = mat[3][0] * x + mat[3][1] * y + mat[3][2] * z + mat[3][3] * w;
nuclear@27 307 return vec;
nuclear@27 308 }
nuclear@27 309
nuclear@27 310 // TODO: implement 4D vector reflection
nuclear@27 311 Vector4 Vector4::reflection(const Vector4 &normal) const
nuclear@27 312 {
nuclear@27 313 return *this;
nuclear@27 314 }
nuclear@27 315
nuclear@27 316 // TODO: implement 4D vector refraction
nuclear@27 317 Vector4 Vector4::refraction(const Vector4 &normal, scalar_t src_ior, scalar_t dst_ior) const
nuclear@27 318 {
nuclear@27 319 return *this;
nuclear@27 320 }
nuclear@27 321
nuclear@27 322 std::ostream &operator <<(std::ostream &out, const Vector4 &vec)
nuclear@27 323 {
nuclear@27 324 out << "[" << vec.x << " " << vec.y << " " << vec.z << " " << vec.w << "]";
nuclear@27 325 return out;
nuclear@27 326 }