Tree Scene Node v2.1

Announce new projects or updates of Irrlicht Engine related tools, games, and applications.
Also check the Wiki
kklouzal
Posts: 343
Joined: Sun Mar 28, 2010 8:14 pm
Location: USA - Arizona

Re: Tree Scene Node v2.1

Post by kklouzal »

I don't believe this works with the latest irrlicht :(

From the example solution provided..
Compile Errors:

Code: Select all

1>------ Build started: Project: ProceduralTreesExample, Configuration: Release Win32 ------
1>Compiling...
1>CBillboardGroupSceneNode.cpp
1>..\CBillboardGroupSceneNode.cpp(88) : error C2027: use of undefined type 'irr::scene::ISceneManager'
1>        d:\irrlicht-1.7.2\include\ISceneNodeAnimator.h(23) : see declaration of 'irr::scene::ISceneManager'
1>..\CBillboardGroupSceneNode.cpp(88) : error C2227: left of '->registerNodeForRendering' must point to class/struct/union/generic type
1>..\CBillboardGroupSceneNode.cpp(96) : error C2027: use of undefined type 'irr::scene::ISceneManager'
1>        d:\irrlicht-1.7.2\include\ISceneNodeAnimator.h(23) : see declaration of 'irr::scene::ISceneManager'
1>..\CBillboardGroupSceneNode.cpp(96) : error C2227: left of '->getVideoDriver' must point to class/struct/union/generic type
1>..\CBillboardGroupSceneNode.cpp(122) : warning C4018: '<' : signed/unsigned mismatch
1>..\CBillboardGroupSceneNode.cpp(153) : warning C4018: '<' : signed/unsigned mismatch
1>..\CBillboardGroupSceneNode.cpp(164) : error C2027: use of undefined type 'irr::scene::ISceneManager'
1>        d:\irrlicht-1.7.2\include\ISceneNodeAnimator.h(23) : see declaration of 'irr::scene::ISceneManager'
1>..\CBillboardGroupSceneNode.cpp(164) : error C2227: left of '->getActiveCamera' must point to class/struct/union/generic type
1>..\CBillboardGroupSceneNode.cpp(206) : warning C4018: '<' : signed/unsigned mismatch
1>Build log was saved at "file://c:\Users\kklouzal\Desktop\ProceduralTrees\ProceduralTreesExample\Release\BuildLog.htm"
1>ProceduralTreesExample - 6 error(s), 3 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I took a look but i'm not sure what to do >.<
Dream Big Or Go Home.
Help Me Help You.
Insomniacp
Posts: 288
Joined: Wed Apr 16, 2008 1:45 am
Contact:

Re: Tree Scene Node v2.1

Post by Insomniacp »

again this was from 2006 and last post in 2010 so it hasn't been updated to work with the latest irrlicht most likely.
ACE247
Posts: 704
Joined: Tue Mar 16, 2010 12:31 am

Re: Tree Scene Node v2.1

Post by ACE247 »

I've made a working build somewhere, will see if i can dig it up and post a link :wink:
ACE247
Posts: 704
Joined: Tue Mar 16, 2010 12:31 am

Re: Tree Scene Node v2.1

Post by ACE247 »

Found it, check if this source works:http://www.mediafire.com/?c2c8mqd63b0ckpu
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Tree Scene Node v2.1

Post by hybrid »

I think both these things were added to irrext, maybe check the code and projects there.
Erelas
Competition winner
Posts: 20
Joined: Mon Apr 18, 2011 8:40 am

Tree Scene Node with billboard creation

Post by Erelas »

Thanks for the nice implementation Klasker!

I made a few changes and added an imposter billboard creation method, which works pretty well for my project.

I thought i'd share it, here it is.

Code: Select all

 
/*  
 Written by Asger Feldthaus
 
 February 2007
 */
 
#ifndef _C_TREE_SCENE_NODE_H_
#define _C_TREE_SCENE_NODE_H_
 
#include <ISceneNode.h>
#include "CBillboardGroupSceneNode.h"
#include "CTreeGenerator.h"
 
