]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - plugins/entity/angles.h
Merge commit '830125fad042fad35dc029b6eb57c8156ad7e176'
[xonotic/netradiant.git] / plugins / entity / angles.h
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
35 inline void default_angles( Vector3& angles ){
36         angles = ANGLESKEY_IDENTITY;
37 }
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 }
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 }
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 }
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
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
104 AnglesKey( const Callback& anglesChanged )
105         : m_anglesChanged( anglesChanged ), m_angles( ANGLESKEY_IDENTITY ){
106 }
107
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
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
120 void write( Entity* entity ) const {
121         write_angles( m_angles, entity );
122 }
123 };
124
125
126 #endif