Il y a quelque chose qui me chagrinne pas mal en ce moment. Dans l'optique d'un prochain projet, je commence
à coder quelques fonctions bien utiles dont je disposais sous DM3D.
Cherchant à faire une fonction de test de visibilité toute bête d'un mesh, j'ai donc employé les fonctions
natives d'Irrlicht, mais là, je suis un peu bloqué car cela ne fonctionne pas vraiment, tout du moins comme
je l'attendais...
Le résultat est toujours TRUE, même quand on sort de la zone visible. Il faut vraiment presque être
derriere la camera pour enfin passer à FALSE.
Bug ou mauvaise utilisation des fonctions d'Irrlicht ?
Voici mon code de test:
#include <irrlicht.h> #include <iostream> using namespace irr; using namespace core; using namespace scene; using namespace video; #ifdef _IRR_WINDOWS_ #pragma comment(lib, "Irrlicht.lib") #endif // données globales bool _bExit = false; int main() { // choix driver video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9; printf("Please select the driver you want for this example:\n"\ " (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\ " (d) Software Renderer\n (e) Burning's Software Renderer\n"\ " (f) NullDevice\n (otherKey) exit\n\n"); char i; std::cin >> i; switch(i) { case 'a': driverType = video::EDT_DIRECT3D9;break; case 'b': driverType = video::EDT_DIRECT3D8;break; case 'c': driverType = video::EDT_OPENGL; break; case 'd': driverType = video::EDT_SOFTWARE; break; case 'e': driverType = video::EDT_BURNINGSVIDEO;break; case 'f': driverType = video::EDT_NULL; break; default: return 0; } IrrlichtDevice *device = createDevice( driverType, dimension2d<s32>(640, 480), 32, false, false, true, NULL); IVideoDriver* driver = device->getVideoDriver(); ISceneManager* scenegraph = device->getSceneManager(); // cube 1 ISceneNode* cube1 = scenegraph->addCubeSceneNode(2.0f, scenegraph->getRootSceneNode()); //cube1->setPosition( vector3df(10,0,0) ); // définition camera. SKeyMap keyMap[4] = { {EKA_MOVE_FORWARD, KEY_UP}, {EKA_MOVE_BACKWARD, KEY_DOWN}, {EKA_STRAFE_LEFT, KEY_LEFT}, {EKA_STRAFE_RIGHT, KEY_RIGHT}, }; ICameraSceneNode* cam = scenegraph->addCameraSceneNodeFPS( scenegraph->getRootSceneNode() , 100.0f, 50.0f, -1, keyMap, 4); cam->setPosition(core::vector3df(0,1,-10)); // boucle principale int lastFPS = -1; while(device->run() & !_bExit) { driver->beginScene(true, true, SColor(255,100,101,140)); scenegraph->drawAll(); driver->endScene(); //============================ // frustum test //============================ const scene::SViewFrustum* frustum = cam->getViewFrustum(); bool FrustumCode = frustum->getBoundingBox().intersectsWithBox(cube1->getBoundingBox()); // info des information temps réél int fps = driver->getFPS(); if (lastFPS != fps) { core::stringw str = L"Test visibilité: "; str += FrustumCode; device->setWindowCaption(str.c_str()); lastFPS = fps; } } device->drop(); return 0; }
Hors ligne
const scene::SViewFrustum* frustum = smgr->getSceneCollisionManager()->getSceneNodeFromCameraBB(camera, 0, false);
bool FrustumCode = frustum->getBoundingBox().intersectsWithBox(cube1->getBoundingBox());
voila normalement sa devrai marcher
Dernière modification par pspmy (24-11-2008 00:14:09)
Hors ligne
pspmy :
const scene::SViewFrustum* frustum = smgr->getSceneCollisionManager()->getSceneNodeFromCameraBB(camera, 0, false);
bool FrustumCode = frustum->getBoundingBox().intersectsWithBox(cube1->getBoundingBox());
voila normalement sa devrai marcher
Non d'un lutin, fallais la trouver celle-la... je vais voir cela, Merci pspmy
[EDIT]
....mais heu non.
smgr->getSceneCollisionManager()->getSceneNodeFromCameraBB(camera, 0, false); retourne visiblement un ISceneNode.
Et même en faisant cela, ça ne fonctionne pas, pire même ça plante au bout de quelques seconde.
Hmmm, plus qu'a me mettre à creuser le truc ce soir
Hors ligne
ptetre
ISceneNode* cube1 = addCubeSceneNode(2.0f, scenegraph->getRootSceneNode(), 1); while (.....) //============= ISceneNode *wievNode = smgr->getSceneCollisionManager()->getSceneNodeFromCameraBB(camera, 0, false); if (wievNode->getID() == cube1->getID())) { //ton cube et visible }
mais dans ce qua il fo donner des id ou des nom a tes node
Dernière modification par pspmy (24-11-2008 10:50:33)
Hors ligne
Hmm, pas vraiment convaincu par la méthode, alors qu'un simple test de Frustum culling tout bête suffit. J'vais me retrouver de nouveau à coder mes
propres fonctions...
Je vais voir cela dans la soirée.
Hors ligne
Bon, j'ai donc pris le temps ce soir de re-coder ma fonction DM3D qui était basée sur du code DX9c pour pouvoir tourner avec
Irrlicht. Cela semble bien fonctionner, je vais l'éprouver pour pouvoir l'intégrer dans mon moteur de terrain.
Le code se décompose en 4 parties:
1- une petite classe Plane, pour me faciliter les choses, quelques lignes pas bien sorcier.
2- UpdateCullInfo: partie qui permet d'établir les 6 plans du cube de polygone de vue.
3- _isVisible: fonction d'interogation pour savoir si un mesh (ou plutot son boundingBox) est visible ou non.
4- corps du programme de test (identique au code ci-dessus du message initial.
Voilà, voici donc le code complet, fonctions et corps de test.
#include <irrlicht.h> #include <iostream> using namespace irr; using namespace core; using namespace scene; using namespace video; #ifdef _IRR_WINDOWS_ #pragma comment(lib, "Irrlicht.lib") #endif // données globales bool _bExit = false; ISceneManager* scenegraph; //----------------------------------------------------------------------------- // Name: Plane class // Desc: petite classe plane personnalisée pour pour ce codage. //----------------------------------------------------------------------------- class Plane { public: float a; float b; float c; float d; Plane(): a(0),b(0),c(0),d(0) {} Plane(float aa, float bb, float cc, float dd): a(aa), b(bb), c(cc), d(dd){} Plane operator-(const Plane& other) const { return Plane(a - other.a, b - other.b, c - other.c, d - other.d); } Plane operator+(const Plane& other) const { return Plane(a + other.a, b + other.b, c + other.c, d + other.d); } float 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; } } void 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; } float DotCoord(float *V) { return (a * V[0] + b * V[1] + c * V[2] + d); } }; // donnée globale, ou autre en fonction des besoins Plane mFrustumPlane[6]; //----------------------------------------------------------------------------- // Name: UpdateCullInfo() // Desc: Update Cull Info, attention avec la camera courante //----------------------------------------------------------------------------- void UpdateCullInfo() { scene::ICameraSceneNode* cam = scenegraph->getActiveCamera(); core::matrix4 pMatProj, pMatView; pMatProj = cam->getProjectionMatrix(); pMatView = cam->getViewMatrix(); core::matrix4 VPI = pMatProj * pMatView; Plane col0(VPI(0,0), VPI(1,0), VPI(2,0), VPI(3,0)); Plane col1(VPI(0,1), VPI(1,1), VPI(2,1), VPI(3,1)); Plane col2(VPI(0,2), VPI(1,2), VPI(2,2), VPI(3,2)); Plane col3(VPI(0,3), VPI(1,3), VPI(2,3), VPI(3,3)); // construit les 6 plane du Frustum view mFrustumPlane[0] = col2; // near mFrustumPlane[1] = (col3 - col2); // far mFrustumPlane[2] = (col3 + col0); // left mFrustumPlane[3] = (col3 - col0); // right mFrustumPlane[4] = (col3 - col1); // top mFrustumPlane[5] = (col3 + col1); // bottom for(int i = 0; i < 6; i++) { mFrustumPlane[i].Normalize(); } } //----------------------------------------------------------------------------- // Name: _isVisible() // Desc: test de visibilité d'un mesh //----------------------------------------------------------------------------- int _isVisible(const core::aabbox3d<f32>& box) { float P[3]; float Q[3]; // la classe vector3d ne possédant pas d'opérateur de surcharge [].... 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) { // pour chaque coordonnées x, y, z... for(int j = 0; j < 3; ++j) { // etabli le poiont PQ dans la même direction que le plan normal sur l'axe. if( mFrustumPlane[i][j] >= 0.0f ) { P[j] = Min[j]; Q[j] = Max[j]; } else { P[j] = Max[j]; Q[j] = Min[j]; } } if( mFrustumPlane[i].DotCoord(Q) < 0.0f ) // en dehor, exit procedure return false; } return true; } int main() { // choix driver video::E_DRIVER_TYPE driverType; printf("Please select the driver you want for this example:\n"\ " (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\ " (d) Software Renderer\n (e) Burning's Software Renderer\n"\ " (f) NullDevice\n (otherKey) exit\n\n"); char i; std::cin >> i; switch(i) { case 'a': driverType = video::EDT_DIRECT3D9;break; case 'b': driverType = video::EDT_DIRECT3D8;break; case 'c': driverType = video::EDT_OPENGL; break; case 'd': driverType = video::EDT_SOFTWARE; break; case 'e': driverType = video::EDT_BURNINGSVIDEO;break; case 'f': driverType = video::EDT_NULL; break; default: return 0; } IrrlichtDevice *device = createDevice( driverType, dimension2d<s32>(640, 480), 32, false, false, true, NULL); IVideoDriver* driver = device->getVideoDriver(); scenegraph = device->getSceneManager(); // cube 1 ISceneNode* cube1 = scenegraph->addCubeSceneNode(2.0f, scenegraph->getRootSceneNode()); cube1->setPosition( vector3df(10,0,0) ); // définition camera. SKeyMap keyMap[4] = { {EKA_MOVE_FORWARD, KEY_UP}, {EKA_MOVE_BACKWARD, KEY_DOWN}, {EKA_STRAFE_LEFT, KEY_LEFT}, {EKA_STRAFE_RIGHT, KEY_RIGHT}, }; ICameraSceneNode* cam = scenegraph->addCameraSceneNodeFPS( scenegraph->getRootSceneNode() , 100.0f, 50.0f, -1, keyMap, 4); cam->setPosition(core::vector3df(0,1,-10)); // boucle principale int lastFPS = -1; while(device->run() & !_bExit) { driver->beginScene(true, true, SColor(255,100,101,140)); scenegraph->drawAll(); driver->endScene(); //============================ // mise a jour frustum //============================ UpdateCullInfo(); //============================ // frustum test //============================ // récupération du boundingBox, puis transformation pour faire le test core::aabbox3d<f32> box = cube1->getBoundingBox(); core::matrix4 matMesh = cube1->getAbsoluteTransformation(); matMesh.transformBoxEx(box); int FrustumCode = _isVisible(box); // des information temps réél int fps = driver->getFPS(); core::stringw str = L"Test visibilité: "; str += FrustumCode; device->setWindowCaption(str.c_str()); lastFPS = fps; } device->drop(); return 0; }
Hors ligne
Merci, je vais mettre à jour donc mon code de terrain, je posterais la mise à jour ici http://forum.irrlicht.fr/viewtopic.php?id=533
quand cela sera fait
Hors ligne
pspmy :
ok tu menvera un mail ok ?
Pas de soucis
Hors ligne
Options | Liens officiels | Caractéristiques | Statistiques | Communauté |
---|---|---|---|---|
Corrections |
|
xhtml 1.0 css 2.1 Propulsé par FluxBB Traduit par FluxBB.fr |
882 membres 1429 sujets 11119 messages |
Dernier membre inscrit: LiseBuisson96 101 invités en ligne Aucun membre connecté RSS Feed |