Zurück   Flashforum > Software > 3D

Antwort
 
LinkBack Themen-Optionen Ansicht
Alt 03-01-2009, 19:30   #1 (permalink)
Neuer User
 
Registriert seit: Nov 2006
Beiträge: 152
3rd person camera

Hi,

wie der Titel schon sagt, ich suche ein script für eine Verfolgerkamera.
Ich hab leider nicht den mathematischen background, um mir sowas zu basteln, such schon ewig im netz und find nix gscheids.

Es geht um eine Spielerei mit Papervision, wo ich ein Raumschiff steuere. Jetzt wärs geil, wenn ich dafür eine Verfolgerkamera hätte, die aber nicht nur stur hinterherfliegt, sondern dynamisch ist, also z.B. die Kurven etwas verzögert mitläuft.

Habt Ihr da irgendwas nützliches für mich? Links, Scripts, ...? Komm da grad nicht weiter.

danke schonmal, lg
grisu
grizu ist offline   Mit Zitat antworten
Alt 04-01-2009, 12:48   #2 (permalink)
Neuer User
 
Registriert seit: Nov 2006
Beiträge: 152
also soweit bin ich schonmal (jetzt auf eine achse mal reduziert):

PHP-Code:
var rotX:Number _model.shipModel.rotationX * (Math.PI 180);
            
_cam._model.shipModel.Math.cos (rotX) * 800;
_cam._model.shipModel.Math.sin (rotX) * 800
sollte ja eigtl. gehen, nur wechselt die camera bei rotation = 90 und -90 auf einmal die ansicht, dann seh ich alles um 180 grad verdreht...
Keiner der mir weiterhelfen kann?


edit:
bin jetzt draufgekommen, das der Fehler mit localRotation zusammenhängt.
Wenn ich mein Objekt über localrotation drehe, nimmt rotation (also die globale Drehung) Werte von 90 bis -90 an, zählt erst hinauf, dann wieder zurück, ganz strange.
Warum? Solang keine andere Achse rotiert wird, sollte das ja derselbe Wert sein oder nicht?

Geändert von grizu (04-01-2009 um 15:45 Uhr)
grizu ist offline   Mit Zitat antworten
Alt 21-01-2009, 09:44   #3 (permalink)
Neuer User
 
Registriert seit: Nov 2006
Beiträge: 152
so ich schreib mal weiter, vielleicht findet sich ja doch noch jemand, ich verstehs grad nicht...

Hab mich mit Vektoren und Matrizen beschäftigt, dann folgenden Ansatz gefunden (hat auch funktioniert):

Einen Normalvektor auf die x-Achse (rechts-links) und die y-Achse (oben-unten) bilden, und auf diesen Vektor dann die Kamera setzen. Hat eigentlich super funktioniert.

Jetzt will ich aber sowas wie eine "easing"-Kamera machen, die dem Ship sanft folgt. Und mir fällt nix ein, wie ich das mit Vektoren lösen könnte (Displacement-Vektor, dann easing drauf?).

Und jetzt versuch ich eben, das mit Kugelkoordinaten umzusetzen:

ActionScript:
  1. var phi : Number = (_ship.rotationX - 90) * Math.PI / 180;
  2. var theta : Number = (_ship.rotationY + 90) * Math.PI / 180;
  3.            
  4. var x1 : Number;
  5. var y1 : Number;
  6. var z1 : Number;
  7.            
  8. x1 = dist * Math.sin (phi) * Math.cos (theta);
  9. y1 = dist * Math.cos (phi);
  10. z1 = dist * Math.sin (phi) * Math.sin (theta);
  11.            
  12. _pvView.camera.copyTransform (_ship);
  13. //_pvView.camera.target = _ship;
  14.            
  15. _pvView.camera.x = x1;
  16. _pvView.camera.y = y1;
  17. _pvView.camera.z = z1;

nur funktioniert das überhaupt nicht. Ich versteh vor allem nicht, warum papervision mir so komische winkelwerte liefert. Also ich weiss jetzt nicht, liegts an meiner Formel, oder spinnt papervision, oder versteh ich da grad irgendwas grundlegendes nicht?

