#1 

23-11-2008 19:53:58

tmyke
Administrateurs
Avatar de tmyke
Date d'inscription:
Messages: 1025
IP: 90.56.192.96
Courriel

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... sad

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:\
"\\
		" (a) Direct3D 9.0c\
 (b) Direct3D 8.1\
 (c) OpenGL 1.5\
"\\
		" (d) Software Renderer\
 (e) Burning's Software Renderer\
"\\
		" (f) NullDevice\
 (otherKey) exit\
\
");
		
	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;
}


Force et sagesse...

Hors ligne


#2 

23-11-2008 23:10:38

hardcpp
Membres
Avatar de hardcpp
Date d'inscription:
Messages: 229
IP: 83.198.244.5
Courriel

const scene::SViewFrustum* frustum = smgr->getSceneCollisionManager()->getSceneNodeFromCameraBB(camera, 0, false);
bool FrustumCode = frustum->getBoundingBox().intersectsWithBox(cube1->getBoundingBox());

voila normalement sa devrai marcher wink


Hors ligne


#3 

24-11-2008 06:02:18

tmyke
Administrateurs
Avatar de tmyke
Date d'inscription:
Messages: 1025
IP: 90.56.254.39
Courriel

pspmy Ecris:

const scene::SViewFrustum* frustum = smgr->getSceneCollisionManager()->getSceneNodeFromCameraBB(camera, 0, false);
bool FrustumCode = frustum->getBoundingBox().intersectsWithBox(cube1->getBoundingBox());

voila normalement sa devrai marcher wink

Non d'un lutin, fallais la trouver celle-la... je vais voir cela, Merci pspmy wink

[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


Force et sagesse...

Hors ligne


#4 

24-11-2008 09:50:02

hardcpp
Membres
Avatar de hardcpp
Date d'inscription:
Messages: 229
IP: 83.198.244.5
Courriel

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


Hors ligne


#5 

24-11-2008 17:36:41

tmyke
Administrateurs
Avatar de tmyke
Date d'inscription:
Messages: 1025
IP: 90.56.254.39
Courriel

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.


Force et sagesse...

Hors ligne


#6 

24-11-2008 17:40:59

hardcpp
Membres
Avatar de hardcpp
Date d'inscription:
Messages: 229
IP: 83.198.244.5
Courriel

dsl


Hors ligne


#7 

25-11-2008 20:46:59

tmyke
Administrateurs
Avatar de tmyke
Date d'inscription:
Messages: 1025
IP: 90.56.127.250
Courriel

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:\
"\\
		" (a) Direct3D 9.0c\
 (b) Direct3D 8.1\
 (c) OpenGL 1.5\
"\\
		" (d) Software Renderer\
 (e) Burning's Software Renderer\
"\\
		" (f) NullDevice\
 (otherKey) exit\
\
");
		
	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;
}


Force et sagesse...

Hors ligne


#8 

25-11-2008 22:06:12

hardcpp
Membres
Avatar de hardcpp
Date d'inscription:
Messages: 229
IP: 83.198.75.19
Courriel

bravo ^^


Hors ligne


#9 

26-11-2008 17:45:35

tmyke
Administrateurs
Avatar de tmyke
Date d'inscription:
Messages: 1025
IP: 90.56.193.137
Courriel

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


Force et sagesse...

Hors ligne


#10 

26-11-2008 17:52:16

hardcpp
Membres
Avatar de hardcpp
Date d'inscription:
Messages: 229
IP: 83.198.198.64
Courriel

ok tu menvera un mail ok ?


Hors ligne


#11 

26-11-2008 18:03:15

tmyke
Administrateurs
Avatar de tmyke
Date d'inscription:
Messages: 1025
IP: 90.56.193.137
Courriel

pspmy Ecris:

ok tu menvera un mail ok ?

Pas de soucis wink


Force et sagesse...

Hors ligne


#12 

26-11-2008 19:46:40

hardcpp
Membres
Avatar de hardcpp
Date d'inscription:
Messages: 229
IP: 83.198.198.64
Courriel

big_smile


Hors ligne


Options Liens officiels Caractéristiques Statistiques Communauté
Préférences cookies
Corrections
irrlicht
irrklang
irredit
irrxml
Propulsé par Django
xhtml 1.0
css 2.1
884 membres
1440 sujets
11337 messages
Dernier membre inscrit: Saidov17
118 invités en ligne
membre en ligne: -
RSS Feed