Historique des modifications - Message

Message #3559

Sujet: creation terrain


Type Date Auteur Contenu
Dernière modification 30-01-2008 14:34:01 Morrigan
Bonjour tout le monde,

Voila, apres deux semaines avec irrlicht, je me suis fait un petit truc qui marche (a moitier). Je suppose que mon code est hyper loin d'etre optimiser et je voudrais vos conseils pour comprendre certain truc et en realisé d'autre ^^.

Donc voila, j'essaye de réaliser un personnage qui se déplace sur un terrain 3D. Pour cela, j'ai un tableau 2D qui represente mon terrain.
1 2 1 3 4
2 3 4 1 1
1 2 3 4 2
2 1 2 2 4
4 1 2 3 3

Chaque nombre representent un type de terrain particulier (0=herbe, 1=foret, ...).
Donc ca c'est mon terrain 2D, et avec je voudrais charger des heightmap en fonction du terrain.
Donc pour pas que je doive charger toute les heightmap d'un coup, ce qui est impossible tellement ca prendrait de memoire, je charge un carré de 3x3. Sur cette aire constitué de 9 heightmap, mon personnage se trouve sur la case du milieu et quand mon personnage change de heightmap, (pour l'instant), je remove les 9 anciennes heightmap et charge les 9 nouvelles.

Par exemple, de base je charge (ca provient de mon tableau 2D ci dessus)
1 2 1
2 3 4
1 2 3
vu que mon personnage est sur le 3 du milieu si il se déplace a droite, je charge et mon perso reste au milieu
2 1 3
3 4 1
2 3 4


Voici mon code :
Dans la boucle du rendu, je fait appelle a cette méthode, et si le joueur a changer de map, ca rentre dans le if qui detruit et charge le nouveau carré de 9 maps.

void genereTerrain::modifieTerrain(irr::scene::ISceneManager *maScene, irr::scene::ICameraSceneNode *cam, irr::video::IVideoDriver *drive)
{
	posJoueurX = (int)floor(cam->getPosition().X) / tailleCase;
	posJoueurZ = (int)floor(cam->getPosition().Z) / tailleCase;

	if (posJoueurX != posPrecJoueurX || posJoueurZ != posPrecJoueurZ)
	{
		std::cout << std::endl << std::endl;
		std::cout << "Position X : " << posJoueurX << std::endl;
		std::cout << "Position Z : " << posJoueurZ << std::endl;

		std::cout << "Effacement des terrains ..." << std::endl;
		
		for (int i=0; i<3; i++)
		{
			for (int j=0; j<3; j++)
			{
				terrain[i][j]->remove();
			}
		}
		
		for (int i=0; i<3; i++)
		{
			for (int j=0; j<3; j++)
			{
				const irr::c8* ntexTerrain;
				int texTerrain = tabTypTerr[posJoueurX+i][posJoueurZ+j];

				switch (texTerrain)
				{
				case 0:
					ntexTerrain = "../../media/plaine.jpg";
					std::cout << "Plaine  :  ";
					break;
				case 1:
					ntexTerrain = "../../media/montagne.jpg";
					std::cout << "Montagne  :  ";
					break;
				case 2:
					ntexTerrain = "../../media/eau.jpg";
					std::cout << "Eau  :  ";
					break;
				case 3:
					ntexTerrain = "../../media/foret.jpg";
					std::cout << "Foret  :  ";
					break;
				}

				terrain[i][j] = maScene->addTerrainSceneNode
					(	"../../media/heightmap2.bmp", 0, i+j, 
						core::vector3df((float)(i+posJoueurX-1)*tailleCase, 0.f, (float)(j+posJoueurZ-1)*tailleCase));
				terrain[i][j]->setScale(core::vector3df(40, 4.4f, 40));
				terrain[i][j]->setMaterialFlag(video::EMF_LIGHTING, false);
				terrain[i][j]->setMaterialTexture(0, drive->getTexture(ntexTerrain));
				terrain[i][j]->setMaterialTexture(1, drive->getTexture("../../media/detailmap3.jpg"));
				terrain[i][j]->setMaterialType(video::EMT_DETAIL_MAP);
				terrain[i][j]->scaleTexture(1.0f, 20.0f);

				selector[i][j] = maScene->createTerrainTriangleSelector(terrain[i][j], 0);
				terrain[i][j]->setTriangleSelector(selector[i][j]);
				selector[i][j]->drop();

				anim[i][j] = maScene->createCollisionResponseAnimator
						( selector[i][j], cam, core::vector3df(60,100,60), core::vector3df(0,0,0), core::vector3df(0,50,0)); 
				cam->addAnimator(anim[i][j]);
				anim[i][j]->drop();
			}
		}
	}

	posPrecJoueurX = posJoueurX;
	posPrecJoueurZ = posJoueurZ;
}

