# Verständnisfrage zum Aufbau des Universe



## Thoralt (17. Feb 2008)

Hallo Leute,

ich mache gerade meine ersten Schritte mit Java3D und habe viele Beispiele und Tutorials gelesen und ausprobiert. Allen gemein ist der Ansatz, daß sie eine 3D-Welt aufbauen und diese über verschiedene Methoden im Nachhinein modifizieren.

Mein Thema ist die Visualisierung von Datensätzen (ich stelle mir ein halbtransparentes, mehrschichtiges Modell meiner Daten aus verschiedenen Gitternetzebenen vor, eingefärbt je nach Höhe). In 2D habe ich bisher beim Eintreffen eines neuen Datensatzes den alten verworfen und auf einem abgeleiteten JPanel neu gezeichnet.

Mit Java3D habe ich jetzt ebenfalls zunächst einmal Testdaten in einem abgeleiteten JPanel dargestellt. Wenn nun ein neuer Datensatz eintrifft - wo genau muß ich hinfassen, um meine Szene neu aufzubauen? Wie kann ich die entsprechenden alten Elemente löschen? Wo muß ich ansetzen?

Hier ein kurzes Beispiel:

```
public class J3DPanel extends JPanel
{
	private static final long serialVersionUID = 1L;

	public J3DPanel()
	{
		setLayout(new BorderLayout());
		Canvas3D c3d = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
		SimpleUniverse simpleU = new SimpleUniverse(c3d);

		BranchGroup bg = new BranchGroup();
		bg.addChild(createGraph());
		bg.compile();

		OrbitBehavior orbit = new OrbitBehavior(c3d, OrbitBehavior.REVERSE_ALL);
		orbit.setSchedulingBounds(new BoundingSphere());
		simpleU.getViewingPlatform().setViewPlatformBehavior(orbit);
		simpleU.getViewingPlatform().setNominalViewingTransform();
		bg.compile();

		simpleU.addBranchGraph(bg);
		this.add(c3d);
	}

	Shape3D createGraph()
	{
		int NUM_TRIANGLES = 2;
		int NUM_POINTS = NUM_TRIANGLES * 3;

		TriangleArray ta;
		Point3f coords[] = new Point3f[NUM_POINTS];
		Color3f colors[] = new Color3f[NUM_POINTS];

		coords[0] = new Point3f(0.0f, 0.0f, 0.0f);
		coords[1] = new Point3f(0.5f, 0.0f, 0.0f);
		coords[2] = new Point3f(0.5f, 0.5f, 0.0f);

		coords[3] = new Point3f(-1.0f, 0.0f, -0.2f);
		coords[4] = new Point3f(-1.0f, -1.0f, -0.2f);
		coords[5] = new Point3f(1.5f, 1.5f, -0.2f);

		colors[0] = new Color3f(1.0f, 0.0f, 0.0f);
		colors[1] = new Color3f(1.0f, 1.0f, 0.0f);
		colors[2] = new Color3f(1.0f, 1.0f, 1.0f);

		colors[3] = new Color3f(1.0f, 0.0f, 0.0f);
		colors[4] = new Color3f(1.0f, 0.0f, 1.0f);
		colors[5] = new Color3f(1.0f, 0.0f, 1.0f);

		ta =
		    new TriangleArray(NUM_TRIANGLES * 3, TriangleArray.COORDINATES
		        | TriangleArray.COLOR_3);
		ta.setCoordinates(0, coords);
		ta.setColors(0, colors);

		Appearance ap = new Appearance();
		ap.setTransparencyAttributes(new TransparencyAttributes(
		    TransparencyAttributes.NICEST, 0.5f));

		Shape3D myShape = new Shape3D(ta);
		myShape.setAppearance(ap);
		return myShape;
	}
}
```

Vielen Dank für Eure Hilfe im Voraus

Thoralt


----------



## Marco13 (18. Feb 2008)

Ach, wieder jemand, der "mal kurz das Universum erklärt bekommen will" :wink:

Es man kann sich dafür wohl eine BranchGroup "aufheben", also sowas wie

```
public class J3DPanel extends JPanel
{
   BranchGroup mainBranchGroup;

   public J3DPanel()
   {
      setLayout(new BorderLayout());
      Canvas3D c3d = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
      SimpleUniverse simpleU = new SimpleUniverse(c3d);

      mainBranchGroup = new BranchGroup();  // Dafür dann noch die Capability bits setzen, ALLOW_CHILDREN_REMOVE und so....!!!!

      OrbitBehavior orbit = new OrbitBehavior(c3d, OrbitBehavior.REVERSE_ALL);
      orbit.setSchedulingBounds(new BoundingSphere());
      simpleU.getViewingPlatform().setViewPlatformBehavior(orbit);
      simpleU.getViewingPlatform().setNominalViewingTransform();

      simpleU.addBranchGraph(mainBranchGroup);
      this.add(c3d);
   }

   void createGraph(Data data...)
   {
      // Mach' die mainBranchGroup leer
      mainBranchGroup.removeAllChilldren();

      ...
      ... Erstelle TriangleArray aus den übergebenen Daten....
      colors[5] = new Color3f(...data...);
      ta = new TriangleArray(NUM_TRIANGLES * 3, TriangleArray.COORDINATES   | TriangleArray.COLOR_3);
      ta.setCoordinates(0, coords);
      ta.setColors(0, colors);

      ...
      // Baue Shape3D und hänge es in die mainBranchGroup
      Shape3D myShape = new Shape3D(ta);
      myShape.setAppearance(ap);
      mainBranchGroup.addChild(myShape);

   }
}
```

Dann sollte es schon reichen, einfach von außen
panel.createGraph(...data...);
mit den passenden Daten aufzurufen.

Ganz grob jedenfalls (hab lange nichts mit J3D gemacht....)


----------



## Thoralt (18. Feb 2008)

Vielen Dank für die Hilfe!

Aufbauend auf den Tips habe ich weitergegoogelt und herausgefunden, daß ich meine Shape3D-Objekte nicht direkt aus einer BranchGroup entfernen kann, sondern nur, wenn diese nocheinmal in eine BranchGroup gekapselt werden.


```
mainBranchGroup = new BranchGroup();  // Dafür dann noch die Capability bits setzen, ALLOW_CHILDREN_REMOVE und so....!!!!
```

Dies war ein wichtiger Hinweis. Konkret brauche ich ALLOW_CHILDREN_WRITE und ALLOW_CHILDREN_EXTEND für die mainBranchGroup und ALLOW_DETACH für die Unter-Branchgroup, welche meine Shape3D kapselt.

Viele Grüße
Thoralt


----------



## Marco13 (18. Feb 2008)

Vielleicht noch als Nachtrag (je nachdem, worum es genau geht) : Wenn die Daten "oft" geändert werden (es also im witesten SInne um eine "Animation" geht) sollte man die Shape3Ds natürlich nicht immer neu aufbauen, sondern sich lieber den TriangleArray aufheben, und den immer nur mit neuen Daten füllen...


----------

