SceneNodes getting clipped

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
Clash
Posts: 80
Joined: Thu Apr 19, 2007 4:20 pm

SceneNodes getting clipped

Post by Clash »

Hello guys!
I still haven't been able to figure why my scene nodes are getting clipped, I've been told to set the bouding box of the sceneNode, I have and it's still getting clipped. Any idea?
It was expected to have a full line of blocks, but here's the result:
Image
In red you can see where there was suppose to be another block(udr_npc.png is 32x32 pixels wide)
Thanks in advance
Code to replicate:

Code: Select all

#ifdef LINUX
#include <unistd.h>
#define Sleep(x) usleep(x)
#else
#include <windows.h>
#endif

#include <iostream>
#include <string>

#include <stdio.h>

#if defined(WIN32)
#include <conio.h>
#else
#include "../common/conio.h"
#endif
#include <irrlicht.h>
using namespace irr;

using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

class CSprite : public ISceneNode
{
    aabbox3d<f32> Box;
    S3DVertex     Vertices[4];
    SMaterial     Material;
    dimension2df  Size;
    f32           Rotation;

public:

    CSprite(dimension2df size, char const * textureName, E_MATERIAL_TYPE materialType,
            bool makeColourKey, IVideoDriver * driver, ISceneNode* parent, ISceneManager* mgr,
            s32 id = -1)
        : ISceneNode(parent, mgr, id)
    {
        Material.Wireframe = false;
        Material.Lighting = false;
        Material.MaterialType = materialType;

        if(driver && textureName)
        {
            ITexture * texture = driver->getTexture(textureName);

            if(texture)
            {
                if(makeColourKey)
                   driver->makeColorKeyTexture(texture, core::position2d<s32>(0,0));

                Material.setTexture(0, texture);
            }
        }


        Size = size;
        Rotation = 0.f;

        Vertices[0].TCoords.set(1.f, 0.f);
        Vertices[1].TCoords.set(1.f, 1.f);
        Vertices[2].TCoords.set(0.f, 1.f);
        Vertices[3].TCoords.set(0.f, 0.f);

        //! Set bounding box
        Box.reset(Vertices[0].Pos);
        Box.addInternalPoint(Vertices[1].Pos);
        Box.addInternalPoint(Vertices[2].Pos);
        Box.addInternalPoint(Vertices[3].Pos);
    }

    void setBox()
    {
        //! Set bounding box
        Box.reset(Vertices[0].Pos);
        Box.addInternalPoint(Vertices[1].Pos);
        Box.addInternalPoint(Vertices[2].Pos);
        Box.addInternalPoint(Vertices[3].Pos);
    }

    virtual void OnRegisterSceneNode()
    {
        if (IsVisible)
            SceneManager->registerNodeForRendering(this);

        ISceneNode::OnRegisterSceneNode();
    }

    virtual void render()
    {
        IVideoDriver* driver = SceneManager->getVideoDriver();
        ICameraSceneNode* camera = SceneManager->getActiveCamera();

        vector3df cameraView = camera->getTarget() - camera->getAbsolutePosition();
        cameraView.normalize();

        vector3df up = camera->getUpVector();
        up.normalize();

        quaternion quat;
        quat.fromAngleAxis(Rotation * DEGTORAD, cameraView);

        matrix4 const rotationMatrix = quat.getMatrix();
        rotationMatrix.transformVect(up);

        vector3df horizontal = cameraView.crossProduct(up).normalize();
        vector3df const vertical = cameraView.crossProduct(horizontal).normalize() * Size.Height * 0.5f;
        horizontal *= Size.Width * 0.5f;

        for (s32 i=0; i<4; ++i)
            Vertices[i].Normal = -cameraView;

        vector3df const myPosition = AbsoluteTransformation.getTranslation();
        Vertices[0].Pos = myPosition - horizontal - vertical;
        Vertices[1].Pos = myPosition - horizontal + vertical;
        Vertices[2].Pos = myPosition + horizontal + vertical;
        Vertices[3].Pos = myPosition + horizontal - vertical;

        static u16 const indices[] = { 0, 1, 2, 0, 2, 3 };

        driver->setMaterial(Material);
        driver->setTransform(ETS_WORLD, IdentityMatrix);
        driver->drawIndexedTriangleList(Vertices, 4, indices, 2);
    }

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

