axial billboard
okay, thanks
I was thinking about using IrrlichtNX soon myself, but if it won't compile right with dev-cpp maybe I won't.
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
Crucible of Stars
-
knightoflight
- Posts: 199
- Joined: Sun Aug 24, 2003 5:47 pm
- Location: Germany
-
knightoflight
- Posts: 199
- Joined: Sun Aug 24, 2003 5:47 pm
- Location: Germany
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.
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
in the constructor to see if it changes something ?
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;-
knightoflight
- Posts: 199
- Joined: Sun Aug 24, 2003 5:47 pm
- Location: Germany
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.
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.
Ok today I manage with help of several people to compile irrlichtnx and test/improve my code
.
As I think the node begins to be usable in a project I call this version v1.0
IAxialBillboardSceneNode.h :
CAxialBillboardSceneNode.h :
CAxialBillboardSceneNode.cpp :
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 JAMESCode: 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 JAMESCode: 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 JAMEShello mm765 :
I don't update the bounding box but I use
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
I don't update the bounding box but I use
Code: Select all
AutomaticCullingEnabled = false;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