axial billboard

Discuss about anything related to the Irrlicht Engine, or read announcements about any significant features or usage changes.
Electron
Posts: 874
Joined: Sun Mar 14, 2004 12:05 am
Location: Massachusetts USA

Post by Electron »

okay, thanks

I was thinking about using IrrlichtNX soon myself, but if it won't compile right with dev-cpp maybe I won't.
You do a lot of programming? Really? I try to get some in, but the debugging keeps me pretty busy.

Crucible of Stars
knightoflight
Posts: 199
Joined: Sun Aug 24, 2003 5:47 pm
Location: Germany

Post by knightoflight »

new test: with your new code no change.
But i found the problem: i use EDT_DIRECTX8 (same result with EDT_DIRECTX9). With EDT_SOFTWARE and EDT_OPENGL everything works.
Have you tested with EDT_OPENGL ? Then please try with DirectX. Why is your code different between DIRECTX and SOFTWARE/OPENGL ???
calimero
Posts: 45
Joined: Sun Aug 08, 2004 4:31 pm
Location: Nice, France

Post by calimero »

knightoflight : I use just OpenGL because with devcpp I'm unable to set up directx8 or 9. I don't know why there is a difference :? between the renderers. have someone an idea ?
knightoflight
Posts: 199
Joined: Sun Aug 24, 2003 5:47 pm
Location: Germany

Post by knightoflight »

btw: sure you can use DirectX. Theres a HowTo for DevC++ (see the HowTo-section), i tested last week and it works. Meanwhile Afecelis wrote a tutorial (see project section) with Relo and i agree to Afecelis that Relo is better than DevC++ if you want to use DirectX, cause it uses the Visual C++ Toolkit.
calimero
Posts: 45
Joined: Sun Aug 08, 2004 4:31 pm
Location: Nice, France

Post by calimero »

Ok I made it the quick way : I just download some dlls that allow the use of directx with devcpp and it works !!!
My current version of the node behave the same way in opengl, directx8 and 9 !!!. I have funnies differences with textures not blurred in directx and some materials which behave differently with the lights but that's all.
I will conduct more tests on the node to see if I'm able to reproduce your problem.

-edited- : knigthoflight -> can you try to add

Code: Select all

AutomaticCullingEnabled = false;
in the constructor to see if it changes something ?
knightoflight
Posts: 199
Joined: Sun Aug 24, 2003 5:47 pm
Location: Germany

Post by knightoflight »

sorry for the inconvenience and if i go on your nerves, but DirectX still doesnt work. But you get it to work, so its maybe an effect of my computer (although all other things work). I will search - thanks, Calimero.
calimero
Posts: 45
Joined: Sun Aug 08, 2004 4:31 pm
Location: Nice, France

Post by calimero »

hello knightoflight to make more test I've taken the example "movement" like you and put my stuff into.
It works well with opengl and directx8 but I experiment some strange behaviour with directx9. The billboards tend to disappear like you describe it.
I think the problem is related with the viewfrustrum of the scene. I don't know why but I'm sure (almost) that the clipping planes are not at the same place when you change the render mode especially left and right plane. Combined with the strange default FOV of the camera in the example and and I think you have a good beginning of explanation :
if the two ends of the axial billboard are outside the frustrum it may not be rendered.
I don't know if it's possible to change easily the clipping planes. (I try setFarValue without much success)
but maybe you can make try with smaller billboards to see if it works and put others nodes in the scene to see if they disappear or not.
calimero
Posts: 45
Joined: Sun Aug 08, 2004 4:31 pm
Location: Nice, France

Post by calimero »

Ok today I manage with help of several people to compile irrlichtnx and test/improve my code :D .
As I think the node begins to be usable in a project I call this version v1.0


IAxialBillboardSceneNode.h :

Code: Select all

//added by JAMES
#ifndef __I_AXIALBB_NODE_H_INCLUDED__ 
#define __I_AXIALBB_NODE_H_INCLUDED__ 

