# Kameradrehung darstellen



## thisisme (8. Jan 2007)

Hallo!

Ich habe einen Würfel, auf den eine Kamera gerichtet ist. Die Kamera hat einen festen Standpunkt, sie kann sich aber nach links und rechts drehen. Dieses drehen möchte ich jetzt darstellen.

Meine Idee ist, den Würfel in die jeweils entgegengesetze Richtung zu verschieben. Dreht sich die Kamera also nach links, schiebe ich den Würfel nach rechts. Problem: irgendwann wird eine Nachbarseite des Würfels sichtbar, was ja nicht sein dürfte. Ich hab überlegt, dass ich den Würfel einfach entsprechend drehen könnte, mir fehlt aber der Ansatz, den Winkel zu bestimmen. Hat jemand von euch eine Idee?


----------



## Marco13 (8. Jan 2007)

Hi

Sorry, keine richtige Antwort auf die Frage, aber nur mal aus Neugier: Wenn du die Kamera drehen willst - warum drehst du dann nicht die Kamera? (Ich glaube mich dunkel zu erinnern, dass das möglich sein müßte...)

bye


----------



## thisisme (9. Jan 2007)

Also wenn das möglich ist würd ich das gerne machen, ich hab bisher nur nicht rausgefunden wie, darum ist mir das mit dem Verschieben eingefallen.


----------



## Gast (9. Jan 2007)

Von welcher API redest du eigentlich?


----------



## thisisme (11. Jan 2007)

Gast hat gesagt.:
			
		

> Von welcher API redest du eigentlich?


Ich? Von der Java3D-API?


----------



## Illuvatar (11. Jan 2007)

Schau dir mal in der API die Klasse ViewingPlatform an, ein Objekt davon erhältst du über SimpleUniverse#getViewingPlatform().


----------



## thisisme (11. Jan 2007)

Also wenn ich das richtig verstehe, dann ist die ViewingPlatform quasi der "Ansichts"-Teil des Szenegraphen, dem ich auch Behaviors usw. hinzufügen kann. Heißt das, ich muss meine Kamerabewegung dort unterbringen? Oder wolltest du auf eine bestimmte Methode der Klasse hinaus? Blick grad nicht mehr ganz durch...


----------



## Illuvatar (11. Jan 2007)

Nein nein, das ist genau richtig, die ViewingPlatform entspricht sozusagen der Kamera. Eine Kamerabewegung ist dort wohl am Besten aufgehoben.


----------



## Marco13 (11. Jan 2007)

Ich glaube, es reicht schon, wenn du dir die TransformGroup der ViewingPlatform mit getViewPlatformTransform holst, und die dann entsprechend veränderst. Aber man muß dazusagen, dass das View-Model von Java3D (zumindest, als ich mich zuletzt damit beschäftigt habe) ziemlich mieserabel dokumentiert ist.  Es gibt zwar Seiten wie http://java.sun.com/products/java-media/3D/forDevelopers/j3dguide/ViewModel.doc.html, aber mal ein sehr treffendes Zitat, über das ich damals gestolpert bin:


> > The Java view model is not really fully documented ...
> 
> It's terrible. I think it's really only fully documented by the source code,
> and even then I would not have come to a full understanding without access
> to the people who implemented it.


