Hello sa fait un baille que j'ai pas poster une ressource x), donc j'ai mit au point mon système de frustrum culling en me basant sur celui de tmyke concrètement cela sert a masquer les node non visible et donc de gagner du frame rate

FrustrumCulling.hppFrustrumCulling.cppPlane.hppPlane.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
///--------------------------------------------------------------------------------
/// @file FrustrumCulling.hpp
/// @brief Technique de culling par masquage d'objet non visible
///--------------------------------------------------------------------------------
#ifndef __FRUSTRUMCULLING_HPP_INCLUDED__
#define __FRUSTRUMCULLING_HPP_INCLUDED__

#include "Plane.hpp"
#include <irrlicht.h>

namespace App { namespace Engine { namespace Culling {

    ///--------------------------------------------------------------------------------
    /// Technique de culling par masquage d'objet non visible
    ///--------------------------------------------------------------------------------
    class FrustrumCulling
    {
        public:
            ///--------------------------------------------------------------------------------
            /// Constructeur
            ///
            /// @param _SceneManager : Gestionnaire de scene
            ///--------------------------------------------------------------------------------
            FrustrumCulling(irr::scene::ISceneManager * _SceneManager);
            ///--------------------------------------------------------------------------------
            /// Destructeur
            ///--------------------------------------------------------------------------------
            ~FrustrumCulling();

            ///--------------------------------------------------------------------------------
            /// Pour crée le culling
            ///--------------------------------------------------------------------------------
            void Create();
            ///--------------------------------------------------------------------------------
            /// Pour recrée le culling
            ///--------------------------------------------------------------------------------
            void Recreate();

            ///--------------------------------------------------------------------------------
            /// Pour mettre a jour le culling
            ///--------------------------------------------------------------------------------
            void Update();

            ///--------------------------------------------------------------------------------
            /// Pour ajouter un scene node
            ///
            /// @param _SceneNode : Pointeur vers le scene node
            ///--------------------------------------------------------------------------------
            void AddSceneNode(const irr::scene::ISceneNode * _SceneNode);
            ///--------------------------------------------------------------------------------
            /// Pour supprimer un scene node
            ///
            /// @param _SceneNode : Pointeur vers le scene node
            ///--------------------------------------------------------------------------------
            void RemoveSceneNode(const irr::scene::ISceneNode * _SceneNode);

            ///--------------------------------------------------------------------------------
            /// Pour tester si une box et visible
            ///
            /// @param _Box : Box a tester
            ///--------------------------------------------------------------------------------
            bool IsVisible(const irr::core::aabbox3d<irr::f32>& box);

        private:
            ///--------------------------------------------------------------------------------
            /// Gestionnaire de scene
            ///--------------------------------------------------------------------------------
            irr::scene::ISceneManager * m_SceneManager;
            ///--------------------------------------------------------------------------------
            /// Pour stocker les nodes
            ///--------------------------------------------------------------------------------
            irr::core::array<irr::scene::ISceneNode *> m_Nodes;
            ///--------------------------------------------------------------------------------
            /// Pour tester si un node est visible
            ///--------------------------------------------------------------------------------
            App::core::Plane m_FrustumPlane[6];
            ///--------------------------------------------------------------------------------
            /// Dernier / derniere position et cible de la camera
            ///--------------------------------------------------------------------------------
            irr::core::vector3df m_LastPosition, m_LastTarget;
    };

}    // Culling
}    // Engine
}    // App

#endif    // __FRUSTRUMCULLING_HPP_INCLUDED__
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
///--------------------------------------------------------------------------------
/// @file FrustrumCulling.cpp
/// @brief Technique de culling par masquage d'objet non visible
///--------------------------------------------------------------------------------

#include "FrustrumCulling.hpp"

namespace App { namespace Engine { namespace Culling {

    ///--------------------------------------------------------------------------------
    /// Constructeur
    ///
    /// @param _SceneManager : Gestionnaire de scene
    ///--------------------------------------------------------------------------------
    FrustrumCulling::FrustrumCulling(irr::scene::ISceneManager * _SceneManager)
        : m_SceneManager(_SceneManager)
    {

    }
    ///--------------------------------------------------------------------------------
    /// Destructeur
    ///--------------------------------------------------------------------------------
    FrustrumCulling::~FrustrumCulling()
    {

    }

    ///--------------------------------------------------------------------------------
    /// Pour crée le culling
    ///--------------------------------------------------------------------------------
    void FrustrumCulling::Create()
    {
        m_SceneManager->getSceneNodesFromType(irr::scene::ESNT_ANY, m_Nodes);

        for (irr::u32 __I = 0 ; __I < m_Nodes.size() ; __I++)
            m_Nodes[__I]->setAutomaticCulling(irr::scene::EAC_OFF);
    }
    ///--------------------------------------------------------------------------------
    /// Pour recrée le culling
    ///--------------------------------------------------------------------------------
    void FrustrumCulling::Recreate()
    {
        m_Nodes.clear();
        Create();
    }

