aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/server/logic_mirror_movement.cpp
diff options
context:
space:
mode:
authorJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
committerJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
commit39ed87570bdb2f86969d4be821c94b722dc71179 (patch)
treeabc53757f75f40c80278e87650ea92808274aa59 /mp/src/game/server/logic_mirror_movement.cpp
downloadsource-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz
source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/game/server/logic_mirror_movement.cpp')
-rw-r--r--mp/src/game/server/logic_mirror_movement.cpp198
1 files changed, 198 insertions, 0 deletions
diff --git a/mp/src/game/server/logic_mirror_movement.cpp b/mp/src/game/server/logic_mirror_movement.cpp
new file mode 100644
index 00000000..157e02da
--- /dev/null
+++ b/mp/src/game/server/logic_mirror_movement.cpp
@@ -0,0 +1,198 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Mirrors the movement of a camera about a given point.
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "baseentity.h"
+#include "modelentities.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//////////////////////////////////////////////////////////////////////////
+// CLogicMirrorMovement
+// This will record the vector offset of an entity's center from a given reference point
+// (most likely the center of a mirror or portal) and place an entity (most likely a point camera)
+// at a the same offset, mirrored about the reference point and orientation.
+//////////////////////////////////////////////////////////////////////////
+class CLogicMirrorMovement : public CLogicalEntity
+{
+ DECLARE_DATADESC();
+ DECLARE_CLASS( CLogicMirrorMovement, CLogicalEntity );
+
+private:
+ void SetMirrorTarget( const char *pName ); // Set entity to watch and mirror (ex. the player)
+ void SetTarget( const char *pName ); // Set entity to move based on the Mirror Target entity (ex. a point_camera)
+ void SetMirrorRelative( const char* pName ); // Set the point about which to measure an offset to orient based upon (ex. portal 1)
+ void SetRemoteTarget ( const char *pName ); // Entity's orientation/location from which to offset the movement target (ex. portal 2)
+ void SetDrawingSurface ( const char *pName );
+
+ void InputSetMirrorTarget( inputdata_t &inputdata );
+ void InputSetTarget( inputdata_t &inputdata );
+ void InputSetRemoteTarget ( inputdata_t &inputdata );
+ void InputSetMirrorRelative ( inputdata_t &inputdata );
+
+ void Think();
+ virtual void Activate();
+
+ string_t m_strMirrorTarget;
+ string_t m_strRemoteTarget;
+ string_t m_strMirrorRelative;
+
+ EHANDLE m_hRemoteTarget;
+ EHANDLE m_hMirrorTarget;
+ EHANDLE m_hMovementTarget;
+ EHANDLE m_hMirrorRelative;
+
+};
+
+LINK_ENTITY_TO_CLASS( logic_mirror_movement, CLogicMirrorMovement );
+
+
+BEGIN_DATADESC( CLogicMirrorMovement )
+
+DEFINE_KEYFIELD( m_strMirrorTarget, FIELD_STRING, "MirrorTarget" ),
+DEFINE_KEYFIELD( m_strRemoteTarget, FIELD_STRING, "RemoteTarget" ),
+DEFINE_KEYFIELD( m_strMirrorRelative, FIELD_STRING, "MirrorRelative" ),
+
+DEFINE_FIELD( m_hMirrorTarget, FIELD_EHANDLE ),
+DEFINE_FIELD( m_hMovementTarget, FIELD_EHANDLE ),
+DEFINE_FIELD( m_hRemoteTarget, FIELD_EHANDLE ),
+DEFINE_FIELD( m_hMirrorRelative, FIELD_EHANDLE ),
+
+DEFINE_INPUTFUNC( FIELD_STRING, "SetMirrorTarget", InputSetMirrorTarget ),
+DEFINE_INPUTFUNC( FIELD_STRING, "SetTarget", InputSetTarget ),
+DEFINE_INPUTFUNC( FIELD_STRING, "SetRemoteTarget", InputSetRemoteTarget ),
+DEFINE_INPUTFUNC( FIELD_STRING, "SetMirrorRelative", InputSetMirrorRelative ),
+
+DEFINE_THINKFUNC( Think ),
+
+END_DATADESC()
+
+
+void CLogicMirrorMovement::Activate()
+{
+ BaseClass::Activate();
+
+ SetMirrorTarget( STRING(m_strMirrorTarget) );
+ SetTarget( STRING(m_target) );
+ SetRemoteTarget( STRING(m_strRemoteTarget ) );
+ SetMirrorRelative( STRING( m_strMirrorRelative) );
+
+ SetThink( &CLogicMirrorMovement::Think );
+ SetNextThink( gpGlobals->curtime + TICK_INTERVAL );
+}
+
+
+void CLogicMirrorMovement::SetMirrorTarget( const char *pName )
+{
+ m_hMirrorTarget = gEntList.FindEntityByName( NULL, pName );
+ if ( !m_hMirrorTarget )
+ {
+ if ( Q_strnicmp( STRING(m_strMirrorTarget), "!player", 8 ) )
+ {
+ Warning("logic_mirror_movement: Unable to find mirror target entity %s\n", pName );
+ }
+ }
+}
+
+void CLogicMirrorMovement::SetTarget( const char *pName )
+{
+ m_hMovementTarget = gEntList.FindEntityByName( NULL, pName );
+ if ( !m_hMovementTarget )
+ {
+ Warning("logic_mirror_movement: Unable to find movement target entity %s\n", pName );
+ }
+}
+
+void CLogicMirrorMovement::SetRemoteTarget(const char *pName )
+{
+ m_hRemoteTarget = gEntList.FindEntityByName( NULL, pName );
+ if ( !m_hRemoteTarget )
+ {
+ Warning("logic_mirror_movement: Unable to find remote target entity %s\n", pName );
+ }
+}
+
+void CLogicMirrorMovement::SetMirrorRelative(const char* pName )
+{
+ m_hMirrorRelative = gEntList.FindEntityByName( NULL, pName );
+ if ( !m_hMirrorRelative )
+ {
+ Warning("logic_mirror_movement: Unable to find mirror relative entity %s\n", pName );
+ }
+}
+
+void CLogicMirrorMovement::InputSetMirrorTarget( inputdata_t &inputdata )
+{
+ m_strMirrorTarget = AllocPooledString( inputdata.value.String() );
+ SetMirrorTarget( inputdata.value.String() );
+}
+
+void CLogicMirrorMovement::InputSetTarget( inputdata_t &inputdata )
+{
+ m_target = AllocPooledString( inputdata.value.String() );
+ SetTarget( inputdata.value.String() );
+}
+
+void CLogicMirrorMovement::InputSetRemoteTarget(inputdata_t &inputdata )
+{
+ m_strRemoteTarget = AllocPooledString( inputdata.value.String() );
+ SetRemoteTarget( inputdata.value.String() );
+}
+
+void CLogicMirrorMovement::InputSetMirrorRelative(inputdata_t &inputdata )
+{
+ m_strMirrorRelative = AllocPooledString ( inputdata.value.String() );
+ SetMirrorRelative( inputdata.value.String() );
+}
+
+
+void CLogicMirrorMovement::Think()
+{
+ // Attempt to get the player's handle because it didn't exist at Activate time
+ if ( !m_hMirrorTarget.Get() )
+ {
+ // If we will never find a target, we don't have a use... shutdown
+ if ( m_strMirrorTarget == NULL_STRING )
+ SetNextThink ( NULL );
+
+ //BUGBUG: If m_strSetMirrorTarget doesn't exist in ent list, we get per-think searches with no results ever...
+ SetMirrorTarget ( STRING(m_strMirrorTarget) );
+ }
+
+ // Make sure all entities are valid
+ if ( m_hMirrorTarget.Get() && m_hMovementTarget.Get() && m_hRemoteTarget.Get() && m_hMirrorRelative.Get() )
+ {
+ // Get our two portal's world transforms transforms
+ VMatrix matPortal1ToWorldInv, matPortal2ToWorld;
+ MatrixInverseGeneral( m_hMirrorRelative->EntityToWorldTransform(), matPortal1ToWorldInv );
+ matPortal2ToWorld = m_hRemoteTarget->EntityToWorldTransform();
+
+ VMatrix matTransformToRemotePortal = matPortal1ToWorldInv * matPortal2ToWorld;
+
+ // Get our scene camera's current orientation
+ Vector ptCameraPosition, vCameraLook, vCameraRight, vCameraUp;
+ ptCameraPosition = m_hMirrorTarget->EyePosition();
+ m_hMirrorTarget->GetVectors ( &vCameraLook, &vCameraRight, &vCameraUp );
+
+ // map this position and orientation to the remote portal, mirrored (invert the result)
+ Vector ptNewPosition, vNewLook;
+ ptNewPosition = matPortal1ToWorldInv * ptCameraPosition;
+ ptNewPosition = matPortal2ToWorld*( Vector( -ptNewPosition.x, -ptNewPosition.y, ptNewPosition.z ) );
+
+ vNewLook = matPortal1ToWorldInv.ApplyRotation( vCameraLook );
+ vNewLook = matPortal2ToWorld.ApplyRotation( Vector( -vNewLook.x, -vNewLook.y, vNewLook.z) );
+
+ // Set the point camera to the new location/orientation
+ QAngle qNewAngles;
+ VectorAngles( vNewLook, qNewAngles );
+ m_hMovementTarget->Teleport( &ptNewPosition, &qNewAngles, NULL );
+ }
+
+ SetNextThink( gpGlobals->curtime + TICK_INTERVAL );
+}
+
+