void CGravControllerPoint::DetachEntity( void )
{
	CBaseEntity *pEntity = m_attachedEntity;
	if ( pEntity )
	{
		IPhysicsObject *pPhys = GetPhysObjFromPhysicsBone( pEntity, m_attachedPhysicsBone );
		if ( pPhys )
		{
			// on the odd chance that it's gone to sleep while under anti-gravity
			pPhys->Wake();
			pPhys->SetDamping( NULL, &m_saveDamping );
			pPhys->SetMass( m_saveMass );
		}
	}
	m_attachedEntity = NULL;
	m_attachedPhysicsBone = 0;
	if ( physenv )
	{
		physenv->DestroyMotionController( m_controller );
	}
	m_controller = NULL;

	// UNDONE: Does this help the networking?
	m_targetPosition = vec3_origin;
	m_worldPosition = vec3_origin;
}
Esempio n. 2
0
bool CPushable::CreateVPhysics( void )
{
	VPhysicsInitNormal( SOLID_VPHYSICS, 0, false );
	IPhysicsObject *pPhysObj = VPhysicsGetObject();
	if ( pPhysObj )
	{
		pPhysObj->SetMass( 30 );
//		Vector vecInertia = Vector(800, 800, 800);
//		pPhysObj->SetInertia( vecInertia );
	}

	return true;
}
Esempio n. 3
0
//-----------------------------------------------------------------------------
// Purpose: Input handler for setting the breakable's mass.
//-----------------------------------------------------------------------------
void CBreakable::InputSetMass( inputdata_t &inputdata )
{
	IPhysicsObject * vPhys = VPhysicsGetObject();
	if ( vPhys )
	{
		float toMass = inputdata.value.Float();
		Assert(toMass > 0);
		vPhys->SetMass( toMass );
	}
	else
	{
		Warning( "Tried to call SetMass() on %s but it has no physics.\n", GetEntityName().ToCStr() );
	}
}
Esempio n. 4
0
//-----------------------------------------------------------------------------
// Purpose: Creates a dense ball with a mass equal to the aggregate mass consumed by the vortex
//-----------------------------------------------------------------------------
void CGravityVortexController::CreateDenseBall( void )
{
	CBaseEntity *pBall = CreateEntityByName( "prop_physics" );
	
	pBall->SetModel( DENSE_BALL_MODEL );
	pBall->SetAbsOrigin( GetAbsOrigin() );
	pBall->Spawn();

	IPhysicsObject *pObj = pBall->VPhysicsGetObject();
	if ( pObj != NULL )
	{
		pObj->SetMass( GetConsumedMass() );
	}
}
void CGrabController::DetachEntity( bool bClearVelocity )
{
	Assert(!PhysIsInCallback());
	CBaseEntity *pEntity = GetAttached();
	if ( pEntity )
	{
		// Restore the LS blocking state
		pEntity->SetBlocksLOS( m_bCarriedEntityBlocksLOS );
		IPhysicsObject *pList[VPHYSICS_MAX_OBJECT_LIST_COUNT];
		int count = pEntity->VPhysicsGetObjectList( pList, ARRAYSIZE(pList) );
		for ( int i = 0; i < count; i++ )
		{
			IPhysicsObject *pPhys = pList[i];
			if ( !pPhys )
				continue;

			// on the odd chance that it's gone to sleep while under anti-gravity
			pPhys->EnableDrag( true );
			pPhys->Wake();
			pPhys->SetMass( m_savedMass[i] );
			pPhys->SetDamping( NULL, &m_savedRotDamping[i] );
			PhysClearGameFlags( pPhys, FVPHYSICS_PLAYER_HELD );
			if ( bClearVelocity )
			{
				PhysForceClearVelocity( pPhys );
			}
			else
			{
				ClampPhysicsVelocity( pPhys, player_walkspeed.GetFloat() * 1.5f, 2.0f * 360.0f );
			}

		}
	}

	m_attachedEntity = NULL;
	physenv->DestroyMotionController( m_controller );
	m_controller = NULL;
}
Esempio n. 6
0
	//Actual work code
	IterationRetval_t EnumElement( IHandleEntity *pHandleEntity )
	{
		C_BaseEntity *pEnt = ClientEntityList().GetBaseEntityFromHandle( pHandleEntity->GetRefEHandle() );
		if ( pEnt == NULL )
			return ITERATION_CONTINUE;

		C_BaseAnimating *pModel = static_cast< C_BaseAnimating * >( pEnt );

		if ( pModel == NULL )
			return ITERATION_CONTINUE;

		trace_t tr;
		enginetrace->ClipRayToEntity( m_rayShot, MASK_SHOT, pModel, &tr );

		IPhysicsObject	*pPhysicsObject = NULL;
		
		//Find the real object we hit.
		if( tr.physicsbone >= 0 )
		{
			if ( pModel->m_pRagdoll )
			{
				CRagdoll *pCRagdoll = dynamic_cast < CRagdoll * > ( pModel->m_pRagdoll );

				if ( pCRagdoll )
				{
					ragdoll_t *pRagdollT = pCRagdoll->GetRagdoll();

					if ( tr.physicsbone < pRagdollT->listCount )
					{
						pPhysicsObject = pRagdollT->list[tr.physicsbone].pObject;
					}
				}
			}
		}

		if ( pPhysicsObject == NULL )
			return ITERATION_CONTINUE;

		if ( tr.fraction < 1.0 )
		{
			IPhysicsObject *pReference = GetWorldPhysObject();

			if ( pReference == NULL || pPhysicsObject == NULL )
				 return ITERATION_CONTINUE;
			
			float flMass = pPhysicsObject->GetMass();
			pPhysicsObject->SetMass( flMass * 2 );

			constraint_ballsocketparams_t ballsocket;
			ballsocket.Defaults();
		
			pReference->WorldToLocal( &ballsocket.constraintPosition[0], m_vWorld );
			pPhysicsObject->WorldToLocal( &ballsocket.constraintPosition[1], tr.endpos );
	
			physenv->CreateBallsocketConstraint( pReference, pPhysicsObject, NULL, ballsocket );

			//Play a sound
			CPASAttenuationFilter filter( pEnt );

			EmitSound_t ep;
			ep.m_nChannel = CHAN_VOICE;
			ep.m_pSoundName =  "Weapon_Crossbow.BoltSkewer";
			ep.m_flVolume = 1.0f;
			ep.m_SoundLevel = SNDLVL_NORM;
			ep.m_pOrigin = &pEnt->GetAbsOrigin();

			C_BaseEntity::EmitSound( filter, SOUND_FROM_WORLD, ep );
	
			return ITERATION_STOP;
		}

		return ITERATION_CONTINUE;
	}
