Exemplo n.º 1
0
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);
		}
	}
}