today I have some spare time and I make a custom node to have axial billboards (to make stuff like laser or energy ray or just trees over a terrain)
I post my code to show you how I make it, I have no pretention to universality. If severals are interested I can make a more complete stuff with more functionnalities (just ask
sorry I'm french (bad english, bad temper , ...)
a little explication : for a ray the node position is the origin of the ray. the end of the ray is given by position + orientation (orientation is the axis above which the billboard can turn) largeur is the width of the ray. You have to provide a texture (for a ray use an image that blend from black to red to white to red to black, blend from left to right of the image)
here is an image of billboards used to make a sort of grid

include file -edited- now you can use it directly (I hope):
Code: Select all
#ifndef __C_AXIALBB_NODE_H_INCLUDED__
#define __C_AXIALBB_NODE_H_INCLUDED__
// jfh custom node
// this is an axial billboard node
#include <irrlicht.h>
using namespace irr;
using namespace core;
using namespace video;
class CAxialBBNode : public scene::ISceneNode
{
public:
CAxialBBNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id,
vector3df orientation, f32 largeur,ITexture* texture);
void OnPreRender();
void render();
const core::aabbox3d<f32>& getBoundingBox() const;
s32 getMaterialCount();
video::SMaterial& getMaterial(s32 i);
private:
core::aabbox3d<f32> Box;
video::S3DVertex vertices[4];
u16 indices[6];
video::SMaterial Material;
vector3df orientation;
f32 largeur;
};
#endifCode: Select all
CAxialBBNode::CAxialBBNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id,
vector3df orientation, f32 largeur, ITexture* texture)
: scene::ISceneNode(parent, mgr, id)
{
this->orientation = orientation;
this->largeur = largeur/2;
indices[0] = 0;
indices[1] = 1;
indices[2] = 2;
indices[3] = 0;
indices[4] = 2;
indices[5] = 3;
Material.Lighting = false;
Material.BackfaceCulling = false;
this->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
this->setMaterialTexture(0,texture);
SColor color = SColor(255,255,255,255);
vertices[0].TCoords.set(0.0f, 0.0f);
vertices[0].Color = color;
vertices[1].TCoords.set(1.0f, 0.0f);
vertices[1].Color = color;
vertices[2].TCoords.set(1.0f, 1.0f);
vertices[2].Color = color;
vertices[3].TCoords.set(0.0f, 1.0f);
vertices[3].Color = color;
}
void CAxialBBNode::OnPreRender()
{
if (IsVisible)
SceneManager->registerNodeForRendering(this);
ISceneNode::OnPreRender();
}
void CAxialBBNode::render()
{
ISceneNode* camera = SceneManager->getActiveCamera();
IVideoDriver* driver = SceneManager->getVideoDriver();
vector3df pos = getAbsolutePosition();
vector3df campos = camera->getAbsolutePosition();
vector3df perp = orientation.crossProduct(campos - pos);
perp.normalize();
perp *= largeur;
vertices[0].Pos = pos - perp;
vertices[1].Pos = pos + perp;
vertices[2].Pos = pos + perp + orientation;
vertices[3].Pos = pos - perp + orientation;
driver->setMaterial(Material);
matrix4 mat;
driver->setTransform(video::ETS_WORLD, mat);
driver->drawIndexedTriangleList(vertices, 4, indices, 2);
}
const core::aabbox3d<f32>& CAxialBBNode::getBoundingBox() const
{
return Box;
}
s32 CAxialBBNode::getMaterialCount()
{
return 1;
}
video::SMaterial& CAxialBBNode::getMaterial(s32 i)
{
return Material;
}Code: Select all
// essai axial bb
CAxialBBNode* myNode2 = 0;
for (int i=0;i<9;i++)
{
myNode2 = new CAxialBBNode(smgr->getRootSceneNode(), smgr,1000,vector3df(100,0,0),3,yourtexture);
myNode2->setPosition(vector3df(-50,i*10,0));
myNode2->drop();
}