z.B.:
Mein Modell liegt Richtung positive z-Achse. Jetzt rotier ich um die lokale z-Achse -90°. Dann lokale x-Achse -90°. Jetzt liegt das Schiff Nase Richtung -x und müsste ja eine globale y-Rotation von -90° aufweisen. Tuts aber nicht. Ahhhh!

Pls, wenn jemand irgendwas dazu sagen kann, bitte! Verzweifel echt grad
grizu ist offline   Mit Zitat antworten
Alt 22-01-2009, 08:50   #4 (permalink)
Neuer User
 
Registriert seit: Nov 2005
Beiträge: 548
Vielleicht kann ich da ein wenig helfen...
Mein Tip: lass die Euler-Winkel ganz weg, das gibt nur Probleme (Gimbal Lock z.B.). Es gäbe noch die Möglichkeit mit Quaternions, aber es geht auch "einfacher" (wer in Mathe nicht tiefer einsteigen will als bis zu Matrizen/Vektoren mein ich jetzt).

Der Ansatz mit den Vektoren und Matrizen war schon ganz gut. Hast du auch schon was von lokalen Koordinatensystemen (Matrizen) gelesen? Vektor-Matrix-Multiplikation? Inverse Matrix? Das brauchst du auch. Papervision hat die Funktionen aber schon implementiert.

Jedes Modell, auch die Kamera, hat eine Matrix, die man auslesen kann und die die aktuelle Position und Ausrichtung (Achsen als Vektoren) enthält.

Algorithmus für weiche Verfolgung:
- Modell in Kamera-Space transformieren: multipliziere den Positionsvektor des Modells (bzw. irgendeine Zielposition, egal iob bewegt oder nicht) mit der inversen Matrix der Kamera, Ergebnis ist ein Vektor, der die Position des Ziels aus Sicht der Kamera angibt.
- diesen Vektor normalisieren. Ergebnis: die Lage und Position der beiden Objekte ist völlig egal; wenn die Kamera direkt auf das Ziel schaut, nähert sich der Vektor dem Wert (0,0,1). Wenn das Objekt aus Sicht der Kamera irgendwo rechts ist, wird der X-Wert des Vektors positiv sein usw. Also:
- wenn von diesem Vektor z<0 (Ziel ist hinter der Kamera), bitte wenden (Yaw oder Pitch geben, solange bis z>0)
- wenn z>0: yaw(x), pitch(y). X und Y sind wegen der Normalisierung zwischen -1 und 1. Pro Frame wird also nur ein sehr kleiner Wert gedreht, daher ist die Reihenfolge egal.
- das kann man noch "weichzeichnen", also eine Art Beschleunigung simulieren, z.B. actualYaw=actualYaw*0.9+x*0.1
- wenn (z.B.) z>0.9 und der Abstand>Mindestabstand: Gas geben (Objekt ist ziemlich direkt vor der Kamera).
- wenn z>0 und Abstand<Mindestabstand: rückwärts bewegen (Objekt ist irgendwo vor der Kamera).
- wenn z<0 und Abstand<Mindestabstand: vorwärts bewegen (Objekt ist irgendwo hinter der Kamera).
(die Abstandsregelung kann man natürlich auch direkter einbauen, indem man die Positionen der Objekte voneinander abzieht und direkt entlang dieses Vektors bewegt - hier nur das Beispiel, wenn die Kamera ausschließlich in Sichtrichtung fliegen kann)

Hier ein Beispiel wie ich das mal so ähnlich ausprobiert habe (leider kein Papervision, sonst würde ich mal den Code posten):
http://www.dfactor.de/cobra/dogfight/dogfight1.swf
Die Kamera ist hier sogar nur auf roll und pitch beschränkt. Derselbe Algo steuert übrigens auch die "Intelligenz" der beiden sich verfolgenden Modelle.
joeydee ist offline   Mit Zitat antworten
Alt 23-01-2009, 10:47   #5 (permalink)
Neuer User
 