Esempio n. 7
0
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pOther -
//-----------------------------------------------------------------------------
void CGrappleHook::HookTouch(CBaseEntity *pOther)
{
	if (!pOther->IsSolid() || pOther->IsSolidFlagSet(FSOLID_VOLUME_CONTENTS))
		return;
	if ((pOther != m_hOwner) && (pOther->m_takedamage != DAMAGE_NO))
	{
		m_hOwner->NotifyHookDied();
		SetTouch(NULL);
		SetThink(NULL);
		UTIL_Remove(this);
	}
	else
	{
		trace_t	tr;
		tr = BaseClass::GetTouchTrace();
		// See if we struck the world
		if (pOther->GetMoveType() == MOVETYPE_NONE && !(tr.surface.flags & SURF_SKY))
		{
			EmitSound("Weapon_AR2.Reload_Push");
			// if what we hit is static architecture, can stay around for a while.
			Vector vecDir = GetAbsVelocity();
			//FIXME: We actually want to stick (with hierarchy) to what we've hit
			SetMoveType(MOVETYPE_NONE);
			Vector vForward;
			AngleVectors(GetAbsAngles(), &vForward);
			VectorNormalize(vForward);
			CEffectData data;
			data.m_vOrigin = tr.endpos;
			data.m_vNormal = vForward;
			data.m_nEntIndex = 0;
			// DispatchEffect( "Impact", data );
			// AddEffects( EF_NODRAW );
			SetTouch(NULL);
			VPhysicsDestroyObject();
			VPhysicsInitNormal(SOLID_VPHYSICS, FSOLID_NOT_STANDABLE, false);
			AddSolidFlags(FSOLID_NOT_SOLID);
			// SetMoveType( MOVETYPE_NONE );
			if (!m_hPlayer)
			{
				Assert(0);
				return;
			}
			// Set Jay's gai flag
			m_hPlayer->SetPhysicsFlag(PFLAG_VPHYSICS_MOTIONCONTROLLER, true);
			//IPhysicsObject *pPhysObject = m_hPlayer->VPhysicsGetObject();
			IPhysicsObject *pRootPhysObject = VPhysicsGetObject();
			Assert(pRootPhysObject);
			//Assert(pPhysObject);
			pRootPhysObject->EnableMotion(false);
			// Root has huge mass, tip has little
			pRootPhysObject->SetMass(VPHYSICS_MAX_MASS);
			// pPhysObject->SetMass( 100 );
			// float damping = 3;
			// pPhysObject->SetDamping( &damping, &damping );
			Vector origin = m_hPlayer->GetAbsOrigin();
			Vector rootOrigin = GetAbsOrigin();
			m_fSpringLength = (origin - rootOrigin).Length();
			m_bPlayerWasStanding = ((m_hPlayer->GetFlags() & FL_DUCKING) == 0);
			SetThink(&CGrappleHook::HookedThink);
			SetNextThink(gpGlobals->curtime + 0.1f);
		}
		else
		{
			// Put a mark unless we've hit the sky
			if ((tr.surface.flags & SURF_SKY) == false)
			{
				UTIL_ImpactTrace(&tr, DMG_BULLET);
			}
			SetTouch(NULL);
			SetThink(NULL);
			m_hOwner->NotifyHookDied();
			UTIL_Remove(this);
		}
	}
}
bool CStatueProp::CreateVPhysicsFromOBBs( CBaseAnimating *pInitBaseAnimating )
{
	// Make enough pointers to convexes for each hitbox
	CPhysConvex **ppConvex = new (CPhysConvex*[ m_pInitOBBs->Count() ]);

	float flTotalVolume = 0.0f;
	float flTotalSurfaceArea = 0.0f;

	for ( int i = 0; i < m_pInitOBBs->Count(); i++ )
	{
		const outer_collision_obb_t *pOBB = &((*m_pInitOBBs)[ i ]);

		// Accumulate volume and area
		Vector flDimentions = pOBB->vecMaxs - pOBB->vecMins;
		flTotalVolume += flDimentions.x * flDimentions.y * flDimentions.z;
		flTotalSurfaceArea += 2.0f * ( flDimentions.x * flDimentions.y + flDimentions.x * flDimentions.z + flDimentions.y * flDimentions.z );

		// Get angled min and max extents
		Vector vecMins, vecMaxs;
		VectorRotate( pOBB->vecMins, pOBB->angAngles, vecMins );
		VectorRotate( pOBB->vecMaxs, pOBB->angAngles, vecMaxs );

		// Get the corners in world space
		Vector vecMinCorner = pOBB->vecPos + vecMins;
		Vector vecMaxCorner = pOBB->vecPos + vecMaxs;

		// Get the normals of the hitbox in world space
		Vector vecForward, vecRight, vecUp;
		AngleVectors( pOBB->angAngles, &vecForward, &vecRight, &vecUp );
		vecRight = -vecRight;

		// Convert corners and normals to local space
		Vector vecCornerLocal[ 2 ];
		Vector vecNormalLocal[ 3 ];

		matrix3x4_t matToWorld = EntityToWorldTransform();
		VectorITransform( vecMaxCorner, matToWorld, vecCornerLocal[ 0 ] );
		VectorITransform( vecMinCorner, matToWorld, vecCornerLocal[ 1 ] );
		VectorIRotate( vecForward, matToWorld, vecNormalLocal[ 0 ] );
		VectorIRotate( vecRight, matToWorld, vecNormalLocal[ 1 ] );
		VectorIRotate( vecUp, matToWorld, vecNormalLocal[ 2 ] );

		// Create 6 planes from the local oriented hit box data
		float pPlanes[ 4 * 6 ];

		for ( int iPlane = 0; iPlane < 6; ++iPlane )
		{
			int iPlaneMod2 = iPlane % 2;
			int iPlaneDiv2 = iPlane / 2;
			bool bOdd = ( iPlaneMod2 == 1 );

			// Plane Normal
			pPlanes[ iPlane * 4 + 0 ] = vecNormalLocal[ iPlaneDiv2 ].x * ( bOdd ? -1.0f : 1.0f );
			pPlanes[ iPlane * 4 + 1 ] = vecNormalLocal[ iPlaneDiv2 ].y * ( bOdd ? -1.0f : 1.0f );
			pPlanes[ iPlane * 4 + 2 ] = vecNormalLocal[ iPlaneDiv2 ].z * ( bOdd ? -1.0f : 1.0f );

			// Plane D
			pPlanes[ iPlane * 4 + 3 ] = ( vecCornerLocal[ iPlaneMod2 ].x * vecNormalLocal[ iPlaneDiv2 ].x + 
				vecCornerLocal[ iPlaneMod2 ].y * vecNormalLocal[ iPlaneDiv2 ].y + 
				vecCornerLocal[ iPlaneMod2 ].z * vecNormalLocal[ iPlaneDiv2 ].z ) * ( bOdd ? -1.0f : 1.0f );
		}

		// Create convex from the intersection of these planes
		ppConvex[ i ] = physcollision->ConvexFromPlanes( pPlanes, 6, 0.0f );
	}

	// Make a single collide out of the group of convex boxes
	CPhysCollide *pPhysCollide = physcollision->ConvertConvexToCollide( ppConvex, m_pInitOBBs->Count() );

	delete[] ppConvex;

	// Create the physics object
	objectparams_t params = g_PhysDefaultObjectParams;
	params.pGameData = static_cast<void *>( this );

	int nMaterialIndex = physprops->GetSurfaceIndex( "ice" );	// use ice material

	IPhysicsObject* p = physenv->CreatePolyObject( pPhysCollide, nMaterialIndex, GetAbsOrigin(), GetAbsAngles(), &params );
	Assert( p != NULL );

	// Set velocity
	Vector vecInitialVelocity = pInitBaseAnimating->GetAbsVelocity();
	p->SetVelocity( &vecInitialVelocity, NULL );

	// Compute mass
	float flMass;
	float flDensity, flThickness;
	physprops->GetPhysicsProperties( nMaterialIndex, &flDensity, &flThickness, NULL, NULL );

	// Make it more hollow
	flThickness = MIN ( 1.0f, flThickness + 0.5f );

	if ( flThickness > 0.0f )
	{
		flMass = flTotalSurfaceArea * flThickness * CUBIC_METERS_PER_CUBIC_INCH * flDensity;
	}
	else
	{
		// density is in kg/m^3, volume is in in^3
		flMass = flTotalVolume * CUBIC_METERS_PER_CUBIC_INCH * flDensity;
	}

	// Mass is somewhere between the original and if it was all ice
	p->SetMass( flMass );

	// Yes, gravity
	p->EnableGravity( true );

	// Use this as our vphysics
	VPhysicsSetObject( p );

	SetSolid( SOLID_VPHYSICS );
	AddSolidFlags( FSOLID_CUSTOMRAYTEST | FSOLID_CUSTOMBOXTEST );

	SetMoveType( MOVETYPE_VPHYSICS );

	m_pInitOBBs = NULL;

	return true;
}
bool CStatueProp::CreateVPhysicsFromHitBoxes( CBaseAnimating *pInitBaseAnimating )
{
	if ( !pInitBaseAnimating )
		return false;

	// Use the current animation sequence and cycle
	CopyAnimationDataFrom( pInitBaseAnimating );

	// Copy over any render color
	color24 colorRender = pInitBaseAnimating->GetRenderColor();
	SetRenderColor( colorRender.r, colorRender.g, colorRender.b );
	SetRenderAlpha( pInitBaseAnimating->GetRenderAlpha() );

	// Get hitbox data
	CStudioHdr *pStudioHdr = GetModelPtr();
	if ( !pStudioHdr )
		return false;

	mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( m_nHitboxSet );
	if ( !set )
		return false;

	Vector position;
	QAngle angles;

	// Make enough pointers to convexes for each hitbox
	CPhysConvex **ppConvex = new (CPhysConvex*[ set->numhitboxes ]);

	float flTotalVolume = 0.0f;
	float flTotalSurfaceArea = 0.0f;

	for ( int i = 0; i < set->numhitboxes; i++ )
	{
		// Get the hitbox info
		mstudiobbox_t *pbox = set->pHitbox( i );
		GetBonePosition( pbox->bone, position, angles );

		// Accumulate volume and area
		Vector flDimentions = pbox->bbmax - pbox->bbmin;
		flTotalVolume += flDimentions.x * flDimentions.y * flDimentions.z;
		flTotalSurfaceArea += 2.0f * ( flDimentions.x * flDimentions.y + flDimentions.x * flDimentions.z + flDimentions.y * flDimentions.z );

		// Get angled min and max extents
		Vector vecMins, vecMaxs;
		VectorRotate( pbox->bbmin, angles, vecMins );
		VectorRotate( pbox->bbmax, angles, vecMaxs );

		// Get the corners in world space
		Vector vecMinCorner = position + vecMins;
		Vector vecMaxCorner = position + vecMaxs;

		// Get the normals of the hitbox in world space
		Vector vecForward, vecRight, vecUp;
		AngleVectors( angles, &vecForward, &vecRight, &vecUp );
		vecRight = -vecRight;

		// Convert corners and normals to local space
		Vector vecCornerLocal[ 2 ];
		Vector vecNormalLocal[ 3 ];

		matrix3x4_t matToWorld = EntityToWorldTransform();
		VectorITransform( vecMaxCorner, matToWorld, vecCornerLocal[ 0 ] );
		VectorITransform( vecMinCorner, matToWorld, vecCornerLocal[ 1 ] );
		VectorIRotate( vecForward, matToWorld, vecNormalLocal[ 0 ] );
		VectorIRotate( vecRight, matToWorld, vecNormalLocal[ 1 ] );
		VectorIRotate( vecUp, matToWorld, vecNormalLocal[ 2 ] );

		// Create 6 planes from the local oriented hit box data
		float pPlanes[ 4 * 6 ];

		for ( int iPlane = 0; iPlane < 6; ++iPlane )
		{
			int iPlaneMod2 = iPlane % 2;
			int iPlaneDiv2 = iPlane / 2;
			bool bOdd = ( iPlaneMod2 == 1 );

			// Plane Normal
			pPlanes[ iPlane * 4 + 0 ] = vecNormalLocal[ iPlaneDiv2 ].x * ( bOdd ? -1.0f : 1.0f );
			pPlanes[ iPlane * 4 + 1 ] = vecNormalLocal[ iPlaneDiv2 ].y * ( bOdd ? -1.0f : 1.0f );
			pPlanes[ iPlane * 4 + 2 ] = vecNormalLocal[ iPlaneDiv2 ].z * ( bOdd ? -1.0f : 1.0f );

			// Plane D
			pPlanes[ iPlane * 4 + 3 ] = ( vecCornerLocal[ iPlaneMod2 ].x * vecNormalLocal[ iPlaneDiv2 ].x + 
				vecCornerLocal[ iPlaneMod2 ].y * vecNormalLocal[ iPlaneDiv2 ].y + 
				vecCornerLocal[ iPlaneMod2 ].z * vecNormalLocal[ iPlaneDiv2 ].z ) * ( bOdd ? -1.0f : 1.0f );
		}

		// Create convex from the intersection of these planes
		ppConvex[ i ] = physcollision->ConvexFromPlanes( pPlanes, 6, 0.0f );
	}

	// Make a single collide out of the group of convex boxes
	CPhysCollide *pPhysCollide = physcollision->ConvertConvexToCollide( ppConvex, set->numhitboxes );

	delete[] ppConvex;

	// Create the physics object
	objectparams_t params = g_PhysDefaultObjectParams;
	params.pGameData = static_cast<void *>( this );

	int nMaterialIndex = physprops->GetSurfaceIndex( "ice" );	// use ice material

	IPhysicsObject* p = physenv->CreatePolyObject( pPhysCollide, nMaterialIndex, GetAbsOrigin(), GetAbsAngles(), &params );
	Assert( p != NULL );

	// Set velocity
	Vector vecInitialVelocity = pInitBaseAnimating->GetAbsVelocity();
	p->SetVelocity( &vecInitialVelocity, NULL );

	// Compute mass
	float flMass;
	float flDensity, flThickness;
	physprops->GetPhysicsProperties( nMaterialIndex, &flDensity, &flThickness, NULL, NULL );

	// Make it more hollow
	flThickness = MIN ( 1.0f, flThickness + 0.5f );

	if ( flThickness > 0.0f )
	{
		flMass = flTotalSurfaceArea * flThickness * CUBIC_METERS_PER_CUBIC_INCH * flDensity;
	}
	else
	{
		// density is in kg/m^3, volume is in in^3
		flMass = flTotalVolume * CUBIC_METERS_PER_CUBIC_INCH * flDensity;
	}

	// Mass is somewhere between the original and if it was all ice
	p->SetMass( flMass );

	// Yes, gravity
	p->EnableGravity( true );

	// Use this as our vphysics
	VPhysicsSetObject( p );

	SetSolid( SOLID_VPHYSICS );
	AddSolidFlags( FSOLID_CUSTOMRAYTEST | FSOLID_CUSTOMBOXTEST );

	SetMoveType( MOVETYPE_VPHYSICS );

	if ( pInitBaseAnimating != this )
	{
		// Transfer children from the init base animating
		TransferChildren( pInitBaseAnimating, this );

		CBaseEntity *pChild = FirstMoveChild();

		while ( pChild )
		{
			CEntityFreezing *pFreezing = dynamic_cast<CEntityFreezing*>( pChild );
			if ( pFreezing )
			{
				pFreezing->FinishFreezing();
			}

			pChild = pChild->NextMovePeer();
		}
	}

	return true;
}