enum PROCEDURAL_TREE_TYPE {
        LE_PT_ASPEN, LE_PT_OAK, LE_PT_PINE, LE_PT_WILLOW
};
 
namespace irr {
namespace scene {
 
#ifdef MAKE_IRR_ID
const int TREE_SCENE_NODE_ID = MAKE_IRR_ID('t','r','e','e');
#else
const int TREE_SCENE_NODE_ID = 'tree';
#endif // MAKE_IRR_ID
 
/*!
 \brief A tree with three levels of detail.
 
 CTreeSceneNode is a tree with three levels of detail. The highest LOD is the mesh with full detail. The second LOD is another mesh with fewer polygons.
 The last LOD is a billboard. The leaves are displayed in the two first levels of detail.
 
 Call setup() to initialize the scene node.
 */
class CTreeSceneNode: public ISceneNode {
public:
        //! Standard constructor for scene nodes. Call setup() to initialize the scene node.
        CTreeSceneNode(f32 midRange, f32 farRange, ISceneNode* parent, ISceneManager* manager, s32 id = -1, const core::vector3df& position = core::vector3df(0, 0, 0), const core::vector3df& rotation = core::vector3df(0, 0, 0), const core::vector3df& scale = core::vector3df(1, 1, 1));
 
        virtual ~CTreeSceneNode();
 
        //! Sets the meshes used by the scene node, the leaf node used and the billboard texture.
        //! \param highLod: The mesh to use when the tree is close to the camera. Must not be 0!
        //! \param midLod: The mesh to use when the camera is at mediocre distance. If 0 highLod is used instead.
        //! \param leafNode: The scene node displaying the leaves on the tree. If 0 no leaves will be displayed.
        //! \param billboardTexture: The texture to display on the billboard when the tree is very far from the camera. If 0 it will not turn into a billboard.
        void setup(const STreeMesh* highLOD, const STreeMesh* midLOD, video::ITexture* billboardTexture = 0);
 
        //! Generates meshes and leaves for the scene node automatically, and specifies the billboard texture.
        //! \param seed: The random number seed used to generate the tree.
        //! \param billboardTexture: The texture to display on the billboard when the tree is very far from the camera. If 0 it will not turn into a billboard.
        void setup(CTreeGenerator* generator, s32 seed = 0, video::ITexture* billboardTexture = 0);
 
        //! Specifies where the tree should switch to medium LOD, and where it should switch to a billboard.
        //! \param midRange: If the camera is closer than this, it will use high LOD. If it is greater than this, but lower than farRange, it will use medium LOD.
        //! \param farRange: If the camera is further away than this, a billboard will be displayed instead of the tree.
        void setDistances(f32 midRange, f32 farRange);
 
        virtual void OnRegisterSceneNode();
 
        virtual void render();
 
        virtual video::SMaterial& getMaterial(u32 i);
 
        virtual u32 getMaterialCount() const;
 
        virtual const core::aabbox3d<f32>& getBoundingBox() const;
 
        /**
         * Get type
         * @return type
         */
        virtual scene::ESCENE_NODE_TYPE getType() const;
 
        s32 getVertexCount() const;
 
        //! Returns the leaf node associated with the tree. Useful for settings the correct texture and material settings.
        CBillboardGroupSceneNode* getLeafNode();
 
        //! Returns root stem mesh for collision shape
        scene::IMesh* getTreeCollisionMesh();
 
        //! Sets the root stem mesh for collision shape
        void setTreeCollisionMesh(scene::IMesh* mesh);
 
        //! Returns root stem mesh for collision shape
        scene::IMesh* getMesh();
 
        void createImposter();
private:
        void updateBillboard();
        void updateSizeAndRange();
 
        video::SMaterial TreeMaterial;
        video::SMaterial BillboardMaterial;
 
        f32 MidRange;
        f32 FarRange;
        f32 Size;
 
        CBillboardGroupSceneNode* LeafNode;
 
        scene::SMesh* mesh;
        SMeshBuffer* HighLODMeshBuffer;
        SMeshBuffer* MidLODMeshBuffer;
 
        SMeshBuffer BillboardMeshBuffer;
 
