diff --git a/libs/eclasslib.h b/libs/eclasslib.h index c143f476..f70da50f 100644 --- a/libs/eclasslib.h +++ b/libs/eclasslib.h @@ -115,6 +115,8 @@ public: bool miscmodel_is; // also definable via model attribute presence in xml .ent definition CopiedString m_miscmodel_key; bool has_angles; // definable via "angle"/"angles"/"direction" attribute presence in xml .ent definition, only affects rendering of group entities angles arrow now + bool has_angles_key; // definable via "angles" attribute presence in xml .ent definition, enables angles support for EclassModel (only angle by default) + bool has_direction_key; // definable via "direction" attribute presence in xml .ent definition, enables -1/-2 angle support for EclassModel, GenericEntity Vector3 mins; Vector3 maxs; @@ -261,6 +263,8 @@ inline EntityClass* Eclass_Alloc(){ e->miscmodel_is = false; e->m_miscmodel_key = "model"; e->has_angles = false; + e->has_angles_key = false; + e->has_direction_key = false; memset( e->flagnames, 0, MAX_FLAGS * 32 ); memset( e->flagAttributes, 0, MAX_FLAGS * sizeof( EntityClassAttribute* ) ); diff --git a/plugins/entity/angles.h b/plugins/entity/angles.h index 77643a8d..8c2d877a 100644 --- a/plugins/entity/angles.h +++ b/plugins/entity/angles.h @@ -99,7 +99,7 @@ inline Matrix4 matrix4_rotation_for_euler_xyz_degrees_quantised( const Vector3& } inline Vector3 angles_snapped_to_zero( const Vector3& angles ){ - float epsilon = ( fabs( angles[0] ) > 0.001f || fabs( angles[1] ) > 0.001f || fabs( angles[2] ) > 0.001f ) ? 5e-5 : 1e-6; + const float epsilon = ( fabs( angles[0] ) > 0.001f || fabs( angles[1] ) > 0.001f || fabs( angles[2] ) > 0.001f ) ? 5e-5 : 1e-6; return Vector3( fabs( angles[0] ) < epsilon ? 0.f : angles[0], fabs( angles[1] ) < epsilon ? 0.f : angles[1], fabs( angles[2] ) < epsilon ? 0.f : angles[2] diff --git a/plugins/entity/eclassmodel.cpp b/plugins/entity/eclassmodel.cpp index 25e2cb29..1cc31e7f 100644 --- a/plugins/entity/eclassmodel.cpp +++ b/plugins/entity/eclassmodel.cpp @@ -43,7 +43,7 @@ #include "targetable.h" #include "origin.h" -#include "angle.h" +#include "angles.h" #include "rotation.h" #include "model.h" #include "filters.h" @@ -67,8 +67,8 @@ class EclassModel : OriginKey m_originKey; Vector3 m_origin; - AngleKey m_angleKey; - float m_angle; + AnglesKey m_anglesKey; + Vector3 m_angles; RotationKey m_rotationKey; Float9 m_rotation; SingletonModel m_model; @@ -100,7 +100,12 @@ class EclassModel : } else { - m_keyObservers.insert( "angle", AngleKey::AngleChangedCaller( m_angleKey ) ); + if( m_entity.getEntityClass().has_direction_key ) + m_keyObservers.insert( "angle", AnglesKey::GroupAngleChangedCaller( m_anglesKey ) ); + else + m_keyObservers.insert( "angle", AnglesKey::AngleChangedCaller( m_anglesKey ) ); + if( m_entity.getEntityClass().has_angles_key ) + m_keyObservers.insert( "angles", AnglesKey::AnglesChangedCaller( m_anglesKey ) ); } m_keyObservers.insert( "origin", OriginKey::OriginChangedCaller( m_originKey ) ); } @@ -111,17 +116,14 @@ public: #endif void updateTransform(){ - m_transform.localToParent() = g_matrix4_identity; - matrix4_translate_by_vec3( m_transform.localToParent(), m_origin ); - - m_translation = m_transform.localToParent(); + m_translation = m_transform.localToParent() = matrix4_translation_for_vec3( m_origin ); if ( g_gameType == eGameTypeDoom3 ) { matrix4_multiply_by_matrix4( m_transform.localToParent(), rotation_toMatrix( m_rotation ) ); } else { - matrix4_multiply_by_matrix4( m_transform.localToParent(), matrix4_rotation_for_z_degrees( m_angle ) ); + matrix4_multiply_by_matrix4( m_transform.localToParent(), matrix4_rotation_for_euler_xyz_degrees( m_angles ) ); } m_transformChanged(); @@ -133,11 +135,11 @@ public: updateTransform(); } typedef MemberCaller OriginChangedCaller; - void angleChanged(){ - m_angle = m_angleKey.m_angle; + void anglesChanged(){ + m_angles = m_anglesKey.m_angles; updateTransform(); } - typedef MemberCaller AngleChangedCaller; + typedef MemberCaller AnglesChangedCaller; void rotationChanged(){ rotation_assign( m_rotation, m_rotationKey.m_rotation ); updateTransform(); @@ -158,8 +160,8 @@ public: m_entity( eclass ), m_originKey( OriginChangedCaller( *this ) ), m_origin( ORIGINKEY_IDENTITY ), - m_angleKey( AngleChangedCaller( *this ) ), - m_angle( ANGLEKEY_IDENTITY ), + m_anglesKey( AnglesChangedCaller( *this ) ), + m_angles( ANGLESKEY_IDENTITY ), m_rotationKey( RotationChangedCaller( *this ) ), m_filter( m_entity, node ), m_named( m_entity ), @@ -176,8 +178,8 @@ public: m_entity( other.m_entity ), m_originKey( OriginChangedCaller( *this ) ), m_origin( ORIGINKEY_IDENTITY ), - m_angleKey( AngleChangedCaller( *this ) ), - m_angle( ANGLEKEY_IDENTITY ), + m_anglesKey( AnglesChangedCaller( *this ) ), + m_angles( ANGLESKEY_IDENTITY ), m_rotationKey( RotationChangedCaller( *this ) ), m_filter( m_entity, node ), m_named( m_entity ), @@ -271,7 +273,9 @@ public: } else { - m_angle = angle_rotated( m_angle, rotation ); + m_angles = angles_rotated( m_angles, rotation ); + if( !m_entity.getEntityClass().has_angles_key ) // yaw angle only + m_angles[0] = m_angles[1] = 0; } } void snapto( float snap ){ @@ -285,7 +289,7 @@ public: } else { - m_angle = m_angleKey.m_angle; + m_angles = m_anglesKey.m_angles; } } void freezeTransform(){ @@ -295,10 +299,10 @@ public: rotation_assign( m_rotationKey.m_rotation, m_rotation ); m_rotationKey.write( &m_entity ); } - else if( m_angleKey.m_angle != m_angle ) + else if( m_anglesKey.m_angles != m_angles ) { - m_angleKey.m_angle = m_angle; - m_angleKey.write( &m_entity ); + m_anglesKey.m_angles = m_angles; + m_anglesKey.write( &m_entity ); } } void transformChanged(){ diff --git a/plugins/entity/generic.cpp b/plugins/entity/generic.cpp index 3c0ff85a..59384a98 100644 --- a/plugins/entity/generic.cpp +++ b/plugins/entity/generic.cpp @@ -89,7 +89,10 @@ class GenericEntity : m_keyObservers.insert( "classname", ClassnameFilter::ClassnameChangedCaller( m_filter ) ); m_keyObservers.insert( Static::instance().m_nameKey, NamedEntity::IdentifierChangedCaller( m_named ) ); - m_keyObservers.insert( "angle", AnglesKey::AngleChangedCaller( m_anglesKey ) ); + if( m_entity.getEntityClass().has_direction_key ) + m_keyObservers.insert( "angle", AnglesKey::GroupAngleChangedCaller( m_anglesKey ) ); + else + m_keyObservers.insert( "angle", AnglesKey::AngleChangedCaller( m_anglesKey ) ); m_keyObservers.insert( "angles", AnglesKey::AnglesChangedCaller( m_anglesKey ) ); m_keyObservers.insert( "origin", OriginKey::OriginChangedCaller( m_originKey ) ); } diff --git a/radiant/eclass_xml.cpp b/radiant/eclass_xml.cpp index 64be1ffa..5b4a6d07 100644 --- a/radiant/eclass_xml.cpp +++ b/radiant/eclass_xml.cpp @@ -220,6 +220,11 @@ public: } else if( string_equal( type, "angle" ) || string_equal( type, "angles" ) || string_equal( type, "direction" ) ){ entityClass->has_angles = true; + + if( string_equal( type, "angles" ) ) + entityClass->has_angles_key = true; + else if( string_equal( type, "direction" ) ) + entityClass->has_direction_key = true; } m_comment << key;