/// Update shader params loaders for the entity.
/// Shader params loaders are shared by entities, and need to be updated every time an entity is rendered.
void UpdateEntityForRendering( CCopyEntity& entity )
{
	BaseEntity& base_entity = *(entity.pBaseEntity);

	// light params writer
	if( entity.GetEntityFlags() & BETYPE_LIGHTING )
	{
		UpdateLightInfo( entity );

		if( base_entity.MeshProperty().m_pShaderLightParamsLoader )
		{
			// Set the entity to the light params loader, because a single light params loader
			// is shared by all the entities of this base entity.
			base_entity.MeshProperty().m_pShaderLightParamsLoader->SetEntity( entity.Self().lock() );
		}
	}

	const float offset_world_transform_threshold = 150000.0f;
	if( square(offset_world_transform_threshold) < Vec3LengthSq(entity.GetWorldPose().vPosition) )
	{
		Camera* pCam = entity.GetStage()->GetCurrentCamera();
		if( pCam )
		{
			sg_pWorldTransLoader->SetActive( true );
			sg_pWorldTransLoader->SetCameraPosition( pCam->GetPosition() );
		}
		else
			sg_pWorldTransLoader->SetActive( false );

	}
	else
		sg_pWorldTransLoader->SetActive( false );
}
/// Perhaps this should be a member of CCopyEntity, not BaseEntity
/// - m_pStage is the only member of the base entity
/// - CCopyEnttiy has m_pStage
void BaseEntity::SetAsEnvMapTarget( CCopyEntity& entity )
{
	if( entity.GetEntityFlags() & BETYPE_ENVMAPTARGET )
	{
//		shared_ptr<CubeTextureParamsLoader> pCubeTexLoader( new CCubeTextureParamsLoader() );
//		pCubeTexLoader->SetCubeTexture( 0, m_pStage->GetEntitySet()->GetRenderManager()->GetEnvMapTexture(entity.GetID()) );

//		entity.m_pMeshRenderMethod->AddShaderParamsLoaderToAllRenderMethods( pCubeTexLoader );

/*
		if( 0 < entity.m_pMeshRenderMethod->MeshRenderMethod().size() )
		{
			// shader LOD: fixed to 0
			entity.m_pMeshRenderMethod->MeshRenderMethod(0).m_vecpShaderParamsLoader.push_back( pCubeTexLoader );
		}
		else
		{
			// alpha entity?
		}*/
	}

}
// sets the following shader params loaders to the render method of an entity
// - CEntityShaderLightParamsLoader
//   - Set if the BETYPE_LIGHTING flag is on
// - BlendTransformsLoader
//   - Set if pEntity->m_MeshHandle is a skeletal mesh
void InitMeshRenderMethod( CCopyEntity &entity, shared_ptr<BlendTransformsLoader> pBlendTransformsLoader )
{
	if( !entity.m_pMeshRenderMethod )
	{
		entity.m_pMeshRenderMethod.reset( new MeshContainerRenderMethod );
//		entity.m_pMeshRenderMethod->MeshRenderMethod().resize( 1 );
	}

	if( entity.GetEntityFlags() & BETYPE_LIGHTING )
	{
		shared_ptr<CEntityShaderLightParamsLoader> pLightParamsLoader( new CEntityShaderLightParamsLoader() );
		pLightParamsLoader->SetEntity( entity.Self() );
		entity.m_pMeshRenderMethod->SetShaderParamsLoaderToAllMeshRenderMethods( pLightParamsLoader );
	}

	// Not used now.
	// Item entities set this in its own member function ItemEntity::InitMesh().
	// Does any entity other than item entty need this?
	if( pBlendTransformsLoader )
		entity.m_pMeshRenderMethod->SetShaderParamsLoaderToAllMeshRenderMethods( pBlendTransformsLoader );
/*
	shared_ptr<BasicMesh> pMesh = entity.m_MeshHandle.GetMesh();
	if( pMesh && pMesh->GetMeshType() == MeshType::SKELETAL )
	{
//		shared_ptr<SkeletalMesh> pSkeletalMesh
//			= boost::dynamic_pointer_cast<SkeletalMesh,BasicMesh>(pMesh);

		if( !pBlendTransformsLoader )
			pBlendTransformsLoader.reset( new BlendTransformsLoader() );

		entity.m_pMeshRenderMethod->SetShaderParamsLoaderToAllMeshRenderMethods( pBlendTransformsLoader );
	}*/

	if( true /* world position of entity has large values */ )
	{
		entity.m_pMeshRenderMethod->SetShaderParamsLoaderToAllMeshRenderMethods( sg_pWorldTransLoader );
	}
}
Exemple #4
0
void EntityManager::UpdatePhysics( float frametime )
{
	PROFILE_FUNCTION();

//	frametime *= 0.5f;

	Scalar total_time = frametime + m_PhysOverlapTime;

	if (total_time > 0.1f)
		total_time = 0.1f;

	// split the timestep into fixed size chunks

	int num_loops = (int) (total_time / m_PhysTimestep);
	Scalar timestep = m_PhysTimestep;

	if ( false /*m_allow_smaller_timesteps*/ )
	{
		if (num_loops == 0)
			num_loops = 1;
		timestep = total_time / num_loops;
	}

	m_PhysOverlapTime = total_time - num_loops * timestep;

//	TCPreAllocDynamicLinkList<CJL_PhysicsActor>& rActorList = m_pStage->m_pPhysicsManager->GetActorList();

//	TCPreAllocDynamicLinkList<CJL_PhysicsActor>::LinkListIterator itrActor;

	int i;
	for (i=0 ; i<num_loops ; ++i)
	{
//		m_physics_time += timestep;

		// apply gravity
/*		for( itrActor = rActorList.Begin();
			itrActor != rActorList.End();
			itrActor++ )
		{
			if( !(itrActor->GetActorFlag() & JL_ACTOR_STATIC) )
                itrActor->AddWorldForce( itrActor->GetMass() * Vector3(0,-9.8f,0) );
		}
*/

		ProfileBegin( "Entity Update (Physics)" );

		// update physics properties that are specific to each entity
		// DO NOT CONFUSE THIS WITH CCopyEntity::UpdatePhysics()
		CCopyEntity *pEntity;
		for( pEntity = m_pEntityInUse.get();
			 pEntity != NULL;
			 pEntity = pEntity->m_pNextRawPtr )
		{
			if( pEntity->GetEntityFlags() & BETYPE_COPY_PARENT_POSE )
				pEntity->CopyParentPose();

//			if( pEntity->inuse && pEntity->pPhysicsActor )
			if( pEntity->inuse && 0 < pEntity->m_vecpPhysicsActor.size() )
                pEntity->pBaseEntity->UpdatePhysics( pEntity, timestep );

			UpdateEntityAfterMoving( pEntity );

		}

		ProfileEnd( "Entity Update (Physics)" );


		{
			PROFILE_SCOPE( "Physics Simulation" );

			// handle the motions and collisions of rigid body entities
//			m_pStage->m_pPhysicsManager->Integrate( timestep );
			m_pStage->GetPhysicsScene()->Simulate( timestep );

			while( !m_pStage->GetPhysicsScene()->FetchResults( physics::SimulationStatus::RigidBodyFinished ) )
			{}
		}

		// clear forces on actors
/*		for( itrActor = rActorList.Begin();
			itrActor != rActorList.End();
			itrActor++ )
		{
			itrActor->ClearForces();
		}
*/
	}
}
Exemple #5
0
void EntityManager::InitEntity( boost::shared_ptr<CCopyEntity> pNewCopyEntPtr,
							 CCopyEntity *pParent,
							 BaseEntity *pBaseEntity,
							 CActorDesc* pPhysActorDesc )
{
	CCopyEntity* pNewCopyEnt = pNewCopyEntPtr.get();

	// Mark the entity as in use
	pNewCopyEnt->inuse = true;

	pNewCopyEnt->m_pSelf = pNewCopyEntPtr;

	pNewCopyEnt->pBaseEntity = pBaseEntity;
	BaseEntity& rBaseEntity = (*pBaseEntity);

	pNewCopyEnt->m_pStage = m_pStage;

	// set id and increment the counter
	pNewCopyEnt->m_ID = m_EntityIDConter++;

	// z-sort is disabled by default initialization
	// Entities that have translucent polygons have to turn on their copy entities'
	// 'BETYPE_USE_ZSORT' in InitCopyEntity()
	if( pNewCopyEnt->m_TypeID == CCopyEntityTypeID::ALPHA_ENTITY )
	{
		// For alpha entity, always use the  z-sorting
		pNewCopyEnt->RaiseEntityFlags( BETYPE_USE_ZSORT );
	}
	else
	{
		// Otherwise, disable z-sorting by default
		pNewCopyEnt->ClearEntityFlags( BETYPE_USE_ZSORT );
	}

	// set the glare type
	if( rBaseEntity.m_EntityFlag & BETYPE_GLARESOURCE )
	{
		pNewCopyEnt->RaiseEntityFlags( BETYPE_GLARESOURCE );
	}
	else if( rBaseEntity.m_EntityFlag & BETYPE_GLAREHINDER )
	{
		pNewCopyEnt->RaiseEntityFlags( BETYPE_GLAREHINDER );
	}

	// update world aabb
	pNewCopyEnt->world_aabb.TransformCoord( pNewCopyEnt->local_aabb, pNewCopyEnt->GetWorldPosition() );


	// link the new copy-entity to the top of 'm_pEntityInUse'
	if( m_pEntityInUse )
		pNewCopyEnt->SetNext( m_pEntityInUse );
	else
		pNewCopyEnt->SetNextToNull(); // first entity in the link list

	m_pEntityInUse = pNewCopyEntPtr;


	// set the created time of the entity
	pNewCopyEnt->m_CreatedTime = m_pStage->GetElapsedTime();

	// set parent entity
	pNewCopyEnt->m_pParent = pParent;
	if( pNewCopyEnt->m_pParent )
	{
		// 'pNewCopyEnt' is being created as a child of another copy entity
		pNewCopyEnt->m_pParent->AddChild( pNewCopyEnt->m_pSelf );	// establish link from the parent to this entity
	}

//	LOG_PRINT( "linking a copy entity of " + rBaseEntity.GetNameString() + " to the tree" );

	// link the new copy-entity to the entity-tree
	Link( pNewCopyEnt );

	// update light information
	if( pNewCopyEnt->Lighting() )
	{
		pNewCopyEnt->ClearLights();
//		UpdateLightInfo( pNewCopyEnt );

		pNewCopyEnt->sState |= CESTATE_LIGHT_INFORMATION_INVALID;
	}

	// create object for physics simulation
	if( pNewCopyEnt->GetEntityFlags() & BETYPE_RIGIDBODY )
	{
		CActor *pPhysActor = NULL;
		if( pPhysActorDesc )
		{
			pPhysActorDesc->WorldPose = pNewCopyEnt->GetWorldPose();// * pNewCopyEnt->GetActorLocalPose();
			pPhysActorDesc->BodyDesc.LinearVelocity = pNewCopyEnt->Velocity();

			// each entity has its own actor desc
			pPhysActor = m_pStage->GetPhysicsScene()->CreateActor( *pPhysActorDesc );
		}
		else if( pBaseEntity->GetPhysicsActorDesc().IsValid() )
		{
			// actor desc is defined by entity attributes
			CActorDesc actor_desc = pBaseEntity->GetPhysicsActorDesc();
			actor_desc.WorldPose = pNewCopyEnt->GetWorldPose();
			actor_desc.BodyDesc.LinearVelocity = pNewCopyEnt->Velocity();
//			pNewCopyEnt->pPhysicsActor = m_pStage->GetPhysicsScene()->CreateActor( actor_desc );
			pPhysActor = m_pStage->GetPhysicsScene()->CreateActor( actor_desc );
		}

		if( pPhysActor )
		{
			pNewCopyEnt->m_vecpPhysicsActor.resize( 1 );
			pNewCopyEnt->m_vecpPhysicsActor[0] = pPhysActor;
			pPhysActor->m_pFrameworkData = pNewCopyEnt;
		}
	}

	// When all the basic properties are copied, InitCopyEntity() is called to 
	// do additional initialization specific to each base entity.
	rBaseEntity.InitCopyEntity( pNewCopyEnt );
}
Exemple #6
0
/**
 Update all the entities cerrently existing in the stage.
 This function must be called once per frame.
 - Basic steps
   - 1. Call BaseEntity::UpdateBaseEntity( dt ) for each base entity
   - 2. Save positions of copy entities
   - 3. Run physics simulator
   - 4. Remove terminated entities from the active list
   - 5. Call CCopyEntity::Act() for each copy entity except for child entities
   - 6. Update link to the entity tree node if an entity has changed its position in Act()
   TODO: Do 5 & 6 in a single loop to update link for each entity right after is Act().
         Current code does this in separate loops.
 */
