[solved] Some sort of clipping problem.

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

Post by bitplane »

I gave agamemnus a code snippet and some advice on IRC. It basically boils down to a bit of compositing:

1) Background pass: draw the sea in the skybox pass with z-writes disabled, followed by all the ground nodes as usual.
2) Foreground pass: draw the sea as a skybox with colour writes disabled but z-write on, followed by boats and other units.

This should prevent ordering problems where the sea swallows up the land, yet allow boats to be partially occluded by the sea.
Submit bugs/patches to the tracker!
Need help right now? Visit the chat room
agamemnus
Posts: 283
Joined: Sun Jan 31, 2010 6:06 pm

Post by agamemnus »

Yeah, so the realization was that putting the ("solid") nodes in some specific order into the scene doesn't matter... what matters is how close each node is to the camera. When I add and start moving the ship nodes, Irrlicht re-sorts nodes and the order they are drawn in. It somehow recalculates the sea node with a very fast but inaccurate distance algorithm so that it isn't always the first node (because it's not farthest to the camera), and that is why I get these seemingly random "area" node disappearances (they are actually just hidden by the sea node).

Bitplane's code looks good, but I am going to make some slight modifications and I will post my full code later on.
agamemnus
Posts: 283
Joined: Sun Jan 31, 2010 6:06 pm

Post by agamemnus »

Ok, here it is.

Code: Select all

class CCustomPassNode : public scene::ISceneNode {
	video::SMaterial material;
 irr::scene::IMeshBuffer *meshBuffer;
	E_SCENE_NODE_RENDER_PASS renderPass;

public:
       CCustomPassNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, IMeshBuffer *mb, E_SCENE_NODE_RENDER_PASS pass)
                : scene::ISceneNode(parent, mgr, id), meshBuffer(mb), renderPass(pass) { 
                 material = meshBuffer->getMaterial();
	}
	virtual void OnRegisterSceneNode() {

  if (IsVisible) SceneManager->registerNodeForRendering (this, renderPass);
		ISceneNode::OnRegisterSceneNode();
	}

	virtual void render()	{
		driver->setMaterial(material);
		driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
		driver->drawMeshBuffer(meshBuffer);
	}

	virtual const core::aabbox3d<f32>& getBoundingBox() const {
		return meshBuffer->getBoundingBox();
	}

	virtual u32 getMaterialCount() const {
		return 1;
	}

	virtual video::SMaterial& getMaterial(u32 i) {
		return material;
	}	
};

// .....

void * DLL_EXPORT IrrAddCustomPassMeshToScene (IAnimatedMesh* mesh, u32 passEnum, s32 id = 0) {
 return (new CCustomPassNode(smgr->getRootSceneNode(), smgr, id, mesh->getMesh(0)->getMeshBuffer(0), (irr::scene::E_SCENE_NODE_RENDER_PASS)passEnum));
}

void DLL_EXPORT IrrRemoveCustomPassMeshFromScene (u32* node) {
 ((CCustomPassNode*)node)->drop();
}
The current mesh I am passing is just two triangles, making a rectangle -- one material.

I would like to add three modifications, though:

1) Make it work for multiple materials.
2) Make it work for actually dynamic meshes.
3) Add a way to record the addition and removal/deletion of nodes into a global data structure so that I can cleanly automatically drop the custom nodes in my cleanup function.

Edit: I realized the roads are going to flicker too (in and out of areas). Not sure what I am going to do about this, but now that I am more clear on how it works, I am confident I will find a solution.
Post Reply