]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - plugins/entity/angles.h
Merge branch 'NateEag-master-patch-12920' into 'master'
[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                         float yaw = angles[2];
77                         entity->setKeyValue( "angles", "" );
78                         write_angle( yaw, entity );
79                 }
80                 else
81                 {
82                         sprintf( value, "%f %f %f", angles[1], angles[2], angles[0] );
83                         entity->setKeyValue( "angle", "" );
84                         entity->setKeyValue( "angles", value );
85                 }
86         }
87 }
88
89 inline Vector3 angles_rotated( const Vector3& angles, const Quaternion& rotation ){
90         return matrix4_get_rotation_euler_xyz_degrees(
91                            matrix4_multiplied_by_matrix4(
92                                    matrix4_rotation_for_euler_xyz_degrees( angles ),
93                                    matrix4_rotation_for_quaternion_quantised( rotation )
94                                    )
95                            );
96 }
97
98 class AnglesKey
99 {
100 Callback<void()> m_anglesChanged;
101 public:
102 Vector3 m_angles;
103
104
105 AnglesKey( const Callback<void()>& anglesChanged )
106         : m_anglesChanged( anglesChanged ), m_angles( ANGLESKEY_IDENTITY ){
107 }
108
109 void angleChanged( const char* value ){
110         read_angle( m_angles, value );
111         m_anglesChanged();
112 }
113 typedef MemberCaller<AnglesKey, void(const char*), &AnglesKey::angleChanged> AngleChangedCaller;
114
115 void anglesChanged( const char* value ){
116         read_angles( m_angles, value );
117         m_anglesChanged();
118 }
119 typedef MemberCaller<AnglesKey, void(const char*), &AnglesKey::anglesChanged> AnglesChangedCaller;
120
121 void write( Entity* entity ) const {
122         write_angles( m_angles, entity );
123 }
124 };
125
126
127 #endif