(C++) Simple Diamond object/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
Panther
Posts: 34
Joined: Tue Jun 06, 2006 1:05 am

(C++) Simple Diamond object/node

Post by Panther »

Here's a simple CDiamond class that you can paste into your code. It's nice because you don't have to physically load this object. I also provide an example of how to make it look nice below.

Code: Select all

class CDiamond : public scene::ISceneNode
{
	core::aabbox3d<f32> Box;
	video::S3DVertex Vertices[13];
	video::SMaterial Material;

public:

	CDiamond(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id)
		: scene::ISceneNode(parent, mgr, id)
	{
		Material.Wireframe = false;
		Material.Lighting = false;

		Vertices[0] =  video::S3DVertex(-8,3,0, 0,1,0, video::SColor(192,192,192,192), 0, 1);
		Vertices[1] =  video::S3DVertex(-5,3,8, 0,1,0, video::SColor(192,192,192,192), 1, 0);
		Vertices[2] =  video::S3DVertex(-5,3,-8, 0,1,0, video::SColor(192,192,192,192), 1, 1);
		Vertices[3] =  video::S3DVertex(8,3,0, 0,1,0, video::SColor(192,192,192,192), 0, 0);
		Vertices[4] =  video::S3DVertex(5,3,8, 0,1,0, video::SColor(192,192,192,192), 0, 1);
		Vertices[5] =  video::S3DVertex(5,3,-8, 0,1,0, video::SColor(192,192,192,192), 1, 1);
		Vertices[6] =  video::S3DVertex(-11,0,0, -1,1,0, video::SColor(192,192,192,192), 1, 0);
		Vertices[7] =  video::S3DVertex(-8,0,11, -1,1,1, video::SColor(192,192,192,192), 0, 0);
		Vertices[8] =  video::S3DVertex(-8,0,-11, -1,1,-1, video::SColor(192,192,192,192), 0, 1);
		Vertices[9] =  video::S3DVertex(11,0,0, 1,1,0, video::SColor(192,192,192,192), 1, 0);
		Vertices[10] = video::S3DVertex(8,0,11, 1,1,1, video::SColor(192,192,192,192), 1, 1);
		Vertices[11] = video::S3DVertex(8,0,-11, 1,1,-1, video::SColor(192,192,192,192), 0, 0);
		Vertices[12] = video::S3DVertex(0,-15,0,0,-1,0, video::SColor(192,192,192,192), 0, 1);

	// The Irrlicht Engine needs to know the bounding box of your scene node. 
		Box.reset(Vertices[0].Pos);
		for (s32 i=1; i<13; ++i)
			Box.addInternalPoint(Vertices[i].Pos);
	}

	// Before it is drawn, the OnPreRender() method of every scene node in the scene 
	//is called by the scene manager.
	virtual void OnPreRender()
	{
		if (IsVisible)
			SceneManager->registerNodeForRendering(this);

		ISceneNode::OnPreRender();
	}

	//	In the render() method most of the interesting stuff happens: The
	// Scene node renders itself. We override this method and draw the diamond.
	virtual void render()
	{
		//If the face isn't showing up, it may be "inside out".  In other words,
		//the vector is reversed.  To fix this, swap the 1st and 3rd terms; for
		//example, if your index is 3,9,7 then change it to 7,9,3 (a,b,c becomes c,b,a).
		u16 indices[] =  //These are the faces of the diamond
		{	2,0,1,
			5,2,1,
			5,1,4,
			5,4,3,
			1,0,6, 
			0,2,8, 
			8,6,0, 
			11,8,2, 
			2,5,11, 
			11,5,3, 
			3,9,11, 
			9,3,4, 
			4,10,9, 
			10,4,1, 
			1,7,10, 
			6,7,1, 
			8,11,12,
			12,11,9,
			12,9,10,
			12,10,7,
			12,7,6, 
			6,8,12
		};
		video::IVideoDriver* driver = SceneManager->getVideoDriver();
		driver->setMaterial(Material);
		driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
		driver->drawIndexedTriangleList(&Vertices[0], 13, &indices[0], 22);
	}

	/*
	At least, we create three small additional methods.
	GetBoundingBox() returns the bounding box of this scene node, 
	GetMaterialCount() returns the amount of materials in this scene node
	(our tetraeder only has one material), and getMaterial() returns the
	material at an index. Because we have only one material here, we can
	return the only one meterial, assuming that no one ever calls getMaterial()
	with an index greater than 0.
	*/
	virtual const core::aabbox3d<f32>& getBoundingBox() const
	{
		return Box;
	}

	virtual s32 getMaterialCount()
	{
		return 1;
	}

	virtual video::SMaterial& getMaterial(s32 i)
	{
		return Material;
	}	
};
Below is an example of how I recommend displaying it - translucent, with a crystal-like finish:

Code: Select all

   diamond = new CDiamond(smgr->getRootSceneNode(), smgr, 123);
   diamond[i]->setMaterialTexture(0, driver->getTexture("crystal.jpg"));
   diamond[i]->setMaterialType(EMT_TRANSPARENT_ADD_COLOR);
Here's a screen-shot:

Image

If you want my crystal.jpg texture, you can get it here:

Image

In my game, I slowly rotate it, so you can see all the faces. If anyone knows how to make it shimmer or glow nicely, please let me know.

Enjoy! :)
JPulham
Posts: 320
Joined: Sat Nov 19, 2005 12:06 pm

Post by JPulham »

Set its material to have high Specular, and also you could add lens affects if you REALLY wanted, but that would be a bit OTT :roll:

Good BTW :wink:
pushpork
Joe_Oliveri
Posts: 448
Joined: Tue Oct 05, 2004 3:24 am
Location: Boston, MA

Post by Joe_Oliveri »

Very cool code 8) Nice post.
Irrlicht Moderator || Game Designer
Learn the basics at </dream.in.code>
Electron
Posts: 874
Joined: Sun Mar 14, 2004 12:05 am
Location: Massachusetts USA

Post by Electron »

Looks nice, but. . .

1) Why create the indices in the render function? Create them once and store them.

2)Why not just create it as a model in a modeling package? Does it really need its own scene node type?
You do a lot of programming? Really? I try to get some in, but the debugging keeps me pretty busy.

Crucible of Stars
Post Reply