Mon probleme, c'est que avec le remove, je dois avoir des grosses traces dans la mémoire étant donner que plus je change de map, plus mon programme prend de mémoire. Si j'utilise un drop, ca plante carrement.

Donc voila tout ca pour vous posez ces questions :
Comment arriver a faire qu'il ne reste plus rien des anciennes maps dans la mémoire ?
Quel est la différence entre remove, drop et drag ?

Et ca je comprend pas :
				selector[i][j] = maScene->createTerrainTriangleSelector(terrain[i][j], 0);
				terrain[i][j]->setTriangleSelector(selector[i][j]);
				selector[i][j]->drop();

				anim[i][j] = maScene->createCollisionResponseAnimator
						( selector[i][j], cam, core::vector3df(60,100,60), core::vector3df(0,0,0), core::vector3df(0,50,0)); 
				cam->addAnimator(anim[i][j]);
				anim[i][j]->drop();

On creer un selector et desuite apres on detruit l'objet avec drop. Donc comment on peut l'utilisé juste après ? Ca marche comment ce truc. Parce que en fait, ca marche ce que j'ai fait mais je sais pas comment. Du coup, j'ai aucune idée de comment je peux optimise ça.

Si vous avez tout lu, je vous remercie.
Création du message 30-01-2008 14:01:23 Morrigan
Bonjour tout le monde,

Voila, apres deux semaines avec irrlicht, je me suis fait un petit truc qui marche (a moitier). Je suppose que mon code est hyper loin d'etre optimiser et je voudrais vos conseils pour comprendre certain truc et en realisé d'autre ^^.

Donc voila, j'essaye de réaliser un personnage qui se déplace sur un terrain 3D. Pour cela, j'ai un tableau 2D qui represente mon terrain.
1 2 1 3 4
2 3 4 1 1
1 2 3 4 2
2 1 2 2 4
4 1 2 3 3

Chaque nombre representent un type de terrain particulier (0=herbe, 1=foret, ...).
Donc ca c'est mon terrain 2D, et avec je voudrais charger des heightmap en fonction du terrain.
Donc pour pas que je doive charger toute les heightmap d'un coup, ce qui est impossible tellement ca prendrait de memoire, je charge un carré de 3x3. Sur cette aire constitué de 9 heightmap, mon personnage se trouve sur la case du milieu et quand mon personnage change de heightmap, (pour l'instant), je remove les 9 anciennes heightmap et charge les 9 nouvelles.

Par exemple, de base je charge (ca provient de mon tableau 2D ci dessus)
1 2 1
2 3 4
1 2 3
vu que mon personnage est sur le 3 du milieu si il se déplace a droite, je charge et mon perso reste au milieu
2 1 3
3 4 1
2 3 4


Voici mon code :
Dans la boucle du rendu, je fait appelle a cette méthode, et si le joueur a changer de map, ca rentre dans le if qui detruit et charge le nouveau carré de 9 maps.

