(C++) Polyline node

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
sdi2000
Posts: 129
Joined: Thu Aug 25, 2005 12:19 pm
Location: Berlin, DE
Contact:

(C++) Polyline node

Post by sdi2000 »

The polylinenode represent a polyline with boxes as connection points between the lines.
Note the boxes was create with the old call "addTestSceneNode", because i use the irrlicht version 0.14
:D

You can switch the visiblity for one connection point or for all.
You can also switch the visibility of all lines.

If you dont want a collision response from the parent node dont set an id.

Any new ideas for this node are welcome.

I use this node to represent a cam in the editor mode of my game framework or a spline for an animated cam.

http://dev-delight.sourceforge.net


check the code out.
the header file.
CPolylineNode.h

Code: Select all

// Copyright (C) 2006 Oliver Klems aka sdi2000 
// This file uses the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h

#ifndef __C_POLYLINE_NODE__
#define __C_POLYLINE_NODE__

#include <Irrlicht.h>

namespace irr{

namespace scene{

/**
 * A class to map a point to an id.
 * A point was also a box to make the position manipulation eaysier.
 */
class CPointIdMap
{
public:
	CPointIdMap()
	{
		m_id = -1;
		m_scale = core::vector3df(1.0, 1.0, 1.0);
		m_visiblePathPoint = true;
	}
	core::vector3df		m_position;
	core::vector3df		m_rotation;
	core::vector3df		m_scale;
	core::string<c8>	m_texture;
	s32					m_id;
	bool				m_visiblePathPoint;
};

/**
 * The CPoliyLine class.
 */
class CPolylineNode : public ISceneNode
{
public:
    CPolylineNode(ISceneNode* parent, ISceneManager* mgr, s32 id = -1, 
			const core::vector3df& position = core::vector3d<f32>(0,0,0),  
			const core::vector3df& rotation = core::vector3d<f32>(0,0,0), 
			const core::vector3df& scale    = core::vector3d<f32>(1,1,1));

	virtual ~CPolylineNode();

	virtual void setPolyLine(const core::array<CPointIdMap> &_pointArray);
	virtual core::array<CPointIdMap> getPolyLine();

	virtual void addPoint(const CPointIdMap &_point);

	virtual void setPoint(const CPointIdMap &_point);
	virtual CPointIdMap getPointById(s32 _id);

	virtual void setAllPointsVisible(bool _visible);
	virtual bool isAllPointsVisible();

	virtual void setPointVisible(bool _visible, s32 _id);
	virtual bool isPointVisible(s32 _id);
	
	virtual void setLinesVisible(bool _visible);
	virtual bool isLinesVisible();

	virtual void removePoint(s32 _id);
	virtual void removeAllPoints();

	virtual void setCubeSize(f32 _size = 10.0f);

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

private:
	void generateBoxes();
	core::array<CPointIdMap> m_pointArray;
	bool					m_allPointVisible;
	bool					m_linesVisible;
	f32						m_size;
	core::aabbox3d<f32>     m_Box;
	bool					m_isID;
};

}
}

#endif //__C_POLYLINE_NODE__

the cpp file.
CPolylineNode.cpp

Code: Select all

#include "CPolyLineNode.h"