// jfh "calimero" custom node 
// this is an axial billboard node
//original code by  calimero,slightly modified by me, JAMES
// calimero 14 august 2004 this is version 1.0 of the node
// I think this version is usable

#include "ISceneNode.h"
 

namespace irr
{
namespace scene
{

class IAxialBillboardSceneNode : public ISceneNode 
{ 
public: 
IAxialBillboardSceneNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id,
const core::vector3df& position = core::vector3df(0,0,0) )
: ISceneNode(parent, mgr, id, position) {} 

void OnPreRender()=0; 
void render()=0; 
const core::aabbox3d<f32>& getBoundingBox() const=0; 
s32 getMaterialCount()=0; 
video::SMaterial& getMaterial(s32 i)=0; 
virtual void setWidth(const f32 width)=0;
virtual f32 getWidth()=0;
virtual void setOrientation(const core::vector3df& orientation)=0;
virtual const core::vector3df& getOrientation()=0;
 
}; 

} // end namespace scene
} // end namespace irr

#endif 
//end added by JAMES
CAxialBillboardSceneNode.h :

Code: Select all

//added by JAMES
#ifndef __C_AXIALBB_NODE_H_INCLUDED__ 
#define __C_AXIALBB_NODE_H_INCLUDED__ 

// jfh "calimero" custom node 
// this is an axial billboard node
//original code by  calimero,slightly modified by me, JAMES
// calimero 14 august 2004 this is version 1.0 of the node
// I think this version is usable

#include "IAxialBillboardSceneNode.h"
#include "S3DVertex.h"
 

namespace irr
{
namespace scene
{

class CAxialBillboardSceneNode : public scene::IAxialBillboardSceneNode 
{ 
public: 
CAxialBillboardSceneNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, 
core::vector3df position,core::vector3df orientation, f32 width); 
virtual ~CAxialBillboardSceneNode();
virtual void OnPreRender(); 
virtual void render(); 
virtual const core::aabbox3d<f32>& getBoundingBox() const; 
virtual s32 getMaterialCount(); 
virtual video::SMaterial& getMaterial(s32 i); 
virtual void setWidth(const f32 width);
virtual f32 getWidth();
virtual void setOrientation(const core::vector3df& orientation);
virtual const core::vector3df& getOrientation();

private: 
core::aabbox3d<f32> Box; 
video::S3DVertex vertices[4]; 
u16 indices[6]; 
video::SMaterial Material; 
core::vector3df orientation; 
f32 width; 
}; 

} // end namespace scene
} // end namespace irr

#endif 
//end added by JAMES
CAxialBillboardSceneNode.cpp :

Code: Select all

//added by JAMES
//original code by calimero, modified slightly by me, JAMES
// calimero 14 august 2004 this is version 1.0 of the node
// I think this version is usable
#include "CAxialBillboardSceneNode.h"
#include "IVideoDriver.h"
#include "ISceneManager.h"
#include "ICameraSceneNode.h"
#include "os.h"

namespace irr
{
namespace scene
{

CAxialBillboardSceneNode::CAxialBillboardSceneNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, 
core::vector3df position,core::vector3df orientation, f32 width) 
: IAxialBillboardSceneNode(parent, mgr, id, position)
{ 
AutomaticCullingEnabled = false;

this->orientation = orientation; 
this->width = width/2; 

indices[0] = 0; 
indices[1] = 1; 
indices[2] = 2; 
indices[3] = 0; 
indices[4] = 2; 
indices[5] = 3; 

// by default the material is set to be used like a laser ray
// but feel free to modify these settings
Material.Lighting = false; 
Material.BackfaceCulling = false; 
this->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);  


video::SColor color = video::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; 

} 

CAxialBillboardSceneNode::~CAxialBillboardSceneNode()
{

}

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


