Editor style Grid SceneNode [Updated: Sept. 27, 2009]

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Post by christianclavet »

I've integrated the node in my editor. It work perfectly.
Thanks.
switch_case
Posts: 34
Joined: Sat Mar 08, 2008 12:46 pm
Location: Germany, FFM
Contact:

Post by switch_case »

i just tested it and it worked. had a few warnings with values beeing initialized to late, but it worked ;)
looks nice, i was about to write one myself those days, but i think i will use yours, so i can waste my time on other projects. :)
if life could only be written in C++...
so much features, money++, remove_childs(), choose parents, life = new life, and no more <IDIOT> templates !
if you're looking for an nerdy coding language: http://lolcode.com/
Dark_Kilauea
Posts: 368
Joined: Tue Aug 21, 2007 1:43 am
Location: The Middle of Nowhere

Post by Dark_Kilauea »

Thanks for the kind words.
rogerborg wrote:Every time someone learns to use a debugger, an angel gets their wings.
unclejoe
Posts: 10
Joined: Fri Mar 28, 2008 2:27 pm
Location: Europe

Post by unclejoe »

Damn! You did a great job! I'm using this in my level editor for sure! :D
I was trying to do someting like it with this piece of code:

Code: Select all

c8 i, j;
for (i=0; i!=64; i++)
for (j=0; j!=64; j++) {
  driver->draw3DLine (core::vector3df (j, i, 0), core::vector3df (j, i+1, 0) );
  driver->draw3DLine (core::vector3df (j+1, i, 0), core::vector3df (j+1, i+1, 0) );
  driver->draw3DLine (core::vector3df (j, i, 0), core::vector3df (j+1, i, 0) );
  driver->draw3DLine (core::vector3df (j, i+1, 0), core::vector3df (j+1, i+1, 0) );
}
But your SceneNode is much faster, and has more options! Great work!
wITTus
Posts: 167
Joined: Tue Jun 24, 2008 7:41 pm
Location: Germany

Warnings

Post by wITTus »

I got some warnings with GCC 4.1.2:

Code: Select all

src/ext/CGridSceneNode.h:127: warning: ‘CGridSceneNode::m_accentlineoffset’ will be initialized after
src/ext/CGridSceneNode.h:126: warning:   ‘irr::video::SColor CGridSceneNode::m_accentgridcolor’
src/ext/CGridSceneNode.h:26: warning:   when initialized here

Code: Select all

src/ext/CGridSceneNode.h:133:34: warning: no newline at end of file
So, here's the patch:

Code: Select all

wittus@hell ~/Projects/Irrlicht/ext $ diff -Naur CGridSceneNode.h CGridSceneNode_fixed.h 
--- CGridSceneNode.h    2008-09-29 18:59:17.560709357 +0300
+++ CGridSceneNode_fixed.h      2008-09-29 18:59:21.432713933 +0300
@@ -25,8 +25,8 @@
                u32 spacing = 8, u32 size = 1024, SColor gridcolor = SColor(255,128,128,128), u32 accentlineoffset = 8, 
                SColor accentgridcolor = SColor(255,192,192,192), bool axislinestate = false)   : ISceneNode(parent_rootSceneNode, smgr, id), 
                m_spacing(spacing), m_size(size), 
-               m_gridcolor(gridcolor), m_accentlineoffset(accentlineoffset), 
-               m_accentgridcolor(accentgridcolor), m_AxisLineState(axislinestate),
+               m_gridcolor(gridcolor), m_accentgridcolor(accentgridcolor),
+               m_accentlineoffset(accentlineoffset), m_AxisLineState(axislinestate),
                m_XLineColor(SColor(255,255,0,0)), m_ZLineColor(SColor(255,0,0,255))
        {
                // Set the material
@@ -131,3 +131,4 @@
 };
 
 #endif // __C_GRID_SCENE_NODE_H__
+
Dark_Kilauea
Posts: 368
Joined: Tue Aug 21, 2007 1:43 am
Location: The Middle of Nowhere

Post by Dark_Kilauea »

gcc can be frickle about the newlines, I'll be sure to update that.

Thanks.
rogerborg wrote:Every time someone learns to use a debugger, an angel gets their wings.
JP
Posts: 4526
Joined: Tue Sep 13, 2005 2:56 pm
Location: UK
Contact:

Post by JP »

Dark_Kilauea, very useful scene node as i've probably mentioned before in this thread. I've been using it in my latest project and i decided to optimise the rendering a tad, so here's an updated version which you may or may not be interested in putting on the front page in some way!

