void MeshRenderSystem::processEntities( const vector<Entity*>& p_entities )
{
	ClientStateSystem* stateSystem = static_cast<ClientStateSystem*>(m_world->getSystem(SystemType::ClientStateSystem));

	/*
	if (stateSystem->getCurrentState() == GameStates::INGAME)
	{
		timeInGame += m_world->getDelta();
		if (timeInGame < 2.0f)
			return;
	}
	*/

	// Cleanup
	for(unsigned int i=0; i<m_instanceLists.size(); i++ ){
		m_instanceLists[i].clear();
	}
	for(unsigned int i=0; i<m_instanceListsTess.size(); i++ ){
		m_instanceListsTess[i].clear();
	}

	for(unsigned int i=0; i<m_boneMatrices.size(); i++ ){
		m_boneMatrices[i].clear();
	}

//	DEBUGPRINT(( ("\nEntities rendered: "+toString(p_entities.size())).c_str() ));
	//NOTE: continues in loop below 
	for( unsigned int i=0; i<p_entities.size(); i++ )
	{
		RenderInfo* renderInfo = getRenderInfo(p_entities[i]);

		// Don't render instances that hasn't got a mesh...
		// NOTE: (Johan) ...or if it's not supposed to render!
		if(renderInfo->m_meshId == -1 || renderInfo->m_shouldBeRendered == false)
		{
			continue;
		}

		Transform* transform = static_cast<Transform*>(
			p_entities[i]->getComponent( ComponentType::ComponentTypeIdx::Transform ) );

		// Don't render instances that hasn't got a transformation
		if( transform == NULL )
		{
			continue;
		}

		// resize vector if the mesh id is outside of the vectors size
		if( m_instanceLists.size() <= static_cast<unsigned int>(renderInfo->m_meshId) )
		{
			m_instanceLists.resize( renderInfo->m_meshId + 1 );
			m_instanceListsTess.resize(renderInfo->m_meshId + 1);
			m_boneMatrices.resize( renderInfo->m_meshId + 1 );
		}
		
		if (!renderInfo->m_shouldBeRendered)
			continue;

		if (renderInfo->m_shouldBeCulled)
			continue;


		SkeletalAnimation* skelAnim = static_cast<SkeletalAnimation*>
			(p_entities[i]->getComponent(ComponentType::SkeletalAnimation));
		AglSkeleton* skeleton = NULL;
		unsigned int jointCount = -1;
		if (skelAnim)
		{
			skeleton = skelAnim->m_scene->getSkeleton(0);
			jointCount = skeleton->getHeader().jointCount;
		}

		// Finally, add the entity to the instance vector
		InstanceData instanceData = transform->getInstanceDataRef();
		fillInstanceData(&instanceData,p_entities[i],renderInfo, jointCount);

		if (renderInfo->m_shouldBeTesselated)
			m_instanceListsTess[renderInfo->m_meshId].push_back( instanceData );
		else
			m_instanceLists[renderInfo->m_meshId].push_back( instanceData );

		//Find animation transforms
		if (skelAnim)
		{
			for (unsigned int i = 0; i < jointCount; i++)
			{
				skelAnim->m_scene->setTime(skelAnim->m_time);
				AglMatrix m = skeleton->getInverseBindMatrix(i) * skeleton->getGlobalTransform(i);

				m *= skelAnim->m_offset.inverse();

				m_boneMatrices[renderInfo->m_meshId].push_back(m);
			}
		}
	}
}
示例#2
0
/** Attach the kart model and wheels to the scene node.
 *  \return the node with the model attached
 */