    ///--------------------------------------------------------------------------------
    /// Pour mettre a jour le culling
    ///--------------------------------------------------------------------------------
    void FrustrumCulling::Update()
    {
        if (m_LastPosition == m_SceneManager->getActiveCamera()->getAbsolutePosition() && m_LastTarget == m_SceneManager->getActiveCamera()->getTarget())
            return;

        irr::core::matrix4 __MatrixProj, __MatrixView;

        __MatrixProj = m_SceneManager->getActiveCamera()->getProjectionMatrix();
        __MatrixView = m_SceneManager->getActiveCamera()->getViewMatrix();
        
        irr::core::matrix4 __VPI = __MatrixProj * __MatrixView;

        App::core::Plane __col0(__VPI(0,0), __VPI(1,0), __VPI(2,0), __VPI(3,0));
        App::core::Plane __col1(__VPI(0,1), __VPI(1,1), __VPI(2,1), __VPI(3,1));
        App::core::Plane __col2(__VPI(0,2), __VPI(1,2), __VPI(2,2), __VPI(3,2));
        App::core::Plane __col3(__VPI(0,3), __VPI(1,3), __VPI(2,3), __VPI(3,3));

        m_FrustumPlane[0] = __col2;         
        m_FrustumPlane[1] = (__col3 - __col2);
        m_FrustumPlane[2] = (__col3 + __col0);
        m_FrustumPlane[3] = (__col3 - __col0);
        m_FrustumPlane[4] = (__col3 - __col1);
        m_FrustumPlane[5] = (__col3 + __col1);
        
        for(int __I = 0 ; __I < 6 ; __I++)       
        {
            m_FrustumPlane[__I].Normalize();
        }

        for (irr::u32 __I = 0 ; __I < m_Nodes.size() ; ++__I)
        {
            if (m_Nodes[__I]->getType() == irr::scene::ESNT_ANIMATED_MESH
                || m_Nodes[__I]->getType() == irr::scene::ESNT_BILLBOARD
                || m_Nodes[__I]->getType() == irr::scene::ESNT_CUBE
                || m_Nodes[__I]->getType() == irr::scene::ESNT_MESH
                || m_Nodes[__I]->getType() == irr::scene::ESNT_OCT_TREE
                || m_Nodes[__I]->getType() == irr::scene::ESNT_PARTICLE_SYSTEM
                || m_Nodes[__I]->getType() == irr::scene::ESNT_SHADOW_VOLUME
                || m_Nodes[__I]->getType() == irr::scene::ESNT_SKY_BOX
                || m_Nodes[__I]->getType() == irr::scene::ESNT_SPHERE
                || m_Nodes[__I]->getType() == irr::scene::ESNT_TERRAIN
                || m_Nodes[__I]->getType() == irr::scene::ESNT_WATER_SURFACE
                )
            {
                irr::core::aabbox3d<irr::f32> _Box    = m_Nodes[__I]->getBoundingBox();
                irr::core::matrix4 _MatrixMesh    = m_Nodes[__I]->getAbsoluteTransformation();

                _MatrixMesh.transformBoxEx(_Box);
                if(IsVisible(_Box) == 0)
                    m_Nodes[__I]->setVisible(false);
                else
                    m_Nodes[__I]->setVisible(true);
            }
        }
    }

    ///--------------------------------------------------------------------------------
    /// Pour ajouter un scene node
    ///
    /// @param _SceneNode : Pointeur vers le scene node
    ///--------------------------------------------------------------------------------
    void FrustrumCulling::AddSceneNode(const irr::scene::ISceneNode * _SceneNode)
    {
        ((irr::scene::ISceneNode*)_SceneNode)->setAutomaticCulling(irr::scene::EAC_OFF);
        m_Nodes.insert((irr::scene::ISceneNode*)_SceneNode);
    }
    ///--------------------------------------------------------------------------------
    /// Pour supprimer un scene node
    ///
    /// @param _SceneNode : Pointeur vers le scene node
    ///--------------------------------------------------------------------------------
    void FrustrumCulling::RemoveSceneNode(const irr::scene::ISceneNode * _SceneNode)
    {
        for (irr::u32 __I = 0 ; __I < m_Nodes.size() ; __I++)
        {
            if (m_Nodes[__I] == _SceneNode)
                m_Nodes.erase(__I);
        }
    }