Basically in your version you're doing a call to driver->draw3DLine() for each line of the grid which doesn't give the best performance as it's a lot of draw calls which are vulnerable to stalls. So i've just wacked all the necessary vertices into a big buffer in the constructor so that in the render function you can just render them all in one draw call, should be quite a performance boost!

CGridSceneNode.h

Code: Select all

#ifndef INC_CGRIDSCENENODE_H
#define INC_CGRIDSCENENODE_H

// Original Author: Dark_Kilauea
// Optimised by: JP
// From: http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=24938

#include <irrlicht.h>

using namespace irr;

class CGridSceneNode : public scene::ISceneNode
{
public:
	//Setting accentlineoffset to 0 causes accentlines to not be rendered.
	//If you need a grid on the XY or ZY axis, simply rotate this node by 90 degrees in the appropiate axis.
	//This node creates an XZ grid by default, which should be fine for normal use.
	CGridSceneNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id = -1, u32 spacing = 4, u32 size = 128, video::SColor gridcolor = video::SColor(255,0,200,0), s32 accentlineoffset = 8, video::SColor accentgridcolor = video::SColor(255,0,255,0));

	//Inherited from ISceneNode
	virtual void OnRegisterSceneNode();
	virtual void render();
	virtual const core::aabbox3d<f32>& getBoundingBox() const;
	virtual u32 getMaterialCount();
	virtual video::SMaterial& getMaterial(u32 i);

	//Various Gets
	s32 GetSpacing();
	s32 GetSize();
	video::SColor GetGridColor();
	s32 GetAccentlineOffset();
	video::SColor GetAccentlineColor();

	//Various Sets
	void SetSpacing(s32 newspacing);
	void SetSize(s32 newsize);
	void SetGridColor(video::SColor newcolor);
	void SetAccentlineOffset(s32 newoffset);
	void SetAccentlineColor(video::SColor newcolor);


private:
	//These are mine!  All Mine!
	core::aabbox3d<f32> Box;
	video::SMaterial Material;
	u32 m_spacing;
	u32 m_size;
	video::SColor m_gridcolor;
	video::SColor m_accentgridcolor;
	s32 m_accentlineoffset;
	video::S3DVertex* m_vertexBuffer;
	u16* m_indexBuffer;
	u32 m_numLines;
	u32 m_numVertices;



};

#endif /* INC_CGRIDSCENENODE_H */

CGridSceneNode.cpp

Code: Select all

#include "CGridSceneNode.h"


