Placing 3D "line" based on end points?

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
Spinland
Posts: 32
Joined: Fri May 14, 2010 1:06 pm
Location: Upstate NY, USA

Placing 3D "line" based on end points?

Post by Spinland »

I've read via forum searches that just drawing a line doesn't give control over the line thickness in this release, and that you have to re-draw the line every display cycle. Given that, I want to depict edges connecting nodes of a 3D graph, and have concluded creating them with geometry seems the best bet (especially since I can create arrow primitives using Irrlicht functions and thereby make directed graphs if desired).

My question is related to placing the edges, given I know the 3D coordinates of the endpoints I want to connect. It seems, based on what I understand of Irrlicht thus far, the most straighforward method is to scale a cube (or arrow) to the desired thickness and length, calculate the midpoint between the endpoints, place the edge mesh at that midpoint (since placement seems to be relative to the center of the mesh), and calculate the rotations to orient it properly.

Is this actually the best method? I've been poring over some of the methods in the Irrlicht documentation and haven't seen anything that leaps out at me as a built-in method for achieving the same results more cheaply. Are there some cool methods for doing this that I'm overlookling?

Many thanks in advance!
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Post by Lonesome Ducky »

No necessarily built in methods, but there was a great beam scene node somebody wrote that would work great. Let me see if I can find it.

Hmm, I could find the original post, but here's the code:

CBeamSceneNode.h:

Code: Select all

#ifndef CBEAMSCENENODE_H
#define CBEAMSCENENODE_H
#include <irrlicht.h>
namespace irr
{
    namespace scene
    {
        class CBeamNode : public ISceneNode
        {
        public:
        private:
            // The beam material.
            video::SMaterial material;
            video::SMaterial material2;

            // Bounding Box
            core::aabbox3d<f32> Box;

            core::vector3df m_start;
            core::vector3df m_end;
            f32 m_thickness;

        public:

            CBeamNode( scene::ISceneNode* parent, scene::ISceneManager *mgr, s32 id, char* szBeam , char* szBeamFront );

            ~CBeamNode(void);

            virtual void OnRegisterSceneNode(void);

            virtual void OnAnimate(u32 timeMs);

            virtual void render(void);

            virtual const core::aabbox3d<f32>& getBoundingBox() const;

            virtual u32 getMaterialCount() const;

            virtual video::SMaterial& getMaterial(u32 i);

			virtual scene::ESCENE_NODE_TYPE getType() const;

            void setLine(core::vector3df start, core::vector3df end, f32 thickness);
        };
    }
}
#endif 
CBeamSceneNode.cpp:

Code: Select all

#include "CBeamSceneNode.h"
namespace irr
{
    namespace scene
    {
        CBeamNode::CBeamNode( ISceneNode* parent, ISceneManager *mgr, s32 id, char* szBeam , char* szBeamFront ) : ISceneNode( parent, mgr, id )
        {
            // Setup the beam material
            material.Wireframe = false;
            material.Lighting = false;
            material.ZWriteEnable = false;

            material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
            material.setTexture(0, mgr->getVideoDriver( )->getTexture( szBeam ));

            m_thickness = 1.0f;

           AutomaticCullingState = EAC_FRUSTUM_SPHERE;

        }

        CBeamNode::~CBeamNode(void)
        {

        }


		scene::ESCENE_NODE_TYPE CBeamNode::getType() const {
			return scene::ESNT_BILLBOARD;
		}

        void CBeamNode::OnRegisterSceneNode(void)
        {
            if (IsVisible)
            {
                SceneManager->registerNodeForRendering(this, irr::scene::ESNRP_TRANSPARENT);
                ISceneNode::OnRegisterSceneNode();
            }
        }

        void CBeamNode::OnAnimate(u32 timeMs)
        {
            ISceneNode::OnAnimate(timeMs);
        }

        void CBeamNode::setLine(core::vector3df start, core::vector3df end, f32 thickness)
        {
            setPosition(start);
            m_start = core::vector3df(0,0,0);
            m_end = end;
            m_thickness = thickness;
        }

        void CBeamNode::render(void)
        {
            video::IVideoDriver* driver = SceneManager->getVideoDriver();
            driver->setTransform(irr::video::ETS_WORLD, AbsoluteTransformation);

            core::vector3df direction = m_end-m_start;
            direction.normalize();
            core::vector3df savesatrt = m_start;
            AbsoluteTransformation.transformVect(savesatrt);
            core::vector3df lookdir = savesatrt-SceneManager->getActiveCamera()->getAbsolutePosition();
            if(lookdir.getLength() < 20)
                return;
            lookdir.normalize();

            core::vector3df view(SceneManager->getActiveCamera()->getTarget() - SceneManager->getActiveCamera()->getAbsolutePosition());
            view.normalize();

            f32 angle = lookdir.dotProduct(direction)/*/(lookdir.getLength()*direction.getLength())*/;

            core::vector3df updown = direction.crossProduct(lookdir);
            updown.normalize();
            core::vector3df normal = direction.crossProduct(updown);
            video::S3DVertex vertices[4];
            u16 indices[] = {0,1,2,1,3,2};

            vertices[0] = video::S3DVertex(m_end-updown*m_thickness*0.5f, normal, video::SColor(255,255,255,255), core::vector2d<f32>(0,0));
            vertices[1] = video::S3DVertex(m_end+updown*m_thickness*0.5f, normal, video::SColor(255,255,255,255), core::vector2d<f32>(0,1));
            vertices[2] = video::S3DVertex(m_start-updown*m_thickness*0.5f, normal, video::SColor(255,255,255,255), core::vector2d<f32>(1,0));
            vertices[3] = video::S3DVertex(m_start+updown*m_thickness*0.5f, normal, video::SColor(255,255,255,255), core::vector2d<f32>(1,1));

            driver->setMaterial(material);
            driver->drawIndexedTriangleList(&vertices[0], 4, &indices[0], 2);
            //driver->draw3DLine(m_start, m_end, video::SColor(255,255,0,0));
        }

