Shields::Shields(SceneGraph::Model *model) : m_enabled(false) { assert(s_initialised); using SceneGraph::Node; using SceneGraph::MatrixTransform; using SceneGraph::StaticGeometry; using SceneGraph::CollisionGeometry; //This will find all matrix transforms meant for shields. SceneGraph::FindNodeVisitor shieldFinder(SceneGraph::FindNodeVisitor::MATCH_NAME_ENDSWITH, s_matrixTransformName); model->GetRoot()->Accept(shieldFinder); const std::vector<Node*> &results = shieldFinder.GetResults(); //Store pointer to the shields for later. for (unsigned int i=0; i < results.size(); i++) { MatrixTransform *mt = dynamic_cast<MatrixTransform*>(results.at(i)); assert(mt); for(Uint32 iChild=0 ; iChild<mt->GetNumChildren() ; ++iChild) { Node* node = mt->GetChildAt(iChild); if (node) { RefCountedPtr<StaticGeometry> sg(dynamic_cast<StaticGeometry*>(node)); assert(sg.Valid()); sg->SetNodeMask(SceneGraph::NODE_TRANSPARENT); Graphics::RenderStateDesc rsd; rsd.blendMode = Graphics::BLEND_ALPHA; rsd.depthWrite = false; sg->SetRenderState(sg->GetRenderer()->CreateRenderState(rsd)); // set the material for (Uint32 iMesh = 0; iMesh < sg->GetNumMeshes(); ++iMesh) { StaticGeometry::Mesh &rMesh = sg->GetMeshAt(iMesh); rMesh.material = GetGlobalShieldMaterial(); } m_shields.push_back(Shield(Color3ub(255), mt->GetTransform(), sg.Get())); } } } }
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); } } }