        f64 DistSQ;
 
        core::vector3df LastViewVec;
 
        scene::IMesh* treeStemMesh;
};
 
} // namespace scene
} // namespace irr
 
#endif
 

Code: Select all

 
/*  
 Written by Asger Feldthaus
 
 February 2007
 */
 
#include "CTreeSceneNode.h"
#include "../../Logger/Logger.h"
#include <ICameraSceneNode.h>
#include <IVideoDriver.h>
 
namespace irr {
namespace scene {
 
const f32 CAMERA_UPDATE_DISTANCE = 100.0f;
 
//MidRange = 500.0f;
//FarRange = 1300.0f;
 
CTreeSceneNode::CTreeSceneNode(f32 midRange, f32 farRange, ISceneNode* parent, ISceneManager* manager, s32 id, const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale) :
                ISceneNode(parent, manager, id, position, rotation, scale) {
        MidRange = midRange;
        FarRange = farRange;
        Size = 0.0f;
 
        HighLODMeshBuffer = 0;
        MidLODMeshBuffer = 0;
        LeafNode = 0;
 
        BillboardMaterial.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
        BillboardMaterial.Lighting = false;
 
        BillboardMeshBuffer.Indices.push_back(2);
        BillboardMeshBuffer.Indices.push_back(1);
        BillboardMeshBuffer.Indices.push_back(0);
 
        BillboardMeshBuffer.Indices.push_back(0);
        BillboardMeshBuffer.Indices.push_back(3);
        BillboardMeshBuffer.Indices.push_back(2);
 
        BillboardMeshBuffer.Vertices.push_back(video::S3DVertex(0, 0, 0, 0, 1.0f, 0, video::SColor(255, 255, 255, 255), 0.0f, 1.0f));
        BillboardMeshBuffer.Vertices.push_back(video::S3DVertex(0, 0, 0, 0, 1.0f, 0, video::SColor(255, 255, 255, 255), 0.0f, 0.0f));
        BillboardMeshBuffer.Vertices.push_back(video::S3DVertex(0, 0, 0, 0, 1.0f, 0, video::SColor(255, 255, 255, 255), 1.0f, 0.0f));
        BillboardMeshBuffer.Vertices.push_back(video::S3DVertex(0, 0, 0, 0, 1.0f, 0, video::SColor(255, 255, 255, 255), 1.0f, 1.0f));
}
 
CTreeSceneNode::~CTreeSceneNode() {
        if (HighLODMeshBuffer) {
                HighLODMeshBuffer->drop();
        }
        if (MidLODMeshBuffer) {
                MidLODMeshBuffer->drop();
        }
        if (treeStemMesh) {
                treeStemMesh->drop();
        }
}
 
void CTreeSceneNode::setup(const STreeMesh* highLOD, const STreeMesh* midLOD, video::ITexture* billboardTexture) {
        if (HighLODMeshBuffer) {
                HighLODMeshBuffer->drop();
        }
        if (MidLODMeshBuffer) {
                MidLODMeshBuffer->drop();
        }
        if (LeafNode) {
                LeafNode->remove();
        }
 
        HighLODMeshBuffer = highLOD->MeshBuffer;
        MidLODMeshBuffer = midLOD->MeshBuffer;
 
        //Set collision mesh
        scene::SMesh* treeCollisionMesh = new SMesh;
        treeCollisionMesh->addMeshBuffer(MidLODMeshBuffer);
        setTreeCollisionMesh(treeCollisionMesh);
 
        LeafNode = 0;
        if (highLOD->Leaves.size() > 0) {
                LeafNode = new CBillboardGroupSceneNode(this, SceneManager);
                LeafNode->drop();
 
                for (u32 i = 0; i < highLOD->Leaves.size(); i++) {
                        if (highLOD->Leaves[i].HasAxis) {
                                LeafNode->addBillboardWithAxis(highLOD->Leaves[i].Position, highLOD->Leaves[i].Size, highLOD->Leaves[i].Axis, highLOD->Leaves[i].Roll, highLOD->Leaves[i].Color);
                        } else {
                                LeafNode->addBillboard(highLOD->Leaves[i].Position, highLOD->Leaves[i].Size, highLOD->Leaves[i].Roll, highLOD->Leaves[i].Color);
                        }
                }
        }
 
        if (HighLODMeshBuffer) {
                HighLODMeshBuffer->grab();
                Size = HighLODMeshBuffer->BoundingBox.getExtent().getLength() / 2.0f;
        }
 
        if (MidLODMeshBuffer) {
                MidLODMeshBuffer->grab();
        }
 
        LastViewVec = core::vector3df(0, 0, 0);
 
        mesh = new scene::SMesh();
        mesh->addMeshBuffer(HighLODMeshBuffer);
        mesh->recalculateBoundingBox();
}
 
void CTreeSceneNode::createImposter() {
        video::IVideoDriver* driver = SceneManager->getVideoDriver();
        video::ITexture* billboardTexture = driver->addRenderTargetTexture(core::dimension2du(1024, 1024), "Imposter1024RTT");
        scene::ICameraSceneNode* originalCam = SceneManager->getActiveCamera();
        scene::ICameraSceneNode* impostorCam = SceneManager->addCameraSceneNode();
 
        //Set position and target on the camera
        updateAbsolutePosition();
        core::vector3df camPos = getAbsolutePosition();
        camPos.X += getBoundingBox().getExtent().Y;
        camPos.Y += getBoundingBox().getExtent().Y / 2.f;
        camPos.Y += 2.5f;
        impostorCam->setPosition(camPos);
        camPos = getAbsolutePosition();
        camPos.Y += getBoundingBox().getExtent().Y / 2.f;
        camPos.Y += 2.5f;
        impostorCam->setTarget(camPos);
 
        //Set near, far and aspect ratio of the camera, so the tree comes in full view
        impostorCam->updateAbsolutePosition();
        impostorCam->setNearValue(0.001f);
        impostorCam->setFarValue(500.f);
        impostorCam->setAspectRatio(irr::core::max_(getBoundingBox().getExtent().X + 1, getBoundingBox().getExtent().Z + 1) / getBoundingBox().getExtent().Y);
        SceneManager->setActiveCamera(impostorCam);
 
        //Set the render target to the billboardTexture
        driver->setRenderTarget(billboardTexture, true, true, video::SColor(0, 0, 0, 0));
 
        //Hide all other nodes
        core::array<scene::ISceneNode *> nodes;
        SceneManager->getSceneNodesFromType((scene::ESCENE_NODE_TYPE) scene::TREE_SCENE_NODE_ID, nodes);
        SceneManager->getSceneNodesFromType(scene::ESNT_TERRAIN, nodes);
        SceneManager->getSceneNodesFromType(scene::ESNT_SKY_BOX, nodes);
        SceneManager->getSceneNodesFromType(scene::ESNT_ANIMATED_MESH, nodes);
        SceneManager->getSceneNodesFromType(scene::ESNT_MESH, nodes);
        SceneManager->getSceneNodesFromType(scene::ESNT_BILLBOARD, nodes);
        for (u32 i = 0; i < nodes.size(); i++) {
                if (nodes[i]->isVisible()) {
                        nodes[i]->setVisible(false);
                } else {
                        nodes[i]->setID(999);
                }
        }
 
        //Make tree and leafnode visible
        setVisible(true);
        OnRegisterSceneNode();
        updateAbsolutePosition();
        LeafNode->setVisible(true);
        LeafNode->OnRegisterSceneNode();
        LeafNode->updateAbsolutePosition();
 
        //Render the nodes to the render target
        SceneManager->drawAll();
 
        //Reset the render target and set the created billboard texture
        driver->setRenderTarget(0, true, true, video::SColor(0, 0, 0, 0));
        SceneManager->setActiveCamera(originalCam);
        BillboardMaterial.TextureLayer[0].Texture = billboardTexture;
        updateBillboard();
 
        impostorCam->remove();
 
        //Restore all other nodes
        for (u32 i = 0; i < nodes.size(); i++) {
                if (nodes[i]->getID() != 999 || nodes[i]->getType() == scene::TREE_SCENE_NODE_ID) {
                        nodes[i]->setVisible(true);
                }
        }
}
 
void CTreeSceneNode::setup(CTreeGenerator* generator, s32 seed, video::ITexture* billboardTexture) {
        STreeMesh* highLOD = generator->generateTree(8, seed, true, 0);
        STreeMesh* midLOD = generator->generateTree(4, seed, false, 1);
 
        setup(highLOD, midLOD, billboardTexture);
 
        highLOD->drop();
        midLOD->drop();
}
 
void CTreeSceneNode::setDistances(f32 midRange, f32 farRange) {
        MidRange = midRange;
        FarRange = farRange;
}
 
void CTreeSceneNode::OnRegisterSceneNode() {
        if (IsVisible) {
                ICameraSceneNode* camera = SceneManager->getActiveCamera();
 
                DistSQ = 0.0f;
                if (camera) {
                        core::vector3df campos = camera->getAbsolutePosition();
 
                        core::vector3df center = HighLODMeshBuffer->BoundingBox.getCenter();
                        AbsoluteTransformation.rotateVect(center);
 
                        center += getAbsolutePosition();
 
                        DistSQ = (campos - center).getLengthSQ();
                }
 
                if (LeafNode) {
                        f32 far = FarRange + Size;
                        LeafNode->setVisible(far * far >= DistSQ);
                }
 
                SceneManager->registerNodeForRendering(this);
        }
        ISceneNode::OnRegisterSceneNode();
}
 
void CTreeSceneNode::render() {
        video::IVideoDriver* driver = SceneManager->getVideoDriver();
 
        f32 far = FarRange + Size;
        f32 mid = MidRange + Size;
 
        if (far * far < DistSQ && BillboardMaterial.TextureLayer[0].Texture != 0) {
                driver->setTransform(video::ETS_WORLD, core::matrix4());
 
                driver->setMaterial(BillboardMaterial);
 
                ICameraSceneNode* camera = SceneManager->getActiveCamera();
 
                core::vector3df view = camera->getAbsolutePosition() - getAbsolutePosition();
 
                if (view.getDistanceFromSQ(LastViewVec) >= CAMERA_UPDATE_DISTANCE * CAMERA_UPDATE_DISTANCE) {
                        updateBillboard();
                        LastViewVec = view;
                }
 
                driver->drawMeshBuffer(&BillboardMeshBuffer);
        } else if (mid * mid < DistSQ && MidLODMeshBuffer != 0) {
                driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
                driver->setMaterial(TreeMaterial);
 
                //Create imposter with high detail
                if (BillboardMaterial.TextureLayer[0].Texture != 0) {
                        driver->drawMeshBuffer(MidLODMeshBuffer);
                } else {
                        driver->drawMeshBuffer(HighLODMeshBuffer);
                }
        } else {
                driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
                driver->setMaterial(TreeMaterial);
                driver->drawMeshBuffer(HighLODMeshBuffer);
        }
}
 
video::SMaterial& CTreeSceneNode::getMaterial(u32 i) {
        return TreeMaterial;
}
 
u32 CTreeSceneNode::getMaterialCount() const {
        return 1;
}
 
const core::aabbox3d<f32>& CTreeSceneNode::getBoundingBox() const {
        return HighLODMeshBuffer->BoundingBox;
}
 
scene::ESCENE_NODE_TYPE CTreeSceneNode::getType() const {
        return (scene::ESCENE_NODE_TYPE) TREE_SCENE_NODE_ID;
}
 
s32 CTreeSceneNode::getVertexCount() const {
        return HighLODMeshBuffer->getVertexCount();
}
 
CBillboardGroupSceneNode* CTreeSceneNode::getLeafNode() {
        return LeafNode;
}
 
//! Returns root stem mesh for collision shape
scene::IMesh* CTreeSceneNode::getTreeCollisionMesh() {
        return treeStemMesh;
}
 
//! Sets the root stem mesh for collision shape
void CTreeSceneNode::setTreeCollisionMesh(scene::IMesh* mesh) {
        this->treeStemMesh = mesh;
}
 
scene::IMesh* CTreeSceneNode::getMesh() {
        return mesh;
}
 
void CTreeSceneNode::updateBillboard() {
        ICameraSceneNode* camera = SceneManager->getActiveCamera();
 
        if (!camera) {
                return;
        }
 
        core::vector3df campos = camera->getAbsolutePosition();
        core::vector3df pos = getAbsolutePosition();
        core::vector3df view = pos - campos;
 
        view.normalize();
 
        core::vector3df up = core::vector3df(0, 1, 0);
 
        AbsoluteTransformation.rotateVect(up);
        up.normalize();
 
        core::vector3df left = view.crossProduct(up);
        left.normalize();
 
        core::vector3df extent = HighLODMeshBuffer->BoundingBox.getExtent();
        core::vector3df yscale = core::vector3df(0, 1.5f, 0);
        AbsoluteTransformation.rotateVect(yscale); // Find the y scale and apply to the height
 
        pos.Y -= extent.Y / 5.f;
        up *= extent.Y * yscale.getLength();
        core::vector3df xz = core::vector3df(1.1f, 0, 1.1f); // Find the xz scale and apply to the width
 
        AbsoluteTransformation.rotateVect(xz);
        extent.Y = 0.0f;
        f32 len = extent.getLength() * xz.getLength() / 1.4f; // Divide by 1.4f to compensate for the extra length of xz.
 
        left *= len / 2.0f;
 
        /*
         1--2
         |  |
         0--3
         */
 
        BillboardMeshBuffer.Vertices[0].Pos = pos - left;
        BillboardMeshBuffer.Vertices[1].Pos = pos - left + up;
        BillboardMeshBuffer.Vertices[2].Pos = pos + left + up;
        BillboardMeshBuffer.Vertices[3].Pos = pos + left;
}
 
} // namespace scene
} // namespace irr
 
