| |||||||
Du magst keine Werbung? Wir auch nicht!
Einfach registrieren und die Werbung ist weg. Diese Nachricht sehen nur nicht registrierte Nutzer.
![]() |
| | LinkBack | Themen-Optionen | Ansicht |
| | #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 |
| | |
| | #2 (permalink) |
| Neuer User Registriert seit: Nov 2006
Beiträge: 152
|
also soweit bin ich schonmal (jetzt auf eine achse mal reduziert): PHP-Code: 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) |
| | |
| | #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:
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 |
| | |
| | #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. |
| | |
| | #5 (permalink) | |||
| Neuer User Registriert seit: Nov 2006
Beiträge: 152
| Zitat:
new Number3D (_object.transform.n14, ...) Zitat:
Zitat:
![]() Hab inzwischen das gefunden, da kann man sich auch einiges abschauen: http://agit8.turbulent.ca/bwp/2009/0...d-papervision/ Danke! lg grisu | |||
| | |
| | #6 (permalink) |
| Neuer User Registriert seit: Nov 2005
Beiträge: 548
| 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);
}
}
} |
| | |
![]() |
| Lesezeichen |
| Themen-Optionen | |
| Ansicht | |
| |