Bonsoir,

J'ai encore un petit soucis lors de mon implémentation d'un système d'octree. Je vais essayer d'être clair même si ça va être assez compliqué.

En gros, l'octree est un arbre, et chaque noeud possède ses propres données de type T (défini par l'argument template). Ici, j'y stocke des objets Spheres *, donc T = Spheres *. Afin que chaque objet Spheres * puisse savoir dans quel noeud il se trouve, dès que j'ajoute un élément dans un noeud, j'appelle la fonction membre AttachNode de la classe Spheres, comme ceci :

elementToAdd->AttachNode (this, numData++);

Et voici la fonction AttachNode, très simple :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
void AttachNode (Octree<Sphere *> * octree, size_t objectID)
{
	octreeNode = octree;
	objID = objectID;
}
ou objID est un size_t, et octreeNode : Octree<Sphere *> * octreeNode;

A l'initialisation, aucun soucis, tout marche bien. Je peux ajouter autant d'élément que je veux, cette fonction est bien appelé, octreeNode pointe bien vers le bon objet... Le problème survient lorsque les objets Spheres bougent et, potentiellement, peuvent changer de noeud. J'appelle tout simplement la fonction Update du noeud dans lequel l'objet se trouve :

octreeNode->UpdateElement (objID);

Je commence, dans cette fonction UpdateElement, à récupérer un pointeur vers l'objet Spheres *, grâce à l'objID (en effet mes objets sont stockés dans une map) :

// On récupère en premier lieu un pointeur vers l'objet, grâce à l'ID passé en
// paramètre
const ptrT element = myDataContener [elementID];

ou ptrT n'est qu'un typedef de T, donc = Spheres *. Et myDataContener est une map (dataContener myDataContener, ou dataContener == std::map <size_t, T>).

Dans cette fonction, je souhaite déplacer cet objet au noeud parent.
J'ai vérifié, le noeud parent est le bon, pas de soucis là-dessus. Je me contente de faire un simple :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
 
parent->AddElementInThisNode (element); // On ajoute l'élément dans le noeud parent
 
// Puis on le supprime de la liste de ce noeud sans appeler le destructeur // (puisque le pointeur sera inséré dans un autre noeud)
myDataContener.erase (elementID);
Et enfin, voici la fonction :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
template <typename T>
void Octree<T>::AddElementInThisNode (const ptrT elementToAdd)
{
	elementToAdd->AttachNode (this, numData++);
	myDataContener.insert (std::pair<size_t, ptrT> (numData++, elementToAdd));
}
Les soucis commencent ici, lorsque je rappelle la fonction AttachNode. J'accède sans soucis à la fonction, ce qui prouve bien que elementToAdd est un pointeur valide vers un objet Spheres *, mais le soucis, c'est dès que je veux réactualiser le pointeur octreeNode :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
void AttachNode (Octree<Sphere *> * octree, size_t objectID)
{
	octreeNode = octree;
	objID = objectID;
}
Pour une raison que j'ignore, ça plante irrémédiablement, alors que ça fonctionnait bien la première fois que je l'appelle... Je ne sais pas d'où ça vient. J'ai vérifié chaque pointeur, chaque élément, ils pointent bien tous vers le bon élément... Mais là ça plante .

EDIT : Compris... Quand j'insérais une donnée dans ma map, je faisais ocmme ça :

elementToAdd->AttachNode (this, numData++);
myDataContener.insert (std::pair<size_t, ptrT> (numData, elementToAdd));

résultat, l'ID attaché à l'objet était par exemple 3, tandis que celui associé à la map pour cet objet, 4... En fait il fallait faire ++numData... Une erreur toute bête, mais qui m'a gâché 2 heures...