After you create the treescenenode, you can call TreeSceneNode::createImposter(). It will render the tree in high detail to a texture that will be set on the billboardmaterial.
This was necessary for our game, because we have multiple tree types and further randomization, so it was easier to let the game provide the billboard textures instead of us creating one for every tree.

This was a quick fix, so the code is not so clean =P
It also may be the case that I got this working for our tree models only and it won't work on yours. I do some "nasty magic with numbers" and there's probably a better way. If there is, please say so ^^

If I managed to clean this up I'll post an update.
Cube_
Posts: 1010
Joined: Mon Oct 24, 2011 10:03 pm
Location: 0x45 61 72 74 68 2c 20 69 6e 20 74 68 65 20 73 6f 6c 20 73 79 73 74 65 6d

Re: Tree Scene Node v2.1

Post by Cube_ »

I have a question. can one load already created models using this and only using it for the random placement? I have already created a lot of trees and smaller plants (bushes and similar)
"this is not the bottleneck you are looking for"
ACE247
Posts: 704
Joined: Tue Mar 16, 2010 12:31 am

Re: Tree Scene Node v2.1

Post by ACE247 »

Its a Random Tree Generator... Not a Random Tree placer!
And randomly placing trees on a heightmap really isn't that hard a script in IrrEdit If you want can even do that.
Or IrrBlender, as I prefer. ;)
Brainsaw
Posts: 1183
Joined: Wed Jan 07, 2004 12:57 pm
Location: Bavaria

