| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved. |
| 3 * Copyright (C) 2009 Torch Mobile, Inc. | 3 * Copyright (C) 2009 Torch Mobile, Inc. |
| 4 * Copyright (C) 2013 Google Inc. All rights reserved. | 4 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 5 * | 5 * |
| 6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
| 7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
| 8 * are met: | 8 * are met: |
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 #include "platform/geometry/LayoutRect.h" | 35 #include "platform/geometry/LayoutRect.h" |
| 36 #include "platform/transforms/AffineTransform.h" | 36 #include "platform/transforms/AffineTransform.h" |
| 37 | 37 |
| 38 #include "wtf/Assertions.h" | 38 #include "wtf/Assertions.h" |
| 39 #include "wtf/MathExtras.h" | 39 #include "wtf/MathExtras.h" |
| 40 | 40 |
| 41 #if CPU(X86_64) | 41 #if CPU(X86_64) |
| 42 #include <emmintrin.h> | 42 #include <emmintrin.h> |
| 43 #endif | 43 #endif |
| 44 | 44 |
| 45 using namespace std; | |
| 46 | |
| 47 namespace blink { | 45 namespace blink { |
| 48 | 46 |
| 49 // | 47 // |
| 50 // Supporting Math Functions | 48 // Supporting Math Functions |
| 51 // | 49 // |
| 52 // This is a set of function from various places (attributed inline) to do thing
s like | 50 // This is a set of function from various places (attributed inline) to do thing
s like |
| 53 // inversion and decomposition of a 4x4 matrix. They are used throughout the cod
e | 51 // inversion and decomposition of a 4x4 matrix. They are used throughout the cod
e |
| 54 // | 52 // |
| 55 | 53 |
| 56 // | 54 // |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 result[1] = (p[0] * m[0][1]) + (p[1] * m[1][1]) + | 252 result[1] = (p[0] * m[0][1]) + (p[1] * m[1][1]) + |
| 255 (p[2] * m[2][1]) + (p[3] * m[3][1]); | 253 (p[2] * m[2][1]) + (p[3] * m[3][1]); |
| 256 result[2] = (p[0] * m[0][2]) + (p[1] * m[1][2]) + | 254 result[2] = (p[0] * m[0][2]) + (p[1] * m[1][2]) + |
| 257 (p[2] * m[2][2]) + (p[3] * m[3][2]); | 255 (p[2] * m[2][2]) + (p[3] * m[3][2]); |
| 258 result[3] = (p[0] * m[0][3]) + (p[1] * m[1][3]) + | 256 result[3] = (p[0] * m[0][3]) + (p[1] * m[1][3]) + |
| 259 (p[2] * m[2][3]) + (p[3] * m[3][3]); | 257 (p[2] * m[2][3]) + (p[3] * m[3][3]); |
| 260 } | 258 } |
| 261 | 259 |
| 262 static double v3Length(Vector3 a) | 260 static double v3Length(Vector3 a) |
| 263 { | 261 { |
| 264 return sqrt((a[0] * a[0]) + (a[1] * a[1]) + (a[2] * a[2])); | 262 return std::sqrt((a[0] * a[0]) + (a[1] * a[1]) + (a[2] * a[2])); |
| 265 } | 263 } |
| 266 | 264 |
| 267 static void v3Scale(Vector3 v, double desiredLength) | 265 static void v3Scale(Vector3 v, double desiredLength) |
| 268 { | 266 { |
| 269 double len = v3Length(v); | 267 double len = v3Length(v); |
| 270 if (len != 0) { | 268 if (len != 0) { |
| 271 double l = desiredLength / len; | 269 double l = desiredLength / len; |
| 272 v[0] *= l; | 270 v[0] *= l; |
| 273 v[1] *= l; | 271 v[1] *= l; |
| 274 v[2] *= l; | 272 v[2] *= l; |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 430 // } else { | 428 // } else { |
| 431 // ret.rotateX = atan2(-row[2][0], row[1][1]); | 429 // ret.rotateX = atan2(-row[2][0], row[1][1]); |
| 432 // ret.rotateZ = 0; | 430 // ret.rotateZ = 0; |
| 433 // } | 431 // } |
| 434 | 432 |
| 435 double s, t, x, y, z, w; | 433 double s, t, x, y, z, w; |
| 436 | 434 |
| 437 t = row[0][0] + row[1][1] + row[2][2] + 1.0; | 435 t = row[0][0] + row[1][1] + row[2][2] + 1.0; |
| 438 | 436 |
| 439 if (t > 1e-4) { | 437 if (t > 1e-4) { |
| 440 s = 0.5 / sqrt(t); | 438 s = 0.5 / std::sqrt(t); |
| 441 w = 0.25 / s; | 439 w = 0.25 / s; |
| 442 x = (row[2][1] - row[1][2]) * s; | 440 x = (row[2][1] - row[1][2]) * s; |
| 443 y = (row[0][2] - row[2][0]) * s; | 441 y = (row[0][2] - row[2][0]) * s; |
| 444 z = (row[1][0] - row[0][1]) * s; | 442 z = (row[1][0] - row[0][1]) * s; |
| 445 } else if (row[0][0] > row[1][1] && row[0][0] > row[2][2]) { | 443 } else if (row[0][0] > row[1][1] && row[0][0] > row[2][2]) { |
| 446 s = sqrt (1.0 + row[0][0] - row[1][1] - row[2][2]) * 2.0; // S=4*qx | 444 s = std::sqrt(1.0 + row[0][0] - row[1][1] - row[2][2]) * 2.0; // S=4*qx |
| 447 x = 0.25 * s; | 445 x = 0.25 * s; |
| 448 y = (row[0][1] + row[1][0]) / s; | 446 y = (row[0][1] + row[1][0]) / s; |
| 449 z = (row[0][2] + row[2][0]) / s; | 447 z = (row[0][2] + row[2][0]) / s; |
| 450 w = (row[2][1] - row[1][2]) / s; | 448 w = (row[2][1] - row[1][2]) / s; |
| 451 } else if (row[1][1] > row[2][2]) { | 449 } else if (row[1][1] > row[2][2]) { |
| 452 s = sqrt (1.0 + row[1][1] - row[0][0] - row[2][2]) * 2.0; // S=4*qy | 450 s = std::sqrt(1.0 + row[1][1] - row[0][0] - row[2][2]) * 2.0; // S=4*qy |
| 453 x = (row[0][1] + row[1][0]) / s; | 451 x = (row[0][1] + row[1][0]) / s; |
| 454 y = 0.25 * s; | 452 y = 0.25 * s; |
| 455 z = (row[1][2] + row[2][1]) / s; | 453 z = (row[1][2] + row[2][1]) / s; |
| 456 w = (row[0][2] - row[2][0]) / s; | 454 w = (row[0][2] - row[2][0]) / s; |
| 457 } else { | 455 } else { |
| 458 s = sqrt(1.0 + row[2][2] - row[0][0] - row[1][1]) * 2.0; // S=4*qz | 456 s = std::sqrt(1.0 + row[2][2] - row[0][0] - row[1][1]) * 2.0; // S=4*qz |
| 459 x = (row[0][2] + row[2][0]) / s; | 457 x = (row[0][2] + row[2][0]) / s; |
| 460 y = (row[1][2] + row[2][1]) / s; | 458 y = (row[1][2] + row[2][1]) / s; |
| 461 z = 0.25 * s; | 459 z = 0.25 * s; |
| 462 w = (row[1][0] - row[0][1]) / s; | 460 w = (row[1][0] - row[0][1]) / s; |
| 463 } | 461 } |
| 464 | 462 |
| 465 result.quaternionX = x; | 463 result.quaternionX = x; |
| 466 result.quaternionY = y; | 464 result.quaternionY = y; |
| 467 result.quaternionZ = z; | 465 result.quaternionZ = z; |
| 468 result.quaternionW = w; | 466 result.quaternionW = w; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 486 angle = ax * bx + ay * by + az * bz + aw * bw; | 484 angle = ax * bx + ay * by + az * bz + aw * bw; |
| 487 | 485 |
| 488 if (angle < 0.0) { | 486 if (angle < 0.0) { |
| 489 ax = -ax; ay = -ay; | 487 ax = -ax; ay = -ay; |
| 490 az = -az; aw = -aw; | 488 az = -az; aw = -aw; |
| 491 angle = -angle; | 489 angle = -angle; |
| 492 } | 490 } |
| 493 | 491 |
| 494 if (angle + 1.0 > .05) { | 492 if (angle + 1.0 > .05) { |
| 495 if (1.0 - angle >= .05) { | 493 if (1.0 - angle >= .05) { |
| 496 th = acos (angle); | 494 th = std::acos(angle); |
| 497 invth = 1.0 / sin (th); | 495 invth = 1.0 / std::sin(th); |
| 498 scale = sin (th * (1.0 - t)) * invth; | 496 scale = std::sin(th * (1.0 - t)) * invth; |
| 499 invscale = sin (th * t) * invth; | 497 invscale = std::sin(th * t) * invth; |
| 500 } else { | 498 } else { |
| 501 scale = 1.0 - t; | 499 scale = 1.0 - t; |
| 502 invscale = t; | 500 invscale = t; |
| 503 } | 501 } |
| 504 } else { | 502 } else { |
| 505 bx = -ay; | 503 bx = -ay; |
| 506 by = ax; | 504 by = ax; |
| 507 bz = -aw; | 505 bz = -aw; |
| 508 bw = az; | 506 bw = az; |
| 509 scale = sin(piDouble * (.5 - t)); | 507 scale = std::sin(piDouble * (.5 - t)); |
| 510 invscale = sin (piDouble * t); | 508 invscale = std::sin(piDouble * t); |
| 511 } | 509 } |
| 512 | 510 |
| 513 cx = ax * scale + bx * invscale; | 511 cx = ax * scale + bx * invscale; |
| 514 cy = ay * scale + by * invscale; | 512 cy = ay * scale + by * invscale; |
| 515 cz = az * scale + bz * invscale; | 513 cz = az * scale + bz * invscale; |
| 516 cw = aw * scale + bw * invscale; | 514 cw = aw * scale + bw * invscale; |
| 517 | 515 |
| 518 qa[0] = cx; qa[1] = cy; qa[2] = cz; qa[3] = cw; | 516 qa[0] = cx; qa[1] = cy; qa[2] = cz; qa[3] = cw; |
| 519 } | 517 } |
| 520 | 518 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 615 bool everythingWasClipped = clamped1 && clamped2 && clamped3 && clamped4; | 613 bool everythingWasClipped = clamped1 && clamped2 && clamped3 && clamped4; |
| 616 if (everythingWasClipped) | 614 if (everythingWasClipped) |
| 617 return FloatQuad(); | 615 return FloatQuad(); |
| 618 | 616 |
| 619 return projectedQuad; | 617 return projectedQuad; |
| 620 } | 618 } |
| 621 | 619 |
| 622 static float clampEdgeValue(float f) | 620 static float clampEdgeValue(float f) |
| 623 { | 621 { |
| 624 ASSERT(!std::isnan(f)); | 622 ASSERT(!std::isnan(f)); |
| 625 return min<float>(max<float>(f, (-LayoutUnit::max() / 2).toFloat()), (Layout
Unit::max() / 2).toFloat()); | 623 return std::min<float>(std::max<float>(f, (-LayoutUnit::max() / 2).toFloat()
), (LayoutUnit::max() / 2).toFloat()); |
| 626 } | 624 } |
| 627 | 625 |
| 628 LayoutRect TransformationMatrix::clampedBoundsOfProjectedQuad(const FloatQuad& q
) const | 626 LayoutRect TransformationMatrix::clampedBoundsOfProjectedQuad(const FloatQuad& q
) const |
| 629 { | 627 { |
| 630 FloatRect mappedQuadBounds = projectQuad(q).boundingBox(); | 628 FloatRect mappedQuadBounds = projectQuad(q).boundingBox(); |
| 631 | 629 |
| 632 float left = clampEdgeValue(floorf(mappedQuadBounds.x())); | 630 float left = clampEdgeValue(floorf(mappedQuadBounds.x())); |
| 633 float top = clampEdgeValue(floorf(mappedQuadBounds.y())); | 631 float top = clampEdgeValue(floorf(mappedQuadBounds.y())); |
| 634 | 632 |
| 635 float right; | 633 float right; |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 m_matrix[2][0] *= sz; | 752 m_matrix[2][0] *= sz; |
| 755 m_matrix[2][1] *= sz; | 753 m_matrix[2][1] *= sz; |
| 756 m_matrix[2][2] *= sz; | 754 m_matrix[2][2] *= sz; |
| 757 m_matrix[2][3] *= sz; | 755 m_matrix[2][3] *= sz; |
| 758 return *this; | 756 return *this; |
| 759 } | 757 } |
| 760 | 758 |
| 761 TransformationMatrix& TransformationMatrix::rotate3d(double x, double y, double
z, double angle) | 759 TransformationMatrix& TransformationMatrix::rotate3d(double x, double y, double
z, double angle) |
| 762 { | 760 { |
| 763 // Normalize the axis of rotation | 761 // Normalize the axis of rotation |
| 764 double length = sqrt(x * x + y * y + z * z); | 762 double length = std::sqrt(x * x + y * y + z * z); |
| 765 if (length == 0) { | 763 if (length == 0) { |
| 766 // A direction vector that cannot be normalized, such as [0, 0, 0], will
cause the rotation to not be applied. | 764 // A direction vector that cannot be normalized, such as [0, 0, 0], will
cause the rotation to not be applied. |
| 767 return *this; | 765 return *this; |
| 768 } else if (length != 1) { | 766 } else if (length != 1) { |
| 769 x /= length; | 767 x /= length; |
| 770 y /= length; | 768 y /= length; |
| 771 z /= length; | 769 z /= length; |
| 772 } | 770 } |
| 773 | 771 |
| 774 // Angles are in degrees. Switch to radians. | 772 // Angles are in degrees. Switch to radians. |
| 775 angle = deg2rad(angle); | 773 angle = deg2rad(angle); |
| 776 | 774 |
| 777 double sinTheta = sin(angle); | 775 double sinTheta = std::sin(angle); |
| 778 double cosTheta = cos(angle); | 776 double cosTheta = std::cos(angle); |
| 779 | 777 |
| 780 TransformationMatrix mat; | 778 TransformationMatrix mat; |
| 781 | 779 |
| 782 // Optimize cases where the axis is along a major axis | 780 // Optimize cases where the axis is along a major axis |
| 783 if (x == 1.0 && y == 0.0 && z == 0.0) { | 781 if (x == 1.0 && y == 0.0 && z == 0.0) { |
| 784 mat.m_matrix[0][0] = 1.0; | 782 mat.m_matrix[0][0] = 1.0; |
| 785 mat.m_matrix[0][1] = 0.0; | 783 mat.m_matrix[0][1] = 0.0; |
| 786 mat.m_matrix[0][2] = 0.0; | 784 mat.m_matrix[0][2] = 0.0; |
| 787 mat.m_matrix[1][0] = 0.0; | 785 mat.m_matrix[1][0] = 0.0; |
| 788 mat.m_matrix[1][1] = cosTheta; | 786 mat.m_matrix[1][1] = cosTheta; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 847 | 845 |
| 848 TransformationMatrix& TransformationMatrix::rotate3d(double rx, double ry, doubl
e rz) | 846 TransformationMatrix& TransformationMatrix::rotate3d(double rx, double ry, doubl
e rz) |
| 849 { | 847 { |
| 850 // Angles are in degrees. Switch to radians. | 848 // Angles are in degrees. Switch to radians. |
| 851 rx = deg2rad(rx); | 849 rx = deg2rad(rx); |
| 852 ry = deg2rad(ry); | 850 ry = deg2rad(ry); |
| 853 rz = deg2rad(rz); | 851 rz = deg2rad(rz); |
| 854 | 852 |
| 855 TransformationMatrix mat; | 853 TransformationMatrix mat; |
| 856 | 854 |
| 857 double sinTheta = sin(rz); | 855 double sinTheta = std::sin(rz); |
| 858 double cosTheta = cos(rz); | 856 double cosTheta = std::cos(rz); |
| 859 | 857 |
| 860 mat.m_matrix[0][0] = cosTheta; | 858 mat.m_matrix[0][0] = cosTheta; |
| 861 mat.m_matrix[0][1] = sinTheta; | 859 mat.m_matrix[0][1] = sinTheta; |
| 862 mat.m_matrix[0][2] = 0.0; | 860 mat.m_matrix[0][2] = 0.0; |
| 863 mat.m_matrix[1][0] = -sinTheta; | 861 mat.m_matrix[1][0] = -sinTheta; |
| 864 mat.m_matrix[1][1] = cosTheta; | 862 mat.m_matrix[1][1] = cosTheta; |
| 865 mat.m_matrix[1][2] = 0.0; | 863 mat.m_matrix[1][2] = 0.0; |
| 866 mat.m_matrix[2][0] = 0.0; | 864 mat.m_matrix[2][0] = 0.0; |
| 867 mat.m_matrix[2][1] = 0.0; | 865 mat.m_matrix[2][1] = 0.0; |
| 868 mat.m_matrix[2][2] = 1.0; | 866 mat.m_matrix[2][2] = 1.0; |
| 869 mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0; | 867 mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0; |
| 870 mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0; | 868 mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0; |
| 871 mat.m_matrix[3][3] = 1.0; | 869 mat.m_matrix[3][3] = 1.0; |
| 872 | 870 |
| 873 TransformationMatrix rmat(mat); | 871 TransformationMatrix rmat(mat); |
| 874 | 872 |
| 875 sinTheta = sin(ry); | 873 sinTheta = std::sin(ry); |
| 876 cosTheta = cos(ry); | 874 cosTheta = std::cos(ry); |
| 877 | 875 |
| 878 mat.m_matrix[0][0] = cosTheta; | 876 mat.m_matrix[0][0] = cosTheta; |
| 879 mat.m_matrix[0][1] = 0.0; | 877 mat.m_matrix[0][1] = 0.0; |
| 880 mat.m_matrix[0][2] = -sinTheta; | 878 mat.m_matrix[0][2] = -sinTheta; |
| 881 mat.m_matrix[1][0] = 0.0; | 879 mat.m_matrix[1][0] = 0.0; |
| 882 mat.m_matrix[1][1] = 1.0; | 880 mat.m_matrix[1][1] = 1.0; |
| 883 mat.m_matrix[1][2] = 0.0; | 881 mat.m_matrix[1][2] = 0.0; |
| 884 mat.m_matrix[2][0] = sinTheta; | 882 mat.m_matrix[2][0] = sinTheta; |
| 885 mat.m_matrix[2][1] = 0.0; | 883 mat.m_matrix[2][1] = 0.0; |
| 886 mat.m_matrix[2][2] = cosTheta; | 884 mat.m_matrix[2][2] = cosTheta; |
| 887 mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0; | 885 mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0; |
| 888 mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0; | 886 mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0; |
| 889 mat.m_matrix[3][3] = 1.0; | 887 mat.m_matrix[3][3] = 1.0; |
| 890 | 888 |
| 891 rmat.multiply(mat); | 889 rmat.multiply(mat); |
| 892 | 890 |
| 893 sinTheta = sin(rx); | 891 sinTheta = std::sin(rx); |
| 894 cosTheta = cos(rx); | 892 cosTheta = std::cos(rx); |
| 895 | 893 |
| 896 mat.m_matrix[0][0] = 1.0; | 894 mat.m_matrix[0][0] = 1.0; |
| 897 mat.m_matrix[0][1] = 0.0; | 895 mat.m_matrix[0][1] = 0.0; |
| 898 mat.m_matrix[0][2] = 0.0; | 896 mat.m_matrix[0][2] = 0.0; |
| 899 mat.m_matrix[1][0] = 0.0; | 897 mat.m_matrix[1][0] = 0.0; |
| 900 mat.m_matrix[1][1] = cosTheta; | 898 mat.m_matrix[1][1] = cosTheta; |
| 901 mat.m_matrix[1][2] = sinTheta; | 899 mat.m_matrix[1][2] = sinTheta; |
| 902 mat.m_matrix[2][0] = 0.0; | 900 mat.m_matrix[2][0] = 0.0; |
| 903 mat.m_matrix[2][1] = -sinTheta; | 901 mat.m_matrix[2][1] = -sinTheta; |
| 904 mat.m_matrix[2][2] = cosTheta; | 902 mat.m_matrix[2][2] = cosTheta; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 return *this; | 960 return *this; |
| 963 } | 961 } |
| 964 | 962 |
| 965 TransformationMatrix& TransformationMatrix::skew(double sx, double sy) | 963 TransformationMatrix& TransformationMatrix::skew(double sx, double sy) |
| 966 { | 964 { |
| 967 // angles are in degrees. Switch to radians | 965 // angles are in degrees. Switch to radians |
| 968 sx = deg2rad(sx); | 966 sx = deg2rad(sx); |
| 969 sy = deg2rad(sy); | 967 sy = deg2rad(sy); |
| 970 | 968 |
| 971 TransformationMatrix mat; | 969 TransformationMatrix mat; |
| 972 mat.m_matrix[0][1] = tan(sy); // note that the y shear goes in the first row | 970 mat.m_matrix[0][1] = std::tan(sy); // note that the y shear goes in the firs
t row |
| 973 mat.m_matrix[1][0] = tan(sx); // and the x shear in the second row | 971 mat.m_matrix[1][0] = std::tan(sx); // and the x shear in the second row |
| 974 | 972 |
| 975 multiply(mat); | 973 multiply(mat); |
| 976 return *this; | 974 return *this; |
| 977 } | 975 } |
| 978 | 976 |
| 979 TransformationMatrix& TransformationMatrix::applyPerspective(double p) | 977 TransformationMatrix& TransformationMatrix::applyPerspective(double p) |
| 980 { | 978 { |
| 981 TransformationMatrix mat; | 979 TransformationMatrix mat; |
| 982 if (p != 0) | 980 if (p != 0) |
| 983 mat.m_matrix[2][3] = -1/p; | 981 mat.m_matrix[2][3] = -1/p; |
| (...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1521 ret.setDouble(2, 2, matrix.m33()); | 1519 ret.setDouble(2, 2, matrix.m33()); |
| 1522 ret.setDouble(2, 3, matrix.m43()); | 1520 ret.setDouble(2, 3, matrix.m43()); |
| 1523 ret.setDouble(3, 0, matrix.m14()); | 1521 ret.setDouble(3, 0, matrix.m14()); |
| 1524 ret.setDouble(3, 1, matrix.m24()); | 1522 ret.setDouble(3, 1, matrix.m24()); |
| 1525 ret.setDouble(3, 2, matrix.m34()); | 1523 ret.setDouble(3, 2, matrix.m34()); |
| 1526 ret.setDouble(3, 3, matrix.m44()); | 1524 ret.setDouble(3, 3, matrix.m44()); |
| 1527 return ret; | 1525 return ret; |
| 1528 } | 1526 } |
| 1529 | 1527 |
| 1530 } | 1528 } |
| OLD | NEW |