void CAxialBillboardSceneNode::render() 
{ 
   // ok in this function is the interesting stuff 
   // jfh "calimero" 11august2004 nice france 
   // the axial billboard has two end, the first is the position of the node 
   // the other is given by orientation in LOCAL coordinates. 
   // for node attached to rootscenenode it behaves like the previous version 
   // in this version orientation is expressed in local coordinates of the node 
   // I think it's more interesting because it gives a more standard behaviour 
   // if the node is attached to a parent different from rootscenenode 
   // you can also attach animator to the node (like rotation) 
    // and I hope it will behave like you expect 
    // 
    // known problem : node disappears if position gets too near of the camera 
   
   core::vector3df orientationglobal; // to store the end of the billboard in world coordinates
	core::matrix4 mat; // to get an identity matrix for final render
	core::matrix4 matnode = getAbsoluteTransformation(); // get the transformation of the node
	
    ISceneNode* camera = SceneManager->getActiveCamera();
  	video::IVideoDriver* driver = SceneManager->getVideoDriver();
	
    
	core::vector3df pos = getAbsolutePosition();
	core::vector3df campos = camera->getAbsolutePosition();
	matnode.transformVect(orientation,orientationglobal);
	core::vector3df vtemp = orientationglobal-pos;
    core::vector3df perp = vtemp.crossProduct(campos - pos);
    
    // perhaps here I should test if perp is null before normalize it ?
    // it doesn't seem to be necessary --> to investigate
    //perp.normalize();
    //perp *= largeur;
    perp.setLength(width);
     
    // here I update the coordinates of the billboard in GLOBAL space 
    vertices[0].Pos = pos - perp;
	vertices[1].Pos = pos + perp;
	vertices[2].Pos = orientationglobal + perp  ;
	vertices[3].Pos = orientationglobal - perp;
	
	// update normals of the node
	core::vector3df norm = (perp).crossProduct(vtemp);
	norm.normalize();
	vertices[0].Normal = norm;
	vertices[1].Normal = norm;
	vertices[2].Normal = norm;
	vertices[3].Normal = norm;
	
	driver->setMaterial(Material);
	
	// doesn't seem to be necessary probably the default constructor
	// build the identity matrix
	//mat.makeIdentity();
  	driver->setTransform(video::ETS_WORLD, mat);
	// finally I draw it 
	driver->drawIndexedTriangleList(vertices, 4, indices, 2); 

}


const core::aabbox3d<f32>& CAxialBillboardSceneNode::getBoundingBox() const 
{ 
return Box; 
} 

s32 CAxialBillboardSceneNode::getMaterialCount() 
{ 
return 1; 
} 

video::SMaterial& CAxialBillboardSceneNode::getMaterial(s32 i) 
{ 
return Material; 
} 

//! sets the width of the billboard
void CAxialBillboardSceneNode::setWidth(const f32 width)
{
	this->width = width/2;
}

//! gets the width of the billboard
f32 CAxialBillboardSceneNode::getWidth()
{
	return (width*2);
}

//! sets the local orientation of the billboard
void CAxialBillboardSceneNode::setOrientation(const core::vector3df& orientation)
{
	this->orientation = orientation;
}

//! gets the local orientation of the billboard
const core::vector3df& CAxialBillboardSceneNode::getOrientation()
{
	return orientation;
}

} // end namespace scene
} // end namespace irr
//end added by JAMES
mm765
Posts: 172
Joined: Fri May 28, 2004 10:12 am

Post by mm765 »

just a guess but i think it disappers because you dont update the boundingbox.
i only looked at your last post so if the update is in a previous post nevermind :)
calimero
Posts: 45
Joined: Sun Aug 08, 2004 4:31 pm
Location: Nice, France

Post by calimero »

hello mm765 :
I don't update the bounding box but I use

Code: Select all

AutomaticCullingEnabled = false;
so I think the boundingbox is useless (but I may mistaken !!!)
I don't think boundingbox is good for axialbillboard especially if you have very long one which goes trough the entire scene. That's why I prefer to disable automatic culling
Post Reply