Placing 3D "line" based on end points?
Placing 3D "line" based on end points?
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!
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!
-
- Competition winner
- Posts: 1123
- Joined: Sun Jun 10, 2007 11:14 pm
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:
CBeamSceneNode.cpp:
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
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;
}
}
}
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''
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''
it's probably because it's called CBeamNode !?!?!liusa80 wrote:scene::CBeamSceneNode* beam
while(!asleep) sheep++;
IrrExtensions:
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
IrrExtensions:
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
-
- Competition winner
- Posts: 1123
- Joined: Sun Jun 10, 2007 11:14 pm
no, it is in the namespace irr::scene !!!Lonesome Ducky wrote:It's also not in the scene namespace
while(!asleep) sheep++;
IrrExtensions:
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
IrrExtensions:
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
-
- Competition winner
- Posts: 1123
- Joined: Sun Jun 10, 2007 11:14 pm
right, but IMO even custom scene nodes are Irrlicht objects !!!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.
I always place selfmade (Irrlicht) components in the appropriate namespace(s)...
while(!asleep) sheep++;
IrrExtensions:
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
IrrExtensions:
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
-
- Competition winner
- Posts: 1123
- Joined: Sun Jun 10, 2007 11:14 pm
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)...
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.)...
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...
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.)...
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:
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
IrrExtensions:
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
how to fix this error
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