# j3d wer kollidiert mit wem?



## bob_sheknowdas (3. Mai 2012)

Hallo,
 ich habe mir für java 3d einen collisionDetector gebaut. Leider weis ich nicht wie ich rausbekommen kann welche Objecte hier miteinander zusammengestoßen sind. Wie kann ich das abfragen?

Hier fix der collisionDetector


```
public class CollisionDetector extends Behavior {
	private WakeupOnCollisionEntry wEnter;
	private WakeupOnCollisionExit wExit;
	private WakeupOnCollisionMovement wMovement;
	private Sphere player;
	private Steuerung st;
	
	public CollisionDetector(Sphere player, Steuerung steuerung) {
		this.player = player;
		st = steuerung;
	}
	
	public void initialize() {
		wEnter = new WakeupOnCollisionEntry(player, WakeupOnCollisionEntry.USE_GEOMETRY);
		wExit = new WakeupOnCollisionExit(player, WakeupOnCollisionExit.USE_GEOMETRY);
		wMovement = new WakeupOnCollisionMovement(player, WakeupOnCollisionMovement.USE_GEOMETRY);
		wakeupOn(wEnter);
	}
	
	public void processStimulus(Enumeration criteria) {
		st.ende();
		wakeupOn(wEnter);
		wakeupOn(wExit);
		wakeupOn(wMovement);
	}
}
```

Eins der beiden Objekte muss ja in jedem Fall der Player sein. Aber wie finde ich raus, mit wem der Player collidiert ist?


----------



## Marco13 (3. Mai 2012)

Wie üblich erstmal die Frage, ob das KSKB von einer Websuche nach [c]WakeupOnCollisionEntry java2s[/c], nämlich The use of the CollisionDetector : Collision3DJava , vielleicht schon hilft?


----------



## bob_sheknowdas (4. Mai 2012)

ich nehme an du spielst auf diesen teil des codes an


```
public void processStimulus(Enumeration criteria) {
    WakeupCriterion theCriterion = (WakeupCriterion) criteria.nextElement();
    if (theCriterion instanceof WakeupOnCollisionEntry) {
      Node theLeaf = ((WakeupOnCollisionEntry) theCriterion)
          .getTriggeringPath().getObject();
      System.out.println("Collided with " + theLeaf.getUserData());
    } else if (theCriterion instanceof WakeupOnCollisionExit) {
      Node theLeaf = ((WakeupOnCollisionExit) theCriterion)
          .getTriggeringPath().getObject();
      System.out.println("Stopped colliding with  "
          + theLeaf.getUserData());
    } else {
      Node theLeaf = ((WakeupOnCollisionMovement) theCriterion)
          .getTriggeringPath().getObject();
      System.out.println("Moved whilst colliding with "
          + theLeaf.getUserData());
    }
    wakeupOn(oredCriteria);
  }
```


Nein, der hilft nicht wirklich. Da steht dann bei mir "Collided with null"...


----------



## Spacerat (4. Mai 2012)

Hehe... lol...
Bei dem Code hatte ich mich auch schon gefragt was das soll... Ich hätte dem Detektor statt der Steuerung ein Interface (z.B. Stimulus) mitgegeben, welches selbst auch eine Methode [c]processStimulus(Enumeration criteria)[/c] enthält und statt der PlayerSphere das jeweilige Kollisionsobjekt übergeben, damit man nicht ewig bei [c]st.ende()[/c] landet, sondern Kollisionsereignisse vernünftig delegieren kann. Natürlich sollten Stimulus und Kollisionsobjekt irgendwie immer im Zusammenhang stehen oder vllt. sogar immer ein und das selbe Objekt sein.


----------



## bob_sheknowdas (4. Mai 2012)

hmm, also die Steuerung übergebe ich ja nur, damit selbige das Ende meines Programms behandeln kann (st.ende()).
Das ist nötig weil in der Steuerung der Threat läuft, der quasi das Spiel ausmacht. Also ist es doch nur vernünftig, wenn sich diese Klasse auch um das Beenden des Threat, und damit des Programms kümmert

