NavLights::NavLights(SceneGraph::Model *model, float period) : m_time(0.f) , m_period(period) , m_enabled(false) { PROFILE_SCOPED(); assert(g_initted); Graphics::Renderer *renderer = model->GetRenderer(); using SceneGraph::Node; using SceneGraph::MatrixTransform; using SceneGraph::Billboard; //This will find all matrix transforms meant for navlights. SceneGraph::FindNodeVisitor lightFinder(SceneGraph::FindNodeVisitor::MATCH_NAME_STARTSWITH, "navlight_"); model->GetRoot()->Accept(lightFinder); const std::vector<Node*> &results = lightFinder.GetResults(); //attach light billboards for (unsigned int i=0; i < results.size(); i++) { MatrixTransform *mt = dynamic_cast<MatrixTransform*>(results.at(i)); assert(mt); Billboard *bblight = new Billboard(model, renderer, BILLBOARD_SIZE); Uint32 group = 0; Uint8 mask = 0xff; //always on Uint8 color = NAVLIGHT_BLUE; if (mt->GetName().substr(9, 3) == "red") { mask = 0x0f; color = NAVLIGHT_RED; } else if (mt->GetName().substr(9, 5) == "green") { mask = 0xf0; color = NAVLIGHT_GREEN; } else if (mt->GetName().substr(9, 3) == "pad") { //group by pad number // due to this problem: http://stackoverflow.com/questions/15825254/why-is-scanfhhu-char-overwriting-other-variables-when-they-are-local // where MSVC is still using a C89 compiler the format identifer %hhu is not recognised. Therefore I've switched to Uint32 for group. PiVerify(1 == sscanf(mt->GetName().c_str(), "navlight_pad%u", &group)); mask = 0xf0; } bblight->SetColorUVoffset(get_color(color)); GroupLightsVecIter glit = std::find_if(m_groupLights.begin(), m_groupLights.end(), GroupMatch(group)); if(glit == m_groupLights.end()) { // didn't find group, create a new one m_groupLights.push_back(TGroupLights(group)); // now use it glit = (m_groupLights.end() - 1); } assert(glit != m_groupLights.end()); glit->m_lights.push_back(LightBulb(group, mask, color, bblight)); mt->SetNodeMask(SceneGraph::NODE_TRANSPARENT); mt->AddChild(bblight); } }
NavLights::NavLights(SceneGraph::Model *model, float period) : m_time(0.f) , m_period(period) , m_enabled(false) { assert(g_initted); Graphics::Renderer *renderer = model->GetRenderer(); using SceneGraph::Node; using SceneGraph::MatrixTransform; using SceneGraph::Billboard; //This will find all matrix transforms meant for navlights. SceneGraph::FindNodeVisitor lightFinder(SceneGraph::FindNodeVisitor::MATCH_NAME_STARTSWITH, "navlight_"); model->GetRoot()->Accept(lightFinder); const std::vector<Node*> &results = lightFinder.GetResults(); //attach light billboards for (unsigned int i=0; i < results.size(); i++) { MatrixTransform *mt = dynamic_cast<MatrixTransform*>(results.at(i)); assert(mt); Billboard *bblight = new Billboard(renderer, matBlue, vector3f(0.f), BILLBOARD_SIZE); Uint8 group = 0; Uint8 mask = 0xff; //always on Uint8 color = NAVLIGHT_BLUE; if (mt->GetName().substr(9, 3) == "red") { bblight->SetMaterial(matRed); mask = 0x0f; color = NAVLIGHT_RED; } else if (mt->GetName().substr(9, 5) == "green") { mask = 0xf0; color = NAVLIGHT_GREEN; } else if (mt->GetName().substr(9, 3) == "pad") { //group by pad number group = atoi(mt->GetName().substr(12, 1).c_str()); mask = 0xf0; } bblight->SetMaterial(get_material(color)); m_lights.push_back(LightBulb(group, mask, color, bblight)); mt->SetNodeMask(SceneGraph::NODE_TRANSPARENT); mt->AddChild(bblight); } }
void Shields::ReparentShieldNodes(SceneGraph::Model* model) { assert(s_initialised); Graphics::Renderer *renderer = model->GetRenderer(); using SceneGraph::Node; using SceneGraph::Group; using SceneGraph::MatrixTransform; using SceneGraph::StaticGeometry; //This will find all matrix transforms meant for navlights. SceneGraph::FindNodeVisitor shieldFinder(SceneGraph::FindNodeVisitor::MATCH_NAME_ENDSWITH, "_shield"); model->GetRoot()->Accept(shieldFinder); const std::vector<Node*> &results = shieldFinder.GetResults(); //Move shield geometry to same level as the LODs for (unsigned int i = 0; i < results.size(); i++) { MatrixTransform *mt = dynamic_cast<MatrixTransform*>(results.at(i)); assert(mt); const Uint32 NumChildren = mt->GetNumChildren(); if (NumChildren>0) { // Group to contain all of the shields we might find Group *shieldGroup = new Group(renderer); shieldGroup->SetName(s_shieldGroupName); // go through all of this MatrixTransforms children to extract all of the shield meshes for (Uint32 iChild = 0; iChild < NumChildren; ++iChild) { Node* node = mt->GetChildAt(iChild); assert(node); if (node) { RefCountedPtr<StaticGeometry> sg(dynamic_cast<StaticGeometry*>(node)); assert(sg.Valid()); sg->SetNodeMask(SceneGraph::NODE_TRANSPARENT); // We can early-out if we've already processed this models scenegraph. if (Graphics::BLEND_ALPHA == sg->m_blendMode) { assert(false); } // force the blend mode sg->m_blendMode = Graphics::BLEND_ALPHA; Graphics::RenderStateDesc rsd; rsd.blendMode = Graphics::BLEND_ALPHA; rsd.depthWrite = false; sg->SetRenderState(renderer->CreateRenderState(rsd)); for (Uint32 iMesh = 0; iMesh < sg->GetNumMeshes(); ++iMesh) { StaticGeometry::Mesh &rMesh = sg->GetMeshAt(iMesh); rMesh.material = GetGlobalShieldMaterial(); } // find the accumulated transform from the root to our node MatrixAccumVisitor mav(mt->GetName()); model->GetRoot()->Accept(mav); // set our nodes transformation to be the accumulated transform MatrixTransform *sg_transform_parent = new MatrixTransform(renderer, mav.outMat); std::stringstream nodeStream; nodeStream << iChild << s_matrixTransformName; sg_transform_parent->SetName(nodeStream.str()); sg_transform_parent->AddChild(sg.Get()); // dettach node from current location in the scenegraph... mt->RemoveChild(node); // attach new transform node which parents the our shields mesh to the shield group. shieldGroup->AddChild(sg_transform_parent); } } model->GetRoot()->AddChild(shieldGroup); } } }