        const core::aabbox3d<f32>& CBeamNode::getBoundingBox() const
        {
            return Box;
        }

        u32 CBeamNode::getMaterialCount() const
        {
            return 1;
        }


        video::SMaterial& CBeamNode::getMaterial(u32 i)
        {
                return material;
        }
    }
} 
liusa80
Posts: 17
Joined: Tue Apr 06, 2010 3:24 am

Post by liusa80 »

how to use this class ?
like this
scene::CBeamSceneNode* beam = new scene::CBeamNode(parent, smgr, -1, "The texture the beam should have when looking at it from the side , "The texture when looking at the cap" );

//now set the beam
beam->setLine(core::vector3df(0,0,0), core::vector3df(10,10,10), 5.0f);

beam->drop();
but it occur errors,
error C2065: 'CBeamSceneNode' : undeclared identifier
1>d:\tddownload\irrlicht\examples\01.helloworld\main.cpp(108) : error C2065: 'beam' : undeclared identifier
1>d:\tddownload\irrlicht\examples\01.helloworld\main.cpp(108) : error C2039: 'CBeamNode' : is not a member of 'irr::scene'
1>d:\tddownload\irrlicht\examples\01.helloworld\main.cpp(108) : error C2061: syntax error : identifier 'CBeamNode'
1>d:\tddownload\irrlicht\examples\01.helloworld\main.cpp(111) : error C2065: 'beam' : undeclared identifier
1>d:\tddownload\irrlicht\examples\01.helloworld\main.cpp(111) : error C2227: left of '->setLine' must point to class/struct/union/generic type
1> type is ''unknown-type''
1>d:\tddownload\irrlicht\examples\01.helloworld\main.cpp(113) : error C2065: 'beam' : undeclared identifier
1>d:\tddownload\irrlicht\examples\01.helloworld\main.cpp(113) : error C2227: left of '->drop' must point to class/struct/union/generic type
1> type is ''unknown-type''
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

liusa80 wrote:scene::CBeamSceneNode* beam
it's probably because it's called CBeamNode !?!?! :lol:
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Post by Lonesome Ducky »

It's also not in the scene namespace
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

Lonesome Ducky wrote:It's also not in the scene namespace
no, it is in the namespace irr::scene !!! ;)
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Post by Lonesome Ducky »

Acki wrote:
Lonesome Ducky wrote:It's also not in the scene namespace
no, it is in the namespace irr::scene !!! ;)
Oh, duh, I can't believe I overlooked that. I'm just use to the classes people write not being in namespaces
slavik262
Posts: 753
Joined: Sun Nov 22, 2009 9:25 pm
Location: Wisconsin, USA

Post by slavik262 »

In your opinions, what's the "right" way to do things: place custom scene nodes in irr::scene or not? I generally stray away from it since in my mind, the irr namespace should be reserved for components of Irrlicht only.
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

slavik262 wrote:In your opinions, what's the "right" way to do things: place custom scene nodes in irr::scene or not? I generally stray away from it since in my mind, the irr namespace should be reserved for components of Irrlicht only.
right, but IMO even custom scene nodes are Irrlicht objects !!!
I always place selfmade (Irrlicht) components in the appropriate namespace(s)... ;)
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
slavik262
Posts: 753
Joined: Sun Nov 22, 2009 9:25 pm
Location: Wisconsin, USA

Post by slavik262 »

I'm not saying I'm against using namespaces - just that I usually put my custom elements in my own custom namespaces.
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Post by Lonesome Ducky »

slavik262 wrote:I'm not saying I'm against using namespaces - just that I usually put my custom elements in my own custom namespaces.
I'm the same way, I leave the irrlicht namespaces for irrlicht, like you said. I think it's more a matter of personal preference than anything else.
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

well, you can put it in any namespace you want, even in no namespace at all, in most cases it's just a matter of taste (as long as you don't get conflicts with other objects/functions that have the same names)... :lol:

but I think it's more intuitive to hold elements in their appropriate namespaces...
scene objects in irr::scene, gui elements in irr::gui, and so on...

it's like with variable names and such, some people like to give them intuitive names (eg. moveSpeed, enemyPosition, etc.) and others don't care about the names (eg. ms, ep, xyz, etc.)... :lol:

but if you don't like it, well, then do it like you please, it's your code and you'll have to live with it... ;)
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
liusa80
Posts: 17
Joined: Tue Apr 06, 2010 3:24 am

how to fix this error

Post by liusa80 »

error LNK2019: unresolved external symbol "public: void __thiscall irr::scene::CBeamSceneNode::setLine(class irr::core::vector3d<float>,class irr::core::vector3d<float>,float)" (?setLine@CBeamSceneNode@scene@irr@@QAEXV?$vector3d@M@core@3@0M@Z) referenced in function _main
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Maybe include the file into your project, or link against it at least?
liusa80
Posts: 17
Joined: Tue Apr 06, 2010 3:24 am

Post by liusa80 »

all have done
Post Reply