/* Copyright (C) 2001-2006, William Joseph. All Rights Reserved. This file is part of GtkRadiant. GtkRadiant is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. GtkRadiant is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GtkRadiant; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #if !defined( INCLUDED_ANGLES_H ) #define INCLUDED_ANGLES_H #include "ientity.h" #include "math/quaternion.h" #include "generic/callback.h" #include "stringio.h" #include "angle.h" const Vector3 ANGLESKEY_IDENTITY = Vector3( 0, 0, 0 ); inline void default_angles( Vector3& angles ){ angles = ANGLESKEY_IDENTITY; } inline void normalise_angles( Vector3& angles ){ angles[0] = static_cast( float_mod( angles[0], 360 ) ); angles[1] = static_cast( float_mod( angles[1], 360 ) ); angles[2] = static_cast( float_mod( angles[2], 360 ) ); } inline void read_angle( Vector3& angles, const char* value ){ if ( !string_parse_float( value, angles[2] ) ) { default_angles( angles ); } else { angles[0] = 0; angles[1] = 0; normalise_angles( angles ); } } inline void read_angles( Vector3& angles, const char* value ){ if ( !string_parse_vector3( value, angles ) ) { default_angles( angles ); } else { angles = Vector3( angles[2], angles[0], angles[1] ); normalise_angles( angles ); } } inline void write_angles( const Vector3& angles, Entity* entity ){ if ( angles[0] == 0 && angles[1] == 0 && angles[2] == 0 ) { entity->setKeyValue( "angle", "" ); entity->setKeyValue( "angles", "" ); } else { char value[64]; if ( angles[0] == 0 && angles[1] == 0 ) { entity->setKeyValue( "angles", "" ); write_angle( angles[2], entity ); } else { sprintf( value, "%f %f %f", angles[1], angles[2], angles[0] ); entity->setKeyValue( "angle", "" ); entity->setKeyValue( "angles", value ); } } } inline Vector3 angles_rotated( const Vector3& angles, const Quaternion& rotation ){ return matrix4_get_rotation_euler_xyz_degrees( matrix4_multiplied_by_matrix4( matrix4_rotation_for_euler_xyz_degrees( angles ), matrix4_rotation_for_quaternion_quantised( rotation ) ) ); } class AnglesKey { Callback m_anglesChanged; public: Vector3 m_angles; AnglesKey( const Callback& anglesChanged ) : m_anglesChanged( anglesChanged ), m_angles( ANGLESKEY_IDENTITY ){ } void angleChanged( const char* value ){ read_angle( m_angles, value ); m_anglesChanged(); } typedef MemberCaller1 AngleChangedCaller; void anglesChanged( const char* value ){ read_angles( m_angles, value ); m_anglesChanged(); } typedef MemberCaller1 AnglesChangedCaller; void write( Entity* entity ) const { write_angles( m_angles, entity ); } }; #endif