1/// @ref gtc_matrix_transform 2/// @file glm/gtc/matrix_transform.inl 3 4#include "../geometric.hpp" 5#include "../trigonometric.hpp" 6#include "../matrix.hpp" 7 8namespace glm 9{ 10 template <typename T, precision P> 11 GLM_FUNC_QUALIFIER tmat4x4<T, P> translate(tmat4x4<T, P> const & m, tvec3<T, P> const & v) 12 { 13 tmat4x4<T, P> Result(m); 14 Result[3] = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3]; 15 return Result; 16 } 17 18 template <typename T, precision P> 19 GLM_FUNC_QUALIFIER tmat4x4<T, P> rotate(tmat4x4<T, P> const & m, T angle, tvec3<T, P> const & v) 20 { 21 T const a = angle; 22 T const c = cos(a); 23 T const s = sin(a); 24 25 tvec3<T, P> axis(normalize(v)); 26 tvec3<T, P> temp((T(1) - c) * axis); 27 28 tmat4x4<T, P> Rotate(uninitialize); 29 Rotate[0][0] = c + temp[0] * axis[0]; 30 Rotate[0][1] = temp[0] * axis[1] + s * axis[2]; 31 Rotate[0][2] = temp[0] * axis[2] - s * axis[1]; 32 33 Rotate[1][0] = temp[1] * axis[0] - s * axis[2]; 34 Rotate[1][1] = c + temp[1] * axis[1]; 35 Rotate[1][2] = temp[1] * axis[2] + s * axis[0]; 36 37 Rotate[2][0] = temp[2] * axis[0] + s * axis[1]; 38 Rotate[2][1] = temp[2] * axis[1] - s * axis[0]; 39 Rotate[2][2] = c + temp[2] * axis[2]; 40 41 tmat4x4<T, P> Result(uninitialize); 42 Result[0] = m[0] * Rotate[0][0] + m[1] * Rotate[0][1] + m[2] * Rotate[0][2]; 43 Result[1] = m[0] * Rotate[1][0] + m[1] * Rotate[1][1] + m[2] * Rotate[1][2]; 44 Result[2] = m[0] * Rotate[2][0] + m[1] * Rotate[2][1] + m[2] * Rotate[2][2]; 45 Result[3] = m[3]; 46 return Result; 47 } 48 49 template <typename T, precision P> 50 GLM_FUNC_QUALIFIER tmat4x4<T, P> rotate_slow(tmat4x4<T, P> const & m, T angle, tvec3<T, P> const & v) 51 { 52 T const a = angle; 53 T const c = cos(a); 54 T const s = sin(a); 55 tmat4x4<T, P> Result; 56 57 tvec3<T, P> axis = normalize(v); 58 59 Result[0][0] = c + (static_cast<T>(1) - c) * axis.x * axis.x; 60 Result[0][1] = (static_cast<T>(1) - c) * axis.x * axis.y + s * axis.z; 61 Result[0][2] = (static_cast<T>(1) - c) * axis.x * axis.z - s * axis.y; 62 Result[0][3] = static_cast<T>(0); 63 64 Result[1][0] = (static_cast<T>(1) - c) * axis.y * axis.x - s * axis.z; 65 Result[1][1] = c + (static_cast<T>(1) - c) * axis.y * axis.y; 66 Result[1][2] = (static_cast<T>(1) - c) * axis.y * axis.z + s * axis.x; 67 Result[1][3] = static_cast<T>(0); 68 69 Result[2][0] = (static_cast<T>(1) - c) * axis.z * axis.x + s * axis.y; 70 Result[2][1] = (static_cast<T>(1) - c) * axis.z * axis.y - s * axis.x; 71 Result[2][2] = c + (static_cast<T>(1) - c) * axis.z * axis.z; 72 Result[2][3] = static_cast<T>(0); 73 74 Result[3] = tvec4<T, P>(0, 0, 0, 1); 75 return m * Result; 76 } 77 78 template <typename T, precision P> 79 GLM_FUNC_QUALIFIER tmat4x4<T, P> scale(tmat4x4<T, P> const & m, tvec3<T, P> const & v) 80 { 81 tmat4x4<T, P> Result(uninitialize); 82 Result[0] = m[0] * v[0]; 83 Result[1] = m[1] * v[1]; 84 Result[2] = m[2] * v[2]; 85 Result[3] = m[3]; 86 return Result; 87 } 88 89 template <typename T, precision P> 90 GLM_FUNC_QUALIFIER tmat4x4<T, P> scale_slow(tmat4x4<T, P> const & m, tvec3<T, P> const & v) 91 { 92 tmat4x4<T, P> Result(T(1)); 93 Result[0][0] = v.x; 94 Result[1][1] = v.y; 95 Result[2][2] = v.z; 96 return m * Result; 97 } 98 99 template <typename T> 100 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> ortho 101 ( 102 T left, T right, 103 T bottom, T top, 104 T zNear, T zFar 105 ) 106 { 107# if GLM_COORDINATE_SYSTEM == GLM_LEFT_HANDED 108 return orthoLH(left, right, bottom, top, zNear, zFar); 109# else 110 return orthoRH(left, right, bottom, top, zNear, zFar); 111# endif 112 } 113 114 template <typename T> 115 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> orthoLH 116 ( 117 T left, T right, 118 T bottom, T top, 119 T zNear, T zFar 120 ) 121 { 122 tmat4x4<T, defaultp> Result(1); 123 Result[0][0] = static_cast<T>(2) / (right - left); 124 Result[1][1] = static_cast<T>(2) / (top - bottom); 125 Result[3][0] = - (right + left) / (right - left); 126 Result[3][1] = - (top + bottom) / (top - bottom); 127 128# if GLM_DEPTH_CLIP_SPACE == GLM_DEPTH_ZERO_TO_ONE 129 Result[2][2] = static_cast<T>(1) / (zFar - zNear); 130 Result[3][2] = - zNear / (zFar - zNear); 131# else 132 Result[2][2] = static_cast<T>(2) / (zFar - zNear); 133 Result[3][2] = - (zFar + zNear) / (zFar - zNear); 134# endif 135 136 return Result; 137 } 138 139 template <typename T> 140 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> orthoRH 141 ( 142 T left, T right, 143 T bottom, T top, 144 T zNear, T zFar 145 ) 146 { 147 tmat4x4<T, defaultp> Result(1); 148 Result[0][0] = static_cast<T>(2) / (right - left); 149 Result[1][1] = static_cast<T>(2) / (top - bottom); 150 Result[3][0] = - (right + left) / (right - left); 151 Result[3][1] = - (top + bottom) / (top - bottom); 152 153# if GLM_DEPTH_CLIP_SPACE == GLM_DEPTH_ZERO_TO_ONE 154 Result[2][2] = - static_cast<T>(1) / (zFar - zNear); 155 Result[3][2] = - zNear / (zFar - zNear); 156# else 157 Result[2][2] = - static_cast<T>(2) / (zFar - zNear); 158 Result[3][2] = - (zFar + zNear) / (zFar - zNear); 159# endif 160 161 return Result; 162 } 163 164 template <typename T> 165 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> ortho 166 ( 167 T left, T right, 168 T bottom, T top 169 ) 170 { 171 tmat4x4<T, defaultp> Result(static_cast<T>(1)); 172 Result[0][0] = static_cast<T>(2) / (right - left); 173 Result[1][1] = static_cast<T>(2) / (top - bottom); 174 Result[2][2] = - static_cast<T>(1); 175 Result[3][0] = - (right + left) / (right - left); 176 Result[3][1] = - (top + bottom) / (top - bottom); 177 return Result; 178 } 179 180 template <typename T> 181 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> frustum 182 ( 183 T left, T right, 184 T bottom, T top, 185 T nearVal, T farVal 186 ) 187 { 188# if GLM_COORDINATE_SYSTEM == GLM_LEFT_HANDED 189 return frustumLH(left, right, bottom, top, nearVal, farVal); 190# else 191 return frustumRH(left, right, bottom, top, nearVal, farVal); 192# endif 193 } 194 195 template <typename T> 196 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> frustumLH 197 ( 198 T left, T right, 199 T bottom, T top, 200 T nearVal, T farVal 201 ) 202 { 203 tmat4x4<T, defaultp> Result(0); 204 Result[0][0] = (static_cast<T>(2) * nearVal) / (right - left); 205 Result[1][1] = (static_cast<T>(2) * nearVal) / (top - bottom); 206 Result[2][0] = (right + left) / (right - left); 207 Result[2][1] = (top + bottom) / (top - bottom); 208 Result[2][3] = static_cast<T>(1); 209 210# if GLM_DEPTH_CLIP_SPACE == GLM_DEPTH_ZERO_TO_ONE 211 Result[2][2] = farVal / (farVal - nearVal); 212 Result[3][2] = -(farVal * nearVal) / (farVal - nearVal); 213# else 214 Result[2][2] = (farVal + nearVal) / (farVal - nearVal); 215 Result[3][2] = - (static_cast<T>(2) * farVal * nearVal) / (farVal - nearVal); 216# endif 217 218 return Result; 219 } 220 221 template <typename T> 222 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> frustumRH 223 ( 224 T left, T right, 225 T bottom, T top, 226 T nearVal, T farVal 227 ) 228 { 229 tmat4x4<T, defaultp> Result(0); 230 Result[0][0] = (static_cast<T>(2) * nearVal) / (right - left); 231 Result[1][1] = (static_cast<T>(2) * nearVal) / (top - bottom); 232 Result[2][0] = (right + left) / (right - left); 233 Result[2][1] = (top + bottom) / (top - bottom); 234 Result[2][3] = static_cast<T>(-1); 235 236# if GLM_DEPTH_CLIP_SPACE == GLM_DEPTH_ZERO_TO_ONE 237 Result[2][2] = farVal / (nearVal - farVal); 238 Result[3][2] = -(farVal * nearVal) / (farVal - nearVal); 239# else 240 Result[2][2] = - (farVal + nearVal) / (farVal - nearVal); 241 Result[3][2] = - (static_cast<T>(2) * farVal * nearVal) / (farVal - nearVal); 242# endif 243 244 return Result; 245 } 246 247 template <typename T> 248 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> perspective(T fovy, T aspect, T zNear, T zFar) 249 { 250# if GLM_COORDINATE_SYSTEM == GLM_LEFT_HANDED 251 return perspectiveLH(fovy, aspect, zNear, zFar); 252# else 253 return perspectiveRH(fovy, aspect, zNear, zFar); 254# endif 255 } 256 257 template <typename T> 258 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> perspectiveRH(T fovy, T aspect, T zNear, T zFar) 259 { 260 assert(abs(aspect - std::numeric_limits<T>::epsilon()) > static_cast<T>(0)); 261 262 T const tanHalfFovy = tan(fovy / static_cast<T>(2)); 263 264 tmat4x4<T, defaultp> Result(static_cast<T>(0)); 265 Result[0][0] = static_cast<T>(1) / (aspect * tanHalfFovy); 266 Result[1][1] = static_cast<T>(1) / (tanHalfFovy); 267 Result[2][3] = - static_cast<T>(1); 268 269# if GLM_DEPTH_CLIP_SPACE == GLM_DEPTH_ZERO_TO_ONE 270 Result[2][2] = zFar / (zNear - zFar); 271 Result[3][2] = -(zFar * zNear) / (zFar - zNear); 272# else 273 Result[2][2] = - (zFar + zNear) / (zFar - zNear); 274 Result[3][2] = - (static_cast<T>(2) * zFar * zNear) / (zFar - zNear); 275# endif 276 277 return Result; 278 } 279 280 template <typename T> 281 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> perspectiveLH(T fovy, T aspect, T zNear, T zFar) 282 { 283 assert(abs(aspect - std::numeric_limits<T>::epsilon()) > static_cast<T>(0)); 284 285 T const tanHalfFovy = tan(fovy / static_cast<T>(2)); 286 287 tmat4x4<T, defaultp> Result(static_cast<T>(0)); 288 Result[0][0] = static_cast<T>(1) / (aspect * tanHalfFovy); 289 Result[1][1] = static_cast<T>(1) / (tanHalfFovy); 290 Result[2][3] = static_cast<T>(1); 291 292# if GLM_DEPTH_CLIP_SPACE == GLM_DEPTH_ZERO_TO_ONE 293 Result[2][2] = zFar / (zFar - zNear); 294 Result[3][2] = -(zFar * zNear) / (zFar - zNear); 295# else 296 Result[2][2] = (zFar + zNear) / (zFar - zNear); 297 Result[3][2] = - (static_cast<T>(2) * zFar * zNear) / (zFar - zNear); 298# endif 299 300 return Result; 301 } 302 303 template <typename T> 304 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> perspectiveFov(T fov, T width, T height, T zNear, T zFar) 305 { 306# if GLM_COORDINATE_SYSTEM == GLM_LEFT_HANDED 307 return perspectiveFovLH(fov, width, height, zNear, zFar); 308# else 309 return perspectiveFovRH(fov, width, height, zNear, zFar); 310# endif 311 } 312 313 template <typename T> 314 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> perspectiveFovRH(T fov, T width, T height, T zNear, T zFar) 315 { 316 assert(width > static_cast<T>(0)); 317 assert(height > static_cast<T>(0)); 318 assert(fov > static_cast<T>(0)); 319 320 T const rad = fov; 321 T const h = glm::cos(static_cast<T>(0.5) * rad) / glm::sin(static_cast<T>(0.5) * rad); 322 T const w = h * height / width; ///todo max(width , Height) / min(width , Height)? 323 324 tmat4x4<T, defaultp> Result(static_cast<T>(0)); 325 Result[0][0] = w; 326 Result[1][1] = h; 327 Result[2][3] = - static_cast<T>(1); 328 329# if GLM_DEPTH_CLIP_SPACE == GLM_DEPTH_ZERO_TO_ONE 330 Result[2][2] = zFar / (zNear - zFar); 331 Result[3][2] = -(zFar * zNear) / (zFar - zNear); 332# else 333 Result[2][2] = - (zFar + zNear) / (zFar - zNear); 334 Result[3][2] = - (static_cast<T>(2) * zFar * zNear) / (zFar - zNear); 335# endif 336 337 return Result; 338 } 339 340 template <typename T> 341 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> perspectiveFovLH(T fov, T width, T height, T zNear, T zFar) 342 { 343 assert(width > static_cast<T>(0)); 344 assert(height > static_cast<T>(0)); 345 assert(fov > static_cast<T>(0)); 346 347 T const rad = fov; 348 T const h = glm::cos(static_cast<T>(0.5) * rad) / glm::sin(static_cast<T>(0.5) * rad); 349 T const w = h * height / width; ///todo max(width , Height) / min(width , Height)? 350 351 tmat4x4<T, defaultp> Result(static_cast<T>(0)); 352 Result[0][0] = w; 353 Result[1][1] = h; 354 Result[2][3] = static_cast<T>(1); 355 356# if GLM_DEPTH_CLIP_SPACE == GLM_DEPTH_ZERO_TO_ONE 357 Result[2][2] = zFar / (zFar - zNear); 358 Result[3][2] = -(zFar * zNear) / (zFar - zNear); 359# else 360 Result[2][2] = (zFar + zNear) / (zFar - zNear); 361 Result[3][2] = - (static_cast<T>(2) * zFar * zNear) / (zFar - zNear); 362# endif 363 364 return Result; 365 } 366 367 template <typename T> 368 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> infinitePerspective(T fovy, T aspect, T zNear) 369 { 370# if GLM_COORDINATE_SYSTEM == GLM_LEFT_HANDED 371 return infinitePerspectiveLH(fovy, aspect, zNear); 372# else 373 return infinitePerspectiveRH(fovy, aspect, zNear); 374# endif 375 } 376 377 template <typename T> 378 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> infinitePerspectiveRH(T fovy, T aspect, T zNear) 379 { 380 T const range = tan(fovy / static_cast<T>(2)) * zNear; 381 T const left = -range * aspect; 382 T const right = range * aspect; 383 T const bottom = -range; 384 T const top = range; 385 386 tmat4x4<T, defaultp> Result(static_cast<T>(0)); 387 Result[0][0] = (static_cast<T>(2) * zNear) / (right - left); 388 Result[1][1] = (static_cast<T>(2) * zNear) / (top - bottom); 389 Result[2][2] = - static_cast<T>(1); 390 Result[2][3] = - static_cast<T>(1); 391 Result[3][2] = - static_cast<T>(2) * zNear; 392 return Result; 393 } 394 395 template <typename T> 396 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> infinitePerspectiveLH(T fovy, T aspect, T zNear) 397 { 398 T const range = tan(fovy / static_cast<T>(2)) * zNear; 399 T const left = -range * aspect; 400 T const right = range * aspect; 401 T const bottom = -range; 402 T const top = range; 403 404 tmat4x4<T, defaultp> Result(T(0)); 405 Result[0][0] = (static_cast<T>(2) * zNear) / (right - left); 406 Result[1][1] = (static_cast<T>(2) * zNear) / (top - bottom); 407 Result[2][2] = static_cast<T>(1); 408 Result[2][3] = static_cast<T>(1); 409 Result[3][2] = - static_cast<T>(2) * zNear; 410 return Result; 411 } 412 413 // Infinite projection matrix: http://www.terathon.com/gdc07_lengyel.pdf 414 template <typename T> 415 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> tweakedInfinitePerspective(T fovy, T aspect, T zNear, T ep) 416 { 417 T const range = tan(fovy / static_cast<T>(2)) * zNear; 418 T const left = -range * aspect; 419 T const right = range * aspect; 420 T const bottom = -range; 421 T const top = range; 422 423 tmat4x4<T, defaultp> Result(static_cast<T>(0)); 424 Result[0][0] = (static_cast<T>(2) * zNear) / (right - left); 425 Result[1][1] = (static_cast<T>(2) * zNear) / (top - bottom); 426 Result[2][2] = ep - static_cast<T>(1); 427 Result[2][3] = static_cast<T>(-1); 428 Result[3][2] = (ep - static_cast<T>(2)) * zNear; 429 return Result; 430 } 431 432 template <typename T> 433 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> tweakedInfinitePerspective(T fovy, T aspect, T zNear) 434 { 435 return tweakedInfinitePerspective(fovy, aspect, zNear, epsilon<T>()); 436 } 437 438 template <typename T, typename U, precision P> 439 GLM_FUNC_QUALIFIER tvec3<T, P> project 440 ( 441 tvec3<T, P> const & obj, 442 tmat4x4<T, P> const & model, 443 tmat4x4<T, P> const & proj, 444 tvec4<U, P> const & viewport 445 ) 446 { 447 tvec4<T, P> tmp = tvec4<T, P>(obj, static_cast<T>(1)); 448 tmp = model * tmp; 449 tmp = proj * tmp; 450 451 tmp /= tmp.w; 452# if GLM_DEPTH_CLIP_SPACE == GLM_DEPTH_ZERO_TO_ONE 453 tmp.x = tmp.x * static_cast<T>(0.5) + static_cast<T>(0.5); 454 tmp.y = tmp.y * static_cast<T>(0.5) + static_cast<T>(0.5); 455# else 456 tmp = tmp * static_cast<T>(0.5) + static_cast<T>(0.5); 457# endif 458 tmp[0] = tmp[0] * T(viewport[2]) + T(viewport[0]); 459 tmp[1] = tmp[1] * T(viewport[3]) + T(viewport[1]); 460 461 return tvec3<T, P>(tmp); 462 } 463 464 template <typename T, typename U, precision P> 465 GLM_FUNC_QUALIFIER tvec3<T, P> unProject 466 ( 467 tvec3<T, P> const & win, 468 tmat4x4<T, P> const & model, 469 tmat4x4<T, P> const & proj, 470 tvec4<U, P> const & viewport 471 ) 472 { 473 tmat4x4<T, P> Inverse = inverse(proj * model); 474 475 tvec4<T, P> tmp = tvec4<T, P>(win, T(1)); 476 tmp.x = (tmp.x - T(viewport[0])) / T(viewport[2]); 477 tmp.y = (tmp.y - T(viewport[1])) / T(viewport[3]); 478# if GLM_DEPTH_CLIP_SPACE == GLM_DEPTH_ZERO_TO_ONE 479 tmp.x = tmp.x * static_cast<T>(2) - static_cast<T>(1); 480 tmp.y = tmp.y * static_cast<T>(2) - static_cast<T>(1); 481# else 482 tmp = tmp * static_cast<T>(2) - static_cast<T>(1); 483# endif 484 485 tvec4<T, P> obj = Inverse * tmp; 486 obj /= obj.w; 487 488 return tvec3<T, P>(obj); 489 } 490 491 template <typename T, precision P, typename U> 492 GLM_FUNC_QUALIFIER tmat4x4<T, P> pickMatrix(tvec2<T, P> const & center, tvec2<T, P> const & delta, tvec4<U, P> const & viewport) 493 { 494 assert(delta.x > static_cast<T>(0) && delta.y > static_cast<T>(0)); 495 tmat4x4<T, P> Result(static_cast<T>(1)); 496 497 if(!(delta.x > static_cast<T>(0) && delta.y > static_cast<T>(0))) 498 return Result; // Error 499 500 tvec3<T, P> Temp( 501 (static_cast<T>(viewport[2]) - static_cast<T>(2) * (center.x - static_cast<T>(viewport[0]))) / delta.x, 502 (static_cast<T>(viewport[3]) - static_cast<T>(2) * (center.y - static_cast<T>(viewport[1]))) / delta.y, 503 static_cast<T>(0)); 504 505 // Translate and scale the picked region to the entire window 506 Result = translate(Result, Temp); 507 return scale(Result, tvec3<T, P>(static_cast<T>(viewport[2]) / delta.x, static_cast<T>(viewport[3]) / delta.y, static_cast<T>(1))); 508 } 509 510 template <typename T, precision P> 511 GLM_FUNC_QUALIFIER tmat4x4<T, P> lookAt(tvec3<T, P> const & eye, tvec3<T, P> const & center, tvec3<T, P> const & up) 512 { 513# if GLM_COORDINATE_SYSTEM == GLM_LEFT_HANDED 514 return lookAtLH(eye, center, up); 515# else 516 return lookAtRH(eye, center, up); 517# endif 518 } 519 520 template <typename T, precision P> 521 GLM_FUNC_QUALIFIER tmat4x4<T, P> lookAtRH 522 ( 523 tvec3<T, P> const & eye, 524 tvec3<T, P> const & center, 525 tvec3<T, P> const & up 526 ) 527 { 528 tvec3<T, P> const f(normalize(center - eye)); 529 tvec3<T, P> const s(normalize(cross(f, up))); 530 tvec3<T, P> const u(cross(s, f)); 531 532 tmat4x4<T, P> Result(1); 533 Result[0][0] = s.x; 534 Result[1][0] = s.y; 535 Result[2][0] = s.z; 536 Result[0][1] = u.x; 537 Result[1][1] = u.y; 538 Result[2][1] = u.z; 539 Result[0][2] =-f.x; 540 Result[1][2] =-f.y; 541 Result[2][2] =-f.z; 542 Result[3][0] =-dot(s, eye); 543 Result[3][1] =-dot(u, eye); 544 Result[3][2] = dot(f, eye); 545 return Result; 546 } 547 548 template <typename T, precision P> 549 GLM_FUNC_QUALIFIER tmat4x4<T, P> lookAtLH 550 ( 551 tvec3<T, P> const & eye, 552 tvec3<T, P> const & center, 553 tvec3<T, P> const & up 554 ) 555 { 556 tvec3<T, P> const f(normalize(center - eye)); 557 tvec3<T, P> const s(normalize(cross(up, f))); 558 tvec3<T, P> const u(cross(f, s)); 559 560 tmat4x4<T, P> Result(1); 561 Result[0][0] = s.x; 562 Result[1][0] = s.y; 563 Result[2][0] = s.z; 564 Result[0][1] = u.x; 565 Result[1][1] = u.y; 566 Result[2][1] = u.z; 567 Result[0][2] = f.x; 568 Result[1][2] = f.y; 569 Result[2][2] = f.z; 570 Result[3][0] = -dot(s, eye); 571 Result[3][1] = -dot(u, eye); 572 Result[3][2] = -dot(f, eye); 573 return Result; 574 } 575}//namespace glm 576