// Original Author: Dark_Kilauea
// Optimised by: JP
// From: http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=24938

	//Setting accentlineoffset to 0 causes accentlines to not be rendered.
	//If you need a grid on the XY or ZY axis, simply rotate this node by 90 degrees in the appropiate axis.
	//This node creates an XZ grid by default, which should be fine for normal use.
	CGridSceneNode::CGridSceneNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, u32 spacing, u32 size, video::SColor gridcolor, s32 accentlineoffset, video::SColor accentgridcolor) : scene::ISceneNode(parent, mgr, id)
	{
		//Set the material
		Material.Wireframe = false;
		Material.Lighting = false;
		Material.Thickness = 1;
		Material.FogEnable = false;

		//Set our internal variables to match the constructor
		m_spacing = spacing;
		m_size = size;
		m_gridcolor = gridcolor;
		m_accentlineoffset = accentlineoffset;
		m_accentgridcolor = accentgridcolor;

		//Create our box, it is the size of the grid exactly, plus 1 in the Y axis
		Box = core::aabbox3df(-(s32)size/2.0f,-1.0f,-(s32)size/2.0f,size/2.0f,1.0f,size/2.0f);

		m_numVertices = ((m_size / m_spacing) + 1) * 2 * 2;
		if (m_accentlineoffset) m_numVertices += ((m_size / (m_spacing * m_accentlineoffset)) + 1) * 2 * 2;
		m_numLines = m_numVertices / 2;

		m_vertexBuffer = new video::S3DVertex[m_numVertices];
		m_indexBuffer = new u16[m_numVertices];

		//Set our left corner
		core::vector3df leftMost = core::vector3df(0,0,0);
		leftMost.X -= m_size/2;
		leftMost.Z -= m_size/2;

		//Set our right corner
		core::vector3df rightMost = core::vector3df(0,0,0);
		rightMost.X += m_size/2;
		rightMost.Z += m_size/2; 

		u32 vertIndex = 0;
		u32 indexIndex = 0;

		//X-axis lines
		for(u32 x = 0; x <= m_size; x+= m_spacing)
		{
			core::vector3df start = leftMost;
			start.X += x ;

			core::vector3df end = rightMost;
			end.X = start.X;

			m_vertexBuffer[vertIndex++] = video::S3DVertex(start, core::vector3df(0,1,0), m_gridcolor, core::vector2df(0.0f, 0.0f));
			m_vertexBuffer[vertIndex++] = video::S3DVertex(end, core::vector3df(0,1,0), m_gridcolor, core::vector2df(0.0f, 0.0f));

			m_indexBuffer[indexIndex] = indexIndex++;
			m_indexBuffer[indexIndex] = indexIndex++;
		}

		//Z-axis lines
		for(u32 z = 0; z <= m_size; z+= m_spacing)
		{
			core::vector3df start = leftMost;
			start.Z += z ;

			core::vector3df end = rightMost;
			end.Z = start.Z;

			m_vertexBuffer[vertIndex++] = video::S3DVertex(start, core::vector3df(0,1,0), m_gridcolor, core::vector2df(0.0f, 0.0f));
			m_vertexBuffer[vertIndex++] = video::S3DVertex(end, core::vector3df(0,1,0), m_gridcolor, core::vector2df(0.0f, 0.0f));

			m_indexBuffer[indexIndex] = indexIndex++;
			m_indexBuffer[indexIndex] = indexIndex++;
		}

		//Accent lines are only drawn if the offset is greater than 0
		if(m_accentlineoffset > 0)
		{
			//X-axis
			for(u32 x = 0; x <= m_size; x+= m_spacing*m_accentlineoffset)
			{
				core::vector3df start = leftMost;
				start.X += x ;

				core::vector3df end = rightMost;
				end.X = start.X;

				m_vertexBuffer[vertIndex++] = video::S3DVertex(start, core::vector3df(0,1,0), m_accentgridcolor, core::vector2df(0.0f, 0.0f));
				m_vertexBuffer[vertIndex++] = video::S3DVertex(end, core::vector3df(0,1,0), m_accentgridcolor, core::vector2df(0.0f, 0.0f));

				m_indexBuffer[indexIndex] = indexIndex++;
				m_indexBuffer[indexIndex] = indexIndex++;
			}

			//Z-axis
			for(u32 z = 0; z <= m_size; z+= m_spacing*m_accentlineoffset)
			{
				core::vector3df start = leftMost;
				start.Z += z ;

				core::vector3df end = rightMost;
				end.Z = start.Z;

				m_vertexBuffer[vertIndex++] = video::S3DVertex(start, core::vector3df(0,1,0), m_accentgridcolor, core::vector2df(0.0f, 0.0f));
				m_vertexBuffer[vertIndex++] = video::S3DVertex(end, core::vector3df(0,1,0), m_accentgridcolor, core::vector2df(0.0f, 0.0f));

				m_indexBuffer[indexIndex] = indexIndex++;
				m_indexBuffer[indexIndex] = indexIndex++;
			}
		}

	}

	//Pre-Register stuff
	void CGridSceneNode::OnRegisterSceneNode()
	{
		if (IsVisible)
			SceneManager->registerNodeForRendering(this);

		ISceneNode::OnRegisterSceneNode();
	}

	//Render our grid of 3D lines
	void CGridSceneNode::render()
	{
		video::IVideoDriver* driver = SceneManager->getVideoDriver();

		//Prep to render
		driver->setMaterial(Material);
		driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);

		driver->drawVertexPrimitiveList(m_vertexBuffer, m_numVertices, m_indexBuffer, m_numLines, video::EVT_STANDARD, scene::EPT_LINES);
	} 

	//////////////////////////////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////////

	//Returns our lovely bounding box
	const core::aabbox3d<f32>& CGridSceneNode::getBoundingBox() const
	{
		return Box;
	}

	//Returns the total number of materials, in this case, only 1
	u32 CGridSceneNode::getMaterialCount()
	{
		return 1;
	}

	//Returns the only material
	video::SMaterial& CGridSceneNode::getMaterial(u32 i)
	{
		return Material;
	}

	//Returns the Spacing of the grid
	s32 CGridSceneNode::GetSpacing()
	{
		return m_spacing;
	}

	//Returns the total size of the grid
	s32 CGridSceneNode::GetSize()
	{
		return m_size;
	}

	//Returns the offset of the accent lines
	s32 CGridSceneNode::GetAccentlineOffset()
	{
		return m_accentlineoffset;
	}

	//Returns the Accent Line Color
	video::SColor CGridSceneNode::GetAccentlineColor()
	{
		return m_accentgridcolor;
	}

	//Returns the Grid Color
	video::SColor CGridSceneNode::GetGridColor()
	{
		return m_gridcolor;
	}

	///////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////////////////////

	//Sets Spacing
	void CGridSceneNode::SetSpacing(s32 newspacing)
	{
		m_spacing = newspacing;
	}

	//Sets Size
	void CGridSceneNode::SetSize(s32 newsize)
	{
		m_size = newsize;
	}

	//Sets the color of the accent lines
	void CGridSceneNode::SetAccentlineColor(video::SColor newcolor)
	{
		m_accentgridcolor = newcolor;
	}

	//Sets the offset for the accent lines
	void CGridSceneNode::SetAccentlineOffset(s32 newoffset)
	{
		m_accentlineoffset = newoffset;
	}

	//Sets the general grid color
	void CGridSceneNode::SetGridColor(video::SColor newcolor)
	{
		m_gridcolor = newcolor;
	}