    u32 getMaterialCount() const { return 1; }

    SMaterial& getMaterial(u32 i) { return Material; }

    void setSpriteRotation(f32 rotation)
    {
        Rotation = rotation;
        while(Rotation >= 360.f)
            Rotation -= 360.f;
        while(Rotation < 0.f)
            Rotation += 360.f;
    }

    f32 getSpriteRotation(void) const { return Rotation; }

    dimension2df const & getSize(void) const { return Size; }

    void setSize(dimension2df const & size) { Size = size; }

};

int main()
{
    IrrlichtDevice *device = 0;

    //! Create device EDT_OPENGL EDT_DIRECT3D8 EDT_DIRECT3D9
	device = createDevice(video::EDT_OPENGL, core::dimension2d<s32>(800, 640), 32, false, false, false);

    if (device == 0)
		return 1; // could not create selected driver.

    //! Get Video Driver
	video::IVideoDriver* driver = device->getVideoDriver();
	driver->setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, false);

	//! Create a Orthogonal Camera
	ISceneManager* smgr = device->getSceneManager();
	ICameraSceneNode *camera = smgr->addCameraSceneNode(0, vector3df(0,5,0), vector3df(0,0,0));
    matrix4 orthoMatrix;
    orthoMatrix.buildProjectionMatrixOrthoLH(static_cast<f32> (800), static_cast<f32> (640), 5.f, 100.f);
    camera->setProjectionMatrix(orthoMatrix, true);
    camera->setPosition(vector3df(520.f, 300.f, -5.f));
    camera->setTarget(vector3df(520.f, 300.f, 0));
    //camera->setIsOrthogonal(true); // 1.4

    //! declare receiver
	IGUIEnvironment* env = device->getGUIEnvironment();

    CSprite * sprites2[500];
    for(int i = 0; i < 500; ++i)
    {
        sprites2[i] = new CSprite(dimension2df(32.f, 32.f), "udr_npc.png",
                                 EMT_TRANSPARENT_ALPHA_CHANNEL_REF, false,
                                 driver, smgr->getRootSceneNode(),
                                 smgr, false);
        sprites2[i]->setPosition(vector3df(32.f*i, 32.f, 0));
        sprites2[i]->drop();
    }


	while(device->run() && driver)
	{
	    //! Let PC do other tasks if needed
	    Sleep(0);

        driver->beginScene(true, true, video::SColor(0,0,0,0));

        smgr->drawAll();
        env->drawAll();
        driver->endScene();
	}
	device->drop();

	return 0;
}
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

the problem is with the bounding box
you try to calculate it, but it doesn't work this way, because all vertices are at (0,0,0) when you update the bounding box...
the positions of the vertices are calculated in the render functions and so they are different from the vertices you created and calculated the bounding box from in the constructor...

so either change the creation and fix the bounding box...
or set automatic culling off for the nodes... ;)

Code: Select all

    CSprite * sprites2[500];
    for(int i = 0; i < 500; ++i)
    {
        sprites2[i] = new CSprite(dimension2df(32.f, 32.f), "udr_npc.png",
                                 EMT_TRANSPARENT_ALPHA_CHANNEL_REF, false,
                                 driver, smgr->getRootSceneNode(),
                                 smgr, false);
        sprites2[i]->setAutomaticCulling(EAC_OFF); // <<<<<<<<<<
        sprites2[i]->setPosition(vector3df(32.f*i, 32.f, 0));
        sprites2[i]->drop();
    }
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Clash
Posts: 80
Joined: Thu Apr 19, 2007 4:20 pm

Post by Clash »

What you are suggesting is setting the bouding box at the render fuction, right? I did that but the results are even stranger, nodes far from the clipping zone are getting clipped
Auto-culling off worked though, but it's not the 'correct' solution, is it?
Thanks in advance
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

You either have to do the culling in OnRegisterSceneNode, or make it manually in render(), with automatic culling turned off. The thing is that you'll start with a wrong position, which might lead to the element being culled. This would also prevent to update its position, because it wouldn't be rendered, ...
Post Reply