//----------------------------------------------------------------------------- // Apply movement //----------------------------------------------------------------------------- void CLogicMeasureMovement::MeasureThink( ) { // FIXME: This is a hack to make measuring !player simpler. The player isn't // created at Activate time, so m_hMeasureTarget may be NULL because of that. if ( !m_hMeasureTarget.Get() && !Q_strnicmp( STRING(m_strMeasureTarget), "!player", 8 ) ) { SetMeasureTarget( STRING(m_strMeasureTarget) ); } // Make sure all entities are valid if ( m_hMeasureTarget.Get() && m_hMeasureReference.Get() && m_hTarget.Get() && m_hTargetReference.Get() ) { matrix3x4_t matRefToMeasure, matWorldToMeasure; switch( m_nMeasureType ) { case MEASURE_POSITION: MatrixInvert( m_hMeasureTarget->EntityToWorldTransform(), matWorldToMeasure ); break; case MEASURE_EYE_POSITION: AngleIMatrix( m_hMeasureTarget->EyeAngles(), m_hMeasureTarget->EyePosition(), matWorldToMeasure ); break; // FIXME: Could add attachment point measurement here easily } ConcatTransforms( matWorldToMeasure, m_hMeasureReference->EntityToWorldTransform(), matRefToMeasure ); // Apply the scale factor if ( ( m_flScale != 0.0f ) && ( m_flScale != 1.0f ) ) { Vector vecTranslation; MatrixGetColumn( matRefToMeasure, 3, vecTranslation ); vecTranslation /= m_flScale; MatrixSetColumn( vecTranslation, 3, matRefToMeasure ); } // Now apply the new matrix to the new reference point matrix3x4_t matMeasureToRef, matNewTargetToWorld; MatrixInvert( matRefToMeasure, matMeasureToRef ); ConcatTransforms( m_hTargetReference->EntityToWorldTransform(), matMeasureToRef, matNewTargetToWorld ); Vector vecNewOrigin; QAngle vecNewAngles; MatrixAngles( matNewTargetToWorld, vecNewAngles, vecNewOrigin ); m_hTarget->SetAbsOrigin( vecNewOrigin ); m_hTarget->SetAbsAngles( vecNewAngles ); } SetNextThink( gpGlobals->curtime + TICK_INTERVAL ); }
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 ); }