Re: Tree Scene Node v2.1

Post by Brainsaw »

I created a plugin for IrrEdit (and a scenenode) that places trees (or other objects) randomly (http://bulletbyte.de/products.php?sub=irr&show=rafo), and it should work with any scenenodes (that provide a "clone" method). Good point is that the trees are not actually stored in the scenefile (which is a huge reduction in file size) but placed by random every time the scene is loaded (using the same random algorithm and the same seed will produce the same output).
Dustbin::Games on the web: https://www.dustbin-online.de/

Dustbin::Games on facebook: https://www.facebook.com/dustbingames/
Dustbin::Games on twitter: https://twitter.com/dustbingames
Cube_
Posts: 1010
Joined: Mon Oct 24, 2011 10:03 pm
Location: 0x45 61 72 74 68 2c 20 69 6e 20 74 68 65 20 73 6f 6c 20 73 79 73 74 65 6d

Re: Tree Scene Node v2.1

Post by Cube_ »

oh nice!
So. just need to generate pseudo random seeds and I'll be one step closer to all maps being unique! Thanks brainsaw!
"this is not the bottleneck you are looking for"
pepeshka
Posts: 29
Joined: Wed Jul 02, 2008 8:42 pm

Re: Tree Scene Node v2.1

Post by pepeshka »

Very cool project. One note, scaling does not scale the leaf textures, which ends up looking weird. You have to set the Scale property of each billboard in the BillboardGroupSceneNode, like this:

Code: Select all

void CBillboardGroupSceneNode::UpdateBillboardSizes(irr::core::dimension2df _size)
{
        for ( u32 i=0; i<Billboards.size(); i++ )
        {
                Billboards[i].Size = _size;
        }
}
Then you can call it from an overloaded TreeSceneNode.scale() or something. Strangely, it doesn't look like the scaling is equivalent - if I scale the tree by 10, I have to scale the leaves by something like 200 to get it looking right. Not sure if that's some issue with my project or if I just don't understand the tree generator well enough yet. 8)
Abraxas)
Posts: 227
Joined: Sun Oct 18, 2009 7:24 am

