transform.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /*************************************************************************/
  2. /* transform.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* http://www.godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  9. /* */
  10. /* Permission is hereby granted, free of charge, to any person obtaining */
  11. /* a copy of this software and associated documentation files (the */
  12. /* "Software"), to deal in the Software without restriction, including */
  13. /* without limitation the rights to use, copy, modify, merge, publish, */
  14. /* distribute, sublicense, and/or sell copies of the Software, and to */
  15. /* permit persons to whom the Software is furnished to do so, subject to */
  16. /* the following conditions: */
  17. /* */
  18. /* The above copyright notice and this permission notice shall be */
  19. /* included in all copies or substantial portions of the Software. */
  20. /* */
  21. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  22. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  23. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  24. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  25. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  26. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  27. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  28. /*************************************************************************/
  29. #include "transform.h"
  30. #include "math_funcs.h"
  31. #include "os/copymem.h"
  32. #include "print_string.h"
  33. void Transform::affine_invert() {
  34. basis.invert();
  35. origin = basis.xform(-origin);
  36. }
  37. Transform Transform::affine_inverse() const {
  38. Transform ret=*this;
  39. ret.affine_invert();
  40. return ret;
  41. }
  42. void Transform::invert() {
  43. basis.transpose();
  44. origin = basis.xform(-origin);
  45. }
  46. Transform Transform::inverse() const {
  47. Transform ret=*this;
  48. ret.invert();
  49. return ret;
  50. }
  51. void Transform::rotate(const Vector3& p_axis,real_t p_phi) {
  52. *this = *this * Transform( Matrix3( p_axis, p_phi ), Vector3() );
  53. }
  54. Transform Transform::rotated(const Vector3& p_axis,real_t p_phi) const{
  55. return *this * Transform( Matrix3( p_axis, p_phi ), Vector3() );
  56. }
  57. void Transform::rotate_basis(const Vector3& p_axis,real_t p_phi) {
  58. basis.rotate(p_axis,p_phi);
  59. }
  60. Transform Transform::looking_at( const Vector3& p_target, const Vector3& p_up ) const {
  61. Transform t = *this;
  62. t.set_look_at(origin,p_target,p_up);
  63. return t;
  64. }
  65. void Transform::set_look_at( const Vector3& p_eye, const Vector3& p_target, const Vector3& p_up ) {
  66. // Reference: MESA source code
  67. Vector3 v_x, v_y, v_z;
  68. /* Make rotation matrix */
  69. /* Z vector */
  70. v_z = p_eye - p_target;
  71. v_z.normalize();
  72. v_y = p_up;
  73. v_x=v_y.cross(v_z);
  74. /* Recompute Y = Z cross X */
  75. v_y=v_z.cross(v_x);
  76. v_x.normalize();
  77. v_y.normalize();
  78. basis.set_axis(0,v_x);
  79. basis.set_axis(1,v_y);
  80. basis.set_axis(2,v_z);
  81. origin=p_eye;
  82. }
  83. Transform Transform::interpolate_with(const Transform& p_transform, float p_c) const {
  84. /* not sure if very "efficient" but good enough? */
  85. Vector3 src_scale = basis.get_scale();
  86. Quat src_rot = basis;
  87. Vector3 src_loc = origin;
  88. Vector3 dst_scale = p_transform.basis.get_scale();
  89. Quat dst_rot = p_transform.basis;
  90. Vector3 dst_loc = p_transform.origin;
  91. Transform dst;
  92. dst.basis=src_rot.slerp(dst_rot,p_c);
  93. dst.basis.scale(src_scale.linear_interpolate(dst_scale,p_c));
  94. dst.origin=src_loc.linear_interpolate(dst_loc,p_c);
  95. return dst;
  96. }
  97. void Transform::scale(const Vector3& p_scale) {
  98. basis.scale(p_scale);
  99. origin*=p_scale;
  100. }
  101. Transform Transform::scaled(const Vector3& p_scale) const {
  102. Transform t = *this;
  103. t.scale(p_scale);
  104. return t;
  105. }
  106. void Transform::scale_basis(const Vector3& p_scale) {
  107. basis.scale(p_scale);
  108. }
  109. void Transform::translate( real_t p_tx, real_t p_ty, real_t p_tz) {
  110. translate( Vector3(p_tx,p_ty,p_tz) );
  111. }
  112. void Transform::translate( const Vector3& p_translation ) {
  113. for( int i = 0; i < 3; i++ ) {
  114. origin[i] += basis[i].dot(p_translation);
  115. }
  116. }
  117. Transform Transform::translated( const Vector3& p_translation ) const {
  118. Transform t=*this;
  119. t.translate(p_translation);
  120. return t;
  121. }
  122. void Transform::orthonormalize() {
  123. basis.orthonormalize();
  124. }
  125. Transform Transform::orthonormalized() const {
  126. Transform _copy = *this;
  127. _copy.orthonormalize();
  128. return _copy;
  129. }
  130. bool Transform::operator==(const Transform& p_transform) const {
  131. return (basis==p_transform.basis && origin==p_transform.origin);
  132. }
  133. bool Transform::operator!=(const Transform& p_transform) const {
  134. return (basis!=p_transform.basis || origin!=p_transform.origin);
  135. }
  136. void Transform::operator*=(const Transform& p_transform) {
  137. origin=xform(p_transform.origin);
  138. basis*=p_transform.basis;
  139. }
  140. Transform Transform::operator*(const Transform& p_transform) const {
  141. Transform t=*this;
  142. t*=p_transform;
  143. return t;
  144. }
  145. Transform::operator String() const {
  146. return basis.operator String() + " - " + origin.operator String();
  147. }
  148. Transform::Transform(const Matrix3& p_basis, const Vector3& p_origin) {
  149. basis=p_basis;
  150. origin=p_origin;
  151. }