# "Kamera"-Position



## Wagner(original) (22. Jun 2007)

Hallo,

Ich hab stundenlang gegoogelt, aber ich bin zu keinem Ergebniss gekommen.

Wie kann ich die Position von der "Kamera" bekommen? (entschuldigt mich dafür, dass ich das Fachchinesisch nicht versteh^^). Es sollte mir ein 3DPoint geben (rein theoretisch), aber wie bekomm ich den und wie geh ich mit dem um? also wie kann ich die einzelnen Punkte(x,y,z) bekommen?

ich bitte euch kein großes Fachchinesisch zu verwenden^^

schonmal im Vorraus vielen vielen Danke

mfg
Wagner

p.s. hab gesehen ich bin nicht eingeloggt, ist mir jetzt zu stressig^^


----------



## merlin2 (22. Jun 2007)

```
Transform3D t = new Transform3D();
Vector3d  = new Vector3d();
Point3d p;
universe.getViewingPlatform().getViewPlatformTransform().getTransform(t); //universe ist dein SimpleUniverse
t.get(v);
p = new Point3d(v.x, v.y, v.z);
```
Ungetestet.


----------



## Wagner (22. Jul 2007)

ok vielen dank  

hab mich wieder seit einer Ewigkeit eingefunden in mein projekt. Nun hab ich den Point3d in ein PickRay eingebaut.

Konstruktor: new PickRay(Point3d, Vector3d); //Vector3d ist die Ausgangskoordinate von diesen "Strahl".