Re: Tree Scene Node v2.1

Post by Abraxas) »

Hello guys,

Does anyone have the original documentation for this? I'm just looking for the main.cpp to know how to use this properly.

I downloaded the updated code posted by ACE247 but there was no main.cpp to base myself off of.

Thanks!
chronologicaldot
Competition winner
Posts: 688
Joined: Mon Sep 10, 2012 8:51 am

Re: Tree Scene Node v2.1

Post by chronologicaldot »

I don't know if there was any documentation.
You might try downloading shogun's irrEdit pluging (http://www.mindermensch.de/trash/klaske ... Plugin.rar) and checking how they use it there, assuming they provided code.

Glancing through the code, it's like most stand-alone scene nodes.
Here's what it looks like you have to do:
1) Call the constructor
2) Call void CTreeSceneNode::setup(CTreeGenerator* generator, s32 seed, video::ITexture* billboardTexture)
You'll need to have created a CTreeGenerator instance. (Go check out it's constructor to see what it needs)
3) Call void CTreeSceneNode::setDistances(f32 midRange, f32 farRange), passing it the values you want for when a) the tree is near enough to be full res and b) the tree is far enough to become a billboard.
Abraxas)
Posts: 227
Joined: Sun Oct 18, 2009 7:24 am

Re: Tree Scene Node v2.1

