Matrix view transform use problem...

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Matrix view transform use problem...

Post by christianclavet »

Hi, I would need help to get a proper scale of the view matrix so the rendering of a node would be displayed correctly on screen.

My current code work, but only on small node (1-2 unit in size), bigger nodes don't render properly (clipped or not rendered). I want to use that for rendering a rotating preview of a node that would automatically scale to fit the area.

Here my current code: (Part of it was inspired from the irrlicht camera code)

EDIT: See next post for the updated code...

Any help to display bigger nodes (bigger than 3 units) would be appreciated...
Last edited by christianclavet on Wed Apr 06, 2011 4:01 pm, edited 1 time in total.
ChaiRuiPeng
Posts: 363
Joined: Thu Dec 16, 2010 8:50 pm
Location: Somewhere in the clouds.. drinking pink lemonade and sunshine..

Post by ChaiRuiPeng »

i think you might need to set it to ignore aa bounding box occluding or properly recalculate bounding box.
ent1ty wrote: success is a matter of concentration and desire
Butler Lampson wrote: all problems in Computer Science can be solved by another level of indirection
at a cost measure in computer resources ;)
pippy3
Posts: 155
Joined: Tue Dec 15, 2009 7:32 am

Post by pippy3 »

Try changing matrix4 to a Matrix<f64>. I've noticed some flakey behavior with 32 bit floating point matrices in 1.7.
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Post by christianclavet »

Thanks for replying...

Found an error in my code. The distance of the "camera" viewport was set incorrectly. I multiplied the Y value. This was fixed. Still the problem is there.

Here is the updated code:

Code: Select all

void NodePreview::draw()
{
    if(!node) return;

	rotation=rotation+0.075f;
	if (rotation>360)
		rotation=0;
	
	IGUISkin* skin = Environment->getSkin();
	core::rect<s32> frameRect(AbsoluteRect);

	if (background)
	{
		skin->draw3DSunkenPane(this, backgroundcolor,
			true, true, frameRect, &AbsoluteClippingRect);
	}
	
	core::rect<s32> originalViewport = driver->getViewPort();
	
    driver->setViewPort(frameRect);

    matrix4 oldProjMat = driver->getTransform(video::ETS_PROJECTION);
    matrix4 oldViewMat = driver->getTransform(video::ETS_VIEW);
    
   	// Determine the best distance for the camera also find the center of the model.
	f32 scale1 = (node->getBoundingBox().getExtent().Y)/2;
	f32 distance = scale1*2;
	f32 scale2 = (node->getBoundingBox().getExtent().X)/2;
	f32 scale3 = (node->getBoundingBox().getExtent().Z)/2;
	if (scale2>distance)
		distance=scale2*2;
	if (scale3>distance)
		distance=scale3*2;

	// Define the aspect ratio for the "camera"
	f32 aspect = ((f32)frameRect.getWidth()/frameRect.getHeight()); 
	SViewFrustum ViewArea;
	

	// Define a perspective projection
	ViewArea.getTransform ( video::ETS_PROJECTION ).buildProjectionMatrixPerspectiveFovLH(0.5f, aspect, 0.1f, 9600.0f);

	// Define a camera that is rotating around it's target
	vector3df camera = (node->getPosition()+vector3df(0,scale1,0) + vector3df(0,rotation,0).rotationToDirection()); 
	camera.X = camera.X *(distance*2.5f);
	camera.Z = camera.Z *(distance*2.5f);
		
	
	ViewArea.getTransform(video::ETS_VIEW).buildCameraLookAtMatrixLH(camera, node->getPosition()+vector3df(0,scale1,0), vector3df(0,1,0));

	// Recalculate the view area from the camera position
	ViewArea.cameraPosition = camera;

	core::matrix4 m(core::matrix4::EM4CONST_NOTHING);
	m.setbyproduct_nocheck(ViewArea.getTransform(video::ETS_PROJECTION),
						ViewArea.getTransform(video::ETS_VIEW));
	ViewArea.setFrom(m);
	
	// Do the transformations (perspective cam)
	driver->setTransform ( video::ETS_PROJECTION, ViewArea.getTransform ( video::ETS_PROJECTION));
	driver->setTransform ( video::ETS_VIEW, ViewArea.getTransform ( video::ETS_VIEW));

	// Node seem to render the meshbuffers directly (scaling of the mesh does not seem to be accounted for)
	node->render();

	// Put back the original transformations
    driver->setTransform ( video::ETS_PROJECTION, oldProjMat );
    driver->setTransform ( video::ETS_VIEW, oldViewMat );
 
    driver->setViewPort(originalViewport);
	// draw children
	IGUIElement::draw();
	
}
The distance is scaled for the X and Z axis and not the Y. With a bigger mesh the camera Y position was not what I had in mind. It should be at the center position of the object. Now it set really at that position.

I checked the ViewArea bounding box (put Fprint statements just before rendering the node) and values seem ok (I set a zFar of 9600 unit and it should work).

Still:
Node 1: Max unit size: 1.82 unit, rendering ok
Node 2: Max unit size: 70.2 unit, nothing rendered in the viewport.

I tried to set the matrix type from f32 to f64 (as matrix4<f64>) and it was not accepted. searched for a specific "Matrix<f64>" and it does not exist.

My code is based on the ccamera.cpp source from IRRlicht. I find it strange that it render small meshes but not bigger ones. I think I still missing something... This code is to be used in a GUI component.


EDIT:
I think I could have found what going on (I'm not sure how to fix it atm), but I the code I'm rendering the node by doing this:

Code: Select all

node->render();
I think that the world transformation for the CURRENT view is not accounted and that could explain the problem. I will have to draw the meshbuffer directly and set the world transformation based on the current view and not use the "render" function since I'm rendering all directly.

If someone that have more experience than me can confirm... I will check the IRRlicht source and try it anyway.
Post Reply