Inner bounding box, without cap or only cap

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Inner bounding box, without cap or only cap

Post by hendu »

Maybe too specific to be useful, in that case, comment on how to optimize it ;)

This draws the inside of a bounding box, with Z and color writes disabled. I use it for occlusion queries when inside a building (can I skip the sky/weather? Can I skip other buildings/terrain? etc).

It backface-culls the exterior walls, and is drawn via triangle strip/fan to be efficient. Too bad u8 indices aren't supported in irr yet, that could save 12 bytes ;) Also a vertex type without normals, texcoords and colors could save on transfers.

boxer.h

Code: Select all

#ifndef BOXER_H
#define BOXER_H
 
#include <irrlicht/irrlicht.h>
 
namespace irr {
 
class boxer {
 
public:
        boxer(const scene::ISceneNode *n, video::IVideoDriver *d, const bool top = false);
        void render();
 
private:
        video::SMaterial mat;
        video::S3DVertex V[8];
        u16 I[12];
        bool istop;
 
        video::IVideoDriver *drv;
};
 
}
 
#endif
boxer.cpp

Code: Select all

#include "boxer.h"
 
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
 
boxer::boxer(const ISceneNode *n, IVideoDriver *d, const bool top):
                istop(top), drv(d) {
 
        const aabbox3df box = n->getTransformedBoundingBox();
 
        u32 i;
        const SColor red(255, 255, 0, 0);
 
        // top
        for (i = 0; i < 8; i++) {
                V[i].Pos = box.MaxEdge;
                V[i].Color = red;
        }
 
        V[1].Pos = box.MinEdge;
 
        V[2].Pos.X = box.MinEdge.X;
 
        V[3].Pos.Z = box.MinEdge.Z;
 
        for (i = 0; i < 4; i++)
                V[i].Pos.Y = box.MaxEdge.Y;
 
        // bottom
        V[4].Pos = box.MinEdge;
 
        V[5].Pos.X = box.MinEdge.X;
 
        V[6].Pos.Z = box.MinEdge.Z;
 
        for (i = 4; i < 8; i++)
                V[i].Pos.Y = box.MinEdge.Y;
 
        // material
        mat.Lighting = false;
        mat.ZWriteEnable = false;
//      mat.Wireframe = true;
        mat.ColorMask = ECP_NONE;
 
        // indices
        if (top) {
                I[0] = 0;
                I[1] = 2;
                I[2] = 1;
                I[3] = 3;
        } else {
                I[0] = 4;
                I[1] = 5;
                I[2] = 6;
                I[3] = 7;
                I[4] = 0;
                I[5] = 5;
                I[6] = 2;
                I[7] = 4;
                I[8] = 1;
                I[9] = 6;
                I[10] = 3;
                I[11] = 0;
        }
 
/*      for (i = 0; i < 8; i++) {
                printf("Vertex %u is pos %f %f %f\n", i, V[i].Pos.X,
                        V[i].Pos.Y, V[i].Pos.Z);
        }*/
}
 
void boxer::render() {
 
        drv->setMaterial(mat);
        drv->setTransform(ETS_WORLD, IdentityMatrix);
 
        if (istop) {
                drv->drawVertexPrimitiveList(V, 4, I, 2, EVT_STANDARD, EPT_TRIANGLE_FAN);
        } else {
                drv->drawVertexPrimitiveList(V, 8, I, 10, EVT_STANDARD, EPT_TRIANGLE_STRIP);
        }
}
Post Reply