OVH Cloud OVH Cloud

[Java3D] Chevauchement d'objets

15 réponses
Avatar
Cedric.Olmanst
Bonjour,

je suppose que ce probl=E8me est connu, mais je n'ai trouv=E9 aucun sujet
qui en parle ici. En fait, je dessine plusieurs formes (des Box pour
faire un graphique). Le probl=E8me que je rencontre est que certaines de
celles qui doivent =EAtre derri=E8res sont affich=E9es devant, ce qui fait
un rendu tr=E8s bizarre et compl=E8tement surr=E9aliste.

A chaque lancement de mon application, c'est d'autres formes qui sont
concern=E9es. On dirait que Java3D fait le rendu des =E9l=E9ments dans un
ordre al=E9atoire, et pas dans l'ordre dans lequel j'ai mis mes
instructions. Mais le probl=E8me peut venir d'ailleurs, vous le savez
certainement mieux que moi.

Est-ce que vous avez d=E9j=E0 rencontr=E9 =E7a ? Savez-vous comment
r=E9soudre ce probl=E8me ?

Merci d'avance pour vos r=E9ponses.

5 réponses

1 2
Avatar
Cedric.Olmanst
Ploc> Si t'avais quelques minutes pour regarder tout ça, ce serait
cool. Merci d'avance, et si tu n'as pas le temps, je comprendrais, bien
évidement :)

Bon voilà, comme toutes mes barres sont sensées être à un endroit
différent, je me dis qu'elles doivent toutes être dans leur propre
TransformGroup. J'ai donc créé une classe TranslatedBox qui hérite
de TransformGroup, et qui contient ma barre... Je te passe les get et
les set, ça prend de la place pour rien.

public class TranslatedBar extends TransformGroup {

// Constantes (longueur et couleur par défaut)
private static final float WID_DEF = 0.10f; // largeur
private static final float DEP_DEF = 0.10f; // profondeur
private static final float HEI_DEF = 0.00f; // hauteur (début)

// Variables d'instance. Elles ne sont à priori pas nécéssaires,
mais
// permettront de récupérer ces infos ou les modifier si le besoin
s'en
// fait sentir
private double posX, posZ;
private Box box;
private float height;


//======================== ========================= ========================
// Constructeurs
//

public TranslatedBar() {
this(WID_DEF, DEP_DEF, HEI_DEF, 0, 0, new BarAppearance());
}

public TranslatedBar(float width, float depth, float height, double
posX, double posZ, Appearance appearance) {
// Position
super();
Transform3D translation = new Transform3D();
Vector3d translationVector = new Vector3d(posX, (double)height,
posZ);
translation.setTranslation(translationVector);
this.setTransform(translation);
// Position et valeur
this.posX = posX;
this.posZ = posZ;
this.value = height;
// Construction de la box
this.box = new Box(width, height, depth, Box.GENERATE_NORMALS,
appearance);
this.addChild(this.box);
}

<SNIP>
}

Je te mets l'endroit où je génère le graphique... je te passe le
reste pour ne pas t'emmerder avec du code inutile... pas parce que
c'est secret... si tu veux le code complet pour voir comment ça
s'exécute, il n'y a pas de problème, je peux faire un peit zip.

//======================== ========================= ========================
// Use cases
//

public void générerGraphique(Canvas3D canvas3D) {
// Création de l'univers
SimpleUniverse universe = new SimpleUniverse(canvas3D);
ViewingPlatform platform = universe.getViewingPlatform();
platform.setNominalViewingTransform();

// On règle la vue
TransformGroup platformTransformGroup =
platform.getViewPlatformTransform();
Transform3D camera = new Transform3D();
platformTransformGroup.getTransform(camera);
Point3d cameraPosition = new Point3d(1.0, 2, 2.3);
camera.lookAt(cameraPosition, new Point3d(0.5, -0.3, 0), new
Vector3d(0, 5, 0));
camera.invert();
platformTransformGroup.setTransform(camera);

// On ajoute tous nos sous-graphes à l'univers
universe.addBranchGraph(createAxisGraph());
universe.addBranchGraph(createBarsGraph(5));
universe.addBranchGraph(createLightGraph());
}

