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); } } } }
/** 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() ); }