Page 1 of 1

Gizmo class, Scale independent Gizmo

Posted: Mon Feb 24, 2014 12:28 am
by RobertRR
Hi all,

I have created Scene node class responsible to draw Gizmo.

I have w few questions about this class. I feel that me solution is not the right one.
1) how I should use scene Nodes inside another Scene node class. In my code I add scene node to scene manager class in constructor, what function Render should look like?
2) how to draw this gizmo in scale/zoom independent way. I want it to be the same size no matter what zoom/camera distance is?
3) is this correct to use using namespace in header file if it is surrounded by anonym namespace? in c++11

Thanks in advance for point me what is wrong in following implementation.


Code: Select all

 
#pragma once
 
#include "irrlicht.h"
 
namespace
{
    using namespace irr;
    using namespace video;
    using namespace core;
    using namespace scene;
 
    class GizmoNode : public scene::ISceneNode
    {
        ISceneNode * baseNode;
 
    public:
 
        GizmoNode(scene::ISceneNode* parent, scene::ISceneManager* smgr, s32 id=-1) : scene::ISceneNode(parent, smgr, id)
        {
            auto colorS = SColor(255, 200, 200, 0);
            const u32 teselCylinder = 4;
            const u32 teselCone = 8;
            const f32 height = 10.0;
            const f32 cylinderHeight = 6.0f;
            const f32 widthCylinder = 0.4f;
            const f32 widthCone = 2.0f;
 
            baseNode = smgr->addEmptySceneNode(this);
 
            auto meshX = smgr->addArrowMesh("AxisX", colorS, SColor(255, 200, 0, 0),teselCylinder,teselCone,height,cylinderHeight,widthCylinder,widthCone );
            auto arrowX = smgr->addAnimatedMeshSceneNode(meshX, baseNode);
            arrowX->setMaterialFlag(video::EMF_LIGHTING, false);
            arrowX->setRotation(vector3df(90, 90, 0));
 
            auto meshY = smgr->addArrowMesh("AxisY", colorS, SColor(255, 0, 200, 0),teselCylinder,teselCone,height,cylinderHeight,widthCylinder,widthCone );
            auto arrowY = smgr->addAnimatedMeshSceneNode(meshY, baseNode);
            arrowY->setMaterialFlag(video::EMF_LIGHTING, false);
            arrowY->setRotation(vector3df(0, 0, 0));        
 
            auto meshZ = smgr->addArrowMesh("AxisZ", colorS, SColor(255, 0, 0, 200),teselCylinder,teselCone,height,cylinderHeight,widthCylinder,widthCone );
            auto arrowZ = smgr->addAnimatedMeshSceneNode(meshZ, baseNode);
            arrowZ->setMaterialFlag(video::EMF_LIGHTING, false);
            arrowZ->setRotation(vector3df(90, 0, 0));
 
        }
 
        virtual void OnRegisterSceneNode()
        {
            if (IsVisible)  SceneManager->registerNodeForRendering(this);
            ISceneNode::OnRegisterSceneNode();
        }
 
 
        virtual void render()
        {
        }
 
        virtual const core::aabbox3d<f32>& getBoundingBox() const
        {
            return baseNode->getBoundingBox();
        }
 
        virtual u32 getMaterialCount() const
        {
            return baseNode->getMaterialCount();
        }
 
        virtual video::SMaterial& getMaterial(u32 i)
        {
            return baseNode->getMaterial(i);
        }   
    };
 
}
 

Re: Gizmo class, Scale independent Gizmo

Posted: Mon Feb 24, 2014 4:55 am
by mongoose7
Why do you want a new class? You could add the three arrows to a normal scene node. If you want the gizmo to appear at a particular place, then you would have to scale it in code.

Re: Gizmo class, Scale independent Gizmo

Posted: Mon Feb 24, 2014 9:34 am
by RobertRR
mongoose7 wrote:Why do you want a new class? You could add the three arrows to a normal scene node. If you want the gizmo to appear at a particular place, then you would have to scale it in code.
This is only a simple example. The point is - How to implement ISceneNode that contains another SceneNode?

I dont want to manual scale it. Lets assume such user case. I have FPPCamera and gizmo. I want gizmo to be the same size no meter how far is camera. but I wand ignore only scale the position and rotation should be correlated with camera position.


I hope this explanation is enough what I'm looking for.
Thanks for yours contribution in my problem.

Re: Gizmo class, Scale independent Gizmo

Posted: Tue Feb 25, 2014 4:17 pm
by hendu
In a custom scene node you control the rendering. In your case you want to ignore the view matrix.

Re: Gizmo class, Scale independent Gizmo

Posted: Tue Feb 25, 2014 5:59 pm
by horvatha4
Hello RobertRR
to the 2)

If you looking something similar like this in the lower left corner: http://youtu.be/YMheW35MNp8
An active camera have added to the root-scenenode:

Code: Select all

 
...
    ActiveCamera = scnmgr->addCameraSceneNode( 0, irr::core::vector3df(0,0,0), irr::core::vector3df(0,0,0), -1, true );
...
 
Add your gismo-scenenode to the camera's scenenode:

Code: Select all

 
...
    /***************** Gizmo ************************/
            auto colorS = SColor(255, 200, 200, 0);
            const u32 teselCylinder = 4;
            const u32 teselCone = 8;
            const f32 height = 0.20f;
            const f32 cylinderHeight = 0.16f;
            const f32 widthCylinder = 0.004f;
            const f32 widthCone = 0.008f;
...
            arrowX = pastssm->scnmgr->addAnimatedMeshSceneNode(meshX, ActiveCamera);
...
            arrowY = pastssm->scnmgr->addAnimatedMeshSceneNode(meshY, ActiveCamera);
...
            arrowZ = pastssm->scnmgr->addAnimatedMeshSceneNode(meshZ, ActiveCamera);
...
 
Then you must recalculate the gismo's position on every frame.
So somewhere in you code, e.g after set the camera new position:

Code: Select all

 
    irr::core::vector3df tmpHPos, tmpVPos, tmpFinalPos,
        dirvector = ActiveCamera->getTarget() - ActiveCamera->getAbsolutePosition();
    dirvector.normalize();
    dirvector *= 1.2f;
    tmpVPos = ActiveCamera->getUpVector();
    tmpHPos = dirvector.crossProduct(tmpVPos);
    tmpHPos.setLength( 0.7f );
    tmpVPos = dirvector.crossProduct(tmpHPos);
    tmpVPos.setLength( -0.4f );
    tmpFinalPos = dirvector + tmpHPos - tmpVPos;
    arrowX->setPosition(tmpFinalPos);
    arrowY->setPosition(tmpFinalPos);
    arrowZ->setPosition(tmpFinalPos);
 
With tmpHPos and tmpVPos can you adjust the gismo's position on the screen.
The dirvector's lenght allocate how "far" sitting your gismo behind the screen. The gismo will cut from the screen/scene if this value too small!
I have resized your arrows to 1/50-th!

Good luck!

Arpi