Image Image Image
Steel Style
Posts: 168
Joined: Sun Feb 04, 2007 3:30 pm
Location: France

Post by Steel Style »

Good work JP but I don't think that now they will be able to change the code.
Dark_Kilauea
Posts: 368
Joined: Tue Aug 21, 2007 1:43 am
Location: The Middle of Nowhere

Post by Dark_Kilauea »

Thanks JP for your optimization, I took your ideas and modified them a little. Now the vertex data is stored in a mesh buffer, making it simpler (at least for me) to understand where all the data is stored.

I also made it possible to regenerate the grid, as well as having the SetFoo() functions that modify the grid automatically regenerate the buffer. I also included a few minor bug fixes, like moving the node to the irr::scene namespace to remove those nasty using namespace declarations.

I highly recommend that past users update to this version.
rogerborg wrote:Every time someone learns to use a debugger, an angel gets their wings.
JP
Posts: 4526
Joined: Tue Sep 13, 2005 2:56 pm
Location: UK
Contact:

Post by JP »

Shocking!

Shows how much attention i paid to your code, i didn't realise there were setter methods to adjust the grid! lol

Storing it in a mesh buffer may be a sort of cleaner method i suppose, a bit safer perhaps! Basically does the same job but wrapped up nicely and if the mesh buffer got optimised in future or something then it would make this code better too!
Image Image Image
Steel Style
Posts: 168
Joined: Sun Feb 04, 2007 3:30 pm
Location: France

Post by Steel Style »

Hi again the link is down, someone is able to reload ?
Dark_Kilauea
Posts: 368
Joined: Tue Aug 21, 2007 1:43 am
Location: The Middle of Nowhere

Post by Dark_Kilauea »

Link works fine here, perhaps you should try again?
rogerborg wrote:Every time someone learns to use a debugger, an angel gets their wings.
geckoman
Posts: 143
Joined: Thu Nov 27, 2008 11:05 am
Location: Germany
Contact:

Post by geckoman »

Hi there is a bug (compile error), I think it's 1.5 related: Line 185 in the cpp file

change from

Code: Select all

		driver->drawVertexPrimitiveList(Buffer.getVertices(), Buffer.getVertexCount(), Buffer.getIndices(), Buffer.getVertexCount()/2, video::EVT_STANDARD, scene::EPT_LINES);

to

Code: Select all

		driver->drawVertexPrimitiveList(Buffer.getVertices(), Buffer.getVertexCount(), Buffer.getIndices(), Buffer.getVertexCount()/2, video::EVT_STANDARD, scene::EPT_LINES, video::EIT_16BIT);

I'm so proud

:D :D :D :D :D
Dark_Kilauea
Posts: 368
Joined: Tue Aug 21, 2007 1:43 am
Location: The Middle of Nowhere

Post by Dark_Kilauea »

Hmm... that may be tricky to fix. If I add that last parameter to drawVertexPrimitiveList( ... ), then any Irrlicht version before 1.5 will be broken by it. I do find it strange that drawVertexPrimitiveList( ... ) does not have a default parameter of video::EIT_16BIT for backwards compatibility?
rogerborg wrote:Every time someone learns to use a debugger, an angel gets their wings.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Yes, the missing default value is a bug. The other things have to be figured out based on the current error reports. Our machines do not show these problems...
Post Reply