    ///--------------------------------------------------------------------------------
    /// Pour tester si une box et visible
    ///
    /// @param _Box : Box a tester
    ///--------------------------------------------------------------------------------
    bool FrustrumCulling::IsVisible(const irr::core::aabbox3d<irr::f32>& _Box)
    {
        float __P[3];
        float __Q[3];

        float __Min[3];    memcpy( __Min, &_Box.MinEdge.X, sizeof(float)*3);
        float __Max[3];    memcpy( __Max, &_Box.MaxEdge.X, sizeof(float)*3);
        
        for(int __I = 0 ; __I < 6 ; ++__I)
        {
            for(int __J = 0 ; __J < 3 ; ++__J)
            {

                if( m_FrustumPlane[__I][__J] >= 0.0f )
                {
                    __P[__J] = __Min[__J];
                    __Q[__J] = __Max[__J];
                }
                else
                {
                    __P[__J] = __Max[__J];
                    __Q[__J] = __Min[__J];
                }
            }
            if( m_FrustumPlane[__I].DotCoord(__Q) < 0.0f  )
                return false;
        }

        return true;
    }

}    // Culling
}    // Engine
}    // App
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
///--------------------------------------------------------------------------------
/// @file Plane.hpp
/// @brief Plane pour les test
///--------------------------------------------------------------------------------
#ifndef __FPLANE_HPP_INCLUDED__
#define __FPLANE_HPP_INCLUDED__

#include <math.h>

namespace App { namespace core {

    ///--------------------------------------------------------------------------------
    /// Plane pour les test
    ///--------------------------------------------------------------------------------
    class Plane
    {
        public:
            ///--------------------------------------------------------------------------------
            /// Constructeur
            ///--------------------------------------------------------------------------------
            Plane();
            ///--------------------------------------------------------------------------------
            /// Constructeur
            ///
            /// @param _a : Point a
            /// @param _b : Point b
            /// @param _c : Point c
            /// @param _d : Point d
            ///--------------------------------------------------------------------------------
            Plane(float _a, float _b, float _c, float _d);

            ///--------------------------------------------------------------------------------
            /// Operateur de soustraction
            ///
            /// @param _Other : Autre Plan
            ///--------------------------------------------------------------------------------
            Plane operator-(const Plane& _Other) const;
            ///--------------------------------------------------------------------------------
            /// Operateur d'addition
            ///
            /// @param _Other : Autre Plan
            ///--------------------------------------------------------------------------------
            Plane operator+(const Plane& _Other) const;
            ///--------------------------------------------------------------------------------
            /// Operateur de tableau
            ///
            /// @param _I : Index
            ///--------------------------------------------------------------------------------
            float operator[](unsigned _I) const;

            ///--------------------------------------------------------------------------------
            /// Pour normaliser le plan
            ///--------------------------------------------------------------------------------
            void Normalize();
            ///--------------------------------------------------------------------------------
            /// Retourne l'addition de la multiplication des 4 point par une valeur
            ///
            /// @param _V : Facteur de multiplication
            ///--------------------------------------------------------------------------------
            float DotCoord(float *_V);

            ///--------------------------------------------------------------------------------
            /// Point a
            ///--------------------------------------------------------------------------------
            float a;
            ///--------------------------------------------------------------------------------
            /// Point b
            ///--------------------------------------------------------------------------------
            float b;
            ///--------------------------------------------------------------------------------
            /// Point c
            ///--------------------------------------------------------------------------------
            float c;
            ///--------------------------------------------------------------------------------
            /// Point d
            ///--------------------------------------------------------------------------------
            float d;
    };

}    // Engine
}    // App

#endif    // __FPLANE_HPP_INCLUDED__
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
///--------------------------------------------------------------------------------
/// @file Plane.cpp
/// @brief Plane pour les test
///--------------------------------------------------------------------------------

#include "Plane.hpp"

namespace App { namespace core {

    ///--------------------------------------------------------------------------------
    /// Constructeur
    ///--------------------------------------------------------------------------------
    Plane::Plane()
        : a(0),b(0),c(0),d(0)
    {
    }
    ///--------------------------------------------------------------------------------
    /// Constructeur
    ///
    /// @param _a : Point a
    /// @param _b : Point b
    /// @param _c : Point c
    /// @param _d : Point d
    ///--------------------------------------------------------------------------------
    Plane::Plane(float _a, float _b, float _c, float _d)
        : a(_a), b(_b), c(_c), d(_d)
    {
    }