Und die Playersphere ist das Objekt, an dem der Kollisionsdetektor hängt. Wenn ich das nicht übergebe weiß der Detector ja gar nicht welches Objekt nicht mit anderen Kollidieren darf?
Die Frage ist halt blos: Mit wem oder was ist meine PlayerSphere kollidiert?


----------



## Spacerat (4. Mai 2012)

Irrtum... Es ist selten nur der Player, welcher nicht mit anderen Objekten kollidieren darf. Bei anderen Objekten kommt halt nur kein Game-Over sondern es passiert was ganz anderes. Was genau wird dadurch bestimmt, was in den Kirterien auftaucht. Wenn bei dir da irgendwo "Collided with null" steht, kann da was nicht stimmen. Evtl. sind ja zwei ganz andere Objekte kollidiert, aber ich rate da nur, weil ich gar nicht allzu genau weis, wie Java3D-Kollisionen funktionieren.


----------



## bob_sheknowdas (7. Mai 2012)

Spacerat hat gesagt.:


> Irrtum... Es ist selten nur der Player, welcher nicht mit anderen Objekten kollidieren darf. Bei anderen Objekten kommt halt nur kein Game-Over sondern es passiert was ganz anderes. Was genau wird dadurch bestimmt, was in den Kirterien auftaucht. Wenn bei dir da irgendwo "Collided with null" steht, kann da was nicht stimmen. Evtl. sind ja zwei ganz andere Objekte kollidiert, aber ich rate da nur, weil ich gar nicht allzu genau weis, wie Java3D-Kollisionen funktionieren.




Hmm, raten hilft mir nicht wirklich weiter...^^

Also wenn ich die Doku zum CollisionDetector richtig gelesen habe, dann detektiert er nur und ausschließlich den Player. Will heißen für jedes Objekt, dessen Kollisionen abgefragt werden sollen muss ein neuer CollisionDetector erstellt werden. 
Davon mal abgesehen ist der Player bei mir das einizge bewegliche Objekt, und damit auch das einzige, was irgendwo gegenrauschen kann. Deine Theorie "evtl. sind ja zwei ganz andere Objekte kollidiert" haut also so oder so nicht hin...


----------



## Marco13 (7. Mai 2012)

Wenn ich das KSKB starte und den Weißen Würfel (mit Draggen mit der Rechten Maustaste) bewege, gibt er aus, mit welchem anderen Würfel er kollidiert ist.


----------



## bob_sheknowdas (7. Mai 2012)

Marco13 hat gesagt.:


> Wenn ich das KSKB starte und den Weißen Würfel (mit Draggen mit der Rechten Maustaste) bewege, gibt er aus, mit welchem anderen Würfel er kollidiert ist.



Das ist bei mir nicht anders...
Nur wenn ich versuche das in mein Projekt einzubinden steht da "Collided with null"


----------



## Marco13 (7. Mai 2012)

Setzt du bei deinen Objekte die "UserData"? Hast du den Code nachvollzogen?


----------



## bob_sheknowdas (7. Mai 2012)

Marco13 hat gesagt.:


> Setzt du bei deinen Objekte die "UserData"? Hast du den Code nachvollzogen?



Ja und ja...

Falls euch das weiterhilft hab ich mal wieder mein gesamtes projekt verpackt und hochgeladen.
"CollsionDetector" ist ne eigene Klasse, die Userdaten werden in "Welt" gesetzt


----------



## bob_sheknowdas (9. Mai 2012)

Was ich vllt noch sagen sollte:
Als ich das KSKB The use of the CollisionDetector : Collision3DJava bei mir asusprobiert habe gabs ne Exception, weil new Canvas3D(null) aufgerufen wurde...
Nachdem ich das auf new Canvas3D(SimpleUniverse.getPreferredConfiguration()) geändert hatte gabs zwar keine Exception mehr, aber der weiße Würfel ließ sich nicht bewegen...


----------



## bob_sheknowdas (9. Mai 2012)

Edit:
weißer Würfel lässt sich doch bewegen.

Das Problem bei meinem Programm scheint folgendes zu sein: Ich kann nicht genau identifizieren, mit was mein Flugzeug kollidiert.
Eigentlich rausche ich in eine Sphere rein, für die ich auch die Userdata gesetzt habe. Wenn ich aber folgendes mache


