Result::Name RegisterAsPlanarMirror( CCopyEntity& entity, BasicMesh& mesh, int subset_index )
{
	const AABB3& aabb = mesh.GetAABB(subset_index);

	EntityRenderManager& entity_render_mgr
		= *(entity.GetStage()->GetEntitySet()->GetRenderManager());

	// >>> TODO: support planes that are not axis-aligned or facing along the negative half-space
	SPlane plane;
	int plane_axis = 1;
	if(      aabb.vMax.x - aabb.vMin.x < 0.001f ) plane_axis = 0;
	else if( aabb.vMax.y - aabb.vMin.y < 0.001f ) plane_axis = 1;
	else if( aabb.vMax.z - aabb.vMin.z < 0.001f ) plane_axis = 2;
	else plane_axis = 1;

	plane.normal = Vector3(0,0,0);
	plane.normal[plane_axis] = 1;
	plane.dist = aabb.vMax[plane_axis];

	Result::Name res = entity_render_mgr.AddPlanarReflector( EntityHandle<>( entity.Self() ), plane );

	if( res != Result::SUCCESS )
		return Result::UNKNOWN_ERROR;

	entity.RaiseEntityFlags( BETYPE_PLANAR_REFLECTOR );

	// Create shader variable loader for mirror 

	if( !entity.m_pMeshRenderMethod )
	{
		if( entity.pBaseEntity->MeshProperty().m_pMeshRenderMethod )
		{
			entity.m_pMeshRenderMethod
				= entity.pBaseEntity->MeshProperty().m_pMeshRenderMethod->CreateCopy();

			if( !entity.m_pMeshRenderMethod )
				return Result::UNKNOWN_ERROR;
		}
		else
			return Result::UNKNOWN_ERROR;
	}

	// create a planar reflection entity
//	shared_ptr<MeshContainerRenderMethod> pMeshRenderMethodCopy
//		= entity.m_pMeshRenderMethod->CreateCopy();

	shared_ptr<MirroredSceneTextureParam> pTexParam;
	pTexParam.reset( new MirroredSceneTextureParam( EntityHandle<>( entity.Self() ) ) );
	pTexParam->m_fReflection = mesh.GetMaterial(subset_index).m_Mat.fReflection;
//	pMeshRenderMethodCopy->SetShaderParamsLoaderToAllMeshRenderMethods( pTexParam );

	// test - we assume that the entity's mesh is composed of polygons that belong to a single plane.
	entity.m_pMeshRenderMethod->SetShaderParamsLoaderToAllMeshRenderMethods( pTexParam );

	// Move the indices of the planar reflection subset(s)
	// to the render method of the planar reflection entity

	return Result::SUCCESS;
}
Exemple #2
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 );
}