private BranchGroup createBarsGraph(int barsCount) {
BranchGroup objRoot = new BranchGroup();

// On définit les différentes apparences de barres, certaines
// seront communes (si elles ont la même couleur)
ArrayList appearanceList = new ArrayList();
Iterator itColors = colorList.iterator();
while (itColors.hasNext()) {
Color3f currentColor = (Color3f) itColors.next();
appearanceList.add(new BarAppearance(currentColor, 0.0f));
}

// Générer les barres
Iterator itRow = data.listLabels();
Iterator itData = data.listData();
int nbDataPerRow = data.getDataPerRow();
int rowNumber = 0;
while (itData.hasNext()) {
int i=0;
while (itRow.hasNext() && i<nbDataPerRow) {
float currentValue = Float.parseFloat( (String)itData.next() );
double posX = DIAM/2.0 + 0.1 + (double)(i*(DIAM+ECART));
BarAppearance currentAppearance = (BarAppearance)
appearanceList.get((i+rowNumber)%appearanceList.size());
objRoot.addChild(new TranslatedBar(DIAM, DIAM, currentValue,
posX, DIAM/2.0+0.1+rowNumber*0.32, currentAppearance));
i++;
}
rowNumber++;
}

objRoot.compile();
return objRoot;
}

<SNIP>
}

BarAppearance hérité bien évidement de Appearance... Il n'était pas
nécéssaire de procéder comme ceci, mais j'avais l'impression la
semaine passée que ça rendait le code plus clair... maintenant,
j'avoue que je me tâte.
Avatar
Ploc
wrote:

public class TranslatedBar extends TransformGroup {

// Constantes (longueur et couleur par défaut)
private static final float WID_DEF = 0.10f; // largeur
private static final float DEP_DEF = 0.10f; // profondeur
private static final float HEI_DEF = 0.00f; // hauteur (début)

// Variables d'instance. Elles ne sont à priori pas nécéssaires,
mais
// permettront de récupérer ces infos ou les modifier si le besoin
s'en
// fait sentir
private double posX, posZ;
private Box box;
private float height;


//======================================================================== > // Constructeurs
//

public TranslatedBar() {
this(WID_DEF, DEP_DEF, HEI_DEF, 0, 0, new BarAppearance());
}

public TranslatedBar(float width, float depth, float height, double
posX, double posZ, Appearance appearance) {
// Position
super();
Transform3D translation = new Transform3D();
Vector3d translationVector = new Vector3d(posX, (double)height,
posZ);



Ce n'est pas height/2. ?


translation.setTranslation(translationVector);
this.setTransform(translation);
// Position et valeur
this.posX = posX;
this.posZ = posZ;
this.value = height;
// Construction de la box
this.box = new Box(width, height, depth, Box.GENERATE_NORMALS,
appearance);
this.addChild(this.box);
}

<SNIP>
}

Je te mets l'endroit où je génère le graphique... je te passe le
reste pour ne pas t'emmerder avec du code inutile... pas parce que
c'est secret... si tu veux le code complet pour voir comment ça
s'exécute, il n'y a pas de problème, je peux faire un peit zip.

//======================================================================== > // Use cases
//

public void générerGraphique(Canvas3D canvas3D) {
// Création de l'univers
SimpleUniverse universe = new SimpleUniverse(canvas3D);
ViewingPlatform platform = universe.getViewingPlatform();
platform.setNominalViewingTransform();

// On règle la vue
TransformGroup platformTransformGroup > platform.getViewPlatformTransform();
Transform3D camera = new Transform3D();
platformTransformGroup.getTransform(camera);
Point3d cameraPosition = new Point3d(1.0, 2, 2.3);
camera.lookAt(cameraPosition, new Point3d(0.5, -0.3, 0), new
Vector3d(0, 5, 0));
camera.invert();
platformTransformGroup.setTransform(camera);

// On ajoute tous nos sous-graphes à l'univers
universe.addBranchGraph(createAxisGraph());
universe.addBranchGraph(createBarsGraph(5));
universe.addBranchGraph(createLightGraph());
}