```
public void processStimulus(Enumeration criteria) {
		WakeupCriterion theCriterion = (WakeupCriterion) criteria.nextElement();
	    if (theCriterion instanceof WakeupOnCollisionEntry) {
	      Node theLeaf = ((WakeupOnCollisionEntry) theCriterion).getTriggeringPath().getObject();
	      System.out.println("Collided with " + theLeaf.getUserData());
	    }
}
```

printet er mir, ich sei mit einem Shape3D kollidiert. Sowas erzeuge ich aber überhaupt nie...


----------



## Marco13 (9. Mai 2012)

Ach ja, das lag noch in meiner TODO-Liste (ich bauch' Urlaub ... erstmal nur zwei, drei Monate, danach weitersehen...  )

Praktisch alle Objekte sind Shape3Ds - also praktisch alle Geometrien, die man so anzeigt. Wenn dein "Objekt" kein Shape3D ist, sondern ein Objekt, das ein Shape3D _enthält_, musst du ggf. weiter oben im Path nachsehen.


----------



## bob_sheknowdas (9. Mai 2012)

Mein Objekt ist eine Sphere. Sphere erben nicht von Shape3D.
Shape3D erbt über 3 Ecken von Node und Sphere erbt über ein paar mehr Ecken auch von Node.
Aber wenn ich mit einer Sphere kollidiere (was eigentlich der Fall ist) sollte da nicht stehen "Collided with javax.media.j3d.Shape3D@14426a6"


----------



## Spacerat (9. Mai 2012)

Got it...
Die Situation ist simpel... Spheres bieten Methoden, um an ihre Shapes zu kommen. Du musst jetzt folgendes in deinen "create3DObject..."-Methoden tun:

```
object.getShape().setUserData(userData)
```
"userData" ist dabei ein String, welchen du natürlich als Parameter mit an die Methode geben musst... z.B. "bullet", "mond", "mars"
Mit "player" und "enemy" musst du dann ebenso verfahren und dir halt immer die Shapes von den Spheres holen.


----------



## bob_sheknowdas (9. Mai 2012)

Spacerat hat gesagt.:


> Got it...
> Die Situation ist simpel... Spheres bieten Methoden, um an ihre Shapes zu kommen. Du musst jetzt folgendes in deinen "create3DObject..."-Methoden tun:
> 
> ```
> ...



jup, das isses :toll:


Kannst du mir noch fix erklären, was genau ein Shape3D ist? Nach dem geposteten KSKB hätte ich gedacht, dass wäre einfach ein Würfel...


----------



## Marco13 (9. Mai 2012)

Ja, sowas in der Art.

Bachte aber, dass das Java2s-Beispiel nur ein Demo-Beispiel ist. Ich bin nicht sicher, ob man für eine "richtige" Anwendung den Weg über das UserData gehen sollte. Man könnte sich auch den SceneGraphPath ansehen, und schauen (mit [c]p.getNode(i) == myObject[/c]) ob ein bestimmtes Objekt darin enthalten ist (oder was ganz anderes, da gibt's sicher etliche Möglichkeiten)


----------



## Spacerat (9. Mai 2012)

Also soweit ich weis ist Shape das englische wort für Figur... also Kegel, Kugel, Würfel, Quader usw.


----------



## bob_sheknowdas (9. Mai 2012)

Hmm, nach eurer Erklärung wäre doch dann die Sphere die Figur, und nicht ein Shape3D, oder?


----------



## Spacerat (9. Mai 2012)

Äh... nach meiner Erklärung. Kannst doch Marco nicht so einfach beschuldigen... :lol:
Evtl. sind die Geometrie-Klassen von Java3D ja nur dazu da, solche Figuren zu erstellen. Das sie aber am Ende Shape3D nicht erweitern halte ich schon mal für fragwürdig.
[EDIT]Ach sieh' mal... Zylinder z.B. besteht aus mehreren Shapes - dem Rumpf und den Kappen. Die kann man auf die Art dann wohl noch sepatat texturieren, wenn man will. So fragwürdig isses also doch nicht.[/EDIT]


----------

