Disable of scaling child node.
Disable of scaling child node.
Is it possible to disable or compensate of scaling child node when the assignment of its parent?
Re: Disable of scaling child node.
Dividing scale values by 1./scale should work I think (interestingly Irrlicht doesn't seem to have a function yet to divide a scalar by a vector, but only the other way round - so you have to do it component wise for now).
At least seems to work in my simple test:
edit: And no - can't be disabled. Thought you can also use a flat scenegraph and do the parent/child computations yourself.
At least seems to work in my simple test:
Code: Select all
#include <irrlicht.h>
using namespace irr;
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
int main(int argc, char *argv[])
{
IrrlichtDevice * Device = createDevice(video::EDT_OPENGL, core::dimension2d<u32>(640,480) );
if (!Device)
return false;
scene::ISceneManager* smgr = Device->getSceneManager();
gui::IGUIEnvironment* guiEnv = Device->getGUIEnvironment();
video::IVideoDriver* videoDriver = Device->getVideoDriver();
smgr->addCameraSceneNodeFPS(0, 20.f, 0.1f );
irr::core::vector3df scale(20.f, 10.f, 3.f);
irr::scene::ISceneNode * parent = smgr->addCubeSceneNode (10.0f, 0, -1,
core::vector3df(0, 20, 100),
core::vector3df(45, 45, 45),
scale);
parent->getMaterial(0).Lighting = false;
irr::scene::ISceneNode * child = smgr->addCubeSceneNode (10.0f, 0, -1,
core::vector3df(0, 20, 100),
core::vector3df(0, 0, 0),
core::vector3df(1.0f/scale.X, 1.0f/scale.Y, 1.0f/scale.Z));
child->getMaterial(0).Lighting = false;
child->setParent(parent);
while ( Device->run() )
{
if ( Device->isWindowActive() )
{
videoDriver->beginScene(true, true);
smgr->drawAll();
guiEnv->drawAll();
videoDriver->endScene();
}
Device->sleep( 1 );
}
Device->closeDevice();
Device->drop();
return 0;
}
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Re: Disable of scaling child node.
Thanks for the quick reply, but somehow it does not work. I add child node with a turn and it is distorted (child node is created as g_GraphicalWorld-> SceneManager () -> addMeshSceneNode (.....); bluish transparent tetrahedron shown in figure is child node).If turn the child node relative parent is set to 0 on all axes, then no distortion and correct scale.
But if you turn a child node, its display distorted, so 30 degrees of rotation axis Y - is on image.
I think that this is due to different axes of child node relative parent node, and accordingly the scale used is not correct. By this I would like to simply prohibit the use of the scale of the parent node to the child.
But if you turn a child node, its display distorted, so 30 degrees of rotation axis Y - is on image.
I think that this is due to different axes of child node relative parent node, and accordingly the scale used is not correct. By this I would like to simply prohibit the use of the scale of the parent node to the child.
Re: Disable of scaling child node.
Sorry, I need a test-case to reproduce it. Can you can adapt my code above to show the problem? I can't see what's wrong in the code from images.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Re: Disable of scaling child node.
Please try this:
Child green Rect is distorted.
Code: Select all
#include "stdafx.h"
#include <irrlicht.h>
using namespace irr;
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
int main()
{
IrrlichtDevice * Device = createDevice(video::EDT_OPENGL, core::dimension2d<u32>(1280,1024) );
if (!Device)
return false;
scene::ISceneManager* smgr = Device->getSceneManager();
gui::IGUIEnvironment* guiEnv = Device->getGUIEnvironment();
video::IVideoDriver* videoDriver = Device->getVideoDriver();
smgr->setAmbientLight(video::SColorf(0.4f, 0.4f, 0.35f, 0.0f));
smgr->addLightSceneNode(0, core::vector3df(0, 2000, -1000), video::SColorf(0.7f, 0.7f, 0.4f, 1.0f), 1000);
smgr->addCameraSceneNodeFPS(0, 200.f, 0.1f );
irr::core::vector3df scale(2.f, 1.f, 0.3f);
irr::scene::ISceneNode * parent = smgr->addCubeSceneNode (10.0f, 0, -1,
core::vector3df(0, 0, 100),
core::vector3df(0, 0, 0),
scale);
parent->getMaterial(0).Lighting = true;
parent->getMaterial(0).AmbientColor = video::SColor(0, 200, 0, 0);
irr::scene::ISceneNode * child = smgr->addCubeSceneNode (30.0f, 0, -1,
core::vector3df(0, 0, 50),
core::vector3df(0, 10, 0),
core::vector3df(1/scale.X, 1/scale.Y, 1/scale.Z));
child->getMaterial(0).Lighting = true;
child->getMaterial(0).AmbientColor = video::SColor(0, 0, 200, 0);
child->setParent(parent);
while ( Device->run() )
{
if ( Device->isWindowActive() )
{
videoDriver->beginScene(true, true);
smgr->drawAll();
guiEnv->drawAll();
videoDriver->endScene();
}
Device->sleep( 1 );
}
Device->closeDevice();
Device->drop();
return 0;
}
Re: Disable of scaling child node.
Hm, the scale is probably along the direction of the rotated original node. I even remember now I had to work around that once ... it's possible, but in the end I didn't use it because it just adds lots of computations.
It probably was something like applying the inverse of the scale and rotation of the parent-matrix (absolute matrix with translation reseted and then getInverse on that). And maybe then you have to apply the rotation part once again to not lose that.
But likely easier (and less to compute) to break the parent/child relationship here and do that calculation yourself completely. So use an own update function which knows about those relation. Alternatively you create your own scenenode which can recalculate the absolute transformation matrix in it's own way by overloading updateAbsolutePosition.
Default scenegraph is nice and easy for many cases, but sometimes it's just the wrong structure.
In those cases keep your scenegraph flat (which is generally faster anyway) and calculate relations between nodes yourself.
It probably was something like applying the inverse of the scale and rotation of the parent-matrix (absolute matrix with translation reseted and then getInverse on that). And maybe then you have to apply the rotation part once again to not lose that.
But likely easier (and less to compute) to break the parent/child relationship here and do that calculation yourself completely. So use an own update function which knows about those relation. Alternatively you create your own scenenode which can recalculate the absolute transformation matrix in it's own way by overloading updateAbsolutePosition.
Default scenegraph is nice and easy for many cases, but sometimes it's just the wrong structure.
In those cases keep your scenegraph flat (which is generally faster anyway) and calculate relations between nodes yourself.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Re: Disable of scaling child node.
Is it possible to easily add the appointment of child nodes of the parent node flag application scale? Maybe it would even increased performance - it is not always necessary to use the parent node scope.
I use Irrlicht to display the results of the Bullet Physics, and there is a class with the aid of which do what you say. But in this case there are problems with the correctness turn nodes ...
You can still add the flag of the application scale?
I use Irrlicht to display the results of the Bullet Physics, and there is a class with the aid of which do what you say. But in this case there are problems with the correctness turn nodes ...
You can still add the flag of the application scale?
Re: Disable of scaling child node.
Not quite sure what you said. You mean we should add a flag for that? Basically - can't do that easily. The reason is that it's just not how the scenegraph works (childs use parent tranformations - if you want to get rid of scale you can no longer use those but have to calculate 2 different types of transformations).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Re: Disable of scaling child node.
Well, I mean ... Tell me, then, please, how do I determine the correct origin and rotation the child node relative to the parent.
Re: Disable of scaling child node.
Hm, yeah - slightly tricky. Maybe following solution is easiest - you add a node in between which filters out the scaling of the parent. Note - only that of the direct parent - so if you a deeper scene-tree here (a few parents) you have to insert it in between each one where you need that.
Code: Select all
#include <irrlicht.h>
using namespace irr;
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
// Can be placed in betweeen parent-child to ignore the scale of the parent.
class IgnoreScaleSceneNode : public irr::scene::ISceneNode
{
public:
//! Constructor
IgnoreScaleSceneNode(irr::scene::ISceneNode* parent, irr::scene::ISceneManager* mgr, s32 id=-1)
: irr::scene::ISceneNode(parent, mgr, id) {}
virtual void updateAbsolutePosition()
{
AbsoluteTransformation.makeIdentity();
if (Parent)
{
AbsoluteTransformation.setRotationDegrees( Parent->getRotation() );
AbsoluteTransformation.setTranslation( Parent->getPosition() );
if ( Parent->getParent() )
{
AbsoluteTransformation = Parent->getParent()->getAbsoluteTransformation() * AbsoluteTransformation;
}
}
}
//! returns the axis aligned bounding box of this node
virtual const core::aabbox3d<f32>& getBoundingBox() const
{
return Box;
}
//! Returns the relative transformation of the scene node.
virtual core::matrix4 getRelativeTransformation() const
{
return RelativeTransformationMatrix;
}
//! does nothing.
virtual void render() _IRR_OVERRIDE_ {}
private:
irr::core::matrix4 RelativeTransformationMatrix; // identity matrix
irr::core::aabbox3d<f32> Box;
};
int main()
{
IrrlichtDevice * Device = createDevice(video::EDT_OPENGL, core::dimension2d<u32>(1280,1024) );
if (!Device)
return false;
scene::ISceneManager* smgr = Device->getSceneManager();
gui::IGUIEnvironment* guiEnv = Device->getGUIEnvironment();
video::IVideoDriver* videoDriver = Device->getVideoDriver();
smgr->setAmbientLight(video::SColorf(0.4f, 0.4f, 0.35f, 0.0f));
smgr->addLightSceneNode(0, core::vector3df(0, 2000, -1000), video::SColorf(0.7f, 0.7f, 0.4f, 1.0f), 1000);
smgr->addCameraSceneNodeFPS(0, 200.f, 0.1f );
irr::core::vector3df scale(2.f, 1.f, 0.3f);
irr::scene::ISceneNode * parent = smgr->addCubeSceneNode (10.0f, 0, -1,
core::vector3df(0, 0, 100),
core::vector3df(0, 0, 0),
scale);
parent->getMaterial(0).Lighting = true;
parent->getMaterial(0).AmbientColor = video::SColor(0, 200, 0, 0);
irr::scene::ISceneNode * child = smgr->addCubeSceneNode (30.0f, 0, -1,
core::vector3df(0, 0, 50),
core::vector3df(0, 10, 0),
core::vector3df(1.f, 1.f, 1.f));
child->getMaterial(0).Lighting = true;
child->getMaterial(0).AmbientColor = video::SColor(0, 0, 200, 0);
IgnoreScaleSceneNode* ignoreNode = new IgnoreScaleSceneNode(parent, smgr);
child->setParent(ignoreNode);
ignoreNode->drop();
while ( Device->run() )
{
if ( Device->isWindowActive() )
{
videoDriver->beginScene(true, true);
smgr->drawAll();
guiEnv->drawAll();
videoDriver->endScene();
}
Device->sleep( 1 );
}
Device->closeDevice();
Device->drop();
return 0;
}
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Re: Disable of scaling child node.
Hm, wait - bad solution. That fails every time the hierarchy is deeper. Have to think again...
edit: I did edit the code above. I think it should work now probably...
edit2: Note that it will be faster if you do the customized updateAbsolutePosition() function directly in the node where you need it.
edit: I did edit the code above. I think it should work now probably...
edit2: Note that it will be faster if you do the customized updateAbsolutePosition() function directly in the node where you need it.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Re: Disable of scaling child node.
Thank you very much. The class that you recommend doing exactly what I need. Since computation physics and rendering scene are performed in different threads, I do not need very high performance graphics engine. I was a little changed your class and spread it here, all of a sudden someone else will need ...
Code: Select all
class IgnoreScaleSceneNode : public scene::ISceneNode
{
private:
core::matrix4 RelativeTransformationMatrix; // identity matrix
core::aabbox3d<f32> Box;
public:
IgnoreScaleSceneNode(irr::scene::ISceneNode* parent, irr::scene::ISceneManager* mgr, s32 id=-1) : irr::scene::ISceneNode(parent, mgr, id) {}
virtual void updateAbsolutePosition()
{
AbsoluteTransformation.makeIdentity();
if (Parent)
{
AbsoluteTransformation.setRotationDegrees(Parent->getRotation());
AbsoluteTransformation.setTranslation(Parent->getPosition());
AbsoluteTransformation *= RelativeTransformationMatrix;
if (Parent->getParent())
{
AbsoluteTransformation = Parent->getParent()->getAbsoluteTransformation() * AbsoluteTransformation;
}
}
}
virtual void setRotation(const core::vector3df& rotation)
{
RelativeRotation = rotation;
RelativeTransformationMatrix.makeIdentity();
RelativeTransformationMatrix.setRotationDegrees(RelativeRotation);
RelativeTransformationMatrix.setTranslation(RelativeTranslation);
}
virtual void setPosition(const core::vector3df& newpos)
{
RelativeTranslation = newpos;
RelativeTransformationMatrix.makeIdentity();
RelativeTransformationMatrix.setRotationDegrees(RelativeRotation);
RelativeTransformationMatrix.setTranslation(RelativeTranslation);
}
virtual const core::aabbox3d<f32>& getBoundingBox() const { return Box; }
virtual core::matrix4 getRelativeTransformation() const { return RelativeTransformationMatrix; }
//! does nothing.
virtual void render() {}
};