soweit alles klar, aber will ich nun den Abstand zum "Objekt" im Universum bekommen (sofern es vom Strahl erfasst wird weiß ich nicht mehr weiter.

muss ich dem Objekt bestimme Fähigkeiten (Capilitys) geben? und mit welcher Methode komm ich an den Wert (Es sollte ein double sein, dass nur den Abstand angibt).

Schonmal vielen Dank im Vorraus.

mfg
Wagner


----------



## merlin2 (22. Jul 2007)

Wenn du ein PickResult mit deinem PickRay erzeugst, kannst du mit getClosestIntersection() ein PickIntersection-Objekt erhalten, dass dir über getDistance() den entsprechenden Wert liefert.


----------



## Guest (22. Jul 2007)

:bahnhof:   ich hätte vll. nochmal erwähnen sollen, dass ich mit dem Fachchinesisch nicht so richtig klar komm 

nun bitte ich dich mir einen kleinen Beispiel-Code zu tippern    

und mir vll erklären was du unter einem PickResult verstehst.

vielen Dank schonmal im Vorraus


----------



## merlin2 (22. Jul 2007)

Das, was du Fachchinesisch nennst, sind Klassennamen, die du in der API (z. B. hier: http://ls7-www.cs.uni-dortmund.de/students/lectures/doc_mmi0405/j3d-html/index.html ) findest.
Hast du kein Lehrbuch/Tutorial?


----------



## Wagner (25. Jul 2007)

Ja i know, ich kann damit auch halbwegs umgehen, bloß anfangs erschlagen mich solche Sachen immer 

Aber ich hab es nun (halbwegs) hinbekommen. 

Mein Problem ist das. Ich hab einen Vector(3d) mit 0.0, -1.0, 0.0 der immer von der Kameraposition ausgeht. Dann hol ich via Picking die Distanz zum nächsten (sofern vorhanden) Objekt.  Anfangs hat meine Methode gar nicht angeschlagen. Ich hab mich gewundert und ewig rumgerätselt, bis ich mal auf die Idee gekommen bin 
"Hey, "lauf" doch mal unten durch". Siehe da, die Methode schlägt an, jetzt kann ich aber nicht die Welt auf den Kopf stellen. Also habe ich den Vektor auf 0.0, 1.0, 0.0 gesetzt, und bin dann oben drüber "gelaufen", schon schlägt die Methode nicht mehr an. Kann mir jemand sagen an was das liegen könnte? Ich bin echt am Ende mit meinem (wenn auch sehr geringem) Latein. 

Und hier noch eine reine Interessenfrage:

Messergebnisse:

Hoehe: 2.520160535999846
Hoehe: 2.520160535999846
Hoehe: 2.520261328864337
Hoehe: 2.520261328864337
Hoehe: 2.5203621308706214
Hoehe: 2.5203621308706214
Hoehe: 2.5204630143136773
Hoehe: 2.5204630143136773
Hoehe: 2.520563956921942
Hoehe: 2.520563956921942

Warum unterscheiden sich die Messwerte nach einigen Stellen hinter dem Komma? obwohl ich waagerecht (denk ich zmd.^^) durchlauf? Diesen geringen Abweichungen sind zwar nicht interessant, aber es wundert mich doch.

Schon vielen Danke für eure Antworten.

Mit freundlichen Grüßen
Wagner


----------



## HaukederAnfänger (25. Jul 2007)

Denke Messabweichungen der Hardware


----------



## Wagner (25. Jul 2007)

nein ich denke nicht, ich mein ich bin dahinter gekommen, am Bildschirm wird ja maximal eine Abweichung von 1 Pixel angezeigt, aber wenn ich die maus nur minimal bewegt, verändert sich meine für mich immer noch waagerechte Linie. Denn in eine double variable passen einige stellen hinter's komma...so erklär ich mir das.

aber mein eigentliches Problem kann ich mir nicht erklären


----------



## HaukederAnfänger (25. Jul 2007)

Kannst du mir vllt nochmal dein Anfangsproblem mit der Camera erläutern.
Ich beschäftige demnächst auch mit der Bestimmiung von Punkten, daher ganz interessant...

Wie gebe ich den Quelltext, der hier gepostet wurde ausführlich ein...sorry,kenn mich noch ned soo aus.
Geb ich den unter 


```
(1)import java.applet.Applet;
(2)import java.awt.BorderLayout;
(3)import java.awt.GraphicsConfiguration;
(4)import com.sun.j3d.utils.applet.MainFrame;
(5)import com.sun.j3d.utils.geometry.*;
(6)import com.sun.j3d.utils.universe.*;
(7)import javax.media.j3d.*;
(8)import javax.vecmath.*;
(9)
(10)public class Universe extends Applet
(11) {
(12) private SimpleUniverse universe = null;
(13)
(14) public universe()
(15) {
(16) }
(17)
(18) public BranchGroup createSceneGraph()
(19) {
BranchGroup RootBG=new BranchGroup();

Transform3D t = new Transform3D();
Vector3d  = new Vector3d();
Point3d p;
universe.getViewingPlatform().getViewPlatformTransform().getTransform(t); //universe ist dein SimpleUniverse
t.get(v);
p = new Point3d(v.x, v.y, v.z);

...
```

ein?

ODer wie sähe der komplette Code aus?


----------



## Wagner (25. Jul 2007)

```
Transform3D t = new Transform3D();
Vector3d v      = new Vector3d();
Point3d p;

universe.getViewingPlatform().getViewPlatformTransform().getTransform(t); //universe ist dein SimpleUniverse
t.get(v);
p = new Point3d(v.x, v.y, v.z); 

System.out.println("X: "+v.x+" Y: "+v.y+" Z: "+v.z);
```

so funktioniert es bei mir


----------



## HaukederAnfänger (25. Jul 2007)

So einfach in Eclipse eingeben?


----------



## Wagner (25. Jul 2007)

yes

außer halt die oberen 3 attribute da eingeben, wo gewöhnlich attribute hinkommen


----------



## merlin2 (25. Jul 2007)

In die main-Methode oder den Konstruktor einer Klasse integrieren. :roll:  :wink: 
Vergiss die Imports nicht. 

Edit: Zu langsam.   :wink:


----------



## Wagner (25. Jul 2007)

hmmm

also um ständig die koordinaten zu bekommen brauchst du eine klasse mit z.b. einem WakeUpOnIrgendwas, oder nur bei einem mausklick, dann brauchst du ein MouseListener, sonst bekommst du nur einmal die Koordinate. Deswegen is weder Konstruktor noch die Main-Methode sinnvoll. Dazu liest du am besten Tutorial für MouseListener (ist am Anfang noch leichter als diese WakeUpOn....- Sachen.)


und mit den Imports:


```
import javax.media.j3d.Transform3D;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
```

aber gibt es in Eclipse nicht auch eine Methode die die Imports "fixt", bei NetBeans ist das auf jeden Fall so.


aber ich möchte nun nicht zu weit von meiner Frage abschweifen .


----------



## HaukederAnfänger (25. Jul 2007)

Hmm...er meckert...


```
import xyz

public static void main(String[] args);
{

 public void Cam()
 {
   der Quelltext von oben...
 };
}
```

Er sagt er hat keine Mainmethode und will auch hinter getViewingPlatform(). eine "{"...


----------



## Wagner (25. Jul 2007)

```
import xyz

public static void main(String[] args){ //hier war vorher eine ";"

//entweder startest du hier die Methode mit:
Cam();
//oder du startest die Methode im Konstruktor (weiß aber nciht wie die Klasse hier heißt, sonst hätte ich dir schnell ein getippert)

{

public void Cam()
{

   der Quelltext von oben...

} //hier war vorher ebenfalls ein ";"
}
```

Du machst noch relativ viele Syntax-Fehler, achte drauf wenn was falsch ist, dass die Syntax stimmt. Am Anfang geht es aber jeden so  (ich bin auch ncoh relativ am anfang und mach auch ncoh häufig solche Fehler)


----------



## Wagner (25. Jul 2007)

Aber ich hätte gerne eine Antwort zu meinem Problem:

hier nochmal der Beitrag:



> Ja i know, ich kann damit auch halbwegs umgehen, bloß anfangs erschlagen mich solche Sachen immer icon_wink.gif
> 
> Aber ich hab es nun (halbwegs) hinbekommen.
> 
> ...


----------



## merlin2 (26. Jul 2007)

Wagner hat gesagt.:
			
		

> Messergebnisse:
> Hoehe: 2.520160535999846
> Hoehe: 2.520160535999846
> Hoehe: 2.520261328864337
> ...



Die Abweichungen werden vielleicht mal interessant, wenn du längere Strecken läufst, da du, langsam aber stetig, bergauf gehst.
Wie läufst du denn herum (Behavior reagiert worauf)?


----------



## merlin2 (26. Jul 2007)

Wagner hat gesagt.:
			
		

> Mein Problem ist das. Ich hab einen Vector(3d) mit 0.0, -1.0, 0.0 der immer von der Kameraposition ausgeht. Dann hol ich via Picking die Distanz zum nächsten (sofern vorhanden) Objekt.  Anfangs hat meine Methode gar nicht angeschlagen. Ich hab mich gewundert und ewig rumgerätselt, bis ich mal auf die Idee gekommen bin
> "Hey, "lauf" doch mal unten durch". Siehe da, die Methode schlägt an, jetzt kann ich aber nicht die Welt auf den Kopf stellen. Also habe ich den Vektor auf 0.0, 1.0, 0.0 gesetzt, und bin dann oben drüber "gelaufen", schon schlägt die Methode nicht mehr an. Kann mir jemand sagen an was das liegen könnte? Ich bin echt am Ende mit meinem (wenn auch sehr geringem) Latein.



Da brauchst du wohl *zwei* PickRays, einen für y=-1 und einen für y=1.


----------



## Wagner (27. Jul 2007)

Hmm scheint nicht zu funktionieren.

Also ich schildere es mal genau:

In einer Klasse in der Bewegungen durchgeführt werden, frag ich vor der Bewegung immer die Distanz von der Kamera zum nächsten Objekt ab. (Sogar in beide Richtungen (oben und unten))

Code:


```
Main.u.getViewingPlatform().getViewPlatformTransform().getTransform(t1);
                t1.get(downVector);
                Main.u.getViewingPlatform().getViewPlatformTransform().getTransform(t2);
                t2.get(upVector);
                
                pDown = new Point3d(downVector.x, downVector.y, downVector.z);
                pUp = new Point3d(upVector.x, upVector.y, upVector.z);
                
                hoeheUnten = tf.Hoehenunterschied(Main.RootBG, pDown, downVector);
                if(hoeheUnten != -1.0){
                    System.out.println("Differenz nach unten: "+hoeheUnten);
                }
                
                hoeheOben = tf.Hoehenunterschied(Main.RootBG, pUp, upVector);
                if(hoeheOben != -1.0){
                    System.out.println("Differenz nach oben: "+hoeheOben);
                }
```


Und mein Objekt befindet sich an Stelle:


```
setTranslation(new Vector3f(0f,+3f,+1.5f)); // Also über "mir"
```

dann geh ich unten durch, und dann bekomm ich ein System.out von beiden, sowohl mit dem upVector als auch mit dem downVector. Das allein wirft schon Rätsel auf. 

Vektoren:


```
public static Vector3d upVector = new Vector3d(0.0, 1.0, 0.0);
    public static Vector3d downVector = new Vector3d(0.0, -1.0, 0.0);
```

verschieb ich das Objekt nun nach unten 


```
setTranslation(new Vector3f(0f,-3f,+1.5f));
```

und ich laufe nochmals durch, dann bekomm ich keine System.out's. Aber ich komme einfach nicht dahinter an was das liegen könnte. Hier meine Methode mit der ich die Distanz bekomme:


```
public double getDistance (BranchGroup bg, Point3d p, Vector3d v1){
   
    double py = -1.0;
    // Die Branchgruppe, die nur das Terrain enthält
    PickTool picktool = new PickTool (bg);
    // ein Strahl von der aktuellen Position nach unten
    picktool.setShapeRay (p, v1);
    // suche nach Bounds
    picktool.setMode (PickTool.BOUNDS);
    // nur die naheliegende Intersection ist wichtig
    PickResult pr = picktool.pickClosest ();
    if (pr != null)
    {
           // wenn es Bounds gibt, dann gibt es auch ein Objekt
        picktool.setMode (PickTool.GEOMETRY_INTERSECT_INFO);
        // diesmal haben wir die Geometrie
        pr = picktool.pickClosest ();
        if (pr != null)
        {
            // die Intersection mit dem Index “0”
            PickIntersection pi = pr.getIntersection (0);
            // die Weltkoordinaten des Punktes
            Point3d intPt = pi.getPointCoordinatesVW ();
            // nur die Y-Koordinate (die Höhe) ist wichtig
            py = intPt.y;
            // gib den Speicher frei
            pr = null;
            // gib den Wert zurück
            return py;
        }
    }
    // wenn es nichts unten gibt, dann gib –1.0 zurück
    return py;
}
```


Was ich einfach nicht verstehen kann, ist das, dass es zwar anschlägt wenn ein Objekt über mir liegt, aber nicht wenn eins unter mir liegt....

Ich hoffe ich hab es ausführlich genug erklärt, und hoffe dass ihr vll auf den Fehler kommt. (Könnte auch gut möglich sein, dass ich die kleinsten Fehler nicht finde, weil ich mich einfach schon zu sehr hinein gesteigert habe  :roll: 

Ich bedanke mich shcon im Vorraus für jede Antwort

mfG
Wagner[/code]


----------



## Wagner (27. Jul 2007)

Gebt euch keine Mühe mehr, habs hinbekommen. Muss iwas bei den Parametern schief geloffen sein.


----------



## Florianer (19. Nov 2007)

Hey du da, könntest du mir vielleicht sagen, was an den Parametern falsch war? 

Ich hab deine Funktion mal übernommen, wenn ich aber das System.out anschaue, bekomm ich zwar immer den richtigen Abstand zur Grundfläche, wie's mit scheint, aber _nur_ wenn ich mich innerhalb eines Objektes befinde. Also, Wenn ich in der Welt laufe, passiert gar nichts. Laufe ich aber in einen Quader hinein (was ich ja eigentlich gar nicht tun dürfte, wenn ich die Kollisionsvermeidung eingebaut habe), dann bekomme ich den Abstand meiner Position zum Boden, einer großen Ebene. Wieso bekomme ich den Abstand zur Ebene nicht auch, wenn ich nicht im Quader bin? (Schließlich will ich später wissen, wie weit der Quader von mir entfernt ist, wenn ich vor ihm stehe und ihn anschaue)


----------



## Guest (23. Nov 2007)

Nimm bei der Methode "getDistance" den Parameter "Vector3D v1" raus, und dann machst einfach in der Klasse ein Vector (am besten noch auf private setzen) 


```
private Vector3d DOWN = new Vector3d(0.0, -1.0, 0.0);
```

und den baust du dann in der Methode ein (anstatt v1)

das war bei mir das Problem...^^


----------



## Florianer (26. Nov 2007)

:bahnhof: 
OK, also... der Smiley hat schon mal den passenden Namen ("bahnhof"  ). Ich hab das gemacht, was du gesagt hast, nur weil ich es mal testen wollte... da ich in der Zwischenzeit ein andres Codefragment gefunden habe... ich hab aber irgendwie ein Problem... anscheinend mit beiden Varianten. Und zwar scheint das beim Picking zu liegen. Der unendliche Strahl, den man ja dafür nehmen sollte, scheint beim mir aus dem Ursprung zu kommen und auf mich zuzulaufen?! Ich blick da irgendwas net...


```
Transform3D startPositionTransformation	= new Transform3D();
	Transform3D endPositionTransformation	= new Transform3D();
	Transform3D startTransformation	= new Transform3D();
	Transform3D endTransformation	= new Transform3D();
	startTransformation.setTranslation( new Vector3f( 0f, 0f, 1f));
	endTransformation.setTranslation( new Vector3f( 0f, 0f, -100f)); //zoom out
	targetTG.getTransform( startPositionTransformation);
	targetTG.getTransform( endPositionTransformation);
	startPositionTransformation.mul( startTransformation);
	endPositionTransformation.mul( endTransformation);

	Vector3d startPosition = new Vector3d();
	Vector3d endPosition = new Vector3d();
	startPositionTransformation.get( startPosition);
	endPositionTransformation.get( 	 endPosition);

	Point3d pForwardStart = new Point3d(startPosition.x, startPosition.y, startPosition.z);
	Point3d pForwardEnd   = new Point3d(endPosition.x, endPosition.y, endPosition.z);
		
	house.updateHUD( startPosition, endPosition);
	house.setDebugPosition( startPosition, endPosition);
	picking( pForwardStart, pForwardEnd);
		
	double hoeheUnten = getDistance( RootBG, pForwardStart);
	if(hoeheUnten != -1.0){
		System.out.println("Differenz nach unten: "+hoeheUnten + "("+pForwardStart+")");
    }
```


```
public double getDistance( BranchGroup bg, Point3d p){
	   
    final Vector3d DOWN = new Vector3d( 0.0, 0.0, -1.0);
    double py = -1.0;
    // Die Branchgruppe, die nur das Terrain enthält
    PickTool picktool = new PickTool( bg);
    // ein Strahl von der aktuellen Position nach unten
    picktool.setShapeRay( p, DOWN);
    // suche nach Bounds
    picktool.setMode( PickTool.BOUNDS);
    // nur die naheliegende Intersection ist wichtig
    PickResult pr = picktool.pickClosest();

    if( pr != null){
        // wenn es Bounds gibt, dann gibt es auch ein Objekt
        picktool.setMode( PickTool.GEOMETRY_INTERSECT_INFO);
        // diesmal haben wir die Geometrie
        pr = picktool.pickClosest();
        if( pr != null){
            // die Intersection mit dem Index “0”
            PickIntersection pi = pr.getIntersection( 0);
            // die Weltkoordinaten des Punktes
            Point3d intPt = pi.getPointCoordinatesVW();
            // nur die Y-Koordinate (die Höhe) ist wichtig
            py = intPt.z;
            // gib den Speicher frei
            pr = null;
            // gib den Wert zurück
            return py;
        }
    }
    // wenn es nichts unten gibt, dann gib –1.0 zurück
    return py;
}
	
public void picking( Point3d start, Point3d end){
    PickTool pick = new PickTool( RootBG);
    PickResult result;
//    pick.setShapeRay( start, forwardVector);
    pick.setShapeSegment(start, end);
    pick.setMode( PickTool.GEOMETRY);
    result = pick.pickClosest();
    if( result != null){
    	if( result.getClosestIntersection(start) != null){	
//    		System.out.println(  result.getClosestIntersection(start).getDistance());
    		GeometryArray ga = result.getClosestIntersection(start).getGeometryArray();
    		house.updateHUD(   result.getClosestIntersection(start).getDistance(), ga.getName());
    	}
    }
}
```
Also dein Code scheint mir immer den Abstand zur Achse zu bringen... ganz egal, ob da ein Objekt geschnitten wird, oder nicht. Der andre macht auch was Komisches... Geh ich nun aber hin, und sag, ich will kein unendlichen Ray, sondern geb Start- und Zielpunkt selbst an, funktioniert die Sache... auch und vor allem mit dem Schnittpunkt. Wobei beim deinem dann das interessante Phänomen auftritt, dass der Strahl hää... ich begreif's net... und wenn ich's zu erklären versuch, isses ja noch schlimmer. Also, Funktionsaufruf abgeändert in:

```
double hoeheUnten = getDistance( RootBG, pForwardStart, pForwardEnd);
```
Funktion nur die eine Zeile... (hier die letzte, Rest is gleich) (und ja, ich schau jetzt net nach unten, sondern nach vorne, auch wenn ich die Kommentare net geändert hab und so...)

```
public double getDistance( BranchGroup bg, Point3d p, Point3d p2){
	final Vector3d DOWN = new Vector3d( 0.0, 0.0, -1.0);
	double py = -1.0;
	// Die Branchgruppe, die nur das Terrain enthält
	PickTool picktool = new PickTool( bg);
	// ein Strahl von der aktuellen Position nach unten
	//picktool.setShapeRay( p, DOWN);
	picktool.setShapeSegment(p, p2);
```
Nun hab ich folgendes Verhalten beobachten können: Ich steh irgendwo, blicke auf die Hauswand und der Strahl scheint nun vom Ursprung auf mich zu zugehen, zeigt mir aber die Entfernung des Schnittpunktes des Strahles mit der Hauswand an, welche mir am nächsten ist und gibt dann die Entfernung vom Ursprung zum Schnittpunkt aus, statt der Entfernung des Schnittpunktes zu meiner Position. 

Was ich will (und ja mir dem andren Teil schon gemacht hab, aber auch gerne deines verwenden und verstehen könnte) ist ja folgendes: Ich stehe irgendwo, (15|10|50) und blicke auf einen Quader der auf (8|0|3) -> (20,5|7|17) steht (über die andren Punkte wird gespannt, denke, das is klar). Wenn ich also direkt auf (15|7|50) gehe, sollte ich, da ich zum Quader blicke, durch einen unendlichen Strahl nach -z doch einen Schnittpunkt bekommen, der bei 33m liegt. Schließlich sollte soviel Platz zwischen mir und der Wand sein, oder? Im Übrigen hab ich anscheinend heraus gefunden, dass die ViewingPlatform und die 'Kamera' noch mal 1m von einander entfernt sind. Deswegen musste ich die startTransformation auf (0|0|1) verschieben, sonst kommt 49 raus... 
Ha, OK, doch ein wenig schlauer geworden durch das Frage stellen...

```
return pi.getDistance(); //py;
```
liefert jetzt nicht mehr die Weltkoordinaten des Schnittpunktes sondern meine Entfernung zu ihm... dennoch.... ahh... Erleuchtung :idea:  ???:L Könnte es sein, dass dieser 
	
	
	
	





```
public static Vector3d forwardVector = new Vector3d(0.0, 0.0, -1.0);
```
 die Rotation nicht mitmacht? Deswegen gehts mit den Start- und Endpunkten, aber net mit dem unendlichen Strahl. Also die ViewingPlatform holen und die Blickrichtung in den Vektor einfließen lassen... 

OK, jetzt hab ich ganz viel geschrieben, dabei anscheinend doch sinnvoll nachgedacht, was man ja vor dem Posten machen sollte  und bin zu dem Schluss gekommen, dass der Fehler wohl bei mir und meinem Vektor liegt, der nicht in die gleiche Richtung schaut, wie ich. Ich lass das Post aber dennoch, vielleicht hat ja jemand mal irgendwann wieder so ein Art verwandtes Problem und freut sich, beim Lesen ne Idee zu bekommen. Nichts für ungut, wer das gelesen und sich schon Gedanken für ne ausführliche Antwort gemacht hat... (kann er ja bei der nächsten Frage dann geben )

ps: Code-Formatierung ist gar nicht so einfach, wie es aussieht. Vor allem, wenn man in Eclipse andere TAB-Weiten zum Einrücken eingestellt hat.


----------

