void CRagdollPropAttached::InitRagdollAttached( IPhysicsObject *pAttached, const Vector &forceVector, int forceBone, matrix3x4_t *pPrevBones, matrix3x4_t *pBoneToWorld, float dt, int collisionGroup, CBaseAnimating *pFollow, int boneIndexRoot, const Vector &boneLocalOrigin, int parentBoneAttach, const Vector &worldAttachOrigin )
{
	int ragdollAttachedIndex = 0;
	if ( parentBoneAttach > 0 )
	{
		studiohdr_t *pStudioHdr = GetModelPtr();
		mstudiobone_t *pBone = pStudioHdr->pBone( parentBoneAttach );
		ragdollAttachedIndex = pBone->physicsbone;
	}

	InitRagdoll( forceVector, forceBone, vec3_origin, pPrevBones, pBoneToWorld, dt, collisionGroup, false );
	
	IPhysicsObject *pRefObject = m_ragdoll.list[ragdollAttachedIndex].pObject;

	Vector attachmentPointRagdollSpace;
	pRefObject->WorldToLocal( attachmentPointRagdollSpace, worldAttachOrigin );

	constraint_ragdollparams_t constraint;
	constraint.Defaults();
	matrix3x4_t tmp, worldToAttached, worldToReference, constraintToWorld;

	Vector offsetWS;
	pAttached->LocalToWorld( offsetWS, boneLocalOrigin );

	AngleMatrix( QAngle(0, pFollow->GetAbsAngles().y, 0 ), offsetWS, constraintToWorld );

	constraint.axes[0].SetAxisFriction( -2, 2, 20 );
	constraint.axes[1].SetAxisFriction( 0, 0, 0 );
	constraint.axes[2].SetAxisFriction( -15, 15, 20 );
	
	pAttached->GetPositionMatrix( tmp );
	MatrixInvert( tmp, worldToAttached );

	pRefObject->GetPositionMatrix( tmp );
	MatrixInvert( tmp, worldToReference );

	ConcatTransforms( worldToReference, constraintToWorld, constraint.constraintToReference );
	ConcatTransforms( worldToAttached, constraintToWorld, constraint.constraintToAttached );

	// for now, just slam this to be the passed in value
	MatrixSetColumn( attachmentPointRagdollSpace, 3, constraint.constraintToReference );

	DisableCollisions( pAttached );
	m_pAttachConstraint = physenv->CreateRagdollConstraint( pRefObject, pAttached, m_ragdoll.pGroup, constraint );

	FollowEntity( pFollow );
	SetOwnerEntity( pFollow );
	RagdollActivate( m_ragdoll );

	Relink();
	m_boneIndexAttached = boneIndexRoot;
	m_ragdollAttachedObjectIndex = ragdollAttachedIndex;
	m_attachmentPointBoneSpace = boneLocalOrigin;
	
	Vector vTemp;
	MatrixGetColumn( constraint.constraintToReference, 3, vTemp );
	m_attachmentPointRagdollSpace = vTemp;
}
//-----------------------------------------------------------------------------
// 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 CRagdollProp::Teleport( const Vector *newPosition, const QAngle *newAngles, const Vector *newVelocity )
{
	matrix3x4_t startMatrixInv;
	matrix3x4_t startMatrix;

	m_ragdoll.list[0].pObject->GetPositionMatrix( startMatrix );
	MatrixInvert( startMatrix, startMatrixInv );
	
	// object 0 MUST be the one to get teleported!
	VPhysicsSwapObject( m_ragdoll.list[0].pObject );
	BaseClass::Teleport( newPosition, newAngles, newVelocity );

	// Calculate the relative transform of the teleport
	matrix3x4_t xform;
	ConcatTransforms( EntityToWorldTransform(), startMatrixInv, xform );
	UpdateNetworkDataFromVPhysics( m_ragdoll.list[0].pObject, 0 );
	for ( int i = 1; i < m_ragdoll.listCount; i++ )
	{
		matrix3x4_t matrix, newMatrix;
		m_ragdoll.list[i].pObject->GetPositionMatrix( matrix );
		ConcatTransforms( xform, matrix, newMatrix );
		m_ragdoll.list[i].pObject->SetPositionMatrix( newMatrix, true );
		UpdateNetworkDataFromVPhysics( m_ragdoll.list[i].pObject, i );
	}
}
예제 #4
0
void C_BaseViewModel::ApplyBoneMatrixTransform( matrix3x4_t& transform )
{
	if ( ShouldFlipViewModel() )
	{
		matrix3x4_t viewMatrix, viewMatrixInverse;

		// We could get MATERIAL_VIEW here, but this is called sometimes before the renderer
		// has set that matrix. Luckily, this is called AFTER the CViewSetup has been initialized.
		const CViewSetup *pSetup = view->GetPlayerViewSetup();
		AngleMatrix( pSetup->angles, pSetup->origin, viewMatrixInverse );
		MatrixInvert( viewMatrixInverse, viewMatrix );

		// Transform into view space.
		matrix3x4_t temp, temp2;
		ConcatTransforms( viewMatrix, transform, temp );
		
		// Flip it along X.
		
		// (This is the slower way to do it, and it equates to negating the top row).
		//matrix3x4_t mScale;
		//SetIdentityMatrix( mScale );
		//mScale[0][0] = 1;
		//mScale[1][1] = -1;
		//mScale[2][2] = 1;
		//ConcatTransforms( mScale, temp, temp2 );
		temp[1][0] = -temp[1][0];
		temp[1][1] = -temp[1][1];
		temp[1][2] = -temp[1][2];
		temp[1][3] = -temp[1][3];

		// Transform back out of view space.
		ConcatTransforms( viewMatrixInverse, temp, transform );
	}
}
예제 #5
0
//-----------------------------------------------------------------------------
// Returns the unperterbed view position for a particular role
//-----------------------------------------------------------------------------
bool CBaseTFVehicle::GetRoleViewPosition( int nRole, Vector *pVehicleEyeOrigin, QAngle *pVehicleEyeAngles )
{
	// Generate the view position in world space.
	Vector vAbsOrigin;
	QAngle vAbsAngle;
	bool bUsingThirdPersonCamera = GetRoleAbsViewPosition( nRole, &vAbsOrigin, &vAbsAngle );

	
	// Make a matrix for it.
	matrix3x4_t absMatrix;
	AngleMatrix( vAbsAngle, absMatrix );
	MatrixSetColumn( vAbsOrigin, 3, absMatrix );


	// Transform the matrix into local space.
	matrix3x4_t worldToEntity, local;
	MatrixInvert( EntityToWorldTransform(), worldToEntity );
	ConcatTransforms( worldToEntity, absMatrix, local ); 


	// Suck out the origin and angles.
	pVehicleEyeOrigin->Init( local[0][3], local[1][3], local[2][3] );
	MatrixAngles( local, *pVehicleEyeAngles );

	return bUsingThirdPersonCamera;
}
void RagdollApplyAnimationAsVelocity( ragdoll_t &ragdoll, matrix3x4_t pBoneToWorld[] )
{
	for ( int i = 0; i < ragdoll.listCount; i++ )
	{
		matrix3x4_t inverse;
		MatrixInvert( pBoneToWorld[i], inverse );
		Quaternion q;
		Vector pos;
		MatrixAngles( inverse, q, pos );

		Vector velocity;
		AngularImpulse angVel;
		float flSpin;

		Vector localVelocity;
		AngularImpulse localAngVelocity;

		QuaternionAxisAngle( q, localAngVelocity, flSpin );
		localAngVelocity *= flSpin;
		localVelocity = pos;

		// move those bone-local coords back to world space using the ragdoll transform
		ragdoll.list[i].pObject->LocalToWorldVector( velocity, localVelocity );
		ragdoll.list[i].pObject->LocalToWorldVector( angVel, localAngVelocity );

		ragdoll.list[i].pObject->AddVelocity( &velocity, &angVel );
	}
}
예제 #7
0
//-----------------------------------------------------------------------------------
void Matrix4x4::MatrixInvertOrthogonal(Matrix4x4* matrix)
{
	Vector3 translation = MatrixGetOffset(matrix);
	MatrixTranspose(matrix);
	MatrixSetColumn(matrix, 3, Vector4(0.0f, 0.0f, 0.0f, 1.0f));
	Matrix4x4 translationMatrix;
	MatrixMakeTranslation(&translationMatrix, translation);
	MatrixInvert(&translationMatrix);
	MatrixMultiply(matrix, &translationMatrix, matrix);
}
void CStickyBomb::Touch( CBaseEntity *pOther )
{
	// Don't stick if already stuck
	if ( GetMoveType() == MOVETYPE_FLYGRAVITY )
	{
		trace_t tr = GetTouchTrace();
		// stickies don't stick to each other or sky
		if ( FClassnameIs(pOther, "grenade_stickybomb") || (tr.surface.flags & SURF_SKY) )
		{
			// bounce
			Vector vecNewVelocity;
			PhysicsClipVelocity( GetAbsVelocity(), tr.plane.normal, vecNewVelocity, 1.0 );
			SetAbsVelocity( vecNewVelocity );
		}
		else 
		{
			SetAbsVelocity( vec3_origin );
			SetMoveType( MOVETYPE_NONE );
			if ( pOther->entindex() != 0 )
			{
				// set up notification if the parent is deleted before we explode
				g_pNotify->AddEntity( this, pOther );

				if ( (tr.surface.flags & SURF_HITBOX) && modelinfo->GetModelType( pOther->GetModel() ) == mod_studio )
				{
					CBaseAnimating *pOtherAnim = dynamic_cast<CBaseAnimating *>(pOther);
					if ( pOtherAnim )
					{
						matrix3x4_t bombWorldSpace;
						MatrixCopy( EntityToWorldTransform(), bombWorldSpace );

						// get the bone info so we can follow the bone
						FollowEntity( pOther );
						SetOwnerEntity( pOther );
						m_boneIndexAttached = pOtherAnim->GetHitboxBone( tr.hitbox );
						matrix3x4_t boneToWorld;
						pOtherAnim->GetBoneTransform( m_boneIndexAttached, boneToWorld );

						// transform my current position/orientation into the hit bone's space
						// UNDONE: Eventually we need to intersect with the mesh here
						// REVISIT: maybe do something like the decal code to find a spot on
						//			the mesh.
						matrix3x4_t worldToBone, localMatrix;
						MatrixInvert( boneToWorld, worldToBone );
						ConcatTransforms( worldToBone, bombWorldSpace, localMatrix );
						MatrixAngles( localMatrix, m_boneAngles.GetForModify(), m_bonePosition.GetForModify() );
						return;
					}
				}
				SetParent( pOther );
			}
		}
	}
}
예제 #9
0
파일: xform.cpp 프로젝트: refnum/quesa
/*
 * Given an Xform structure and forward and inverse transformations,
 * propagate the information in the Xform structure to the
 * transformations.
 * In this case, the information "in" the Xform structure is
 * actually stored in the forward transformation; the Xform
 * points to NULL.
 */