(von http://archives.java.sun.com/cgi-bin/wa?A2=ind0406&L=java3d-interest&P=12357)

Das klang sehr ermutigend... :wink:
[/quote]


----------



## Guest (12. Jan 2007)

thisisme hat gesagt.:
			
		

> Gast hat gesagt.:
> 
> 
> 
> ...



Kein Wunder dass keiner weiß was du willst wenn du dich nicht orgendlich ausdrückst: hellsehen kann keiner und nur du weißt was du verwendest. Und dass du J3D hast lässt sich bei deiner Fragestellung kaum erahnen da es dort wie oben schon erwähnt eben keine Kamera gibt.


----------



## thisisme (12. Jan 2007)

Marco13 hat gesagt.:
			
		

> Ich glaube, es reicht schon, wenn du dir die TransformGroup der ViewingPlatform mit getViewPlatformTransform holst, und die dann entsprechend veränderst.



Danke für die Antworten, ich versuch das mal. Angenommen, ich möchte die Kamera um 45° um die Y-Achse drehen. Ich hab versucht mir das ganze bei der Drehung des Würfels ein bisschen abzugucken. Aus Gründen der Einfachheit das ganze erstmal ohne Events, sondern gleich bei der Initialisierung des Graphen:


```
SimpleUniverse simpleU = new SimpleUniverse(canvas3D);
simpleU.getViewingPlatform().setNominalViewingTransform();

TransformGroup vpTrans = simpleU.getViewingPlatform().getViewPlatformTransform();
Transform3D trans = new Transform3D();
Transform3D temp = new Transform3D();
temp.set(trans);
trans.rotY(Math.PI / 4);
trans.mul(temp);
vpTrans.setTransform(trans);

BranchGroup scene = createSceneGraph();	
simpleU.addBranchGraph(scene);
```

Das kann so nicht stimmen, weil ich in meiner Applikation dann gar nichts mehr sehen. Hat jemand von euch vielleicht ein kleines Beispiel? Oder auch nur einen Tipp wie ich das richtig angehen?

*EDIT:*
Oder wäre lookAt() der richtige Ansatz?

Danke!


----------



## Illuvatar (12. Jan 2007)

Die lookAt-Methode hab ich noch nie wirklich verstanden... :?

Die Sache ist die, bist du dir denn wirklich sicher, dass da, wo du hinschaust, auch etwas zu sehen ist? Bedenke auch folgendes: setNominalViewingTransform macht afaik nichts anderes, als die Kamera ein Stück auf der z-Achse nach hinten zu versetzen. Wenn du dann setTransform machst, ist dieser Effekt wieder weg. Probier vielleicht mal, entweder das setNominalViewingTransform hinter die Zeilen 5-11 zu setzen, oder probier mal folgendes:
An dem Code von dir ist es zunächst mal eigentlich recht sinnlos, wenn auch nicht falsch, dass du zwei Transform3D verwendest. Aber wenn du temp nicht auf trans setzt, sondern auf den alten Wert in der TransformGroup, macht das schon eher Sinn und funktioniert vielleicht auch: (ich hab hier aber die Variablennamen andersrum verwendet, weil ich das logischer finde)

```
TransformGroup vpTrans = simpleU.getViewingPlatform().getViewPlatformTransform(); 
Transform3D trans = new Transform3D(); 
Transform3D temp = new Transform3D(); 
vpTrans.getTransform(trans);
temp.rotY(Math.PI / 4); 
trans.mul(temp); 
vpTrans.setTransform(trans);
```


----------



## thisisme (12. Jan 2007)

Danke für die schnelle Antwort, jetzt klappt es soweit!


			
				Illuvatar hat gesagt.:
			
		

> bist du dir denn wirklich sicher, dass da, wo du hinschaust, auch etwas zu sehen ist?


 Da hast du recht, die Drehung war zu weit gewählt.


			
				Illuvatar hat gesagt.:
			
		

> An dem Code von dir ist es zunächst mal eigentlich recht sinnlos, wenn auch nicht falsch, dass du zwei Transform3D verwendest. Aber wenn du temp nicht auf trans setzt, sondern auf den alten Wert in der TransformGroup, macht das schon eher Sinn und funktioniert vielleicht auch


Nochmal  . Da war ich zu schnell...

Eine (hoffentlich) letzte Frage zu dem Thema hätt ich noch:
ich möchte die Drehung gern in ein Behavior "auslagern", das auf die Tastatur reagiert. Dazu hab ich meine Behavior-Klasse von ViewPlatformBehavior abgeleitet. Um das Behavior-Objekt hinzuzufügen hab ich folgenden Code verwendet:

```
TransformGroup vpTrans = simpleU.getViewingPlatform().getViewPlatformTransform();
MyMovement m = new MyMovement(vpTrans);
simpleU.getViewingPlatform().setViewPlatformBehavior(m);
```

Leiderwird die processStimulus()-Methode nicht aufgerufen, wenn ich eine Taste drücke. Hier noch ein Ausschnitt aus meinem Behavior. Die Klasse führt noch keine Transformation durch, ich wollte nur testen ob die Methoden aufgerufen werden.

```
public class MyMovement extends ViewPlatformBehavior {

     public MyMovement(TransformGroup targetTG) {
          System.out.println("Konstruktor");
     }

     @Override
          public void initialize() {
	      System.out.println("init!");
	      wakeupOn(new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED));		
	}

       @Override
	public void processStimulus(Enumeration arg0) {
		WakeupOnAWTEvent event = (WakeupOnAWTEvent) arg0.nextElement();
		KeyEvent key = (KeyEvent) event.getAWTEvent()[0];
		char c = key.getKeyChar();
		System.out.println("process stimulus"); 
		
		wakeupOn(new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED));
	}
}
```


----------



## Illuvatar (12. Jan 2007)

Weiß ich erstmal nicht... hast du schedulingBounds gesetzt?
Und ich sehe gerade, dass es da noch eine Subklasse ViewPlatformAWTBehavior gibt. Vielleicht geht es nur mit der?


----------



## thisisme (14. Jan 2007)

An den SchedulingBounds hats gelegen!

Vielen Dank für die geduldige Hilfe!


----------



## AMiGA (17. Jan 2007)

Ich habe ein ähnliches Problem, bzw. eine Verständnisfrage: Wenn ich mittels TransformGroup#setTransform den beeinflusse, ändere ich ja nur einmalig die View-Position, oder? Ich würde gerne wissen, wie ich die Objekte selber rotieren kann. Ich dachte, dass das über die den Objekten zugewiesene TransformGroup geht. Das klappt bei mir aber leider nicht.

Mein Problem ist: der Benutzer kann über (Maus-) Behaviors die Szene zoomen, rotieren, etc. Ich würde ihm gerne über ein Popup-Menü die Möglichkeit zur Verfügung stellen, das ganze zurückzusetzen, bzw. bestimmte "Kamerapositionen" (Blick von vorne, Blick von oben, etc.) anzuspringen. 

Gruß,
AMiGA


----------



## Marco13 (17. Jan 2007)

Normalerweise hängt das Objekt an einer TransformGroup. Wenn man deren Transform ändert, ändert sich die Position des Objekts. Was das Objekt mit dem zurücksetzen der Kamera zu tun hat, ist mir nicht ganz klar, aber du kannst natürlich die gewünschte Transform (die die Ansicht z.B. von oben oder von der Seite beschreibt) per Hand setzen...


----------



## AMiGA (17. Jan 2007)

Wenn ich mittels


```
Transform3D t3d = new Transform3D();
t3d.set(new Vector3f(0f, 1f, 0f));
transGroupObjects.setTransform(t3d);
```

die Transform der Objekte ändere, so ändert sich ja auch wieder nur die Sichtweise/der View. Wenn ich dann mittels Maus rotiere und zoome und die Transform danach nochmals setze, tut sich nichts. Ist ja eigentlich auch logisch, die Sichtweise/der View ist ja schon auf die Werte gesetzt.

Gruß,
AMiGA


----------



## Marco13 (17. Jan 2007)

Was sich dann tut oder nicht tut, hängt davon ab, wie der Szenegraph aussieht. Wenn du die Transform für eine TransformGroup setzt, wo NUR die Objekte dranhängen, bleibt die View davon unbeeinflußt. Evtl. würde ein compilierbarer Codeschnipsel und eine Beschreibung des gewünschten Verhaltens weiterhelfen...?


----------



## AMiGA (22. Jan 2007)

Du hast recht! Der Graph war falsch aufgebaut. TransformGroup der Objekte und TransformGroup des Universums hingen zusammen. Jetzt funktioniert es, danke!

Gruß,
AMiGA


----------

