1 /*
2 Copyright (C) 2001-2006, William Joseph.
3 All Rights Reserved.
4
5 This file is part of GtkRadiant.
6
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.
11
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.
16
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
20 */
21
22 #if !defined( INCLUDED_ANGLES_H )
23 #define INCLUDED_ANGLES_H
24
25 #include "ientity.h"
26
27 #include "math/quaternion.h"
28 #include "generic/callback.h"
29 #include "stringio.h"
30
31 #include "angle.h"
32
33 const Vector3 ANGLESKEY_IDENTITY = Vector3( 0, 0, 0 );
34
default_angles(Vector3 & angles)35 inline void default_angles( Vector3& angles ){
36 angles = ANGLESKEY_IDENTITY;
37 }
normalise_angles(Vector3 & angles)38 inline void normalise_angles( Vector3& angles ){
39 angles[0] = static_cast<float>( float_mod( angles[0], 360 ) );
40 angles[1] = static_cast<float>( float_mod( angles[1], 360 ) );
41 angles[2] = static_cast<float>( float_mod( angles[2], 360 ) );
42 }
read_angle(Vector3 & angles,const char * value)43 inline void read_angle( Vector3& angles, const char* value ){
44 if ( !string_parse_float( value, angles[2] ) ) {
45 default_angles( angles );
46 }
47 else
48 {
49 angles[0] = 0;
50 angles[1] = 0;
51 normalise_angles( angles );
52 }
53 }
read_angles(Vector3 & angles,const char * value)54 inline void read_angles( Vector3& angles, const char* value ){
55 if ( !string_parse_vector3( value, angles ) ) {
56 default_angles( angles );
57 }
58 else
59 {
60 angles = Vector3( angles[2], angles[0], angles[1] );
61 normalise_angles( angles );
62 }
63 }
write_angles(const Vector3 & angles,Entity * entity)64 inline void write_angles( const Vector3& angles, Entity* entity ){
65 if ( angles[0] == 0
66 && angles[1] == 0
67 && angles[2] == 0 ) {
68 entity->setKeyValue( "angle", "" );
69 entity->setKeyValue( "angles", "" );
70 }
71 else
72 {
73 char value[64];
74
75 if ( angles[0] == 0 && angles[1] == 0 ) {
76 entity->setKeyValue( "angles", "" );
77 write_angle( angles[2], entity );
78 }
79 else
80 {
81 sprintf( value, "%f %f %f", angles[1], angles[2], angles[0] );
82 entity->setKeyValue( "angle", "" );
83 entity->setKeyValue( "angles", value );
84 }
85 }
86 }
87
angles_rotated(const Vector3 & angles,const Quaternion & rotation)88 inline Vector3 angles_rotated( const Vector3& angles, const Quaternion& rotation ){
89 return matrix4_get_rotation_euler_xyz_degrees(
90 matrix4_multiplied_by_matrix4(
91 matrix4_rotation_for_euler_xyz_degrees( angles ),
92 matrix4_rotation_for_quaternion_quantised( rotation )
93 )
94 );
95 }
96
97 class AnglesKey
98 {
99 Callback m_anglesChanged;
100 public:
101 Vector3 m_angles;
102
103
AnglesKey(const Callback & anglesChanged)104 AnglesKey( const Callback& anglesChanged )
105 : m_anglesChanged( anglesChanged ), m_angles( ANGLESKEY_IDENTITY ){
106 }
107
angleChanged(const char * value)108 void angleChanged( const char* value ){
109 read_angle( m_angles, value );
110 m_anglesChanged();
111 }
112 typedef MemberCaller1<AnglesKey, const char*, &AnglesKey::angleChanged> AngleChangedCaller;
113
anglesChanged(const char * value)114 void anglesChanged( const char* value ){
115 read_angles( m_angles, value );
116 m_anglesChanged();
117 }
118 typedef MemberCaller1<AnglesKey, const char*, &AnglesKey::anglesChanged> AnglesChangedCaller;
119
write(Entity * entity)120 void write( Entity* entity ) const {
121 write_angles( m_angles, entity );
122 }
123 };
124
125
126 #endif
127