/// 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 ); }
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; }
void UpdateLightInfo( CCopyEntity& entity ) { if( entity.Lighting() ) { if( entity.sState & CESTATE_LIGHT_INFORMATION_INVALID ) { // need to update light information - find lights that reaches to this entity entity.ClearLights(); entity.GetStage()->GetEntitySet()->UpdateLights( &entity ); entity.sState &= ~CESTATE_LIGHT_INFORMATION_INVALID; } } }