Registriert seit: Nov 2006
Beiträge: 152
Zitat:
Zitat von joeydee Beitrag anzeigen
Vielleicht kann ich da ein wenig helfen...
Mein Tip: lass die Euler-Winkel ganz weg, das gibt nur Probleme (Gimbal Lock z.B.). Es gäbe noch die Möglichkeit mit Quaternions, aber es geht auch "einfacher" (wer in Mathe nicht tiefer einsteigen will als bis zu Matrizen/Vektoren mein ich jetzt).

Der Ansatz mit den Vektoren und Matrizen war schon ganz gut. Hast du auch schon was von lokalen Koordinatensystemen (Matrizen) gelesen? Vektor-Matrix-Multiplikation? Inverse Matrix? Das brauchst du auch. Papervision hat die Funktionen aber schon implementiert.

Jedes Modell, auch die Kamera, hat eine Matrix, die man auslesen kann und die die aktuelle Position und Ausrichtung (Achsen als Vektoren) enthält.
so hab ich das mit der Vektorenlösung gemacht:

new Number3D (_object.transform.n14, ...)

Zitat:
Algorithmus für weiche Verfolgung:
- Modell in Kamera-Space transformieren: multipliziere den Positionsvektor des Modells (bzw. irgendeine Zielposition, egal iob bewegt oder nicht) mit der inversen Matrix der Kamera, Ergebnis ist ein Vektor, der die Position des Ziels aus Sicht der Kamera angibt.
reicht da nicht eine Subtraktion? also Modellvektor - Kameravektor?

Zitat:
- diesen Vektor normalisieren. Ergebnis: die Lage und Position der beiden Objekte ist völlig egal; wenn die Kamera direkt auf das Ziel schaut, nähert sich der Vektor dem Wert (0,0,1). Wenn das Objekt aus Sicht der Kamera irgendwo rechts ist, wird der X-Wert des Vektors positiv sein usw. Also:
- wenn von diesem Vektor z<0 (Ziel ist hinter der Kamera), bitte wenden (Yaw oder Pitch geben, solange bis z>0)
- wenn z>0: yaw(x), pitch(y). X und Y sind wegen der Normalisierung zwischen -1 und 1. Pro Frame wird also nur ein sehr kleiner Wert gedreht, daher ist die Reihenfolge egal.
- das kann man noch "weichzeichnen", also eine Art Beschleunigung simulieren, z.B. actualYaw=actualYaw*0.9+x*0.1
- wenn (z.B.) z>0.9 und der Abstand>Mindestabstand: Gas geben (Objekt ist ziemlich direkt vor der Kamera).
- wenn z>0 und Abstand<Mindestabstand: rückwärts bewegen (Objekt ist irgendwo vor der Kamera).
- wenn z<0 und Abstand<Mindestabstand: vorwärts bewegen (Objekt ist irgendwo hinter der Kamera).
(die Abstandsregelung kann man natürlich auch direkter einbauen, indem man die Positionen der Objekte voneinander abzieht und direkt entlang dieses Vektors bewegt - hier nur das Beispiel, wenn die Kamera ausschließlich in Sichtrichtung fliegen kann)

Hier ein Beispiel wie ich das mal so ähnlich ausprobiert habe (leider kein Papervision, sonst würde ich mal den Code posten):
http://www.dfactor.de/cobra/dogfight/dogfight1.swf
Die Kamera ist hier sogar nur auf roll und pitch beschränkt. Derselbe Algo steuert übrigens auch die "Intelligenz" der beiden sich verfolgenden Modelle.
Ich werd das mal ausprobieren, danke. Hab nur grad im moment viel anderes zu tun, werd aber hier weiter berichten

Hab inzwischen das gefunden, da kann man sich auch einiges abschauen:
http://agit8.turbulent.ca/bwp/2009/0...d-papervision/

Danke!

lg
grisu
grizu ist offline   Mit Zitat antworten
Alt 23-01-2009, 18:33   #6 (permalink)
Neuer User
 