void
XformPropagate(TransRef tr, RSMatrix *trans,RSMatrix* itrans)
{
    Xform *xform = (Xform*)tr;
	/*
	 * The Xform methods change the forward trans
	 * directly, so it's already all set.
	 * Build the inverse...
	 */
	MatrixInvert(trans, itrans);
}
예제 #10
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CPropServerVehicleManhack::GetVehicleViewPosition( int nRole, Vector *pAbsOrigin, QAngle *pAbsAngles, float *pFOV )
{
	Assert( nRole == VEHICLE_ROLE_DRIVER );
	CBasePlayer *pPlayer = ToBasePlayer( GetDrivableVehicle()->GetDriver() );
	Assert( pPlayer );//*/

	//commented out because this really should be setting the manhack angle, not the vehicle angle
	*pAbsAngles = pPlayer->EyeAngles(); // yuck. this is an in/out parameter.
	//*pAbsOrigin = pPlayer->EyePosition();

	CNPC_Manhack *pManhack=NULL;

	if (GetManhack())
		pManhack=GetManhack()->GetManhack();
	
	if (pManhack != NULL) 
	{
		Vector  m_vecManhackEye = GetManhack()->GetManhackEyePosition(); //pManhack->GetManhackView();
		QAngle m_angManhackEye = pManhack->GetAbsAngles();

		matrix3x4_t vehicleEyePosToWorld;

		AngleMatrix( m_angManhackEye, vehicleEyePosToWorld );

		// Dampen the eye positional change as we drive around.
		//*pAbsAngles = pPlayer->EyeAngles();

		CPropVehicleManhack *pDriveable = assert_cast<CPropVehicleManhack*>(GetDrivableVehicle());
		if (pDriveable) pDriveable->DampenEyePosition( m_vecManhackEye, m_angManhackEye );
	
		// Compute the relative rotation between the unperturbed eye attachment + the eye angles
		matrix3x4_t cameraToWorld;
		AngleMatrix( *pAbsAngles, cameraToWorld );

		matrix3x4_t worldToEyePos;
		MatrixInvert( vehicleEyePosToWorld, worldToEyePos );

		matrix3x4_t vehicleCameraToEyePos;
		ConcatTransforms( worldToEyePos, cameraToWorld, vehicleCameraToEyePos );

		AngleMatrix( m_angManhackEye, m_vecManhackEye, vehicleEyePosToWorld );

		// Now treat the relative eye angles as being relative to this new, perturbed view position...
		matrix3x4_t newCameraToWorld;
		ConcatTransforms( vehicleEyePosToWorld, vehicleCameraToEyePos, newCameraToWorld );

		// output new view abs angles
		MatrixAngles( newCameraToWorld, *pAbsAngles );

		// UNDONE: *pOrigin would already be correct in single player if the HandleView() on the server ran after vphysics
		MatrixGetColumn( newCameraToWorld, 3, *pAbsOrigin );

	} else DevMsg("fail\n");
}
예제 #11
0
void CStudioPhysics::Load( MDLHandle_t mdlHandle )
{
	m_MDLHandle = mdlHandle;

	LoadPhysicsProperties();

	vcollide_t *pVCollide = GetVCollide( );
	if ( !pVCollide )
	{
		m_pList = NULL;
		m_listCount = 0;
		return;
	}

	m_pList = new CPhysmesh[pVCollide->solidCount];
	m_listCount = pVCollide->solidCount;

	int i;

	for ( i = 0; i < pVCollide->solidCount; i++ )
	{
		m_pList[i].Clear();
		m_pList[i].m_vertCount = physcollision->CreateDebugMesh( pVCollide->solids[i], &m_pList[i].m_pVerts );
		m_pList[i].m_pCollisionModel = physcollision->CreateQueryModel( pVCollide->solids[i] );
	}

	ParseKeydata();

	CStudioHdr studioHdr( g_pMDLCache->GetStudioHdr( mdlHandle ), g_pMDLCache );
	for ( i = 0; i < pVCollide->solidCount; i++ )
	{
		CPhysmesh *pmesh = m_pList + i;
		int boneIndex = FindBoneIndex( &studioHdr, pmesh->m_boneName );
		if ( boneIndex < 0 )
			continue;

		if ( pmesh->m_constraint.parentIndex >= 0 )
		{
			CPhysmesh *pparent = m_pList + pmesh->m_constraint.parentIndex;
			int parentIndex = FindBoneIndex( &studioHdr, pparent->m_boneName );
			Studio_CalcBoneToBoneTransform( &studioHdr, boneIndex, parentIndex, pmesh->m_matrix );
		}
		else
		{
			MatrixInvert( studioHdr.pBone(boneIndex)->poseToBone, pmesh->m_matrix );
		}
	}

	// doesn't have a root bone?  Make it the first bone
	if ( !m_edit.rootName[0] )
	{
		strcpy( m_edit.rootName, m_pList[0].m_boneName );
	}
}
예제 #12
0
//-----------------------------------------------------------------------------
// Purpose: Tell the vehicle physics system whenever we teleport, so it can fixup the wheels.
//-----------------------------------------------------------------------------
void CPropVehicle::Teleport( const Vector *newPosition, const QAngle *newAngles, const Vector *newVelocity )
{
	matrix3x4_t startMatrixInv;

	MatrixInvert( EntityToWorldTransform(), startMatrixInv );
	BaseClass::Teleport( newPosition, newAngles, newVelocity );

	// Calculate the relative transform of the teleport
	matrix3x4_t xform;
	ConcatTransforms( EntityToWorldTransform(), startMatrixInv, xform );
	m_VehiclePhysics.Teleport( xform );
}
void CAPC2FourWheelServerVehicle::GetVehicleViewPosition( int nRole, Vector *pAbsOrigin, QAngle *pAbsAngles )
{
	//FixMe, wtf?
	#ifndef DEBUG
	Assert( nRole == VEHICLE_DRIVER );
	#endif
	CBaseCombatCharacter *pPlayer = GetPassenger( VEHICLE_ROLE_DRIVER );
	Assert( pPlayer );

	float flPitchFactor=1.0;
	*pAbsAngles = pPlayer->EyeAngles();
	matrix3x4_t vehicleEyePosToWorld;
	Vector vehicleEyeOrigin;
	QAngle vehicleEyeAngles;
	GetAPC()->GetAttachment( "cannon_muzzle", vehicleEyeOrigin, vehicleEyeAngles );
	Vector up,forward;
	GetAPC()->GetVectors(NULL,&forward,&up);
	vehicleEyeOrigin+=(forward*37)+(up*35);
	AngleMatrix( vehicleEyeAngles, vehicleEyePosToWorld );

//#ifdef HL2_DLL
//	// View dampening.
//	if ( r_VehicleViewDampen.GetInt() )
//	{
//		GetAPC()->DampenEyePosition( vehicleEyeOrigin, vehicleEyeAngles );
//	}
//#endif

	// Compute the relative rotation between the unperterbed eye attachment + the eye angles
	matrix3x4_t cameraToWorld;
	AngleMatrix( *pAbsAngles, cameraToWorld );

	matrix3x4_t worldToEyePos;
	MatrixInvert( vehicleEyePosToWorld, worldToEyePos );

	matrix3x4_t vehicleCameraToEyePos;
	ConcatTransforms( worldToEyePos, cameraToWorld, vehicleCameraToEyePos );

	// Now perterb the attachment point
	vehicleEyeAngles.x = RemapAngleRange( PITCH_CURVE_ZERO * flPitchFactor, PITCH_CURVE_LINEAR, vehicleEyeAngles.x );
	vehicleEyeAngles.z = RemapAngleRange( ROLL_CURVE_ZERO * flPitchFactor, ROLL_CURVE_LINEAR, vehicleEyeAngles.z );
	AngleMatrix( vehicleEyeAngles, vehicleEyeOrigin, vehicleEyePosToWorld );

	// Now treat the relative eye angles as being relative to this new, perterbed view position...
	matrix3x4_t newCameraToWorld;
	ConcatTransforms( vehicleEyePosToWorld, vehicleCameraToEyePos, newCameraToWorld );

	// output new view abs angles
	MatrixAngles( newCameraToWorld, *pAbsAngles );

	// UNDONE: *pOrigin would already be correct in single player if the HandleView() on the server ran after vphysics
	MatrixGetColumn( newCameraToWorld, 3, *pAbsOrigin );
}
예제 #14
0
파일: cal.c 프로젝트: ajmas/NewSRT
void polyfitr(int npoly, int nfreq, float ddata[], float wtt[], float dataout[])
{
    int i, j, k, kk, m1, m2;
    double re, dd, freq;
    long double aarr[NPOLY * NPOLY], bbrr[NPOLY * NPOLY];
    static float mcalc[NSPEC * NPOLY];
    for (i = 0; i < nfreq; i++) {
        kk = i * npoly;
        freq = (double) (i - d1.fc * d1.nfreq) / ((double) (d1.fc * nfreq));
        for (j = 0; j < npoly; j++) {
            mcalc[kk] = pow(freq, (double) j);
            kk++;
        }
    }
    for (i = 0; i < npoly; i++) {
        re = 0.0;
        m1 = i;
        for (k = 0; k < nfreq; k++) {
            dd = log10(ddata[k]);
            if (wtt[k] > 0)
                re += mcalc[m1] * dd * wtt[k];
            m1 += npoly;
        }
        bbrr[i] = re;
        for (j = 0; j <= i; j++) {
            re = 0.0;
            m1 = i;
            m2 = j;
            for (k = 0; k < nfreq; k++) {
                if (wtt[k] > 0)
                    re += mcalc[m1] * mcalc[m2] * wtt[k];
                m1 += npoly;
                m2 += npoly;
            }
            k = j + (i * (i + 1)) / 2;

            aarr[k] = re;
        }
    }
    MatrixInvert(npoly, aarr, bbrr);

//        for (j = 0; j < npoly; j++) printf("poly %d %f\n",j,(double)bbrr[j]);
    for (i = 0; i < nfreq; i++) {
        re = 0.0;
        freq = (double) (i - d1.fc * d1.nfreq) / ((double) (d1.fc * nfreq));
        for (j = 0; j < npoly; j++) {
            re += bbrr[j] * pow(freq, (double) j);
        }
        dd = pow(10.0, re);
        dataout[i] = dd;
    }
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CChoreoGenericServerVehicle::GetVehicleViewPosition( int nRole, Vector *pAbsOrigin, QAngle *pAbsAngles, float *pFOV /*= NULL*/ )
{
	// FIXME: This needs to be reconciled with the other versions of this function!
	Assert( nRole == VEHICLE_ROLE_DRIVER );
	CBasePlayer *pPlayer = ToBasePlayer( GetDrivableVehicle()->GetDriver() );
	Assert( pPlayer );

	// Use the player's eyes instead of the attachment point
	if ( GetVehicle()->m_bForcePlayerEyePoint )
	{
		// Call to BaseClass because CBasePlayer::EyePosition calls this function.
	  *pAbsOrigin = pPlayer->CBaseCombatCharacter::EyePosition();
	  *pAbsAngles = pPlayer->CBaseCombatCharacter::EyeAngles();
		return;
	}

	*pAbsAngles = pPlayer->EyeAngles(); // yuck. this is an in/out parameter.

	float flPitchFactor = 1.0;
	matrix3x4_t vehicleEyePosToWorld;
	Vector vehicleEyeOrigin;
	QAngle vehicleEyeAngles;
	GetVehicle()->GetAttachment( "vehicle_driver_eyes", vehicleEyeOrigin, vehicleEyeAngles );
	AngleMatrix( vehicleEyeAngles, vehicleEyePosToWorld );

	// Compute the relative rotation between the unperterbed eye attachment + the eye angles
	matrix3x4_t cameraToWorld;
	AngleMatrix( *pAbsAngles, cameraToWorld );

	matrix3x4_t worldToEyePos;
	MatrixInvert( vehicleEyePosToWorld, worldToEyePos );

	matrix3x4_t vehicleCameraToEyePos;
	ConcatTransforms( worldToEyePos, cameraToWorld, vehicleCameraToEyePos );

	// Now perterb the attachment point
	vehicleEyeAngles.x = RemapAngleRange( PITCH_CURVE_ZERO * flPitchFactor, PITCH_CURVE_LINEAR, vehicleEyeAngles.x );
	vehicleEyeAngles.z = RemapAngleRange( ROLL_CURVE_ZERO * flPitchFactor, ROLL_CURVE_LINEAR, vehicleEyeAngles.z );

	AngleMatrix( vehicleEyeAngles, vehicleEyeOrigin, vehicleEyePosToWorld );

	// Now treat the relative eye angles as being relative to this new, perterbed view position...
	matrix3x4_t newCameraToWorld;
	ConcatTransforms( vehicleEyePosToWorld, vehicleCameraToEyePos, newCameraToWorld );

	// output new view abs angles
	MatrixAngles( newCameraToWorld, *pAbsAngles );

	// UNDONE: *pOrigin would already be correct in single player if the HandleView() on the server ran after vphysics
	MatrixGetColumn( newCameraToWorld, 3, *pAbsOrigin );
}
예제 #16
0
void CBeam::SetAbsEndPos( const Vector &pos )
{
	if (!GetMoveParent())
	{
		SetEndPos( pos );
		return;
	}

	Vector vecLocalPos;
	matrix3x4_t worldToBeam;
	MatrixInvert( EntityToWorldTransform(), worldToBeam );
	VectorTransform( pos, worldToBeam, vecLocalPos );
	SetEndPos( vecLocalPos );
}
예제 #17
0
        void TransformUtil::transformPointWithParent(DBTransform &transform, DBTransform &parent)
        {
            transformToMatrix(parent, _helpMatrix);
            _helpMatrix = MatrixInvert(_helpMatrix);

            Number x = transform.x;
            Number y = transform.y;

            transform.x = _helpMatrix.a * x + _helpMatrix.c * y + _helpMatrix.tx;
            transform.y = _helpMatrix.b * x + _helpMatrix.d * y + _helpMatrix.ty;

            transform.skewX = formatRadian(transform.skewX - parent.skewX);
            transform.skewY = formatRadian(transform.skewY - parent.skewY);
        }
예제 #18
0
파일: mapping.cpp 프로젝트: refnum/quesa
Mapping *
LinearMappingCreate(
        Vector          *center,
        Vector          *vaxis,
        Vector          *uaxis)
{
	Mapping *res;
	RSMatrix m;
	Vector n;

	res = (Mapping *)Malloc(sizeof(Mapping));
	res->flags = OBJSPACE;
	res->method= LinearMapping;

	if (center)
		res->center = *center;
	else
		res->center.x = res->center.y = res->center.z = 0.;

	if (uaxis && vaxis) {
		VecCross(uaxis, vaxis, &n);
		/* this is wrong, since uaxis and vaxis
		 * give U and V in world space, and we
		 * need the inverse.
		 */
		ArbitraryMatrix(
			uaxis->x, uaxis->y, uaxis->z,
			vaxis->x, vaxis->y, vaxis->z,
			n.x, n.y, n.z,
			res->center.x, res->center.y, res->center.z,
			&m);
		MatrixInvert(&m, &res->m);
		res->uaxis = *uaxis;
		res->vaxis = *vaxis;
		VecNormalize(&res->uaxis);
		VecNormalize(&res->vaxis);
	} else {
		VecScale(-1., res->center, &n);
		TranslationMatrix(n.x, n.y, n.z, &res->m);
		res->uaxis.x = res->vaxis.y = 1.;
		res->uaxis.y = res->uaxis.z = res->vaxis.x =
			res->vaxis.z = 0.;
	}
	return res;
}
예제 #19
0
int 
FindContext(double M[2][2])  /* array to search for                          */
{
       register int i;       /* loop variable for search                     */
       for (i=0; i < nextcontext; i++)
               if (M[0][0] == contexts[i].normal[0][0] && M[1][0] == contexts[i].normal[1][0]
                   && M[0][1] == contexts[i].normal[0][1] && M[1][1] == contexts[i].normal[1][1])
                       break;
 
       if (i >= nextcontext) {
               if (i >= MAXCONTEXTS)
                       Abort("Context:  out of them");
               LONGCOPY(contexts[i].normal, M, sizeof(contexts[i].normal));
               MatrixInvert(M, contexts[i].inverse);
               nextcontext++;
       }
 
       return(i);
}
예제 #20
0
//-----------------------------------------------------------------------------
// Shared code to compute the vehicle view position
//-----------------------------------------------------------------------------
void CFourWheelVehiclePhysics::GetVehicleViewPosition( const char *pViewAttachment, float flPitchFactor, Vector *pAbsOrigin, QAngle *pAbsAngles )
{
	matrix3x4_t vehicleEyePosToWorld;
	Vector vehicleEyeOrigin;
	QAngle vehicleEyeAngles;
	GetAttachment( pViewAttachment, vehicleEyeOrigin, vehicleEyeAngles );
	AngleMatrix( vehicleEyeAngles, vehicleEyePosToWorld );

#ifdef HL2_DLL
	// View dampening.
	if ( r_VehicleViewDampen.GetInt() )
	{
		m_pOuterServerVehicle->GetFourWheelVehicle()->DampenEyePosition( vehicleEyeOrigin, vehicleEyeAngles );
	}
#endif

	// Compute the relative rotation between the unperterbed eye attachment + the eye angles
	matrix3x4_t cameraToWorld;
	AngleMatrix( *pAbsAngles, cameraToWorld );

	matrix3x4_t worldToEyePos;
	MatrixInvert( vehicleEyePosToWorld, worldToEyePos );

	matrix3x4_t vehicleCameraToEyePos;
	ConcatTransforms( worldToEyePos, cameraToWorld, vehicleCameraToEyePos );

	// Now perterb the attachment point
	vehicleEyeAngles.x = RemapAngleRange( PITCH_CURVE_ZERO * flPitchFactor, PITCH_CURVE_LINEAR, vehicleEyeAngles.x );
	vehicleEyeAngles.z = RemapAngleRange( ROLL_CURVE_ZERO * flPitchFactor, ROLL_CURVE_LINEAR, vehicleEyeAngles.z );
	AngleMatrix( vehicleEyeAngles, vehicleEyeOrigin, vehicleEyePosToWorld );

	// Now treat the relative eye angles as being relative to this new, perterbed view position...
	matrix3x4_t newCameraToWorld;
	ConcatTransforms( vehicleEyePosToWorld, vehicleCameraToEyePos, newCameraToWorld );

	// output new view abs angles
	MatrixAngles( newCameraToWorld, *pAbsAngles );

	// UNDONE: *pOrigin would already be correct in single player if the HandleView() on the server ran after vphysics
	MatrixGetColumn( newCameraToWorld, 3, *pAbsOrigin );
}
예제 #21
0
//-----------------------------------------------------------------------------
// Sets up the camera
//-----------------------------------------------------------------------------
void CRenderManager::SetupCameraRenderState( )
{
	CCameraProperty *pCamera = g_pWorldManager->GetLocalPlayer()->m_pCameraProperty;

	matrix3x4_t cameraToWorld;
	AngleMatrix( pCamera->m_Angles, pCamera->m_Origin, cameraToWorld );

	matrix3x4_t matRotate;
	matrix3x4_t matRotateZ;
	MatrixBuildRotationAboutAxis( Vector(0,0,1), -90, matRotateZ );
	MatrixMultiply( cameraToWorld, matRotateZ, matRotate );

	matrix3x4_t matRotateX;
	MatrixBuildRotationAboutAxis( Vector(1,0,0), 90, matRotateX );
	MatrixMultiply( matRotate, matRotateX, matRotate );

	matrix3x4_t view;
	MatrixInvert( matRotate, view );

	CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
	pRenderContext->MatrixMode( MATERIAL_VIEW );
	pRenderContext->LoadMatrix( view );
}
//-----------------------------------------------------------------------------
// Purpose: Recompute my rendering box
//-----------------------------------------------------------------------------
void C_QUA_Strider::ClientThink()
{
	int i;
	Vector vecMins, vecMaxs;
	Vector vecAbsMins, vecAbsMaxs;
	matrix3x4_t worldToStrider, hitboxToStrider;
	Vector vecBoxMins, vecBoxMaxs;
	Vector vecBoxAbsMins, vecBoxAbsMaxs;
	mstudiohitboxset_t *set;
	CBoneCache *pCache = NULL;

	// The reason why this is here, as opposed to in SetObjectCollisionBox,
	// is because of IK. The code below recomputes bones so as to get at the hitboxes,
	// which causes IK to trigger, which causes raycasts against the other entities to occur,
	// which is illegal to do while in the Relink phase.

	studiohdr_t *pStudioHdr = GetModel()?modelinfo->GetStudiomodel( GetModel() ):NULL;
	if (!pStudioHdr)
		goto doneWithComputation;

	set = pStudioHdr->pHitboxSet( m_nHitboxSet );
	if ( !set || !set->numhitboxes )
		goto doneWithComputation;

	CStudioHdr *hdr = GetModelPtr();
	pCache = GetBoneCache( hdr );

	matrix3x4_t *hitboxbones[MAXSTUDIOBONES];
	pCache->ReadCachedBonePointers( hitboxbones, pStudioHdr->numbones );

//	// Compute a box in world space that surrounds this entity
	m_vecRenderMins.Init( FLT_MAX, FLT_MAX, FLT_MAX );
	m_vecRenderMaxs.Init( -FLT_MAX, -FLT_MAX, -FLT_MAX );
//
	MatrixInvert( EntityToWorldTransform(), worldToStrider );
//
	for ( i = 0; i < set->numhitboxes; i++ )
	{
		mstudiobbox_t *pbox = set->pHitbox(i);
		ConcatTransforms( worldToStrider, *hitboxbones[pbox->bone], hitboxToStrider );

		TransformAABB( hitboxToStrider, pbox->bbmin, pbox->bbmax, vecBoxMins, vecBoxMaxs );
		VectorMin( m_vecRenderMins, vecBoxMins, m_vecRenderMins );
		VectorMax( m_vecRenderMaxs, vecBoxMaxs, m_vecRenderMaxs );
	}
//	// Deberiamos poner aqui lo de la vista??
//
//	// UNDONE: Disabled this until we can get closer to a final map and tune
//#if 0
//	// Cut ropes.
//	if ( gpGlobals->curtime >= m_flNextRopeCutTime )
//	{
//		// Blow the bbox out a little.
//		Vector vExtendedMins = vecMins - Vector( 50, 50, 50 );
//		Vector vExtendedMaxs = vecMaxs + Vector( 50, 50, 50 );
//
//		C_RopeKeyframe *ropes[512];
//		int nRopes = C_RopeKeyframe::GetRopesIntersectingAABB( ropes, ARRAYSIZE( ropes ), GetAbsOrigin() + vExtendedMins, GetAbsOrigin() + vExtendedMaxs );
//		for ( int i=0; i < nRopes; i++ )
//		{
//			C_RopeKeyframe *pRope = ropes[i];
//
//			if ( pRope->GetEndEntity() )
//			{
//				Vector vPos;
//				if ( pRope->GetEndPointPos( 1, vPos ) )
//				{
//					// Detach the endpoint.
//					pRope->SetEndEntity( NULL );
//					
//					// Make some spark effect here..
//					g_pEffects->Sparks( vPos );
//				}				
//			}
//		}
//
//		m_flNextRopeCutTime = gpGlobals->curtime + 0.5;
//	}
//#endif

doneWithComputation:	
	// True argument because the origin may have stayed the same, but the size is expected to always change
	g_pClientShadowMgr->AddToDirtyShadowList( this, true );
}
//-----------------------------------------------------------------------------
// Purpose: Vehicle dampening shared between server and client
//-----------------------------------------------------------------------------
void SharedVehicleViewSmoothing(CBasePlayer *pPlayer,
                                Vector *pAbsOrigin, QAngle *pAbsAngles,
                                bool bEnterAnimOn, bool bExitAnimOn,
                                const Vector &vecEyeExitEndpoint,
                                ViewSmoothingData_t *pData,
                                float *pFOV )
{
    int eyeAttachmentIndex = pData->pVehicle->LookupAttachment( "vehicle_driver_eyes" );
    matrix3x4_t vehicleEyePosToWorld;
    Vector vehicleEyeOrigin;
    QAngle vehicleEyeAngles;
    pData->pVehicle->GetAttachment( eyeAttachmentIndex, vehicleEyeOrigin, vehicleEyeAngles );
    AngleMatrix( vehicleEyeAngles, vehicleEyePosToWorld );

    // Dampen the eye positional change as we drive around.
    *pAbsAngles = pPlayer->EyeAngles();
    if ( r_VehicleViewDampen.GetInt() && pData->bDampenEyePosition )
    {
        CPropVehicleDriveable *pDriveable = assert_cast<CPropVehicleDriveable*>(pData->pVehicle);
        pDriveable->DampenEyePosition( vehicleEyeOrigin, vehicleEyeAngles );
    }

    // Started running an entry or exit anim?
    bool bRunningAnim = ( bEnterAnimOn || bExitAnimOn );
    if ( bRunningAnim && !pData->bWasRunningAnim )
    {
        pData->bRunningEnterExit = true;
        pData->flEnterExitStartTime = gpGlobals->curtime;
        pData->flEnterExitDuration = pData->pVehicle->SequenceDuration( pData->pVehicle->GetSequence() );

#ifdef CLIENT_DLL
        pData->vecOriginSaved = PrevMainViewOrigin();
        pData->vecAnglesSaved = PrevMainViewAngles();
#endif

        // Save our initial angular error, which we will blend out over the length of the animation.
        pData->vecAngleDiffSaved.x = AngleDiff( vehicleEyeAngles.x, pData->vecAnglesSaved.x );
        pData->vecAngleDiffSaved.y = AngleDiff( vehicleEyeAngles.y, pData->vecAnglesSaved.y );
        pData->vecAngleDiffSaved.z = AngleDiff( vehicleEyeAngles.z, pData->vecAnglesSaved.z );

        pData->vecAngleDiffMin = pData->vecAngleDiffSaved;
    }

    pData->bWasRunningAnim = bRunningAnim;

    float frac = 0;
    float flFracFOV = 0;

    // If we're in an enter/exit animation, blend the player's eye angles to the attachment's
    if ( bRunningAnim || pData->bRunningEnterExit )
    {
        *pAbsAngles = vehicleEyeAngles;

        // Forward integrate to determine the elapsed time in this entry/exit anim.
        frac = ( gpGlobals->curtime - pData->flEnterExitStartTime ) / pData->flEnterExitDuration;
        frac = clamp( frac, 0.0f, 1.0f );

        flFracFOV = ( gpGlobals->curtime - pData->flEnterExitStartTime ) / ( pData->flEnterExitDuration * 0.85f );
        flFracFOV = clamp( flFracFOV, 0.0f, 1.0f );

        //Msg("Frac: %f\n", frac );

        if ( frac < 1.0 )
        {
            // Blend to the desired vehicle eye origin
            //Vector vecToView = (vehicleEyeOrigin - PrevMainViewOrigin());
            //vehicleEyeOrigin = PrevMainViewOrigin() + (vecToView * SimpleSpline(frac));
            //debugoverlay->AddBoxOverlay( vehicleEyeOrigin, -Vector(1,1,1), Vector(1,1,1), vec3_angle, 0,255,255, 64, 10 );
        }
        else
        {
            pData->bRunningEnterExit = false;

            // Enter animation has finished, align view with the eye attachment point
            // so they can start mouselooking around.
#if !defined ( HL2MP_DEV_DLL ) && !defined ( HL2MP_DEV_VEHICLE_FIX )
            if ( !bExitAnimOn )
            {
                Vector localEyeOrigin;
                QAngle localEyeAngles;

                pData->pVehicle->GetAttachmentLocal( eyeAttachmentIndex, localEyeOrigin, localEyeAngles );
#ifdef CLIENT_DLL
                engine->SetViewAngles( localEyeAngles );
#endif
            }
#else

#ifdef CLIENT_DLL
            pPlayer = C_BasePlayer::GetLocalPlayer();
#endif
            if ( pPlayer )
            {
                if ( !bExitAnimOn )
                {
                    Vector localEyeOrigin;
                    QAngle localEyeAngles;

                    pData->pVehicle->GetAttachmentLocal( eyeAttachmentIndex, localEyeOrigin, localEyeAngles );
#ifdef CLIENT_DLL
                    engine->SetViewAngles( localEyeAngles );
#endif
                }
            }
#endif
        }
    }

    // Compute the relative rotation between the unperturbed eye attachment + the eye angles
    matrix3x4_t cameraToWorld;
    AngleMatrix( *pAbsAngles, cameraToWorld );

    matrix3x4_t worldToEyePos;
    MatrixInvert( vehicleEyePosToWorld, worldToEyePos );

    matrix3x4_t vehicleCameraToEyePos;
    ConcatTransforms( worldToEyePos, cameraToWorld, vehicleCameraToEyePos );

    // Damp out some of the vehicle motion (neck/head would do this)
    if ( pData->bClampEyeAngles )
    {
        RemapViewAngles( pData, vehicleEyeAngles );
    }

    AngleMatrix( vehicleEyeAngles, vehicleEyeOrigin, vehicleEyePosToWorld );

    // Now treat the relative eye angles as being relative to this new, perturbed view position...
    matrix3x4_t newCameraToWorld;
    ConcatTransforms( vehicleEyePosToWorld, vehicleCameraToEyePos, newCameraToWorld );

    // output new view abs angles
    MatrixAngles( newCameraToWorld, *pAbsAngles );

    // UNDONE: *pOrigin would already be correct in single player if the HandleView() on the server ran after vphysics
    MatrixGetColumn( newCameraToWorld, 3, *pAbsOrigin );

    float flDefaultFOV;
#ifdef CLIENT_DLL
    flDefaultFOV = default_fov.GetFloat();
#else
    flDefaultFOV = pPlayer->GetDefaultFOV();
#endif

    // If we're playing an entry or exit animation...
    if ( bRunningAnim || pData->bRunningEnterExit )
    {
        float flSplineFrac = clamp( SimpleSpline( frac ), 0.f, 1.f );

        // Blend out the error between the player's initial eye angles and the animation's initial
        // eye angles over the duration of the animation.
        QAngle vecAngleDiffBlend = ( ( 1 - flSplineFrac ) * pData->vecAngleDiffSaved );

        // If our current error is less than the error amount that we're blending
        // out, use that. This lets the angles converge as quickly as possible.
        QAngle vecAngleDiffCur;
        vecAngleDiffCur.x = AngleDiff( vehicleEyeAngles.x, pData->vecAnglesSaved.x );
        vecAngleDiffCur.y = AngleDiff( vehicleEyeAngles.y, pData->vecAnglesSaved.y );
        vecAngleDiffCur.z = AngleDiff( vehicleEyeAngles.z, pData->vecAnglesSaved.z );

        // In either case, never increase the error, so track the minimum error and clamp to that.
        for (int i = 0; i < 3; i++)
        {
            if ( fabs(vecAngleDiffCur[i] ) < fabs( pData->vecAngleDiffMin[i] ) )
            {
                pData->vecAngleDiffMin[i] = vecAngleDiffCur[i];
            }

            if ( fabs(vecAngleDiffBlend[i] ) < fabs( pData->vecAngleDiffMin[i] ) )
            {
                pData->vecAngleDiffMin[i] = vecAngleDiffBlend[i];
            }
        }

        // Add the error to the animation's eye angles.
        *pAbsAngles -= pData->vecAngleDiffMin;

        // Use this as the basis for the next error calculation.
        pData->vecAnglesSaved = *pAbsAngles;

        //if ( gpGlobals->frametime )
        //{
        //	Msg("Angle : %.2f %.2f %.2f\n", target.x, target.y, target.z );
        //}
        //Msg("Prev: %.2f %.2f %.2f\n", pData->vecAnglesSaved.x, pData->vecAnglesSaved.y, pData->vecAnglesSaved.z );

        Vector vecAbsOrigin = *pAbsOrigin;

        // If we're exiting, our desired position is the server-sent exit position
        if ( bExitAnimOn )
        {
            //debugoverlay->AddBoxOverlay( vecEyeExitEndpoint, -Vector(1,1,1), Vector(1,1,1), vec3_angle, 255,255,255, 64, 10 );

            // Blend to the exit position
            *pAbsOrigin = Lerp( flSplineFrac, vecAbsOrigin, vecEyeExitEndpoint );

            if ( pFOV != NULL )
            {
                if ( pData->flFOV > flDefaultFOV )
                {
                    *pFOV = Lerp( flFracFOV, pData->flFOV, flDefaultFOV );
                }
            }
        }
        else
        {
            // Blend from our starting position to the desired origin
            *pAbsOrigin = Lerp( flSplineFrac, pData->vecOriginSaved, vecAbsOrigin );

            if ( pFOV != NULL )
            {
                if ( pData->flFOV > flDefaultFOV )
                {
                    *pFOV = Lerp( flFracFOV, flDefaultFOV, pData->flFOV );
                }
            }
        }
    }
    else if ( pFOV != NULL )
    {
        if ( pData->flFOV > flDefaultFOV )
        {
            // Not running an entry/exit anim. Just use the vehicle's FOV.
            *pFOV = pData->flFOV;
        }
    }
}
예제 #24
0
// apply custom pitch to bone merge
void CASW_Bone_Merge_Cache::MergeMatchingBones( int boneMask, CBoneBitList &boneComputed, bool bOverrideDirection, const Vector &vecDir )
{
	UpdateCache();

	// If this is set, then all the other cache data is set.
	if ( !m_pOwnerHdr || m_MergedBones.Count() == 0 )
		return;

	// Have the entity we're following setup its bones.
	m_pFollow->SetupBones( NULL, -1, m_nFollowBoneSetupMask, gpGlobals->curtime );

	matrix3x4_t matPitchUp;
	AngleMatrix( QAngle( asw_weapon_pitch.GetFloat(), 0, 0 ), matPitchUp );

	// Now copy the bone matrices.
	for ( int i=0; i < m_MergedBones.Count(); i++ )
	{
		int iOwnerBone = m_MergedBones[i].m_iMyBone;
		int iParentBone = m_MergedBones[i].m_iParentBone;

		// Only update bones reference by the bone mask.
		if ( !( m_pOwnerHdr->boneFlags( iOwnerBone ) & boneMask ) )
			continue;

		if ( bOverrideDirection && m_nRightHandBoneID == -1 )		// only want to change direction of the right hand bone, cache its index here
		{
			mstudiobone_t *pOwnerBones = m_pOwnerHdr->pBone( 0 );
			for ( int k = 0; k < m_pOwnerHdr->numbones(); k++ )
			{
				if ( !Q_stricmp( pOwnerBones[k].pszName(), "ValveBiped.Bip01_R_Hand" ) )
				{
					m_nRightHandBoneID = k;
					break;
				}
			}
		}
		
		if ( bOverrideDirection && i == m_nRightHandBoneID )
		{
			matrix3x4_t matParentBoneToWorld;
			m_pFollow->GetBoneTransform( iParentBone, matParentBoneToWorld );
			MatrixSetColumn( vec3_origin, 3, matParentBoneToWorld );		// remove translation

			matrix3x4_t matParentBoneToWorldInv;
			MatrixInvert( matParentBoneToWorld, matParentBoneToWorldInv );

			QAngle angAiming;
			VectorAngles( vecDir, Vector( 0, 0, -1 ), angAiming );
			matrix3x4_t matAimDirection;
			AngleMatrix( angAiming, matAimDirection );
			MatrixSetColumn( vec3_origin, 3, matAimDirection );		// remove translation

			matrix3x4_t matCorrection;
			ConcatTransforms( matParentBoneToWorldInv, matAimDirection, matCorrection );

			ConcatTransforms( m_pFollow->GetBone( iParentBone ), matCorrection, m_pOwner->GetBoneForWrite( iOwnerBone ) );
		}
		else
		{
			ConcatTransforms( m_pFollow->GetBone( iParentBone ), matPitchUp, m_pOwner->GetBoneForWrite( iOwnerBone ) );
		}

		boneComputed.Set( i );
	}
}
void IFaceposerModels::CFacePoserModel::CreateNewBitmap( char const *pchBitmapFilename, int sequence, int nSnapShotSize, bool bZoomInOnFace, CExpression *pExpression, mxbitmapdata_t *bitmap )
{
	MatSysWindow *pWnd = g_pMatSysWindow;
	if ( !pWnd ) 
		return;

	StudioModel *model = m_pModel;
	if ( !model )
		return;

	CStudioHdr *hdr = model->GetStudioHdr();
	if ( !hdr )
		return;
	if ( sequence < 0 || sequence >= hdr->GetNumSeq() )
		return;

	mstudioseqdesc_t &seqdesc = hdr->pSeqdesc( sequence );

	Con_ColorPrintf( FILE_COLOR, "Creating bitmap %s for sequence '%s'\n", pchBitmapFilename, seqdesc.pszLabel() );

	model->ClearOverlaysSequences();
	int iLayer = model->GetNewAnimationLayer();
	model->SetOverlaySequence( iLayer, sequence, 1.0 );
	model->SetOverlayRate( iLayer, FindPoseCycle( model, sequence ), 0.0 );

	for (int i = 0; i < hdr->GetNumPoseParameters(); i++)
	{
		model->SetPoseParameter( i, 0.0 );
	}

	float flexValues[ GLOBAL_STUDIO_FLEX_CONTROL_COUNT ] = { 0 };

	if ( pExpression )
	{
		float *settings = pExpression->GetSettings();
		float *weights = pExpression->GetWeights();

		// Save existing settings from model
		for ( LocalFlexController_t i = LocalFlexController_t(0); i < hdr->numflexcontrollers(); ++i )
		{
			int j = hdr->pFlexcontroller( i )->localToGlobal;
			if ( j == -1 )
				continue;
			flexValues[ i ] = model->GetFlexController( i );
			// Set Value from passed in settings
			model->SetFlexController( i, settings[ j ] * weights[ j ] );
		}
	}

	model->ClearLookTargets( );

	QAngle oldrot, oldLight;
	Vector oldtrans;
	
	VectorCopy( model->m_angles, oldrot );
	VectorCopy( model->m_origin, oldtrans );
	VectorCopy( g_viewerSettings.lightrot, oldLight );

	model->m_angles.Init();
	model->m_origin.Init();
	g_viewerSettings.lightrot.Init();

	g_viewerSettings.lightrot.y = -180;

	bool bSaveGround = g_viewerSettings.showGround;
	g_viewerSettings.showGround = false;

	if ( bZoomInOnFace )
	{
		Vector size;
		VectorSubtract( hdr->hull_max(), hdr->hull_min(), size );

		float eyeheight = hdr->hull_min().z + 0.9 * size.z;
		//	float width = ( size.x + size.y ) / 2.0f;

		model->m_origin.x = size.z * .6f;

		if ( hdr->GetNumAttachments() > 0 )
		{
			for (int i = 0; i < hdr->GetNumAttachments(); i++)
			{
				const mstudioattachment_t &attachment = hdr->pAttachment( i );
				int iBone = hdr->GetAttachmentBone( i );

				if ( Q_stricmp( attachment.pszName(), "eyes" ) )
					continue;

				mstudiobone_t *bone = hdr->pBone( iBone );
				if ( !bone )
					continue;

				matrix3x4_t boneToPose;
				MatrixInvert( bone->poseToBone, boneToPose );

				matrix3x4_t attachmentPoseToLocal;
				ConcatTransforms( boneToPose, attachment.local, attachmentPoseToLocal );

				Vector localSpaceEyePosition;
				VectorITransform( vec3_origin, attachmentPoseToLocal, localSpaceEyePosition );

				// Not sure why this must be negative?
				eyeheight = -localSpaceEyePosition.z + hdr->hull_min().z;
				break;
			}
		}

		KeyValues *seqKeyValues = new KeyValues("");
		if ( seqKeyValues->LoadFromBuffer( model->GetFileName( ), model->GetKeyValueText( sequence ) ) )
		{
			// Do we have a build point section?
			KeyValues *pkvAllFaceposer = seqKeyValues->FindKey("faceposer");
			if ( pkvAllFaceposer )
			{
				float flEyeheight = pkvAllFaceposer->GetFloat( "eye_height", -9999.0f );
				if ( flEyeheight != -9999.0f )
				{
					eyeheight = flEyeheight;
				}
			}
		}

		model->m_origin.z += eyeheight;
	}
	else
	{
		Vector mins, maxs;
		model->ExtractBbox(mins, maxs);
		Vector size;
		VectorSubtract( maxs, mins, size );

		float maxdim = size.x;
		if ( size.y > maxdim )
			maxdim = size.y;
		if ( size.z > maxdim )
			maxdim = size.z;

		float midpoint = mins.z + 0.5 * size.z;

		model->m_origin.x = 3 * maxdim;
		model->m_origin.z += midpoint;
	}

	pWnd->SuppressResize( true );

	RECT rcClient;
	HWND wnd = (HWND)pWnd->getHandle();

	WINDOWPLACEMENT wp;

	GetWindowPlacement( wnd, &wp );

	GetClientRect( wnd, &rcClient );

	MoveWindow( wnd, 0, 0, nSnapShotSize + 16, nSnapShotSize + 16, TRUE );

	// Snapshots are taken of the back buffer; 
	// we need to render to the back buffer but not move it to the front
	pWnd->SuppressBufferSwap( true );
	pWnd->redraw();
	pWnd->SuppressBufferSwap( false );

	// make it square, assumes w > h
	char fullpath[ 512 ];
	Q_snprintf( fullpath, sizeof( fullpath ), "%s%s", GetGameDirectory(), pchBitmapFilename );
	pWnd->TakeSnapshotRect( fullpath, 0, 0, nSnapShotSize, nSnapShotSize );

	// Move back to original position
	SetWindowPlacement( wnd, &wp );

	pWnd->SuppressResize( false );

	VectorCopy( oldrot, model->m_angles );
	VectorCopy( oldtrans, model->m_origin );
	VectorCopy( oldLight, g_viewerSettings.lightrot );

	g_viewerSettings.showGround = bSaveGround;

	if ( pExpression )
	{
		// Save existing settings from model
		for ( LocalFlexController_t i = LocalFlexController_t(0); i < hdr->numflexcontrollers(); ++i )
		{
			int j = hdr->pFlexcontroller( i )->localToGlobal;
			if ( j == -1 )
				continue;

			model->SetFlexController( i, flexValues[ i ] );
		}
	}

	model->ClearOverlaysSequences();
	
	if ( bitmap->valid )
	{
		DeleteObject( bitmap->image );
		bitmap->image = 0;
		bitmap->valid = false;
	}

	LoadBitmapFromFile( pchBitmapFilename, *bitmap );
}
예제 #26
0
void ControlPanel::CenterOnFace( void )
{
	if ( !models->GetActiveStudioModel() )
		return;

	StudioModel *mdl = models->GetActiveStudioModel();
	if ( !mdl )
		return;

	CStudioHdr *hdr = mdl->GetStudioHdr();
	if ( !hdr )
		return;

	setSpeed( 1.0f );

	int oldSeq = models->GetActiveStudioModel()->GetSequence();

	int seq = models->GetActiveStudioModel()->LookupSequence( "idle_suble" );
	if ( seq == -1 )
		seq = 0;

	if ( seq != oldSeq )
	{
		Con_Printf( "Centering changed model sequence # to %d\n", seq );
	}

	setSequence( seq );
	initPoseParameters( );

	mdl->m_angles.Init();
	mdl->m_origin.Init();

	Vector size;
	VectorSubtract( hdr->hull_max(), hdr->hull_min(), size );

	float eyeheight = hdr->hull_min().z + 0.9 * size.z;

	if ( hdr->GetNumAttachments() > 0 )
	{
		for (int i = 0; i < hdr->GetNumAttachments(); i++)
		{
			const mstudioattachment_t &attachment = hdr->pAttachment( i );
			int iBone = hdr->GetAttachmentBone( i );

			if ( Q_stricmp( attachment.pszName(), "eyes" ) )
				continue;

			mstudiobone_t *bone = hdr->pBone( iBone );
			if ( !bone )
				continue;

			matrix3x4_t boneToPose;
			MatrixInvert( bone->poseToBone, boneToPose );

			matrix3x4_t attachmentPoseToLocal;
			ConcatTransforms( boneToPose, attachment.local, attachmentPoseToLocal );

			Vector localSpaceEyePosition;
			VectorITransform( vec3_origin, attachmentPoseToLocal, localSpaceEyePosition );

			// Not sure why this must be negative?
			eyeheight = -localSpaceEyePosition.z + hdr->hull_min().z;
			break;
		}
	}

	KeyValues *seqKeyValues = new KeyValues("");
	if ( seqKeyValues->LoadFromBuffer( mdl->GetFileName( ), mdl->GetKeyValueText( seq ) ) )
	{
		// Do we have a build point section?
		KeyValues *pkvAllFaceposer = seqKeyValues->FindKey("faceposer");
		if ( pkvAllFaceposer )
		{
			float flEyeheight = pkvAllFaceposer->GetFloat( "eye_height", -9999.0f );
			if ( flEyeheight != -9999.0f )
			{
				eyeheight = flEyeheight;
			}
		}
	}

	seqKeyValues->deleteThis();

	mdl->m_origin.x = size.z * .65f;
	mdl->m_origin.z += eyeheight;

	CUtlVector< StudioModel * > modellist;

	modellist.AddToTail( models->GetActiveStudioModel() );

	int i;
	if ( models->CountVisibleModels() > 0 )
	{
		modellist.RemoveAll();
		for ( i = 0; i < models->Count(); i++ )
		{
			if ( models->IsModelShownIn3DView( i ) )
			{
				modellist.AddToTail( models->GetStudioModel( i ) );
			}
		}
	}

	int modelcount = modellist.Count();
	int countover2 = modelcount / 2;
	int ydelta = GetModelGap();
	int yoffset = -countover2 * ydelta;
	for ( i = 0 ; i < modelcount; i++ )
	{
		if ( models->GetStudioHeader( i ) == hdr )
		{
			mdl->m_origin.y = -yoffset;
		}
		yoffset += ydelta;
	}

	g_pMatSysWindow->redraw();
}
예제 #27
0
bool _ComputeRagdollBones( const ragdoll_t *pRagdoll, matrix3x4_t &parentTransform, matrix3x4_t *pBones, Vector *pPositions, QAngle *pAngles )
{
	matrix3x4_t inverted, output;

#ifdef _DEBUG
	CBitVec<MAXSTUDIOBONES> vBonesComputed;
	vBonesComputed.ClearAll();
#endif

	for ( int i = 0; i < pRagdoll->listCount; ++i )
	{
		const ragdollelement_t& element = pRagdoll->list[ i ];

		// during restore if a model has changed since the file was saved, this could be NULL
		if ( !element.pObject )
			return false;

		int const boneIndex = pRagdoll->boneIndex[ i ];
		if ( boneIndex < 0 )
		{
			AssertMsg( 0, "Replay: No mapping for ragdoll bone\n" );
			return false;
		}

		// Get global transform and put it into the bone cache
		element.pObject->GetPositionMatrix( &pBones[ boneIndex ] );

		// Ensure a fixed translation from the parent (no stretching)
		if ( element.parentIndex >= 0 && !pRagdoll->allowStretch )
		{
			int parentIndex = pRagdoll->boneIndex[ element.parentIndex ];

#ifdef _DEBUG
			// Make sure we computed the parent already
			Assert( vBonesComputed.IsBitSet(parentIndex) );
#endif

			// overwrite the position from physics to force rigid attachment
			// NOTE: On the client we actually override this with the proper parent bone in each LOD
			Vector out;
			VectorTransform( element.originParentSpace, pBones[ parentIndex ], out );
			MatrixSetColumn( out, 3, pBones[ boneIndex ] );

			MatrixInvert( pBones[ parentIndex ], inverted );
		}
		else if ( element.parentIndex == - 1 )
		{
			// Decompose into parent space
			MatrixInvert( parentTransform, inverted );
		}

#ifdef _DEBUG
		vBonesComputed.Set( boneIndex, true );
#endif

		// Compute local transform and put into 'output'
 		ConcatTransforms( inverted, pBones[ boneIndex ], output );

		// Cache as Euler/position
 		MatrixAngles( output, pAngles[ i ], pPositions[ i ] );
	}
	return true;
}
//-----------------------------------------------------------------------------
// This is called by the base object when it's time to spawn the control panels
//-----------------------------------------------------------------------------
void CBaseViewModel::SpawnControlPanels()
{
#if defined( VGUI_CONTROL_PANELS )
	char buf[64];

	// Destroy existing panels
	DestroyControlPanels();

	CBaseCombatWeapon *weapon = m_hWeapon.Get();

	if ( weapon == NULL )
	{
		return;
	}

	MDLCACHE_CRITICAL_SECTION();

	// FIXME: Deal with dynamically resizing control panels?

	// If we're attached to an entity, spawn control panels on it instead of use
	CBaseAnimating *pEntityToSpawnOn = this;
	char *pOrgLL = "controlpanel%d_ll";
	char *pOrgUR = "controlpanel%d_ur";
	char *pAttachmentNameLL = pOrgLL;
	char *pAttachmentNameUR = pOrgUR;
	/*
	if ( IsBuiltOnAttachment() )
	{
		pEntityToSpawnOn = dynamic_cast<CBaseAnimating*>((CBaseEntity*)m_hBuiltOnEntity.Get());
		if ( pEntityToSpawnOn )
		{
			char sBuildPointLL[64];
			char sBuildPointUR[64];
			Q_snprintf( sBuildPointLL, sizeof( sBuildPointLL ), "bp%d_controlpanel%%d_ll", m_iBuiltOnPoint );
			Q_snprintf( sBuildPointUR, sizeof( sBuildPointUR ), "bp%d_controlpanel%%d_ur", m_iBuiltOnPoint );
			pAttachmentNameLL = sBuildPointLL;
			pAttachmentNameUR = sBuildPointUR;
		}
		else
		{
			pEntityToSpawnOn = this;
		}
	}
	*/

	Assert( pEntityToSpawnOn );

	// Lookup the attachment point...
	int nPanel;
	for ( nPanel = 0; true; ++nPanel )
	{
		Q_snprintf( buf, sizeof( buf ), pAttachmentNameLL, nPanel );
		int nLLAttachmentIndex = pEntityToSpawnOn->LookupAttachment(buf);
		if (nLLAttachmentIndex <= 0)
		{
			// Try and use my panels then
			pEntityToSpawnOn = this;
			Q_snprintf( buf, sizeof( buf ), pOrgLL, nPanel );
			nLLAttachmentIndex = pEntityToSpawnOn->LookupAttachment(buf);
			if (nLLAttachmentIndex <= 0)
				return;
		}

		Q_snprintf( buf, sizeof( buf ), pAttachmentNameUR, nPanel );
		int nURAttachmentIndex = pEntityToSpawnOn->LookupAttachment(buf);
		if (nURAttachmentIndex <= 0)
		{
			// Try and use my panels then
			Q_snprintf( buf, sizeof( buf ), pOrgUR, nPanel );
			nURAttachmentIndex = pEntityToSpawnOn->LookupAttachment(buf);
			if (nURAttachmentIndex <= 0)
				return;
		}

		const char *pScreenName;
		weapon->GetControlPanelInfo( nPanel, pScreenName );
		if (!pScreenName)
			continue;

		const char *pScreenClassname;
		weapon->GetControlPanelClassName( nPanel, pScreenClassname );
		if ( !pScreenClassname )
			continue;

		// Compute the screen size from the attachment points...
		matrix3x4_t	panelToWorld;
		pEntityToSpawnOn->GetAttachment( nLLAttachmentIndex, panelToWorld );

		matrix3x4_t	worldToPanel;
		MatrixInvert( panelToWorld, worldToPanel );

		// Now get the lower right position + transform into panel space
		Vector lr, lrlocal;
		pEntityToSpawnOn->GetAttachment( nURAttachmentIndex, panelToWorld );
		MatrixGetColumn( panelToWorld, 3, lr );
		VectorTransform( lr, worldToPanel, lrlocal );

		float flWidth = lrlocal.x;
		float flHeight = lrlocal.y;

		CVGuiScreen *pScreen = CreateVGuiScreen( pScreenClassname, pScreenName, pEntityToSpawnOn, this, nLLAttachmentIndex );
		pScreen->ChangeTeam( GetTeamNumber() );
		pScreen->SetActualSize( flWidth, flHeight );
		pScreen->SetActive( false );
		pScreen->MakeVisibleOnlyToTeammates( false );
	
#ifdef INVASION_DLL
		pScreen->SetOverlayMaterial( SCREEN_OVERLAY_MATERIAL );
#endif
		pScreen->SetAttachedToViewModel( true );
		int nScreen = m_hScreens.AddToTail( );
		m_hScreens[nScreen].Set( pScreen );
	}
#endif
}
예제 #29
0
void CRagdollPropAttached::InitRagdollAttached( 
	IPhysicsObject *pAttached, 
	const Vector &forceVector, 
	int forceBone, 
	matrix3x4_t *pPrevBones, 
	matrix3x4_t *pBoneToWorld, 
	float dt, 
	int collisionGroup, 
	CBaseAnimating *pFollow, 
	int boneIndexRoot, 
	const Vector &boneLocalOrigin, 
	int parentBoneAttach, 
	const Vector &worldAttachOrigin )
{
	int ragdollAttachedIndex = 0;
	if ( parentBoneAttach > 0 )
	{
		CStudioHdr *pStudioHdr = GetModelPtr();
		mstudiobone_t *pBone = pStudioHdr->pBone( parentBoneAttach );
		ragdollAttachedIndex = pBone->physicsbone;
	}

	InitRagdoll( forceVector, forceBone, vec3_origin, pPrevBones, pBoneToWorld, dt, collisionGroup, false );
	
	IPhysicsObject *pRefObject = m_ragdoll.list[ragdollAttachedIndex].pObject;

	Vector attachmentPointRagdollSpace;
	pRefObject->WorldToLocal( &attachmentPointRagdollSpace, worldAttachOrigin );

	constraint_ragdollparams_t constraint;
	constraint.Defaults();
	matrix3x4_t tmp, worldToAttached, worldToReference, constraintToWorld;

	Vector offsetWS;
	pAttached->LocalToWorld( &offsetWS, boneLocalOrigin );

	AngleMatrix( QAngle(0, pFollow->GetAbsAngles().y, 0 ), offsetWS, constraintToWorld );

	constraint.axes[0].SetAxisFriction( -2, 2, 20 );
	constraint.axes[1].SetAxisFriction( 0, 0, 0 );
	constraint.axes[2].SetAxisFriction( -15, 15, 20 );

	// Exaggerate the bone's ability to pull the mass of the ragdoll around
	constraint.constraint.bodyMassScale[1] = 50.0f;

	pAttached->GetPositionMatrix( &tmp );
	MatrixInvert( tmp, worldToAttached );

	pRefObject->GetPositionMatrix( &tmp );
	MatrixInvert( tmp, worldToReference );

	ConcatTransforms( worldToReference, constraintToWorld, constraint.constraintToReference );
	ConcatTransforms( worldToAttached, constraintToWorld, constraint.constraintToAttached );

	// for now, just slam this to be the passed in value
	MatrixSetColumn( attachmentPointRagdollSpace, 3, constraint.constraintToReference );

	PhysDisableEntityCollisions( pAttached, m_ragdoll.list[0].pObject );
	m_pAttachConstraint = physenv->CreateRagdollConstraint( pRefObject, pAttached, m_ragdoll.pGroup, constraint );

	SetParent( pFollow );
	SetOwnerEntity( pFollow );

	RagdollActivate( m_ragdoll, modelinfo->GetVCollide( GetModelIndex() ), GetModelIndex() );

	// add a bunch of dampening to the ragdoll
	for ( int i = 0; i < m_ragdoll.listCount; i++ )
	{
		float damping, rotdamping;
		m_ragdoll.list[i].pObject->GetDamping( &damping, &rotdamping );
		damping *= ATTACHED_DAMPING_SCALE;
		rotdamping *= ATTACHED_DAMPING_SCALE;
		m_ragdoll.list[i].pObject->SetDamping( &damping, &rotdamping );
	}

	m_boneIndexAttached = boneIndexRoot;
	m_ragdollAttachedObjectIndex = ragdollAttachedIndex;
	m_attachmentPointBoneSpace = boneLocalOrigin;
	
	Vector vTemp;
	MatrixGetColumn( constraint.constraintToReference, 3, vTemp );
	m_attachmentPointRagdollSpace = vTemp;
}
예제 #30
0
	//-----------------------------------------------------------------------------
	// This is called by the base object when it's time to spawn the control panels
	//-----------------------------------------------------------------------------
	void CPlantedC4::SpawnControlPanels()
	{
		char buf[64];

		// FIXME: Deal with dynamically resizing control panels?

		// If we're attached to an entity, spawn control panels on it instead of use
		CBaseAnimating *pEntityToSpawnOn = this;
		char *pOrgLL = "controlpanel%d_ll";
		char *pOrgUR = "controlpanel%d_ur";
		char *pAttachmentNameLL = pOrgLL;
		char *pAttachmentNameUR = pOrgUR;

		Assert( pEntityToSpawnOn );

		// Lookup the attachment point...
		int nPanel;
		for ( nPanel = 0; true; ++nPanel )
		{
			Q_snprintf( buf, sizeof( buf ), pAttachmentNameLL, nPanel );
			int nLLAttachmentIndex = pEntityToSpawnOn->LookupAttachment(buf);
			if (nLLAttachmentIndex <= 0)
			{
				// Try and use my panels then
				pEntityToSpawnOn = this;
				Q_snprintf( buf, sizeof( buf ), pOrgLL, nPanel );
				nLLAttachmentIndex = pEntityToSpawnOn->LookupAttachment(buf);
				if (nLLAttachmentIndex <= 0)
					return;
			}

			Q_snprintf( buf, sizeof( buf ), pAttachmentNameUR, nPanel );
			int nURAttachmentIndex = pEntityToSpawnOn->LookupAttachment(buf);
			if (nURAttachmentIndex <= 0)
			{
				// Try and use my panels then
				Q_snprintf( buf, sizeof( buf ), pOrgUR, nPanel );
				nURAttachmentIndex = pEntityToSpawnOn->LookupAttachment(buf);
				if (nURAttachmentIndex <= 0)
					return;
			}

			const char *pScreenName;
			GetControlPanelInfo( nPanel, pScreenName );
			if (!pScreenName)
				continue;

			const char *pScreenClassname;
			GetControlPanelClassName( nPanel, pScreenClassname );
			if ( !pScreenClassname )
				continue;

			// Compute the screen size from the attachment points...
			matrix3x4_t	panelToWorld;
			pEntityToSpawnOn->GetAttachment( nLLAttachmentIndex, panelToWorld );

			matrix3x4_t	worldToPanel;
			MatrixInvert( panelToWorld, worldToPanel );

			// Now get the lower right position + transform into panel space
			Vector lr, lrlocal;
			pEntityToSpawnOn->GetAttachment( nURAttachmentIndex, panelToWorld );
			MatrixGetColumn( panelToWorld, 3, lr );
			VectorTransform( lr, worldToPanel, lrlocal );

			float flWidth = lrlocal.x;
			float flHeight = lrlocal.y;

			CVGuiScreen *pScreen = CreateVGuiScreen( pScreenClassname, pScreenName, pEntityToSpawnOn, this, nLLAttachmentIndex );
			pScreen->ChangeTeam( GetTeamNumber() );
			pScreen->SetActualSize( flWidth, flHeight );
			pScreen->SetActive( true );
			pScreen->MakeVisibleOnlyToTeammates( false );
			int nScreen = m_hScreens.AddToTail( );
			m_hScreens[nScreen].Set( pScreen );			
		}
	}