void genereTerrain::modifieTerrain(irr::scene::ISceneManager *maScene, irr::scene::ICameraSceneNode *cam, irr::video::IVideoDriver *drive)
{
	posJoueurX = (int)floor(cam->getPosition().X) / tailleCase;
	posJoueurZ = (int)floor(cam->getPosition().Z) / tailleCase;

	if (posJoueurX != posPrecJoueurX || posJoueurZ != posPrecJoueurZ)
	{
		std::cout << std::endl << std::endl;
		std::cout << "Position X : " << posJoueurX << std::endl;
		std::cout << "Position Z : " << posJoueurZ << std::endl;

		std::cout << "Effacement des terrains ..." << std::endl;
		
		for (int i=0; i<3; i++)
		{
			for (int j=0; j<3; j++)
			{
				terrain[i][j]->remove();
			}
		}
		
		for (int i=0; i<3; i++)
		{
			for (int j=0; j<3; j++)
			{
				const irr::c8* ntexTerrain;
				int texTerrain = tabTypTerr[posJoueurX+i][posJoueurZ+j];

				switch (texTerrain)
				{
				case 0:
					ntexTerrain = "../../media/plaine.jpg";
					std::cout << "Plaine  :  ";
					break;
				case 1:
					ntexTerrain = "../../media/montagne.jpg";
					std::cout << "Montagne  :  ";
					break;
				case 2:
					ntexTerrain = "../../media/eau.jpg";
					std::cout << "Eau  :  ";
					break;
				case 3:
					ntexTerrain = "../../media/foret.jpg";
					std::cout << "Foret  :  ";
					break;
				}

				terrain[i][j] = maScene->addTerrainSceneNode
					(	"../../media/heightmap2.bmp", 0, i+j, 
						core::vector3df((float)(i+posJoueurX-1)*tailleCase, 0.f, (float)(j+posJoueurZ-1)*tailleCase));
				terrain[i][j]->setScale(core::vector3df(40, 4.4f, 40));
				terrain[i][j]->setMaterialFlag(video::EMF_LIGHTING, false);
				terrain[i][j]->setMaterialTexture(0, drive->getTexture(ntexTerrain));
				terrain[i][j]->setMaterialTexture(1, drive->getTexture("../../media/detailmap3.jpg"));
				terrain[i][j]->setMaterialType(video::EMT_DETAIL_MAP);
				terrain[i][j]->scaleTexture(1.0f, 20.0f);

				selector[i][j] = maScene->createTerrainTriangleSelector(terrain[i][j], 0);
				terrain[i][j]->setTriangleSelector(selector[i][j]);
				selector[i][j]->drop();

				anim[i][j] = maScene->createCollisionResponseAnimator
						( selector[i][j], cam, core::vector3df(60,100,60), core::vector3df(0,0,0), core::vector3df(0,50,0)); 
				cam->addAnimator(anim[i][j]);
				anim[i][j]->drop();
			}
		}
	}

	posPrecJoueurX = posJoueurX;
	posPrecJoueurZ = posJoueurZ;
}

Mon probleme, c'est que avec le remove, je dois avoir des grosses traces dans la mémoire étant donner que plus je change de map, plus mon programme prend de mémoire. Si j'utilise un drop, ca plante carrement.

Donc voila tout ca pour vous posez ces questions :
Comment arriver a faire qu'il ne reste plus rien des anciennes maps dans la mémoire ?
Quel est la différence entre remove, drop et drag ?

Et ca je comprend pas :
				selector[i][j] = maScene->createTerrainTriangleSelector(terrain[i][j], 0);
				terrain[i][j]->setTriangleSelector(selector[i][j]);
				selector[i][j]->drop();

				anim[i][j] = maScene->createCollisionResponseAnimator
						( selector[i][j], cam, core::vector3df(60,100,60), core::vector3df(0,0,0), core::vector3df(0,50,0)); 
				cam->addAnimator(anim[i][j]);
				anim[i][j]->drop();

On creer un selector et desuite apres on detruit l'objet avec drop. Donc comment on peut l'utilisé juste après ? Ca marche comment ce truc. Parce que en fait, ca marche ce que j'ai fait mais je sais pas comment. Du coup, j'ai aucune idée de comment je peux optimise ça.

Si vous avez tout lu, je vous remercie.

Retour

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
173 invités en ligne
membre en ligne: -
RSS Feed