private BranchGroup createBarsGraph(int barsCount) {
BranchGroup objRoot = new BranchGroup();

// On définit les différentes apparences de barres, certaines
// seront communes (si elles ont la même couleur)
ArrayList appearanceList = new ArrayList();
Iterator itColors = colorList.iterator();
while (itColors.hasNext()) {
Color3f currentColor = (Color3f) itColors.next();
appearanceList.add(new BarAppearance(currentColor, 0.0f));
}

// Générer les barres
Iterator itRow = data.listLabels();
Iterator itData = data.listData();
int nbDataPerRow = data.getDataPerRow();
int rowNumber = 0;
while (itData.hasNext()) {
int i=0;
while (itRow.hasNext() && i<nbDataPerRow) {
float currentValue = Float.parseFloat( (String)itData.next() );
double posX = DIAM/2.0 + 0.1 + (double)(i*(DIAM+ECART));
BarAppearance currentAppearance = (BarAppearance)
appearanceList.get((i+rowNumber)%appearanceList.size());
objRoot.addChild(new TranslatedBar(DIAM, DIAM, currentValue,
posX, DIAM/2.0+0.1+rowNumber*0.32, currentAppearance));
i++;
}
rowNumber++;
}

objRoot.compile();
return objRoot;
}

<SNIP>
}


Cote java 3d, ca a l'air d'etre bon.

Questions:
- est-ce que les donnees sont toujours dans le bon ordre?
- est-ce que ce qu'on dessine correspond aux donnees qu'on envoie?

A priori, pour repondre a ces questions, il faudrait :
- trouver un cas dans lequel tu as le bug (pas trop gros de preference)
- verifier que les donnees passees a TranslatedBar sont bonnes, par
exemple en affichant les valeurs passees au constructeur.
- si elles sont bonnes et pas l'affichage, il faudra voir du cote du
translatedbar ou de java3D, sinon, verifier en amont.

Bon courage.

Avatar
Cedric.Olmanst
Merci beaucoup pour ton aide. En fait, on a résolu mon problème sur
le forum de Sun :

view.setTransparencySortingPolicy(View.TRANSPARENCY_SORT_GEOMETRY);

===== DEBUT JAVADOC JAVA3D =====

public void setTransparencySortingPolicy(int policy)

Sets the transparency sorting policy for this view. This attribute
is one of:

* TRANSPARENCY_SORT_NONE, to specify that no depth sorting of
transparent objects is performed. Transparent objects are drawn after
opaque objects, but are not sorted from back to front.
* TRANSPARENCY_SORT_GEOMETRY, to specify that transparent
objects are depth-sorted on a per-geometry basis. Each geometry object
of each transparent Shape3D node is drawn from back to front. Note that
this policy will not split geometry into smaller pieces, so
intersecting or intertwined objects may not be sorted correctly.

The default policy is TRANSPARENCY_SORT_NONE.

Parameters:
policy - the new policy, one of TRANSPARENCY_SORT_NONE or
TRANSPARENCY_SORT_GEOMETRY.
Since:
Java 3D 1.3
===== FIN JAVADOC JAVA3D =====
Avatar
Ploc
wrote:
Merci beaucoup pour ton aide. En fait, on a résolu mon problème sur
le forum de Sun :


Oui, j'ai vu.
Tres bien, mais la prochaine fois n'oublie pas de preciser que tu
utilises des transparences ;)
Ca pourrait aider...

Avatar
Cedric.Olmanst
Lol oui, j'y penserai :) J'ai en effet une légère transparence pour
pouvoir voir le niveau des barres de mon graphique qui seraient
éventuellement cachées par des barres plus hautes, et ce, sans avoir
besoin de changer la vue.

Mais bon, je ne pouvais pas me douter que c'était à cause de la
transparence qu'il décide de me mettre certaines surfaces devant :)
D'ailleurs, j'ai testé en y ajoutant une transparence de O donc
complètement opaque, et il me fait aussi l'erreur, donc dès qu'on
introduit la notion de transparence, même si on ne l'utilise pas, il
fait foirer mon bidule.

En tout cas, merci pour le temps que tu m'as consacré :)
1 2