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