Post by Abraxas) »

Thanks, I found it in IRRext

I'm having one problem. I can get the tree to instance and display fine, but the shaders on the leafs aren't loading.

Code: Select all

leafMaterialType = (video::E_MATERIAL_TYPE) driver->getGPUProgrammingServices()->addHighLevelShaderMaterialFromFiles( "../shaders/leaves.vert","main", EVST_VS_2_0, "../shaders/leaves.frag", "main", EPST_PS_2_0, 0,  EMT_TRANSPARENT_ALPHA_CHANNEL,   0);
is the line from the main.cpp causing a problem. It compiles and runs, but this is the error the console window gives me:

"(pathname)\(programfolder)\memory<1,9>: error X3000: Invalid target or usage string"

without that line, the leaves display fine as far as I can tell.

With the line, the leaves are just black squares.

Could someone shed some light on the error? I copy pasted the whole line from the main.cpp and I have the files in the right folder.

Thanks!
Abraxas)
Posts: 227
Joined: Sun Oct 18, 2009 7:24 am

Re: Tree Scene Node v2.1

Post by Abraxas) »

Also one more thing.

Code that begins like this:
for (int x=1;x<=110;x++)
{
seed = rand() % 1000;

tree[x] = new CTreeSceneNode( smgr->getRootSceneNode(), smgr );

if x goes somewhere beyond 106, the program crashes with "Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. "

It did some weird thing with my booleans where I had to redefine one as "false" because it was setting them to "true".

weird stuff so far.
Post Reply