示例#1
0
文件: Push.cpp 项目: albertz/iodoom3
int idPush::TryTranslatePushEntity( trace_t &results, idEntity *check, idClipModel *clipModel, const int flags,
										const idVec3 &newOrigin, const idVec3 &move ) {
	trace_t		trace;
	idVec3		checkMove;
	idVec3		oldOrigin;
	idPhysics	*physics;

	physics = check->GetPhysics();

#ifdef TRANSLATIONAL_PUSH_DEBUG
	bool startsolid = false;
	if ( physics->ClipContents( clipModel ) ) {
		startsolid = true;
	}
#endif

	results.fraction = 1.0f;
	results.endpos = newOrigin;
	results.endAxis = clipModel->GetAxis();
	memset( &results.c, 0, sizeof( results.c ) );

	// always pushed when standing on the pusher
	if ( physics->IsGroundClipModel( clipModel->GetEntity()->entityNumber, clipModel->GetId() ) ) {
		// move the entity colliding with all other entities except the pusher itself
		ClipEntityTranslation( trace, check, NULL, clipModel, move );
		// if there is a collision
		if ( trace.fraction < 1.0f ) {
			// vector along which the entity is pushed
			checkMove = move * trace.fraction;
			// test if the entity can stay at it's partly pushed position by moving the entity in reverse only colliding with pusher
			ClipEntityTranslation( results, check, clipModel, NULL, -(move - checkMove) );
			// if there is a collision
			if ( results.fraction < 1.0f ) {

				// FIXME: try to push the blocking entity as well or try to slide along collision plane(s)?

				results.c.normal = -results.c.normal;
				results.c.dist = -results.c.dist;

				// the entity will be crushed between the pusher and some other entity
				return PUSH_BLOCKED;
			}
		}
		else {
			// vector along which the entity is pushed
			checkMove = move;
		}
	}
	else {
		// move entity in reverse only colliding with pusher
		ClipEntityTranslation( results, check, clipModel, NULL, -move );
		// if no collision with the pusher then the entity is not pushed by the pusher
		if ( results.fraction >= 1.0f ) {
			return PUSH_NO;
		}
		// vector along which the entity is pushed
		checkMove = move * (1.0f - results.fraction);
		// move the entity colliding with all other entities except the pusher itself
		ClipEntityTranslation( trace, check, NULL, clipModel, checkMove );
		// if there is a collisions
		if ( trace.fraction < 1.0f ) {

			results.c.normal = -results.c.normal;
			results.c.dist = -results.c.dist;

			// FIXME: try to push the blocking entity as well ?
			// FIXME: handle sliding along more than one collision plane ?
			// FIXME: this code has issues, player pushing box into corner in "maps/mre/aaron/test.map"

/*
			oldOrigin = physics->GetOrigin();

			// movement still remaining
			checkMove *= (1.0f - trace.fraction);

			// project the movement along the collision plane
			if ( !checkMove.ProjectAlongPlane( trace.c.normal, 0.1f, 1.001f ) ) {
				return PUSH_BLOCKED;
			}
			checkMove *= 1.001f;

			// move entity from collision point along the collision plane
			physics->SetOrigin( trace.endpos );
			ClipEntityTranslation( trace, check, NULL, NULL, checkMove );

			if ( trace.fraction < 1.0f ) {
				physics->SetOrigin( oldOrigin );
				return PUSH_BLOCKED;
			}

			checkMove = trace.endpos - oldOrigin;

			// move entity in reverse only colliding with pusher
			physics->SetOrigin( trace.endpos );
			ClipEntityTranslation( trace, check, clipModel, NULL, -move );

			physics->SetOrigin( oldOrigin );
*/
			if ( trace.fraction < 1.0f ) {
				return PUSH_BLOCKED;
			}
		}
	}

	SaveEntityPosition( check );

	// translate the entity
	physics->Translate( checkMove );

#ifdef TRANSLATIONAL_PUSH_DEBUG
	// set the pusher in the translated position
	clipModel->Link( gameLocal.clip, clipModel->GetEntity(), clipModel->GetId(), newOrigin, clipModel->GetAxis() );
	if ( physics->ClipContents( clipModel ) ) {
		if ( !startsolid ) {
			int bah = 1;
		}
	}
#endif

	return PUSH_OK;
}
示例#2
0
文件: Push.cpp 项目: albertz/iodoom3
int idPush::TryRotatePushEntity( trace_t &results, idEntity *check, idClipModel *clipModel, const int flags,
											 const idMat3 &newAxis, const idRotation &rotation ) {
	trace_t trace;
	idVec3 rotationPoint;
	idRotation newRotation;
	float checkAngle;
	idPhysics *physics;

	physics = check->GetPhysics();

#ifdef ROTATIONAL_PUSH_DEBUG
	bool startsolid = false;
	if ( physics->ClipContents( clipModel ) ) {
		startsolid = true;
	}
#endif

	results.fraction = 1.0f;
	results.endpos = clipModel->GetOrigin();
	results.endAxis = newAxis;
	memset( &results.c, 0, sizeof( results.c ) );

	// always pushed when standing on the pusher
	if ( physics->IsGroundClipModel( clipModel->GetEntity()->entityNumber, clipModel->GetId() ) ) {
		// rotate the entity colliding with all other entities except the pusher itself
		ClipEntityRotation( trace, check, NULL, clipModel, rotation );
		// if there is a collision
		if ( trace.fraction < 1.0f ) {
			// angle along which the entity is pushed
			checkAngle = rotation.GetAngle() * trace.fraction;
			// test if the entity can stay at it's partly pushed position by rotating
			// the entity in reverse only colliding with pusher
			newRotation.Set( rotation.GetOrigin(), rotation.GetVec(), -(rotation.GetAngle() - checkAngle) );
			ClipEntityRotation( results, check, clipModel, NULL, newRotation );
			// if there is a collision
			if ( results.fraction < 1.0f ) {

				// FIXME: try to push the blocking entity as well or try to slide along collision plane(s)?

				results.c.normal = -results.c.normal;
				results.c.dist = -results.c.dist;

				// the entity will be crushed between the pusher and some other entity
				return PUSH_BLOCKED;
			}
		}
		else {
			// angle along which the entity is pushed
			checkAngle = rotation.GetAngle();
		}
		// point to rotate entity bbox around back to axial
		rotationPoint = physics->GetOrigin();
	}
	else {
		// rotate entity in reverse only colliding with pusher
		newRotation = rotation;
		newRotation.Scale( -1 );
		//
		ClipEntityRotation( results, check, clipModel, NULL, newRotation );
		// if no collision with the pusher then the entity is not pushed by the pusher
		if ( results.fraction >= 1.0f ) {
#ifdef ROTATIONAL_PUSH_DEBUG
			// set pusher into final position
			clipModel->Link( gameLocal.clip, clipModel->GetEntity(), clipModel->GetId(), clipModel->GetOrigin(), newAxis );
			if ( physics->ClipContents( clipModel ) ) {
				if ( !startsolid ) {
					int bah = 1;
				}
			}
#endif
			return PUSH_NO;
		}
		// get point to rotate bbox around back to axial
		rotationPoint = results.c.point;
		// angle along which the entity will be pushed
		checkAngle = rotation.GetAngle() * (1.0f - results.fraction);
		// rotate the entity colliding with all other entities except the pusher itself
		newRotation.Set( rotation.GetOrigin(), rotation.GetVec(), checkAngle );
		ClipEntityRotation( trace, check, NULL, clipModel, newRotation );
		// if there is a collision
		if ( trace.fraction < 1.0f ) {

			// FIXME: try to push the blocking entity as well or try to slide along collision plane(s)?

			results.c.normal = -results.c.normal;
			results.c.dist = -results.c.dist;

			// the entity will be crushed between the pusher and some other entity
			return PUSH_BLOCKED;
		}
	}

	SaveEntityPosition( check );

	newRotation.Set( rotation.GetOrigin(), rotation.GetVec(), checkAngle );
	// NOTE:	this code prevents msvc 6.0 & 7.0 from screwing up the above code in
	//			release builds moving less floats than it should
	static float shit = checkAngle;
	#pragma unused(shit)

	newRotation.RotatePoint( rotationPoint );

	// rotate the entity
	physics->Rotate( newRotation );

	// set pusher into final position
	clipModel->Link( gameLocal.clip, clipModel->GetEntity(), clipModel->GetId(), clipModel->GetOrigin(), newAxis );

#ifdef ROTATIONAL_PUSH_DEBUG
	if ( physics->ClipContents( clipModel ) ) {
		if ( !startsolid ) {
			int bah = 1;
		}
	}
#endif

	// if the entity uses actor physics
	if ( physics->IsType( idPhysics_Actor::Type ) ) {

		// rotate the collision model back to axial
		if ( !RotateEntityToAxial( check, rotationPoint ) ) {
			// don't allow rotation if the bbox is no longer axial
			return PUSH_BLOCKED;
		}
	}

#ifdef ROTATIONAL_PUSH_DEBUG
	if ( physics->ClipContents( clipModel ) ) {
		if ( !startsolid ) {
			int bah = 1;
		}
	}
#endif

	// if the entity is an actor using actor physics
	if ( check->IsType( idActor::Type ) && physics->IsType( idPhysics_Actor::Type ) ) {

		// if the entity is standing ontop of the pusher
		if ( physics->IsGroundClipModel( clipModel->GetEntity()->entityNumber, clipModel->GetId() ) ) {
			// rotate actor view
			idActor *actor = static_cast<idActor *>(check);
			idAngles delta = actor->GetDeltaViewAngles();
			delta.yaw += newRotation.ToMat3()[0].ToYaw();
			actor->SetDeltaViewAngles( delta );
		}
	}

	return PUSH_OK;
}
示例#3
0
文件: Push.cpp 项目: albertz/iodoom3
/*
============
idPush::ClipTranslationalPush

  Try to push other entities by translating the given entity.
============
*/
float idPush::ClipTranslationalPush( trace_t &results, idEntity *pusher, const int flags,
										const idVec3 &newOrigin, const idVec3 &translation ) {
	int i, j, numListedEntities;
	idEntity *curPusher, *ent, *entityList[ MAX_GENTITIES ];
	float fraction;
	bool groundContact, blocked = false;
	float totalMass;
	trace_t trace;
	idVec3 realTranslation, partialTranslation;

	totalMass = 0.0f;

	results.fraction = 1.0f;
	results.endpos = newOrigin;
	results.endAxis = pusher->GetPhysics()->GetAxis();
	memset( results.c, 0, sizeof( results.c ) );

	if ( translation == vec3_origin ) {
		return totalMass;
	}

	// clip against all non-pushable physics objects
	if ( flags & PUSHFL_CLIP ) {

		numListedEntities = GetPushableEntitiesForTranslation( pusher, pusher, flags, translation, entityList, MAX_GENTITIES );
		// disable pushable entities for collision detection
		for ( i = 0; i < numListedEntities; i++ ) {
			entityList[i]->GetPhysics()->DisableClip();
		}
		// clip translation
		pusher->GetPhysics()->ClipTranslation( results, translation, NULL );
		// enable pushable entities
		for ( i = 0; i < numListedEntities; i++ ) {
			entityList[i]->GetPhysics()->EnableClip();
		}
		if ( results.fraction == 0.0f ) {
			return totalMass;
		}
		realTranslation = results.fraction * translation;
	}
	else {
		realTranslation = translation;
	}

	// put the pusher in the group of pushed physics objects
	pushedGroup[0].ent = pusher;
	pushedGroup[0].fraction = 1.0f;
	pushedGroup[0].groundContact = true;
	pushedGroup[0].test = true;
	pushedGroupSize = 1;

	// get all physics objects that need to be pushed
	for ( i = 0; i < pushedGroupSize; ) {
		if ( !pushedGroup[i].test ) {
			i++;
			continue;
		}
		pushedGroup[i].test = false;
		curPusher = pushedGroup[i].ent;
		fraction = pushedGroup[i].fraction;
		groundContact = pushedGroup[i].groundContact;
		i = 0;

		numListedEntities = GetPushableEntitiesForTranslation( curPusher, pusher, flags, realTranslation, entityList, MAX_GENTITIES );

		for ( j = 0; j < numListedEntities; j++ ) {
			ent = entityList[ j ];

			if ( IsFullyPushed( ent ) ) {
				continue;
			}

			if ( !CanPushEntity( ent, curPusher, pusher, flags ) ) {
				continue;
			}

			if ( ent->GetPhysics()->IsGroundEntity( curPusher->entityNumber ) ) {
				AddEntityToPushedGroup( ent, 1.0f * fraction, false );
			}
			else if ( ClipTranslationAgainstPusher( trace, ent, curPusher, -fraction * realTranslation ) ) {
				AddEntityToPushedGroup( ent, ( 1.0f - trace.fraction ) * fraction, groundContact );
			}
		}
	}

	// save physics states and disable physics objects for collision detection
	for ( i = 0; i < pushedGroupSize; i++ ) {
		SaveEntityPosition( pushedGroup[i].ent );
		pushedGroup[i].ent->GetPhysics()->DisableClip();
	}

	// clip all pushed physics objects
	for ( i = 1; i < pushedGroupSize; i++ ) {
		partialTranslation = realTranslation * pushedGroup[i].fraction;

		pushedGroup[i].ent->GetPhysics()->ClipTranslation( trace, partialTranslation, NULL );

		if ( trace.fraction < 1.0f ) {
			blocked = true;
			break;
		}
	}

	// enable all physics objects for collision detection
	for ( i = 1; i < pushedGroupSize; i++ ) {
		pushedGroup[i].ent->GetPhysics()->EnableClip();
	}

	// push all or nothing
	if ( blocked ) {
		if ( flags & PUSHFL_CLIP ) {
			pusher->GetPhysics()->ClipTranslation( results, realTranslation, NULL );
		}
		else {
			results.fraction = 0.0f;
			results.endpos = pusher->GetPhysics()->GetOrigin();
			results.endAxis = pusher->GetPhysics()->GetAxis();
		}
	}
	else {
		// translate all pushed physics objects
		for ( i = 1; i < pushedGroupSize; i++ ) {
			partialTranslation = realTranslation * pushedGroup[i].fraction;
			pushedGroup[i].ent->GetPhysics()->Translate( partialTranslation );
			totalMass += pushedGroup[i].ent->GetPhysics()->GetMass();
		}
		// translate the clip models of the pusher
		for ( i = 0; i < pusher->GetPhysics()->GetNumClipModels(); i++ ) {
			pusher->GetPhysics()->GetClipModel(i)->Translate( results.fraction * realTranslation );
			pusher->GetPhysics()->GetClipModel(i)->Link( gameLocal.clip );
		}
	}

	return totalMass;
}
示例#4
0
文件: Push.cpp 项目: albertz/iodoom3
/*
============
idPush::ClipRotationalPush

  Try to push other entities by rotating the given entity.
============
*/
float idPush::ClipRotationalPush( trace_t &results, idEntity *pusher, const int flags,
									const idMat3 &newAxis, const idRotation &rotation ) {
	int i, j, numListedEntities;
	idEntity *curPusher, *ent, *entityList[ MAX_GENTITIES ];
	float fraction;
	bool groundContact, blocked = false;
	float totalMass;
	trace_t trace;
	idRotation realRotation, partialRotation;
	idMat3 oldAxis;

	totalMass = 0.0f;

	results.fraction = 1.0f;
	results.endpos = pusher->GetPhysics()->GetOrigin();
	results.endAxis = newAxis;
	memset( results.c, 0, sizeof( results.c ) );

	if ( !rotation.GetAngle() ) {
		return totalMass;
	}

	// clip against all non-pushable physics objects
	if ( flags & PUSHFL_CLIP ) {

		numListedEntities = GetPushableEntitiesForRotation( pusher, pusher, flags, rotation, entityList, MAX_GENTITIES );
		// disable pushable entities for collision detection
		for ( i = 0; i < numListedEntities; i++ ) {
			entityList[i]->GetPhysics()->DisableClip();
		}
		// clip rotation
		pusher->GetPhysics()->ClipRotation( results, rotation, NULL );
		// enable pushable entities
		for ( i = 0; i < numListedEntities; i++ ) {
			entityList[i]->GetPhysics()->EnableClip();
		}
		if ( results.fraction == 0.0f ) {
			return totalMass;
		}
		realRotation = results.fraction * rotation;
	}
	else {
		realRotation = rotation;
	}

	// put the pusher in the group of pushed physics objects
	pushedGroup[0].ent = pusher;
	pushedGroup[0].fraction = 1.0f;
	pushedGroup[0].groundContact = true;
	pushedGroup[0].test = true;
	pushedGroupSize = 1;

	// get all physics objects that need to be pushed
	for ( i = 0; i < pushedGroupSize; ) {
		if ( !pushedGroup[i].test ) {
			i++;
			continue;
		}
		pushedGroup[i].test = false;
		curPusher = pushedGroup[i].ent;
		fraction = pushedGroup[i].fraction;
		groundContact = pushedGroup[i].groundContact;
		i = 0;

		numListedEntities = GetPushableEntitiesForRotation( curPusher, pusher, flags, realRotation, entityList, MAX_GENTITIES );

		for ( j = 0; j < numListedEntities; j++ ) {
			ent = entityList[ j ];

			if ( IsFullyPushed( ent ) ) {
				continue;
			}

			if ( ent->GetPhysics()->IsGroundEntity( curPusher->entityNumber ) ) {
				AddEntityToPushedGroup( ent, 1.0f * fraction, false );
			}
			else if ( ClipRotationAgainstPusher( trace, ent, curPusher, -fraction * realRotation ) ) {
				AddEntityToPushedGroup( ent, ( 1.0f - trace.fraction ) * fraction, groundContact );
			}
		}
	}

	// save physics states and disable physics objects for collision detection
	for ( i = 1; i < pushedGroupSize; i++ ) {
		SaveEntityPosition( pushedGroup[i].ent );
		pushedGroup[i].ent->GetPhysics()->DisableClip();
	}

	// clip all pushed physics objects
	for ( i = 1; i < pushedGroupSize; i++ ) {
		partialRotation = realRotation * pushedGroup[i].fraction;

		pushedGroup[i].ent->GetPhysics()->ClipRotation( trace, partialRotation, NULL );

		if ( trace.fraction < 1.0f ) {
			blocked = true;
			break;
		}
	}

	// enable all physics objects for collision detection
	for ( i = 1; i < pushedGroupSize; i++ ) {
		pushedGroup[i].ent->GetPhysics()->EnableClip();
	}

	// push all or nothing
	if ( blocked ) {
		if ( flags & PUSHFL_CLIP ) {
			pusher->GetPhysics()->ClipRotation( results, realRotation, NULL );
		}
		else {
			results.fraction = 0.0f;
			results.endpos = pusher->GetPhysics()->GetOrigin();
			results.endAxis = pusher->GetPhysics()->GetAxis();
		}
	}
	else {
		// rotate all pushed physics objects
		for ( i = 1; i < pushedGroupSize; i++ ) {
			partialRotation = realRotation * pushedGroup[i].fraction;
			pushedGroup[i].ent->GetPhysics()->Rotate( partialRotation );
			totalMass += pushedGroup[i].ent->GetPhysics()->GetMass();
		}
		// rotate the clip models of the pusher
		for ( i = 0; i < pusher->GetPhysics()->GetNumClipModels(); i++ ) {
			pusher->GetPhysics()->GetClipModel(i)->Rotate( realRotation );
			pusher->GetPhysics()->GetClipModel(i)->Link( gameLocal.clip );
			pusher->GetPhysics()->GetClipModel(i)->Enable();
		}
		// rotate any actors back to axial
		for ( i = 1; i < pushedGroupSize; i++ ) {
			// if the entity is using actor physics
			if ( pushedGroup[i].ent->GetPhysics()->IsType( idPhysics_Actor::Type ) ) {

				// rotate the collision model back to axial
				if ( !RotateEntityToAxial( pushedGroup[i].ent, pushedGroup[i].ent->GetPhysics()->GetOrigin() ) ) {
					// don't allow rotation if the bbox is no longer axial
					results.fraction = 0.0f;
					results.endpos = pusher->GetPhysics()->GetOrigin();
					results.endAxis = pusher->GetPhysics()->GetAxis();
				}
			}
		}
	}

	return totalMass;
}
示例#5
0
int idPush::TryTranslatePushEntity( trace_t &results, idEntity *check, idClipModel *clipModel, const int flags,
										const idVec3 &newOrigin, const idVec3 &move ) {
	trace_t		trace;
	idVec3		checkMove;
	idVec3		oldOrigin;

	idPhysics* physics = check->GetPhysics();

#ifdef TRANSLATIONAL_PUSH_DEBUG
	bool startsolid = false;
	if ( physics->ClipContents( clipModel ) ) {
		startsolid = true;
	}
#endif

	results.fraction = 1.0f;
	results.endpos = newOrigin;
	results.endAxis = clipModel->GetAxis();
	memset( &results.c, 0, sizeof( results.c ) );

	// always pushed when standing on the pusher
	if ( physics->IsGroundClipModel( clipModel->GetEntity()->entityNumber, clipModel->GetId() ) ) {
		// move the entity colliding with all other entities except the pusher itself

		// grayman #3029 - if this is an AI with attachments, we have to make them
		// temporarily non-solid for the translation check. Though weapons don't
		// impede movement, pauldrons do.

		if ( check->IsType(idAI::Type) )
		{
			idAI* checkAI = static_cast<idAI*>(check);

			checkAI->SaveAttachmentContents();
			checkAI->SetAttachmentContents(0);
			ClipEntityTranslation( trace, check, NULL, clipModel, move );
			checkAI->RestoreAttachmentContents();
		}
		else
		{
			ClipEntityTranslation( trace, check, NULL, clipModel, move );
		}

		// if there is a collision
		if ( trace.fraction < 1.0f ) {
			// vector along which the entity is pushed
			checkMove = move * trace.fraction;
			// test if the entity can stay at it's partly pushed position by moving the entity in reverse only colliding with pusher
			ClipEntityTranslation( results, check, clipModel, NULL, -(move - checkMove) );
			// if there is a collision
			if ( results.fraction < 1.0f ) {

				// FIXME: try to push the blocking entity as well or try to slide along collision plane(s)?

				results.c.normal = -results.c.normal;
				results.c.dist = -results.c.dist;

				// the entity will be crushed between the pusher and some other entity
				return PUSH_BLOCKED;
			}
		}
		else {
			// vector along which the entity is pushed
			checkMove = move;
		}
	}
	else
	{
		// move entity in reverse only colliding with pusher
		ClipEntityTranslation( results, check, clipModel, NULL, -move );
		// if no collision with the pusher then the entity is not pushed by the pusher
		if ( results.fraction >= 1.0f )
		{
			return PUSH_NO;
		}

		
		// greebo: At this point, the pushes knows that the check entity is in the way
		// Normally, the pusher tries to rotate the entity to see if the entity itself 
		// is colliding with anything else, but for players, we want to (optionally) skip that.
		if ((flags & PUSHFL_NOPLAYER) && check->IsType(idPlayer::Type)) 
		{
			// We are colliding with a player and are not allowed to push it, return BLOCKED
			results.c.normal = -results.c.normal;
			results.c.dist = -results.c.dist;

			return PUSH_BLOCKED;
		}

		// vector along which the entity is pushed
		checkMove = move * (1.0f - results.fraction);
		// move the entity colliding with all other entities except the pusher itself
		ClipEntityTranslation( trace, check, NULL, clipModel, checkMove );
		// if there is a collisions
		if ( trace.fraction < 1.0f ) {

			results.c.normal = -results.c.normal;
			results.c.dist = -results.c.dist;

			// FIXME: try to push the blocking entity as well ?
			// FIXME: handle sliding along more than one collision plane ?
			// FIXME: this code has issues, player pushing box into corner in "maps/mre/aaron/test.map"

/*
			oldOrigin = physics->GetOrigin();

			// movement still remaining
			checkMove *= (1.0f - trace.fraction);

			// project the movement along the collision plane
			if ( !checkMove.ProjectAlongPlane( trace.c.normal, 0.1f, 1.001f ) ) {
				return PUSH_BLOCKED;
			}
			checkMove *= 1.001f;

			// move entity from collision point along the collision plane
			physics->SetOrigin( trace.endpos );
			ClipEntityTranslation( trace, check, NULL, NULL, checkMove );

			if ( trace.fraction < 1.0f ) {
				physics->SetOrigin( oldOrigin );
				return PUSH_BLOCKED;
			}

			checkMove = trace.endpos - oldOrigin;

			// move entity in reverse only colliding with pusher
			physics->SetOrigin( trace.endpos );
			ClipEntityTranslation( trace, check, clipModel, NULL, -move );

			physics->SetOrigin( oldOrigin );
*/
			if ( trace.fraction < 1.0f ) {
				return PUSH_BLOCKED;
			}
		}
	}

	SaveEntityPosition( check );

	// translate the entity
	physics->Translate( checkMove );

#ifdef TRANSLATIONAL_PUSH_DEBUG
	// set the pusher in the translated position
	clipModel->Link( gameLocal.clip, clipModel->GetEntity(), clipModel->GetId(), newOrigin, clipModel->GetAxis() );
	if ( physics->ClipContents( clipModel ) ) {
		if ( !startsolid ) {
			int bah = 1;
		}
	}
#endif

	return PUSH_OK;
}