    ///--------------------------------------------------------------------------------
    /// Operateur de soustraction
    ///
    /// @param _Other : Autre Plan
    ///--------------------------------------------------------------------------------
    Plane Plane::operator-(const Plane& _Other) const
    {
        return Plane(a - _Other.a, b - _Other.b, c - _Other.c, d - _Other.d);
    }
    ///--------------------------------------------------------------------------------
    /// Operateur d'addition
    ///
    /// @param _Other : Autre Plan
    ///--------------------------------------------------------------------------------
    Plane Plane::operator+(const Plane& _Other) const
    {
        return Plane(a + _Other.a, b + _Other.b, c + _Other.c, d + _Other.d);
    }
    ///--------------------------------------------------------------------------------
    /// Operateur de tableau
    ///
    /// @param _I : Index
    ///--------------------------------------------------------------------------------
    float Plane::operator[](unsigned _I) const     
    {
        switch(_I)
        {
            case 0:
                return a;
            case 1:
                return b;
            case 2:
                return c;
            case 3:
                return d;
            default:
                return 0;   
        }   
    }

    ///--------------------------------------------------------------------------------
    /// Pour normaliser le plan
    ///--------------------------------------------------------------------------------
    void Plane::Normalize()
    {
        float _M;   
        _M = sqrt( a*a + b*b + c*c + d*d );   
        a = a / _M;   
        b = b / _M;   
        c = c / _M;   
        d = d / _M;   
    }

    ///--------------------------------------------------------------------------------
    /// Retourne l'addition de la multiplication des 4 point par une valeur
    ///
    /// @param _V : Facteur de multiplication
    ///--------------------------------------------------------------------------------
    float Plane::DotCoord(float *_V)
    {   
        return (a * _V[0] + b * _V[1] + c * _V[2] + d);   
    }
               
}    // Engine
}    // App


Donc voila alors pour l'utilisation ajouter juste avant la boucle de rendu

Code c++ :

App::Engine::Culling::FrustrumCulling * m_FrustrumCulling = new App::Engine::Culling::FrustrumCulling(m_SceneManager);
m_FrustrumCulling->Create();


et dans le boucle de rendu

Code c++ :

m_FrustrumCulling->Update();
m_Driver->beginScene(.........


=========================================

Exemple complet :

Code c++ :

#include <irrlicht.h>
#include "FrustrumCulling.hpp"

using namespace irr;

#pragma comment(lib, "Irrlicht.lib")

int main()
{
    irr::SIrrlichtCreationParameters m_IrrlichtCreationParameters;
    m_IrrlichtCreationParameters.AntiAlias            = true;
    m_IrrlichtCreationParameters.Bits                = 32;
    m_IrrlichtCreationParameters.DriverType            = irr::video::EDT_DIRECT3D9;
    m_IrrlichtCreationParameters.Fullscreen            = false;
    m_IrrlichtCreationParameters.HighPrecisionFPU    = true;
    m_IrrlichtCreationParameters.Stencilbuffer        = true;
    m_IrrlichtCreationParameters.WindowSize            = irr::core::dimension2di(800,600);

    irr::IrrlichtDevice            * m_Device            = irr::createDeviceEx(m_IrrlichtCreationParameters);
    irr::video::IVideoDriver    * m_Driver            = m_Device->getVideoDriver();
    irr::scene::ISceneManager    * m_SceneManager    = m_Device->getSceneManager();

    for( int x = 0 ; x != 10 ; x++)
        for( int y = 0 ; y != 10 ; y++)
            for( int z = 0 ; z != 10 ; z++)
                m_SceneManager->addCubeSceneNode(1, 0 , -1, irr::core::vector3df(x * 10 ,y* 10, z* 10));

    irr::scene::ICameraSceneNode * m_Camera = m_SceneManager->addCameraSceneNodeFPS(0, 40.f, 0.01f);
    m_Camera->setPosition(m_Camera->getPosition() + irr::core::vector3df(0,20,0));
   
    App::Engine::Culling::FrustrumCulling * m_FrustrumCulling = new App::Engine::Culling::FrustrumCulling(m_SceneManager);

    m_FrustrumCulling->Create();
    int __LastFPS = -1;

    while(m_Device->run())
    {
        if (m_Device->isWindowActive())
        {
            m_FrustrumCulling->Update();
            m_Driver->beginScene(true, true, irr::video::SColor(0,200,200,200));
            m_SceneManager->drawAll();
            m_Driver->endScene();
           
            int __Fps = m_Driver->getFPS();
            if (__LastFPS != __Fps)
            {
                core::stringw __Str;
                __Str += "FPS:";
                __Str += __Fps;
                m_Device->setWindowCaption(__Str.c_str());
                __LastFPS = __Fps;
            }

        }
    }
    delete m_FrustrumCulling;
    m_Device->drop();

    return 0;
}