2 Copyright (C) 2001-2006, William Joseph.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #if !defined( INCLUDED_ROTATION_H )
23 #define INCLUDED_ROTATION_H
27 #include "math/quaternion.h"
28 #include "generic/callback.h"
35 typedef float Float9[9];
37 inline void default_rotation( Float9 rotation ){
48 inline void write_rotation( const Float9 rotation, Entity* entity, const char* key = "rotation" ){
57 && rotation[8] == 1 ) {
58 entity->setKeyValue( key, "" );
62 std::ostringstream value;
63 value << rotation[0] << ' '
72 entity->setKeyValue( key, value.str().c_str() );
75 inline void read_rotation( Float9 rotation, const char* value ){
76 if ( !string_parse_vector( value, rotation, rotation + 9 ) ) {
77 default_rotation( rotation );
81 inline Matrix4 rotation_toMatrix( const Float9 rotation ){
102 inline void rotation_fromMatrix( Float9 rotation, const Matrix4& matrix ){
103 rotation[0] = matrix.xx();
104 rotation[1] = matrix.xy();
105 rotation[2] = matrix.xz();
106 rotation[3] = matrix.yx();
107 rotation[4] = matrix.yy();
108 rotation[5] = matrix.yz();
109 rotation[6] = matrix.zx();
110 rotation[7] = matrix.zy();
111 rotation[8] = matrix.zz();
114 inline void rotation_assign( Float9 rotation, const Float9 other ){
115 rotation[0] = other[0];
116 rotation[1] = other[1];
117 rotation[2] = other[2];
118 rotation[3] = other[3];
119 rotation[4] = other[4];
120 rotation[5] = other[5];
121 rotation[6] = other[6];
122 rotation[7] = other[7];
123 rotation[8] = other[8];
126 inline void rotation_rotate( Float9 rotation, const Quaternion& rotate ){
127 rotation_fromMatrix( rotation,
128 matrix4_multiplied_by_matrix4(
129 rotation_toMatrix( rotation ),
130 matrix4_rotation_for_quaternion_quantised( rotate )
135 inline void read_angle( Float9 rotation, const char* value ){
137 if ( !string_parse_float( value, angle ) ) {
138 default_rotation( rotation );
142 rotation_fromMatrix( rotation, matrix4_rotation_for_z_degrees( angle ) );
148 Callback<void()> m_rotationChanged;
153 RotationKey( const Callback<void()>& rotationChanged )
154 : m_rotationChanged( rotationChanged ){
155 default_rotation( m_rotation );
158 void angleChanged( const char* value ){
159 read_angle( m_rotation, value );
162 typedef MemberCaller<RotationKey, void(const char*), &RotationKey::angleChanged> AngleChangedCaller;
164 void rotationChanged( const char* value ){
165 read_rotation( m_rotation, value );
168 typedef MemberCaller<RotationKey, void(const char*), &RotationKey::rotationChanged> RotationChangedCaller;
170 void write( Entity* entity ) const {
171 Vector3 euler = matrix4_get_rotation_euler_xyz_degrees( rotation_toMatrix( m_rotation ) );
172 if ( euler[0] == 0 && euler[1] == 0 ) {
173 entity->setKeyValue( "rotation", "" );
174 write_angle( euler[2], entity );
178 entity->setKeyValue( "angle", "" );
179 write_rotation( m_rotation, entity );