void EntityManager::UpdateAllEntities( float dt )
{
	CCopyEntity *pEntity = NULL;
	CCopyEntity *pPrevEntity = NULL;
	CCopyEntity *pTouchedEnt = NULL;

	ONCE( LOG_PRINT( " - updating base entities" ) );

	size_t i, num_base_entities = m_vecpBaseEntity.size();
	for( i=0; i<num_base_entities; i++ )
	{
		m_vecpBaseEntity[i]->UpdateBaseEntity( dt );
	}

	// save the current entity positions
	for( pEntity = m_pEntityInUse.get();
	     pEntity != NULL;
	     pEntity = pEntity->m_pNextRawPtr )
	{
		pEntity->PrevPosition() = pEntity->GetWorldPosition();
	}

	// run physics simulator
	// entity position may be modified in this call
	UpdatePhysics( dt );

	ONCE( LOG_PRINT( " - updated physics" ) );

	// remove terminated entities from the active entity list
	ReleaseTerminatedEntities();

	ONCE( LOG_PRINT( " - removed terminated entities from the active entity list" ) );

	// update active entities
	for( pEntity = this->m_pEntityInUse.get(), pPrevEntity = NULL;
		 pEntity != NULL;
		 pPrevEntity = pEntity, pEntity = pEntity->m_pNextRawPtr )
	{
		// before updating pEntity, check if it has been terminated.
		if( !pEntity->inuse )
			continue;

		// set the results of physics simulation to
		// pose, velocity and angular velocity of the entity
//		if( pEntity->pPhysicsActor && pEntity->GetEntityFlags() & BETYPE_USE_PHYSSIM_RESULTS )
		if( 0 < pEntity->m_vecpPhysicsActor.size() && pEntity->GetEntityFlags() & BETYPE_USE_PHYSSIM_RESULTS )
			pEntity->UpdatePhysics();

		if( pEntity->sState & CESTATE_ATREST )
			continue;

		if( !pEntity->m_pParent || !pEntity->m_pParent->inuse )
		{
			// 'pEntity' has no parent or its parent is already terminated
			pEntity->pBaseEntity->Act( pEntity );
		}

		if( !pEntity->inuse )
			continue; // terminated in its own update routine

		UpdateEntityAfterMoving( pEntity );

		// deal with entities touched during this frame
		for(int i=0; i<pEntity->vecpTouchedEntity.size(); i++)
		{
			pTouchedEnt = pEntity->vecpTouchedEntity[i];
			pEntity->pBaseEntity->Touch( pEntity, pTouchedEnt );

			if( pTouchedEnt )
				pTouchedEnt->pBaseEntity->Touch( pTouchedEnt, pEntity );
		}

		// clear touched entities for the next frame
		pEntity->vecpTouchedEntity.clear();
	}

	ONCE( LOG_PRINT( " - updated active entities" ) );

	// unlink and link the entity in the entity tree if it changed its position
/*
	for( pEntity = m_pEntityInUse.get();
		 pEntity != NULL;
		 pPrevEntity = pEntity, pEntity = pEntity->m_pNextRawPtr )
	{
		if( !pEntity->inuse )
			continue;

		UpdateEntityAfterMoving();
	}
*/
}