Registriert seit: Nov 2005
Beiträge: 548
Zitat:
Zitat von grizu Beitrag anzeigen
reicht da nicht eine Subtraktion? also Modellvektor - Kameravektor?
Nein, da passiert was anderes. Stell dir vor, die Kamera (bei 0,0,0) schaut in Richtung X statt Z, wurde also irgendwann mal um 90 Grad nach rechts gedreht. Das Ziel befindet sich bei (0,0,100). Die Positionsdifferenz ergibt (0,0,100), also das Ziel 100 Einheiten in Richtung Z. Egal wohin die Kamera schaut, das Ergebnis wird immer dasselbe sein und sagt uns nicht, wie wir die Kamera drehen müssen damit das Ziel in Sicht kommt.
Die Multiplikation mit der Inversen ergibt stattdessen (-100,0,0), also die Info, dass sich das Ziel 100 Einheiten exakt links von der Kamera befindet.
Das war nur ein einfaches Beispiel, das mit der Inversen funktioniert immer, egal wie wild die Kamera "verdreht" ist. Das benutze ich übrigens auch, um ein 3D-Radar der Umgebung zu zeichnen: Der Vektor (skaliert natürlich) gibt exakt die Position im Radar an.

Die "Springcam" sieht auch gut aus, interessanter Link, kann ich auch gebrauchen, dankeschön :-)

Ich hab meinen Code inzwischen mal in PV portiert:

Code:
   import org.papervision3d.objects.DisplayObject3D; 
   import org.papervision3d.core.math.Matrix3D; 
   import org.papervision3d.core.math.Number3D; 


//obj1 folgt obj2 in bestimmter Distanz. 
//Es kann auch ein camera-Objekt übergeben werden. 
//Beispiel für Verfolgerkamera (per-Frame-Aufruf): follow(camera,mymodel,50); -> camera folgt mymodel in einer Distanz von 50 Einheiten. 
      public function follow(obj1:DisplayObject3D,obj2:DisplayObject3D,optDistance:Number){ 
          
         //Informationen aus den beiden Objektmatrizen gewinnen 
         var viewMatrix:Matrix3D=obj1.transform; //Matrix des Verfolgers 
         var viewInverse:Matrix3D=Matrix3D.inverse(viewMatrix); //Inverse berechnen 
         var targetVector:Number3D=new Number3D(obj2.transform.n14,obj2.transform.n24,obj2.transform.n34); //Position des Ziels 
         Matrix3D.multiplyVector4x4(viewInverse,targetVector); //Zielvektor aus Sicht des Verfolgers 
         var actDistance:Number=targetVector.modulo;//Distanz berechnen 
         targetVector.normalize();//Vektor normalisieren 

         //A.I.-Routine 
         var toMove:Number=(actDistance-optDistance)/100; //Abweichung von der Wunschdistanz 
         if(toMove>1)toMove=1; //max. Vorwärtsbewegung 
         if(toMove<-1)toMove=-1; //max. Rückwärtsbewegung 
          
         //Ziel ist vor dem Verfolger 
         if(targetVector.z>0){ 
            obj1.yaw(targetVector.x); //horizontal drehen in Richtung Ziel 
            obj1.pitch(-targetVector.y); //vertikal drehen in Richtung Ziel 
            obj1.moveForward(toMove*Math.pow(targetVector.z,100)); //je mittiger das Ziel, desto schneller bewegen 
            } 
             
         //Ziel ist hinter dem Verfolger 
         else{ 
            //Wende einleiten, kürzeste Drehrichtung beachten 
            if(targetVector.x<0){ 
               obj1.yaw(-1); 
               } 
            else{ 
               obj1.yaw(1); 
               } 
            } 
         }
joeydee ist offline   Mit Zitat antworten
Antwort

Lesezeichen

Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind an
Pingbacks sind an
Refbacks sind an



Alle Zeitangaben in WEZ +1. Es ist jetzt 10:49 Uhr.

Domains, Webhosting & Vserver von Host Europe
Unterstützt das Flashforum!
Adobe User Group


Copyright ©1999 – 2012 Marc Thiele