scene::ISceneNode* KartModel::attachModel(bool animated_models, bool always_animated)
{
    assert(!m_is_master);

    scene::ISceneNode* node = NULL;
    m_render_info.setKartModelRenderInfo(m_krt);

    if (animated_models)
    {
        LODNode* lod_node = new LODNode("kart",
                                        irr_driver->getSceneManager()->getRootSceneNode(),
                                        irr_driver->getSceneManager()                    );


        node = irr_driver->addAnimatedMesh(m_mesh, "kartmesh",
               NULL/*parent*/, getRenderInfo());
        // as animated mesh are not cheap to render use frustum box culling
        if (CVS->isGLSL())
            node->setAutomaticCulling(scene::EAC_OFF);
        else
            node->setAutomaticCulling(scene::EAC_FRUSTUM_BOX);

        if (always_animated)
        {
            // give a huge LOD distance for the player's kart. the reason is that it should
            // use its animations for the shadow pass too, where the camera can be quite far
            lod_node->add(10000, node, true);
            scene::ISceneNode* static_model = attachModel(false, false);
            lod_node->add(10001, static_model, true);
            m_animated_node = static_cast<scene::IAnimatedMeshSceneNode*>(node);
        }
        else
        {
            lod_node->add(20, node, true);
            scene::ISceneNode* static_model = attachModel(false, false);
            lod_node->add(100, static_model, true);
            m_animated_node = static_cast<scene::IAnimatedMeshSceneNode*>(node);
        }

        attachHat();

#ifdef DEBUG
        std::string debug_name = m_model_filename+" (animated-kart-model)";
        node->setName(debug_name.c_str());
#if SKELETON_DEBUG
        irr_driver->addDebugMesh(m_animated_node);
#endif
#endif
        m_animated_node->setLoopMode(false);
        m_animated_node->grab();
        node = lod_node;

        // Become the owner of the wheels
        for(unsigned int i=0; i<4; i++)
        {
            if (!m_wheel_model[i] || !m_wheel_node[i]) continue;
            m_wheel_node[i]->setParent(lod_node);
        }

        // Become the owner of the speed weighted objects
        for(size_t i=0; i<m_speed_weighted_objects.size(); i++)
        {
            if(!m_speed_weighted_objects[i].m_node) continue;
            m_speed_weighted_objects[i].m_node->setParent(lod_node);
        }

        // Enable rim lighting for the kart
        irr_driver->applyObjectPassShader(lod_node, true);
        std::vector<scene::ISceneNode*> &lodnodes = lod_node->getAllNodes();
        const u32 max = (u32)lodnodes.size();
        for (u32 i = 0; i < max; i++)
        {
            irr_driver->applyObjectPassShader(lodnodes[i], true);
        }
    }
    else
    {
        // If no animations are shown, make sure to pick the frame
        // with a straight ahead animation (if exist).
        int straight_frame = m_animation_frame[AF_STRAIGHT]>=0
                           ? m_animation_frame[AF_STRAIGHT]
                           : 0;

        scene::IMesh* main_frame = m_mesh->getMesh(straight_frame);
        main_frame->setHardwareMappingHint(scene::EHM_STATIC);

        std::string debug_name;

#ifdef DEBUG
       debug_name = m_model_filename + " (kart-model)";
#endif

        node = irr_driver->addMesh(main_frame, debug_name,
               NULL /*parent*/, getRenderInfo());

#ifdef DEBUG
        node->setName(debug_name.c_str());
#endif


        // Attach the wheels
        for(unsigned int i=0; i<4; i++)
        {
            if(!m_wheel_model[i]) continue;
            m_wheel_node[i] = irr_driver->addMesh(m_wheel_model[i], "wheel",
                              node, getRenderInfo(), true/*all_parts_colorized*/);
            Vec3 wheel_min, wheel_max;
            MeshTools::minMax3D(m_wheel_model[i], &wheel_min, &wheel_max);
            m_wheel_graphics_radius[i] = 0.5f*(wheel_max.getY() - wheel_min.getY());

            m_wheel_node[i]->grab();
            ((scene::IMeshSceneNode *) m_wheel_node[i])->setReadOnlyMaterials(true);
    #ifdef DEBUG
            std::string debug_name = m_wheel_filename[i]+" (wheel)";
            m_wheel_node[i]->setName(debug_name.c_str());
    #endif
            m_wheel_node[i]->setPosition(m_wheel_graphics_position[i].toIrrVector());
        }

        // Attach the speed weighted objects + set the animation state
        for(size_t i=0 ; i < m_speed_weighted_objects.size() ; i++)
        {
            SpeedWeightedObject&    obj = m_speed_weighted_objects[i];
            obj.m_node = NULL;
            if(obj.m_model)
            {
                obj.m_node = irr_driver->addAnimatedMesh(obj.m_model, 
                             "speedweighted", node, getRenderInfo(),
                             true/*all_parts_colorized*/);
                obj.m_node->grab();

                obj.m_node->setFrameLoop(m_animation_frame[AF_SPEED_WEIGHTED_START],
                                         m_animation_frame[AF_SPEED_WEIGHTED_END]);

        #ifdef DEBUG
                std::string debug_name = obj.m_name+" (speed-weighted)";
                obj.m_node->setName(debug_name.c_str());
        #endif
                obj.m_node->setPosition(obj.m_position.toIrrVector());
            }
        }
    }
    return node;
}   // attachModel
void MeshRenderSystem::fillInstanceData(InstanceData* p_data, Entity* p_entity, 
										RenderInfo* p_renderInfo, int p_boneCount){
	MaterialInfo matInfo;

	p_data->setNumberOfActiveBones(p_boneCount);

	// Try and get the gradient component
	auto gradient = static_cast<GradientComponent*>(p_entity->getComponent(
		ComponentType::Gradient));
	if(gradient != NULL){ 

		// Set all the values needed
		matInfo = m_gfxBackend->getGfxWrapper()->getMaterialInfoFromMeshID(
			p_renderInfo->m_meshId);
		matInfo.setGradientLayer(1,gradient->m_color.layerOne);
		matInfo.setGradientLayer(2,gradient->m_color.layerTwo);
		p_data->setNumberOfActiveGradientLayers( matInfo.numberOfLayers );
	}
	// If none was found check why
	else{
		// Assume its a valid Ship Module
		ShipModule* shipModule = static_cast<ShipModule*>(m_world->
			getComponentManager()->getComponent(p_entity,ComponentType::ShipModule));

		if(shipModule != NULL && shipModule->m_parentEntity > -1){
			
			Entity* parentShip = m_world->getEntity(shipModule->m_parentEntity);
			ModuleHelper::FindParentShip(m_world,&parentShip, shipModule);

			if(parentShip != NULL){
				RenderInfo* parentShipRenderInfo = getRenderInfo(parentShip);
				matInfo = m_gfxBackend->getGfxWrapper()->getMaterialInfoFromMeshID(
					parentShipRenderInfo->m_meshId);

				auto gradient = static_cast<GradientComponent*>(parentShip->getComponent(
					ComponentType::Gradient));

				matInfo.setGradientLayer(1,gradient->m_color.layerOne);
				matInfo.setGradientLayer(2,gradient->m_color.layerTwo);
				p_data->setNumberOfActiveGradientLayers( matInfo.numberOfLayers );
			}
		}
		// If not a Ship Module set values to default
		else{
			matInfo.setGradientLayer(1, AglVector4(1,1,1,1));
			matInfo.setGradientLayer(2, AglVector4(1,1,1,1));
			p_data->setNumberOfActiveGradientLayers( 1 );
		}
	}	

	auto colorTone = static_cast<ColorTone*>(p_entity->getComponent(ComponentType::ColorTone));
	if (colorTone && colorTone->toneEnabled)
		p_data->setColorTone(colorTone->color);

	auto glowAnimation = static_cast<GlowAnimation*>(p_entity->getComponent(
		ComponentType::GlowAnimation));
	if(glowAnimation && glowAnimation->enabled)
	{
		p_data->setColorTone(glowAnimation->color);
	}

	//neg-x creates additive blending
	//neg-y replaces color entirely

	if (p_entity->getComponent(ComponentType::SelectionMarker))
		p_data->setColorTone(AglVector4(-0.6f, 0.8f, 0.2f, 1)); ///< neg-sign on y for total color replacement
	else if (p_entity->getComponent(ComponentType::TAG_Highlight))
		p_data->setColorTone(AglVector4(0.5f, 1, 1, 1));


	ShipHighlight* highlight = static_cast<ShipHighlight*>(p_entity->getComponent(ComponentType::ShipHighlight));
	if (highlight && highlight->active)
		p_data->setColorTone(highlight->color);

	ShineSpawn* shineSpawn = static_cast<ShineSpawn*>(p_entity->getComponent(ComponentType::ShineSpawn));
	if (shineSpawn)
	{
		float age = m_world->getElapsedTime()-shineSpawn->m_createdAt;
		if (age < shineSpawn->m_lifetime)
			p_data->setColorTone(AglVector4(-1, 1, 1, 1) * ((shineSpawn->m_lifetime-age) / shineSpawn->m_lifetime));
	}

	p_data->setGradientColor( matInfo.getGradientColors() );
}