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
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
et dans le boucle de rendu
=========================================
Exemple complet :