namespace irr{

namespace scene{


CPolylineNode::CPolylineNode(ISceneNode* parent, ISceneManager* mgr, s32 id, 
							 const core::vector3df& position,  
							 const core::vector3df& rotation, 
							 const core::vector3df& scale)
: ISceneNode(parent, mgr, id, position, rotation, scale)
{
	m_allPointVisible = true;
	m_linesVisible = true;
	m_size = 10.0f;

	m_isID = false;

	if(id != -1)
		m_isID = true;
    #ifdef _DEBUG
    setDebugName("CPolylineNode");
    #endif
	m_Box.reset(getPosition());
}

CPolylineNode::~CPolylineNode()
{
}

void CPolylineNode::setPolyLine(const core::array<CPointIdMap> &_pointArray)
{
	m_Box.reset(getPosition());
	m_pointArray = _pointArray;
	generateBoxes();
}

core::array<CPointIdMap> CPolylineNode::getPolyLine()
{
	return m_pointArray;
}

void CPolylineNode::addPoint(const CPointIdMap &_point)
{
	m_pointArray.push_back(_point);
	ISceneNode *node = SceneManager->addTestSceneNode(m_size, this, _point.m_id, _point.m_position, _point.m_rotation, _point.m_scale);
	if(node != NULL)
	{
		if(_point.m_texture.size()>0)
		{
			video::ITexture *texture = SceneManager->getVideoDriver()->getTexture(_point.m_texture.c_str());
			if(texture != NULL)
			{
				texture->regenerateMipMapLevels();
				node->setMaterialTexture(0,texture);
			}
		}
		if(m_isID)
			m_Box.addInternalBox(node->getTransformedBoundingBox());
		node->setVisible(_point.m_visiblePathPoint);
	}
}

void CPolylineNode::setPoint(const CPointIdMap &_point)
{
	ISceneNode *node = NULL;
	u32 idx = 0;
	for(idx = 0; idx < m_pointArray.size(); ++idx)
	{
		if(m_pointArray[idx].m_id == _point.m_id)
		{
			m_pointArray[idx] = _point;
			break;
		}
	}

	node = SceneManager->getSceneNodeFromId(_point.m_id);
	if(node != NULL)
	{
		node->setPosition(_point.m_position);
		node->setRotation(_point.m_rotation);
		node->setScale(_point.m_scale);

		if(_point.m_texture.size()>0)
		{
			video::ITexture *texture = SceneManager->getVideoDriver()->getTexture(_point.m_texture.c_str());
			if(texture != NULL)
			{
				texture->regenerateMipMapLevels();
				node->setMaterialTexture(0,texture);
			}
		}
	}

	m_Box.reset(getPosition());
	for(idx = 0; idx < m_pointArray.size(); ++idx)
	{
		node = SceneManager->getSceneNodeFromId(m_pointArray[idx].m_id);
		if(node != NULL)
		{
			if(m_isID)
				m_Box.addInternalBox(node->getTransformedBoundingBox());
		}
	}
}

CPointIdMap CPolylineNode::getPointById(s32 _id)
{
	u32 idx = 0;
	for(idx = 0; idx < m_pointArray.size(); ++idx)
	{
		if(m_pointArray[idx].m_id == _id)
			return m_pointArray[idx];
	}
	return CPointIdMap();
}

void CPolylineNode::setAllPointsVisible(bool _visible)
{
	m_allPointVisible = _visible;
	for(u32 idx = 0; idx < m_pointArray.size(); ++idx)
	{
		ISceneNode *node = SceneManager->getSceneNodeFromId(m_pointArray[idx].m_id);
		if(node != NULL)
		{
			node->setVisible(m_allPointVisible);
		}
	}
}

bool CPolylineNode::isAllPointsVisible()
{
	return m_allPointVisible;
}

void CPolylineNode::setPointVisible(bool _visible, s32 _id)
{
	ISceneNode *node = SceneManager->getSceneNodeFromId(_id);
	if(node != NULL)
	{
		node->setVisible(_visible);
	}
}

bool CPolylineNode::isPointVisible(s32 _id)
{
	ISceneNode *node = SceneManager->getSceneNodeFromId(_id);
	if(node != NULL)
	{
		return node->isVisible();
	}
	return false;
}

void CPolylineNode::setLinesVisible(bool _visible)
{
	m_linesVisible = _visible;
}

bool CPolylineNode::isLinesVisible()
{
	return m_linesVisible;
}

void CPolylineNode::removePoint(s32 _id)
{
	ISceneNode *node = SceneManager->getSceneNodeFromId(_id);
	if(node != NULL)
	{
		SceneManager->addToDeletionQueue(node);
	}
	for(u32 idx = 0; idx < m_pointArray.size(); ++idx)
	{
		if(m_pointArray[idx].m_id == _id)
			break;
	}
	m_pointArray.erase(idx);
}

void CPolylineNode::removeAllPoints()
{
	for(u32 idx = 0; idx < m_pointArray.size(); ++idx)
	{
		ISceneNode *node = SceneManager->getSceneNodeFromId(m_pointArray[idx].m_id);
		if(node != NULL)
		{
			SceneManager->addToDeletionQueue(node);
		}
	}
	m_pointArray.clear();
	m_Box.reset(getPosition());
}

void CPolylineNode::setCubeSize(f32 _size)
{
	m_size = _size;
}

const core::aabbox3d<f32>& CPolylineNode::getBoundingBox() const
{
	return m_Box;
}

void CPolylineNode::OnPreRender()
{
    if (IsVisible)
    {
		SceneManager->registerNodeForRendering(this);
		ISceneNode::OnPreRender();
	}
}

void CPolylineNode::render()
{
	if(!m_linesVisible)
		return;

	SceneManager->getVideoDriver()->setTransform(video::ETS_WORLD, AbsoluteTransformation);
	video::SMaterial m;
	m.Lighting = false;
	SceneManager->getVideoDriver()->setMaterial(m);
	// for debug purposes only:
	if (DebugDataVisible)
	{
		SceneManager->getVideoDriver()->draw3DBox(m_Box, video::SColor(0,255,255,255));		
	}

	irr::core::line3df line;
	for(u32 idx = 0; idx < m_pointArray.size(); ++idx)
	{
		if(idx == 0)
		{
			line.start = m_pointArray[idx].m_position;
		}
		else if(idx == 1)
		{
			line.end = m_pointArray[idx].m_position;
		}
		else
		{
			line.start = line.end;
			line.end = m_pointArray[idx].m_position;
		}

		if(idx > 0)
			SceneManager->getVideoDriver()->draw3DLine(line.start, line.end, video::SColor(1,255,255,255));
	}
}

void CPolylineNode::generateBoxes()
{
	u32 idx = 0;
	for(idx = 0; idx < m_pointArray.size(); ++idx)
	{
		ISceneNode *node = SceneManager->addTestSceneNode(m_size, this, m_pointArray[idx].m_id, 
														  m_pointArray[idx].m_position, 
														  m_pointArray[idx].m_rotation, 
														  m_pointArray[idx].m_scale);
		if(node != NULL)
		{
			if(m_pointArray[idx].m_texture.size()>0)
			{
				video::ITexture *texture = SceneManager->getVideoDriver()->getTexture(m_pointArray[idx].m_texture.c_str());
				if(texture != NULL)
				{
					texture->regenerateMipMapLevels();
					node->setMaterialTexture(0,texture);
				}
			}
			if(m_isID)
				m_Box.addInternalBox(node->getTransformedBoundingBox());
			node->setVisible(m_pointArray[idx].m_visiblePathPoint);
		}
	}
}


}
}
i hope that code is usefull for anyone....
have fun...


:D
sdi2000
Posts: 129
Joined: Thu Aug 25, 2005 12:19 pm
Location: Berlin, DE
Contact:

Post by sdi2000 »

an update to prevent some errors in the "removePoint" function :oops:
new code:

Code: Select all


void CPolylineNode::removePoint(s32 _id)
{
   ISceneNode *node = SceneManager->getSceneNodeFromId(_id);
   if(node != NULL)
   {
      SceneManager->addToDeletionQueue(node);
   }
   for(u32 idx = 0; idx < m_pointArray.size(); ++idx)
   {
      if(m_pointArray[idx].m_id == _id)
      {
         m_pointArray.erase(idx);
         break;
      }
   }

} 
okay thats all
sdi2000
Posts: 129
Joined: Thu Aug 25, 2005 12:19 pm
Location: Berlin, DE
Contact:

Post by sdi2000 »

a screenshot: polylinenode in action
Image
Post Reply