Page 1 of 1

Huge meshes dont draw all the way

Posted: Tue Jan 24, 2006 3:41 pm
by Anteater
Ok, this may not be a true bug as much as it is a limitation, because it may have something to do with the 16 indices thing. Anyway, here's the problem: Huge meshes (in this case they're created in the .x format but I don't think that has much to do with it), simply aren't drawn, nor is collision detected with them. Also, by "Huge" I mean virtual size, not poly count.

Posted: Thu Jan 26, 2006 7:21 pm
by Pr3t3nd3r_guest
any way i believe huge meshes Will be drowned very badly because of the z-buffer errors ... maybe you should scale them ...

Posted: Thu Jan 26, 2006 8:42 pm
by Anteater
Iv'e tried scaling them from small models-- almost the same thing happens, they VISUALLY look the same, but collision/triselecting doesn't work.

Posted: Thu Jan 26, 2006 8:43 pm
by pfo
I've seen problems like this too. The terrain node does it when its scaled very large, and you're standing over a tile, it can 'disappear'. Also, I made a custom DeleD loader that would create specified meshes as MeshSceneNodes (these were dynamic objects, not just static level geometry). If these were large, then sometimes they would 'disappear' when I was close to them. One thing I noticed about all of these disappearing acts is that it seems like at least 1 of the objects faces has to be clipped by the camera. Meaning you had to be close to the obect. Does this sound like what you are experiencing? I know little about clipping and culling algorithms so I didn't dare try to understand why it was happening.

Posted: Fri Jan 27, 2006 2:45 am
by burivuh
It's culling problem, I think.
Yesterday I try the commented code - "more exact" version of culling. Some nodes began to disappear. Seems like huge size leads to the situation, where culling bug can be noticed.

Posted: Fri Jan 27, 2006 3:38 am
by afecelis

Code: Select all

camera->setFarValue (  50000.0f  ) ; //sets the distance for the culling plane

Posted: Fri Jan 27, 2006 8:26 am
by Xaron
afecelis wrote:

Code: Select all

camera->setFarValue (  50000.0f  ) ; //sets the distance for the culling plane
Well this is no real solution. ;) The frame rate drops a lot as more triangles have to be rendered...

Regards - Xaron

Posted: Fri Jan 27, 2006 2:39 pm
by Anteater
The far value is not the problem. No matter how close you get to the edge, the rest of the model isn't drawn. Nor is collision detected. It may have something to do with a culling bug, but I don't know. To demonstrate this bug, load a normal-sized version of DeleD's "Secred Place" file into the Irrlicht Mesh Viewer, and it'll look fine. Go into DeleD, and add stuff to it (cubes, prefabs, whatever) to it, until it's huge (on the X/Y axis, you don't need to bother with the Z axis) and try loading it again. The outer-most objects cease to exist, even if you move the camera close to them.

Posted: Sat Mar 11, 2006 5:59 pm
by Xaron
Hi,

are there any news on that culling bug? It pop ups rather often if the terrain is scaled large (in my case factor 20 in xz-axis)

Where could I do some research in the irrlicht code? I would like to get rid of this error. ;)

Regards - Xaron

Posted: Sun Mar 12, 2006 1:06 am
by Spintz
I was having the same problem with terrains, with patches not being drawn that were close the camera because they thought they were culled, this fixed it ( Replace the code for isCulled in CSceneManager.cpp with this code )

Code: Select all

bool CSceneManager::isCulled(ISceneNode* node)
{
	if (!node->getAutomaticCulling())
		return false;

	if( !ActiveCamera )
		return false;

	core::aabbox3d<f32> tbox = node->getTransformedBoundingBox();
	const SViewFrustrum* f = getActiveCamera()->getViewFrustrum();

	// first check if the frustrum box intersects with node, if so, then check each
	// plane of frustrum with nodes box
	if( tbox.intersectsWithBox( ActiveCameraFrustrumBBox ) )
	{
		if( ( tbox.classifyPlaneRelation( f->planes[SViewFrustrum::VF_NEAR_PLANE] ) == core::ISREL3D_BACK ) ||
			( tbox.classifyPlaneRelation( f->planes[SViewFrustrum::VF_FAR_PLANE] ) == core::ISREL3D_BACK ) ||
			( tbox.classifyPlaneRelation( f->planes[SViewFrustrum::VF_LEFT_PLANE] ) == core::ISREL3D_BACK ) ||
			( tbox.classifyPlaneRelation( f->planes[SViewFrustrum::VF_RIGHT_PLANE] ) == core::ISREL3D_BACK ) ||
			( tbox.classifyPlaneRelation( f->planes[SViewFrustrum::VF_BOTTOM_PLANE] ) == core::ISREL3D_BACK ) ||
			( tbox.classifyPlaneRelation( f->planes[SViewFrustrum::VF_TOP_PLANE] ) == core::ISREL3D_BACK ) )
		{
			return true;
		}
	}

	return false;
}

