/*
================
idBrittleFracture::Think
================
*/
void idBrittleFracture::Think( void ) {
	int i, startTime, endTime, droppedTime;
	shard_t *shard;
	bool atRest = true, fading = false;
	// remove overdue shards
	for( i = 0; i < shards.Num(); i++ ) {
		droppedTime = shards[i]->droppedTime;
		if( droppedTime != -1 ) {
			if( gameLocal.time - droppedTime > SHARD_ALIVE_TIME ) {
				RemoveShard( i );
				i--;
			}
			fading = true;
		}
	}
	// remove the entity when nothing is visible
	if( !shards.Num() ) {
		PostEventMS( &EV_Remove, 0 );
		return;
	}
	if( thinkFlags & TH_PHYSICS ) {
		startTime = gameLocal.previousTime;
		endTime = gameLocal.time;
		// run physics on shards
		for( i = 0; i < shards.Num(); i++ ) {
			shard = shards[i];
			if( shard->droppedTime == -1 ) {
				continue;
			}
			shard->physicsObj.Evaluate( endTime - startTime, endTime );
			if( !shard->physicsObj.IsAtRest() ) {
				atRest = false;
			}
		}
		if( atRest ) {
			BecomeInactive( TH_PHYSICS );
		} else {
			BecomeActive( TH_PHYSICS );
		}
	}
	if( !atRest || bounds.IsCleared() ) {
		bounds.Clear();
		for( i = 0; i < shards.Num(); i++ ) {
			bounds.AddBounds( shards[i]->clipModel->GetAbsBounds() );
		}
	}
	if( fading ) {
		BecomeActive( TH_UPDATEVISUALS | TH_THINK );
	} else {
		BecomeInactive( TH_THINK );
	}
	RunPhysics();
	Present();
}
Пример #2
0
/*
================
idBrittleFracture::Restore
================
*/
void idBrittleFracture::Restore( idRestoreGame* savefile )
{

	savefile->ReadInt( health );
	savefile->Read( &fl, sizeof( fl ) );
	LittleBitField( &fl, sizeof( fl ) );
	
	// setttings
	savefile->ReadMaterial( material );
	savefile->ReadMaterial( decalMaterial );
	savefile->ReadFloat( decalSize );
	savefile->ReadFloat( maxShardArea );
	savefile->ReadFloat( maxShatterRadius );
	savefile->ReadFloat( minShatterRadius );
	savefile->ReadFloat( linearVelocityScale );
	savefile->ReadFloat( angularVelocityScale );
	savefile->ReadFloat( shardMass );
	savefile->ReadFloat( density );
	savefile->ReadFloat( friction );
	savefile->ReadFloat( bouncyness );
	savefile->ReadString( fxFracture );
	
	// state
	savefile->ReadBounds( bounds );
	savefile->ReadBool( disableFracture );
	
	savefile->ReadInt( lastRenderEntityUpdate );
	savefile->ReadBool( changed );
	
	savefile->ReadModel( defaultRenderModel );
	
	// Reset all brittle Fractures so we can re-break them if necessary
	fl.takedamage = true;
	CreateFractures( defaultRenderModel );
	FindNeighbours();
	
	int numEvents = 0;
	bool resolveBreaks = false;
	savefile->ReadInt( numEvents );
	for( int i = 0; i < numEvents; i++ )
	{
		fractureEvent_s restoredEvent;
		
		savefile->ReadInt( restoredEvent.eventType );
		savefile->ReadVec3( restoredEvent.point );
		savefile->ReadVec3( restoredEvent.vector );
		
		if( restoredEvent.eventType == EVENT_PROJECT_DECAL )
		{
			ProjectDecal( restoredEvent.point, restoredEvent.vector, gameLocal.time, NULL );
		}
		else
		{
			Shatter( restoredEvent.point, restoredEvent.vector, gameLocal.time );
		}
		resolveBreaks = true;
	}
	
	// remove any dropped shards
	for( int i = 0; resolveBreaks && i < shards.Num(); i++ )
	{
		if( shards[i]->droppedTime != -1 )
		{
			RemoveShard( i );
			i--;
		}
	}
	
	renderEntity.hModel = renderModelManager->AllocModel();
	renderEntity.hModel->InitEmpty( brittleFracture_SnapshotName );
	renderEntity.callback = idBrittleFracture::ModelCallback;
	renderEntity.noShadow = true;
	renderEntity.noSelfShadow = true;
	renderEntity.noDynamicInteractions = false;
	
	savefile->ReadBool( isXraySurface );
}