# [Java3D] Animation von mehreren Objekten



## macfly (23. Jul 2011)

Hallo,

ich stehe gerade vor einem Problem. Ich hab vor mehrere Objekt nacheinandern auf Knopfdruck einen bestimmten Pfad (via PositionPathInterpolator, von A nach B) entlang gehen zu lassen. Wenn ich jedoch, nachdem ich ein Objekt losgeschickt habe, ein zweites losschicke, dann befindet sich das zweite Objekt an der selben Stelle, wie das erste, welches früher losgeschickt wurde. Möchte aber, dass dieses sozusagen hinterherläuft.

Ich befürchte, dass dies an dem Alpha-Objekt liegt. Habe jedoch keinen Schmimmer, wie ich dieses Problem lösen kann.

Hier ein Auszug aus meiner Animation-Klasse:


```
public BranchGroup objektEinsAnimation(TransformGroup tg) {

	    BranchGroup objRoot = new BranchGroup();

	    Alpha alpha = new Alpha(-1, 5000);
	    Transform3D axisOfPos = new Transform3D();
	    float[] knots = { 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f, 0.8f, 0.9f, 1.0f };
	    Point3f[] positions = new Point3f[9];

	    AxisAngle4f axis = new AxisAngle4f(1.0f, 0.0f, 0.0f, 0.0f);
	    axisOfPos.set(axis);

	    positions[0] = new Point3f(0.0f, -4.0f, 10.0f);
	    positions[1] = new Point3f(-4.0f, -4.0f, 10.0f);
	    positions[2] = new Point3f(-8.0f, -4.0f, 10.0f);
	    positions[3] = new Point3f(-12.0f, -4.0f, 10.0f);
	    positions[4] = new Point3f(-16.0f, -4.0f, 10.0f);
	    positions[5] = new Point3f(-20.0f, -4.0f, 10.0f);
	    positions[6] = new Point3f(-24.0f, -4.0f, 10.0f);
	    positions[7] = new Point3f(-28.0f, -4.0f, 10.0f);
	    positions[8] = positions[0];

	    PositionPathInterpolator posPath = new PositionPathInterpolator(alpha, tg, axisOfPos, knots, positions);
	    posPath.setSchedulingBounds(new BoundingSphere());

	    objRoot.addChild(posPath);

	    return objRoot;
	}

public BranchGroup objektZweiAnimation(TransformGroup tg)
...
public BranchGroup objektDreiAnimation(TransformGroup tg)
...
public BranchGroup objektVierAnimation(TransformGroup tg)
...
```


----------



## Marco13 (23. Jul 2011)

*ins blaue rat*: Vermutlich musst du beim Alpha die passende startzeit setzen. Oder eine andere Position für die Transformation? Am besten wäre ein KSKB, schau auch mal hier: http://www.java-forum.org/spiele-mu...ng/120983-rotation-knopfdruck.html#post782570


----------



## macfly (24. Jul 2011)

Vielen Dank Marco. setStartTime(System.currentTimeMillis()); wars.

Nun bin ich aber auf ein weiteres Problem gestoßen. Ich möchte, solange die Animation stattfindet, also das Objekt von A nach B "läuft", einen Button ausgrauen (setEnable(false)). Das geht auch mehr oder weniger wunderbar.

Ich habe folgenden Code:

```
while(!ani.animationBeendet()) {
    		buttonWuerfeln.setEnabled(false);
    	}
		buttonWuerfeln.setEnabled(true);
```

Ich klicke auf den Button, der Button wird ausgegraut, 2 Sekunden später ist der Button wieder klickbar und das Objekt ist von A nach B. Aber nun kommts: Die Animation wird nicht angezeigt. Das Objekt wurde sozusagen von A nach B "gebeamt".

*edit:*

Ich sollte vllt erwähnen, dass "ani" ein Objekt der Animation-Klasse ist und die Methode animationBeendet() true zurückgibt, sollte das Alpha-Objekt "durch" (finished()) sein.


----------



## Marco13 (24. Jul 2011)

Das muss in einem eigenen Thread gemacht werden. Mit so einer while-Schleife ist das "busy waiting", und eigentlich ein no-go, aber als HACK könnte man sowas machen wie

```
void doit()
{
    Thread t = new Thread(new Runnable()
    { 
        public void run()
        {
            setButtonEnabled(false);
            while(!ani.animationBeendet()) { // HACK!!! Busy waiting
                try{
                Thread.sleep(10);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
            setButtonEnabled(true);
    });
    t.start();
}

private void setButtonEnabled(final boolean enabled)
{
    SwingUtilities.invokeLater(new Runnable()
    {
        public void run()
        {
            buttonWuerfeln.setEnabled(enabled);
        }
    });
}
```

Um das "richtig" zu machen müßte man mehr über deine Gesamtstruktur wissen, und schauen, ob man irgendwie auf das Ende einer Alpha-Animation hören kann.... (mit wait()/notify() oder Locks und Conditions arbeiten....)

Eigentlich hätte ich das nicht schreiben sollen  Nochmal: Das ist eigentlich Bogus. Poste ggf. mal mehr Code, am besten... (du ahnst es vielleicht schon) ... mit einem KSKB.


----------



## macfly (24. Jul 2011)

Hallo Marco, vielen Dank, dein Hack macht genau das, was ich wollte!

Jetzt stehe ich aber wieder vor einem anderen Problem, auf dessen Lösung ich einfach nicht komme.

Ich habe ein Objekt, welches ich richtig positioniert habe und auch in die für mich richtige Richtung "schaut". Wird jedoch die Animation (siehe meinen ersten Post in diesem Thread) ausgeführt, dreht sich das Objekt um 90°.

Also nach dem Start ist alles richtig positioniert. Klicke ich auf den Button, der die Animation ausführt, dreht sich das Objekt um 90°, fährt aber quasi seitwärts den gewünschten Pfad entlang.

Hast du dafür auch eine Lösung parat?


----------



## Marco13 (24. Jul 2011)

Pragmatisch: VOR das Objekt noch eine TransformGroup hängen, die eine Drehung um 90° enthält. Aber was beim _Ablauf_ nicht passt, ist ohne ein richtiges Beispiel schwer zu sagen.


----------



## macfly (24. Jul 2011)

Was meinst du mit "VOR das Objekt"? Das Objekt befindet sich in einer TransformGroup. Diese TransformGroup wird an die Animation übergeben:


```
public BranchGroup objektEinsAnimation(TransformGroup tg)
```


----------



## Marco13 (24. Jul 2011)

Bisher ist es also sowas wie

```
Shape3D object = new Shape3D();
TransformGroup tg = new TransformGroup();
tg.addChild(object);
objektEinsAnimation(tg);
```
Ggf. reicht schon sowas wie

```
Shape3D object = new Shape3D();
TransformGroup other = new TransformGroup(); // Rotation von 90 grad einstellen....
other.addChild(object);
TransformGroup tg = new TransformGroup();
tg.add(other);
objektEinsAnimation(tg);
```
Wenn nicht hilft bestimmt ein KSKB.


----------