Posted: Sun Mar 12, 2006 1:13 am
by Spintz
Sorry, you also have to the following -

In CSceneManager.h, add

Code: Select all

core::aabbox3df		ActiveCameraFrustrumBBox;
in the private section. Also in the registerNodeForRendering function in CSceneManager.cpp change the case for ESNRP_LIGHT_AND_CAMERA to this

Code: Select all

case ESNRP_LIGHT_AND_CAMERA:
	LightAndCameraList.push_back(node);

	if( ActiveCamera )
	{
        ActiveCameraFrustrumBBox = ActiveCamera->getViewFrustrum()->boundingBox;
	}
	break;

Posted: Sun Mar 12, 2006 1:19 am
by Spintz
Damn forgot this one too....

Need to fix SViewFrustrum ctor from a core::matrix, the normals are screwed up. Here's the new function, it's in SVewFrustrum.h.

Code: Select all

//! This constructor creates a view frustrum based on a projection and/or
//! view matrix.
inline SViewFrustrum::SViewFrustrum(const core::matrix4& mat)
{
	#define sw(a,b)		(mat((b),(a)))

	// left clipping plane
	planes[SViewFrustrum::VF_LEFT_PLANE].Normal.X = (sw(0,3) + sw(0,0));
	planes[SViewFrustrum::VF_LEFT_PLANE].Normal.Y = (sw(1,3) + sw(1,0));
	planes[SViewFrustrum::VF_LEFT_PLANE].Normal.Z = (sw(2,3) + sw(2,0));
	planes[SViewFrustrum::VF_LEFT_PLANE].D =		(sw(3,3) + sw(3,0));
                                                 
	// right clipping plane                  
	planes[SViewFrustrum::VF_RIGHT_PLANE].Normal.X = (sw(0,3) - sw(0,0));
	planes[SViewFrustrum::VF_RIGHT_PLANE].Normal.Y = (sw(1,3) - sw(1,0));
	planes[SViewFrustrum::VF_RIGHT_PLANE].Normal.Z = (sw(2,3) - sw(2,0));
	planes[SViewFrustrum::VF_RIGHT_PLANE].D =        (sw(3,3) - sw(3,0));
    
	// top clipping plane                  
	planes[SViewFrustrum::VF_TOP_PLANE].Normal.X = (sw(0,3) - sw(0,1));
	planes[SViewFrustrum::VF_TOP_PLANE].Normal.Y = (sw(1,3) - sw(1,1));
	planes[SViewFrustrum::VF_TOP_PLANE].Normal.Z = (sw(2,3) - sw(2,1));
	planes[SViewFrustrum::VF_TOP_PLANE].D =        (sw(3,3) - sw(3,1));

	// bottom clipping plane                  
	planes[SViewFrustrum::VF_BOTTOM_PLANE].Normal.X = (sw(0,3) + sw(0,1));
	planes[SViewFrustrum::VF_BOTTOM_PLANE].Normal.Y = (sw(1,3) + sw(1,1));
	planes[SViewFrustrum::VF_BOTTOM_PLANE].Normal.Z = (sw(2,3) + sw(2,1));
	planes[SViewFrustrum::VF_BOTTOM_PLANE].D =        (sw(3,3) + sw(3,1));
 
	// near clipping plane                   
	planes[SViewFrustrum::VF_NEAR_PLANE].Normal.X = sw(0,2);
	planes[SViewFrustrum::VF_NEAR_PLANE].Normal.Y = sw(1,2);
	planes[SViewFrustrum::VF_NEAR_PLANE].Normal.Z = sw(2,2);
	planes[SViewFrustrum::VF_NEAR_PLANE].D =        sw(3,2);
                                                 
	// far clipping plane                    
	planes[SViewFrustrum::VF_FAR_PLANE].Normal.X = (sw(0,3) - sw(0,2));
	planes[SViewFrustrum::VF_FAR_PLANE].Normal.Y = (sw(1,3) - sw(1,2));
	planes[SViewFrustrum::VF_FAR_PLANE].Normal.Z = (sw(2,3) - sw(2,2));
	planes[SViewFrustrum::VF_FAR_PLANE].D =        (sw(3,3) - sw(3,2));

	// normalize normals
	
	for (s32 i=0; i<6; ++i)
	{
		f32 len = (f32)(1.0f / planes[i].Normal.getLength());
		planes[i].Normal *= len;
		planes[i].D *= len;
	}

	// make bounding box

	recalculateBoundingBox();
}

Posted: Sat Mar 18, 2006 12:01 pm
by ry
I was having similar problems to, but I don't think it has much to do with the Culling of the node. My file format was in '.x' and almost every object that was in that format had those same problems, so i converted them into '.3ds' and they worked fine without the problems.

I had tried Spintz modification to the engine but the problem was still there. It's either the way that Irrlicht is loading up the .x files and rendering them, or it is the version of the .x format that we are using