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 "stream/stringstream.h"
28 #include "math/quaternion.h"
29 #include "generic/callback.h"
34 typedef float Float9[9];
36 inline void default_rotation( Float9 rotation ){
47 inline void write_rotation( const Float9 rotation, Entity* entity, const char* key = "rotation" ){
56 && rotation[8] == 1 ) {
57 entity->setKeyValue( key, "" );
61 StringOutputStream value( 256 );
62 value << rotation[0] << ' '
71 entity->setKeyValue( key, value.c_str() );
74 inline void read_rotation( Float9 rotation, const char* value ){
75 if ( !string_parse_vector( value, rotation, rotation + 9 ) ) {
76 default_rotation( rotation );
80 inline Matrix4 rotation_toMatrix( const Float9 rotation ){
101 inline void rotation_fromMatrix( Float9 rotation, const Matrix4& matrix ){
102 rotation[0] = matrix.xx();
103 rotation[1] = matrix.xy();
104 rotation[2] = matrix.xz();
105 rotation[3] = matrix.yx();
106 rotation[4] = matrix.yy();
107 rotation[5] = matrix.yz();
108 rotation[6] = matrix.zx();
109 rotation[7] = matrix.zy();
110 rotation[8] = matrix.zz();
113 inline void rotation_assign( Float9 rotation, const Float9 other ){
114 rotation[0] = other[0];
115 rotation[1] = other[1];
116 rotation[2] = other[2];
117 rotation[3] = other[3];
118 rotation[4] = other[4];
119 rotation[5] = other[5];
120 rotation[6] = other[6];
121 rotation[7] = other[7];
122 rotation[8] = other[8];
125 inline void rotation_rotate( Float9 rotation, const Quaternion& rotate ){
126 rotation_fromMatrix( rotation,
127 matrix4_multiplied_by_matrix4(
128 rotation_toMatrix( rotation ),
129 matrix4_rotation_for_quaternion_quantised( rotate )
134 inline void read_angle( Float9 rotation, const char* value ){
136 if ( !string_parse_float( value, angle ) ) {
137 default_rotation( rotation );
141 rotation_fromMatrix( rotation, matrix4_rotation_for_z_degrees( angle ) );
147 Callback m_rotationChanged;
152 RotationKey( const Callback& rotationChanged )
153 : m_rotationChanged( rotationChanged ){
154 default_rotation( m_rotation );
157 void angleChanged( const char* value ){
158 read_angle( m_rotation, value );
161 typedef MemberCaller1<RotationKey, const char*, &RotationKey::angleChanged> AngleChangedCaller;
163 void rotationChanged( const char* value ){
164 read_rotation( m_rotation, value );
167 typedef MemberCaller1<RotationKey, const char*, &RotationKey::rotationChanged> RotationChangedCaller;
169 void write( Entity* entity ) const {
170 Vector3 euler = matrix4_get_rotation_euler_xyz_degrees( rotation_toMatrix( m_rotation ) );
171 if ( euler[0] == 0 && euler[1] == 0 ) {
172 entity->setKeyValue( "rotation", "" );
173 write_angle( euler[2], entity );
177 entity->setKeyValue( "angle", "" );
178 write_rotation( m_rotation, entity );