Quaternion + Drehung um gekippte verschobene Achse zu Target?



  • Da ich mit Euler-Winkeln nicht wirklich weiter komme und so oder so auf quaternions umsteigen werden muss wollte ich hier schomal anfragen ob jemand für mein aktuelles Problem evtl. einen Link hat der sich mit der gleichen Thematiik beschäftigt, ich lese zwar gerade die Bücher "Mathematics for 3D Game Programming and Computer Graphics, Second Edition" und "Visualizing Quaternions" aber mir fehlen Praxisbezogene Beispiele, ich bin leider nicht wirklich der Theorethiker.

    Zum Problem:
    Ich hab:
    * ein 3Dimensionesales Koordinatensystem.
    * darin eine (willkürlich) gekippte Achse die von eigentlichen 0.0.0 Punkt verschoben ist.
    - Von dieser Achse ist mir ein Punkt bekannt durch den Sie verläuft und des weiteren 2 Vektoren so das ich ein Cross-Produkt bilden und somit den Verlauf der Achse in Form eines Vektors berechnen könnte.
    * einen Zielpunkt welcher zusammen mit dem mir bekannten Ausgangspunkt durch den die Achse verläuft, einen Vektor (bezogen auf das nicht gekippte "Globale" Koordinatensystem) in Richtung Ziel ergibt.

    Was ich nun bräuchte sind die beiden Drehungen(Rotationswinkel) um die X-Achse und die Y-Achse welche von der gekippten und verschobenen Achse ausgehen um den Start -> Ziel Vektor zu erfüllen.

    Der übliche Upvektor des Koordinatensystems ist die Y-Achse.

    Für eine nicht gekippte aber verschobene Achse als Ausgangspunkt mit dem selben Upvektor wie das Ziel besitzt(also parallelen Achsen von Start & Ziel) habe ich mittels Euler bereits eine Funktionierende Lösung welche auch eine Drehung / Rotation Korrekt berechnen, sobald ich die Achse jedoch Kippe erhalte ich fehlerhafte Ergebnisse.

    Wi bereits erwähnt bin ich nicht wirklich ein Theoretiker von daher wären Codebeispiele sehr schön.

    Danke im voraus.



  • schnapp dir einfach eine Mathe-Bibliothek wie http://cmldev.net/?p=42 und berechne damit ein dir bekanntes Szenario durch



  • Quaternionen können nur Rotationen darstellen, keine Translationen. Verschobene Achse mit Quaternion allein is also nicht drin 😉

    Was genau willst du denn erreichen!? Es ist nämlich nicht so dass Eulerwinkel irgendwas mit Matritzen zu tun hätten. Nur weil du also keine Eulerwinkel verwenden willst (wer will das schon) bedeutet das noch lange nicht (absolut und überhaupt garnicht) dass du nicht mit Matritzen arbeiten kannst...



  • BTW:

    float head = cml::rad(160.0f);
    float pitch =  cml::rad(100.0f);
    float roll =  cml::rad(120.0f);
    
    // aus Euler Winkel bauen wir uns eine schöne Quaternion
    cml::quaternion_rotation_euler(q, pitch, head, roll, cml::euler_order_xyz);
    
    float norm = q.norm();
    
    std::cout<<"norm = "<<norm<<std::endl;
    
    cml::quaternionf p(0.0f,10.0f,2.0f,3.0f);
    
    cml::quaternionf v = q * p * cml::conjugate(q);
    
    std::cout<<"w = "<<v[0]<<std::endl;
    std::cout<<"x = "<<v[1]<<std::endl;
    std::cout<<"y = "<<v[2]<<std::endl;
    std::cout<<"z = "<<v[3]<<std::endl;
    
    float head2, pitch2, roll2;
    
    // aus der Quaternion holen wir jetzt wieder die Euler Winkel
    cml::quaternion_to_euler(q, pitch2, head2, roll2, cml::euler_order_xyz);
    
    std::cout<<"head = "<<cml::deg(head2)<<std::endl;
    std::cout<<"pitch = "<<cml::deg(pitch2)<<std::endl;
    std::cout<<"roll = "<<cml::deg(roll2)<<std::endl;
    


  • @Vertexwahn
    danke für des source und den hinweis auf cml, scheint eine sehr umfangreiche Mathe lib zu sein, ich werde mal versuchen das ganze anzupassen, die Umwandlung in einen Quaternion war ja nicht das Problem eher die gekippte Achse, bei deinem Quelltext geht es wohl eher um das umgehen eines Gimbal Locks, ich werde trotzdem schauen ob ich CML zur Anwendung benutzen kann.

    @dot
    Ich "bastle" gerade(eigentlich schon etwas länger, ich hatte nur aus privaten Gründen eine Pause eigelegt), an einem 3D Spiel herum.

    Um den Aufbau kurz zu beschreiben:

    Das Zentrum des Raumschiffes des Spielers, ist im Koordinatensystem auf 0.0f, 0.0f, 0.0f gelegt und verlässt diese Koordinaten auch nicht.
    Das Raumschiff kann um die X-Achse sowie auch um die Y-Achse (normaler Up-Vektor des Koordinatensystems) gedreht/rotiert werden, ein Roll (Rotation um die Z-Achse wird ggf. später eingebaut spielt im bezig auf das Raumschiff aktuell keine Rolle).
    Die Kammerasteuerung entspricht der aus bekannten 3D Editoren wie Maya, Blender, 3DMax oder halt einem First Person Shooter.

    An dem Raumschiff sind mehrere Waffen "montiert", welche aus zwei Meshe´s bestehen. einem drehbaren "Turm" und einem neigbaren "Abschussrohr".

    Dabei kann man sich den Parent->Child aufbau so vorstellen

    World -> Raumschiff -> Waffenturm -> Abschussrohr.

    Um das Problem zu verdeutlichen kann hier:

    http://www.bilder-hochladen.net/files/big/43qm-5x.png

    ein Bild angesehen werden, Links und Obenrechts ist das Feuernde Raumschiff gedreht und gekippt, Untenrechts hingegen befindet es sich auf einer 0° Rotation und die waffen zielen auch in die richtige Richtung, bei der gekippten Variante ist dies nicht der Fall.

    Da sich die Waffe versetzt von den Koordinaten 0.0f, 0.0f, 0.0f befindet kommt eine verschobene Achse zustande, wenn der Up-Vektor sich nicht ändert, also nur eine Rotation um die Y-Achse stattfindet macht das absolut nichts aus, die Winkel werden korrekt berchnet und auch die Eigenrotation des Raumschiffes, welche in die Formeln mit einfliesst , wird korrekt berechnet.

    Das Problem beginnt in dem Moment in dem das Raumschiff, damit die Waffe und somit auch der Up-Vektor durch eine Rotation der X-Achse gekippt wird.

    Ich habe mich extra in das Thema Matrizen eingelesen (bin schon etwas älter und es ist schon ne Weile her) mir oben besagte 2 Bücher besorgt und mir mehrere Stunden Videos Mathevorlesungen( http://www.j3l7h.de/videos.html 05 01 - 07 02 von Playlist: Mathe 2 Teil 1, Sommer 2009) angetan (die sind im übrigen recht leicht verständlich und kann man empfehlen).

    Nur näher bin ich der Lösung des Problems nicht auch wenn ich nun einiges mehr weiss als zuvor.
    Ich hoffe mal das ich mit CML evtl. etwas reissen kann, falls Dir aber spontan noch etwas dazu einfällt, nur aus damit.

    btw. ich habe Aktuell beim "flugverhalten" des Raumschiffes eh das Gimbal Lock Problem und zudem werden alle anderen Objekte später wenn beschleunigungen zum ganzen hinzu kommen um die Koordinate 0.0f, 0.0f, 0.0f gedreht.
    Dabei hätte ich dann wieder zwei Möglichkeiten und Quaternions scheien da die bessere Wahl zu sein.



  • BTW: cml ist keine umfangreiche Mathe lib - für C++ gibt es Mathe libs wie Sand am mehr - die meisten sind wesentlich umfangreicher



  • Vertexwahn schrieb:

    BTW: cml ist keine umfangreiche Mathe lib - für C++ gibt es Mathe libs wie Sand am mehr - die meisten sind wesentlich umfangreicher

    Das glaub ich dir sogar, ich habe bisher halt den Fehler bei mir gesucht, da ich zugegebnermassen nicht viel mit Matrizen am Hut hatte.

    Dadurch habe ich die vorhandenen Klassen und Funktionen der 3D Engine (Irrlicht) als hauptsächliche Werkzeuge benutzt und mit meinem Wissen über Eulersche Winkel rumhantiert, was auch solange gut geht bis die Ursprüngliche Y-Achse durch eine Drehung der X-Achse gekippt wird, dadurch stimmt dann auch die Drehung des Waffenturmes nicht mehr mit den errechneten Werten überein da diese sich auf Parallel zum Kordinatensystem verlaufende Achsen beziehen und wenn ich den Waffenturm nun um die Lokale (gekippte) Achse drehe ist auch der Richtungsvector mit gekippt, zudem kommt als zweites problem die einberechnung des Neigungswinkels des Abschussrohres hinzu welche bei 90° zum Tiel keine Rolle und bei 0° zum Ziel voll mit eingerechnet werden muss eine Rolle..

    Durch diese Fehler und das Auftreten von Gimbal Locks habe ich beschlossen gehabt mich in die Materie weiter hinein zu lesen und ggf. frei zur verfügung stehende Mathe Libs vernachlässigt aber mir war es halt wichtig die Ursache des Fehlers zu verstehen.

    Nur komme ich ehrlich gesagt mit dem Wissen nun auch nicht wirklich weiter denn alle ähnlichen Probleme die Irgendwo beschrieben sind beziehen sich grundsäzlich auf Parallel zum Koordinatensystem verlaufende Achsen, nicht auf gekippte.



  • Naja, wenn ich dich richtig verstehe hast du also einen funktionierenden Weg um deine Turrets auf Punkte relativ zum Schiffsystem auszurichten. Dein Problem ist dass, wenn das Schiffsystem gekippt ist, Weltkoordinaten nichtmehr in diesem System liegen. Aber das lässt sich ganz einfach lösen: Transformier deinen Zielpunkt mit der inversen Schiffstransformation. Das gibt dir den Punkt in Schiffskoordinaten und auf den kannst du deine Turrets ausrichten...



  • dot schrieb:

    Transformier deinen Zielpunkt mit der inversen Schiffstransformation. Das gibt dir den Punkt in Schiffskoordinaten und auf den kannst du deine Turrets ausrichten...

    hmm jain so einfach ist das nicht ganz.

    Zum einen drehen sich die Turrets (die Türme) ja entlang der Lokalen Z-Achse um die "Lokae" Y-Achse des Schiffes womit im Falle eines "Gekippten Schiffes" und einem 105° Winkel zum Ziel (Annähernd einer "Breitseite" entsprechend) es nicht mehr die 105° sind um die Ich den Turm dann auch Drehe.
    Durch den "Kippwinkel" (Rotation um die "Lokale" X-Achse) und die Tatsache das sich die Waffen am Bug und Heck des Schiffes befinden müsste sich der Vektor mitdrehen.
    Dies habe ich miteinberechnet und muss dies nochmal überprüfen evtl. besteht da ein Fehler bezüglich einberechnung der Anteile des Globalen Kippwinkels, ansonsten wird natürlich auf die Y-Drehung des Schiffes mit eingerechnet.

    In dem selben Beispiel den NeigungsWinkel der Abschussrohre Anzupassen ist wiederum ein anderes Problem, hier muss gar keine Anpassung stattfinden, im Falle eines 0° Winkels also Z-Achse des Schiffes auf 0 oder 180° muss diese zu 100% miteingerechnet werden.

    Sieh es mal so, wenn du das Schiff Kippst auf meinetwegen 45° auf der X-Achse müsste der Vektor zum Ziel um eben den selben Winkel gedreht werden, Drehst du nun das Schiff noch um die Y-Achse auf 0° Richtung Ziel entfällt dieser Ausgleich, da ein Kippwinkel über die "Globale" X-Achse nicht mehr gegeben ist, dafür muss hier ein Voller Ausgleich des Kippwinkels des Neigungswinkels Stattfinden der bei 90° nicht benütigt wird, de eine Neigung des Schiffes um die X-Achse hier beispielsweise uninteressant ist wenn das Schiff und das Ziel parallel dazu liegt.

    🙂

    Wenn es so einfach wäre hätte ich die Lösung bereits eine Weile glaube ich 🙂



  • Ich glaub du denkst viel zu kompliziert. Am einfachsten geht man das mit einer Hierarchie von Transformationen an. Du hast eine Transformation die dein Turret relativ zum Schiff platziert. Und dann hast du die Transformation die dein Schiff relativ zur Welt platziert. Die absolute Transformation vom Turret ergibt sich dann indem du die Turret- und Schiffstransformation konkatenierst. Dein Turret richtest du relativ zum Schiff aus. Damit du das kannst brauchst du eben die Koordinaten deines Ziels im Koordinatensystem des Schiffes. Die bekommst du einfach indem du eben das Ziel in Weltkoordinaten mit der inversen Schiffstransformation transformierst. Damit hast du die Ausrichtung des Schiffes relativ zur Welt automatisch berücksichtigt. Jetzt musst du nur noch die Turrets relativ zum Schiff auf diesen transformierten Punkt ausrichten und bekommst damit deine Turret Transformation. Und über die Hierarchie (Welt <- Schiff <- Turret) bekommst du schlussendlich die Transformation die dein Turret in Weltkoordinaten übersetzt.



  • dot schrieb:

    ...Die absolute Transformation vom Turret ergibt sich dann indem du die Turret- und Schiffstransformation konkatenierst.Dein Turret richtest du relativ zum Schiff aus. Damit du das kannst brauchst du eben die Koordinaten deines Ziels im Koordinatensystem des Schiffes. Die bekommst du einfach indem du eben das Ziel in Weltkoordinaten mit der inversen Schiffstransformation transformierst. Damit hast du die Ausrichtung des Schiffes relativ zur Welt automatisch berücksichtigt.

    siehe zweiter Beitrag von mir

    WeakPeak schrieb:

    ...Das Zentrum des Raumschiffes des Spielers, ist im Koordinatensystem auf 0.0f, 0.0f, 0.0f gelegt...also nur eine Rotation um die Y-Achse stattfindet macht das absolut nichts aus, die Winkel werden korrekt berchnet und auch die Eigenrotation des Raumschiffes, welche in die Formeln mit einfliesst , wird korrekt berechnet...

    dot schrieb:

    Jetzt musst du nur noch die Turrets relativ zum Schiff auf diesen transformierten Punkt ausrichten und bekommst damit deine Turret Transformation. Und über die Hierarchie (Welt <- Schiff <- Turret) bekommst du schlussendlich die Transformation die dein Turret in Weltkoordinaten übersetzt.

    einfach:

    f32 turmrotationY = getFixedAngle(thisY - 90 - rotationsDifferenz.Y);
    //getFixedAngle() = Funktion um Rotationswerte auf Werte Zwischen 0° und 359,999...° zu Runden (mittels fmodf)
    //thisY = Y-Drehung des Schiffes um die Koordinate 0.0,0.0,0.0
    //-90 = Die Waffen sind damit Sie in, wenn sie nicht schiessen in Flugrichtung zeigen um 90° gedreht, diese pre-definierte Rotation der Waffen wird hier "Neutralisiert"
    //RotationsDifferenz = ein Vector3D<f32> welcher die zuvor errechneten "Horizonthalwinkel" (einen Normalisierten Vektor in Richtung des Zielpunktes welcher aus der (Zielskoordinate - Absoluter Position der Waffen) errechnet wird, das .Y wählt dann hier nur die Y-Rotation aus. auch diese Rechnung habe ich mittels atan funktion der math.h nachgerechnet und ja ich habe das PI/180 zur umrechnung zwischen RAD und DEG nicht vergessen.
    

    etwas Komplizierter:

    core::vector3df thisVector = emptyY->getAbsolutePosition();//!das wäre der spatiale up vector(ein normalisierter Vektor in die Richtung der Achse um die die Waffe gedreht wird)
        thisVectorsROTX = thisVector.getSphericalCoordinateAngles().X;
        thisVectorsROTZ = thisVector.getSphericalCoordinateAngles().Z;//!hier stimmt noch etwas ganz und gar nicht
        core::vector3df toTargetROT = toTarget;
        toTargetROT.rotateXYBy(thisVectorsROTX , core::vector3df (weaponAbsPos.X, weaponAbsPos.Y + 0.75f , weaponAbsPos.Z));
        toTargetROT.rotateYZBy(thisVectorsROTZ , core::vector3df (weaponAbsPos.X, weaponAbsPos.Y + 0.75f , weaponAbsPos.Z));
        core::vector3df rotationsDifferenzFINAL = toTargetROT.getHorizontalAngle();
    

    hierdurch wird der Waffe->Ziel Vektor um die Waffe als Ursprung gedreht, ohne diese Anpassung sieht man ab ca. 20° Kippwinkel(Rotation um die X-Achse bei gleichzeitigem ca 90° Winkel zwischen Schiff und Ziel) mit blossem Auge das die Rotation des Turmes nicht stimmt da die Horizonthalen Winkel für den Nicht gekippten Vektor bzw. die Welt-Achsen berechnet wurden.

    für die eingebauten Funktionen bitte ich die definitionen :
    [url][/url]
    http://irrlicht.sourceforge.net/docu/classirr_1_1core_1_1vector3d.html

    hier zu entnehmen damit ich nicht nicht jede einzelne Funktion erklären muss.
    rotatationDifferenzFINAL, also mit gekipptem Vector wird dann im obern Code anstelle von rotationsDifferenz (ohne vectorrotation um den Waffenpunkt als Center) eingetragen, diese Anpassung habe ich kürzlich erst hinzugefügt aber sie ist nicht ganz korrekt da sich bei der Berechnung von thisVectorsROTX/Z ein Fehler eingeschlichen hat, es werden lokale Winkel des Objectes welche sich mit eines Y-Rotation gegenüber den Globalen ändern benutzt, dies wird noch korrigiert.

    Von einfach bis Kompliziert habe ich alles durch was in irgendeiner Formelsammlung hierzu steht 🙂



  • Ich würde dir generell erstmal empfehlen dich von diesem Denken in Eulerwinkeln zu lösen, Winkel sind meiner Erfahrung nach wenn dann überhaupt nur sehr bedingt hilfreich, vor allem in 3D. Für mich hab ich jedenfalls festgestellt dass man sobald irgendwelche Winkel ins Spiel kommen meistens am komplett falschen Weg gelandet ist da man damit, wenn überhaupt, meistens zu einer unnötig komplexen und suboptimalen Lösung kommt. Ich sprach absichtlich von Transformationen und nicht von Rotationen. Angenommen du arbeitest mit Matritzen und Zeilenvektoren (wegen der Multiplikationsreihenfolge) so würde ich ganz naiv erstmal folgendes versuchen:

    1. Zielposition (TargetPosition) ins lokale Koordinatensystem deines Schiffes Transformieren (ShipTransform ist die Worldmatrix deines Schiffes): RelativeTargetPosition = TargetPosition * ShipTransform^(-1)
    2. Turret im Schiffskoordinatensystem auf RelativeTargetPosition ausrichten (hier kann man evtl. mit Winkeln rummachen) -> TurretTransform
    3. Fertig, TurretTransform * ShipTransform ist die finale WorldMatrix für dein Turret

    Wenn du z.B. nur eine Matrix berechnen willst die ein Objekt irgendwie ausrichtet brauchst du nix mit Winkeln anfangen. Wenn du beispielsweise eine Achse kennst (z.B. die lokale z-Achse) und einen zweiten Vektor der in einer Ebene mit dieser Achse liegt (z.B. Up Vektor) kannst du über zwei Kreuzprodukte einfach die beiden anderen Achsen ausrechnen. Jetzt nur noch die drei Achsenvektoren in die Zeilen einer Matrix packen und fertig. Unkompliziert und ganz ohne irgendwelche obskuren Winkelberechnungen 😉

    Wenn deine Turrets noch relativ zum Schiff irgendwie "schräg" platziert sind kannst du auch einfach den kompletten Weg gehen (TurretLocal ist die Transformation von Turret nach Schiff, definiert also wie auf dem Schiff dein Turret platziert ist):

    1. Zielposition relativ zum Turret berechnen: RelativeTargetPosition = TargetPosition * ShipTransform^(-1) * TurretLocal^(-1)
    2. Turret lokal auf RelativeTargetPosition ausrichten -> TurretTransform
    3. Fertig, TurretTransform * TurretLocal * ShipTransform ist die finale WorldMatrix für dein Turret

    Wie dir auffällt rechne ich da oben ausschließlich direkt mit Matritzen, irgendwelche Winkel kommen nirgendwo vor. Ein Turret dient nicht umsonst oft als das Paradebeispiel für eine Transformationshierarchie schlechthin 😉



  • Ok ich baue jetzt erst nochmal alles auf Matrixtransformationen um dann melde ich mich wieder, Danke schonmal.



  • Dumme Frage:

    Über den Aufbau hatten wir ja bereits gesprochen.
    Die Waffen sind ja an diversen Stellen des Schiffes plaziert, manche haben durch die die Predifinierte Drehung / Rotation / Transformation einen Winkelrichtung CCW also entgegengesetzt zu der des Schiffes...

    Schiff 10° im Uhrzeigersinn = Waffe -10° im Uhrzeigersinn
    was bei allen Waffen "Abschussrohren" zum Beispiel zutrifft.

    Ich habs umgebaut sieht gerade so aus:

    //--- rotate node relative to its current rotation -used in turn,pitch,roll ---
    void shipObject::rotate(irr::scene::ISceneNode *node, irr::core::vector3df rot)
    {
        irr::core::matrix4 m;
        m.setRotationDegrees(node->getRotation());
        irr::core::matrix4 n;
        n.setRotationDegrees(rot);
        m *= n;
        node->setRotation( m.getRotationDegrees() );
        node->updateAbsolutePosition();
    }
    
    //--- turn ship or any node left or right ---
    void shipObject::turn(irr::scene::ISceneNode *node, irr::f32 rot)
    {
        rotate(node, irr::core::vector3df(0.0f, rot, 0.0f) );
    }
    
    //--- pitch ship or any node up or down ---
    void shipObject::pitch(irr::scene::ISceneNode *node, irr::f32 rot)
    {
        rotate(node, irr::core::vector3df(rot, 0.0f, 0.0f) );
    }
    
    //--- roll ship or any node left or right ---
    void shipObject::roll(irr::scene::ISceneNode *node, irr::f32 rot)
    {
        rotate(node, irr::core::vector3df(0.0f, 0.0f, rot) );
    }
    
    //!! Zielen
    //--- aim the target ---
    void shipObject::aim(irr::scene::ISceneNode *nodeTarget, irr::scene::ISceneNode *nodeTurret, irr::scene::ISceneNode *nodeWeapon)
    {
        // --- get absolute and relative transformation matices for all nodes ---
        irr::core::matrix4 sh = this->getAbsoluteTransformation ();
        irr::core::matrix4 tu = nodeTurret->getRelativeTransformation ();
        irr::core::matrix4 we = nodeWeapon->getRelativeTransformation ();
        irr::core::matrix4 ta = nodeTarget->getAbsoluteTransformation ();
        //-- get inverse matrices --
        irr::core::matrix4 sh_i;
        sh.getInverse(sh_i);
        irr::core::matrix4 tu_i;
        sh.getInverse(tu_i);
        irr::core::matrix4 we_i;
        sh.getInverse(we_i);
        //-- get relative turret  + weapon to target matrices --
        irr::core::matrix4 relativeTargetMatrixTur = ta * sh_i * tu_i;
        irr::core::matrix4 relativeTargetMatrixWea = relativeTargetMatrixTur * we_i;
        irr::core::vector3df relRotTurTar = relativeTargetMatrixTur.getRotationDegrees();
        irr::core::vector3df relRotWeaTar = relativeTargetMatrixWea.getRotationDegrees();
        turn(nodeTurret, relRotTurTar.Y);
        pitch(nodeWeapon, relRotWeaTar.X);
    }
    
    //--- reset weapon position ---
    void shipObject::resetWeaponPosition(irr::scene::ISceneNode *nodeWeapon)
    {
        irr::core::matrix4 w;
        w.setRotationDegrees(irr::core::vector3df(0.0f, 0.0f, 0.0f));
        nodeWeapon->setRotation( w.getRotationDegrees() );
        nodeWeapon->updateAbsolutePosition();
    }
    
    //--- reset weapon position ---
    void shipObject::resetTurretPosition(irr::scene::ISceneNode *nodeTurret, irr::core::vector3df rot)
    {
        irr::core::matrix4 t;
        t.setRotationDegrees(rot);
        nodeTurret->setRotation( t.getRotationDegrees() );
        nodeTurret->updateAbsolutePosition();
    }
    

    aber leider flippen die Waffen in die Ausgangslage zurück während des Schiessens

    die Waffen die oben auf dem Schiff montiert sind Beispielsweise, hier der code für die Ausrichtung dieser

    turretRotationsList.push_back( core::vector3df(0,90,180) );
    

    leicht zu sehen Z Drehung = 180° stehen also upside down.
    Der code zum schiessen (in einfacher form, normalerweise wird hier via timer noch laserstrahldicke, visibilty etc, eingestellt:

    aim( fireTarget, (*turretsIT), (*turretWeaponListIT));
    

    und zum reseten der Drehungen in die Ausgangslage:

    resetTurretPosition((*turretsIT), (*turretRotationsIT));
                        resetWeaponPosition((*turretWeaponListIT));
    

    Fällt die da was auf warum die Turrets welche upside down sein sollten während des schiessen zurück flippen in 0,0,0 Rotation?



  • Also im moment habe ich je nach Drehung des Schiffes und Target Position alles zwischen sich wild drehenden Waffen und Turrets die upside-down hin und her flippen.

    Ich hab da nochmal weiter rumgetestet und habe ja noch ältere, stimmende werte im Kopf.

    bei diese Zeile erhalte ich schon komische Werte:

    irr::core::matrix4 relativeTargetMatrixTur = ta * sh_i * tu_i;
    

    von 0, 90, 0

    es sollten aber sein irgendwas, 105.irgendwas, 0.

    hmm



  • Also aktuell sieht mein Code so aus (unkomplett und fehlerhaft) aber ich muss nun erstmal etwas Schlafen.

    void shipObject::aim(irr::scene::ISceneNode *nodeTarget, irr::scene::ISceneNode *nodeTurret, irr::scene::ISceneNode *nodeWeapon)
    {
       //! std::cout << "\n rotationZ 2 > " << nodeTurret->getRotation().Z;
        // --- get absolute and relative transformation matices for all nodes ---
        irr::core::matrix4 sh = this->getAbsoluteTransformation ();
        irr::core::matrix4 tu = nodeTurret->getAbsoluteTransformation ();
        irr::core::matrix4 we = nodeWeapon->getAbsoluteTransformation ();
        irr::core::matrix4 ta = nodeTarget->getAbsoluteTransformation ();
        //-- get inverse matrices --
        irr::core::matrix4 sh_i;
        sh.getInverse(sh_i);
        irr::core::matrix4 tu_i;
        tu.getInverse(tu_i);
        irr::core::matrix4 we_i;
        we.getInverse(we_i);
        //-- get relative turret  + weapon to target matrices --
        irr::core::matrix4 relativeTargetMatrixTur = ta * tu_i;
        irr::core::matrix4 relativeTargetMatrixWea = ta * we_i;
        //-- get the Translations --
        irr::core::vector3df relTranslation = relativeTargetMatrixWea.getTranslation();
        irr::core::vector3df relTransAngle = relTranslation.getHorizontalAngle();
    
        irr::core::matrix4 tu_to_ta;
        tu_to_ta.setRotationDegrees(relTransAngle);
    
        tu_to_ta *= tu_i;
        irr::core::vector3df finTuRot = tu_to_ta.getRotationDegrees();
    
        turn(nodeTurret, finTuRot.Y);
        //!!!pitch(nodeWeapon, relRotWeaTar.X);
    
    }
    

    Komischerweise erhalte ich übrigens bei sowas:

    irr::core::vector3df rot = nodeTurret->getAbsoluteTransformation ().getRotationDegrees();
    std::cout << "\n rot > " << rot.X << " - "<< rot.Y << " - "<< rot.Z;
    irr::core::vector3df rot2 = nodeTurret->getRotation();
    std::cout << "\n rot2 > " << rot2.X << " - "<< rot2.Y << " - "<< rot2.Z;
    

    folgendes Vrgebniss

    rot > 0 - 270 - 360
    rot2 > 0 - 90 - 180

    naja Morgen / Heute ist auch noch ein tag 🙂



  • Achja das wilde umherzappelnten Turrets hatte übrigens was damit zu tun das die Idee mit dem mit-einberechnen der aktuellen Rotation zwar ganz nett ist aber in einer onRender Funktion dazu führt das die Waffen umherkreiseln / springen 🙂 zumindest in verbindung mit einer relativen Veränderung zur aktuellen Rotation.

    Ausserdem kommen bei Inversen Matrizen alles mögliche raus nur nichts sinnvolles.

    Warum kann ich Matritzen niche einfach regulär lassen und einfach subtrahieren, warum invertieren und multiplizieren?



  • Ich versteh nicht was du da jetzt immer noch dauernd mit diesen ganzen Rotationswinkeln willst.

    WeakPeak schrieb:

    Warum kann ich Matritzen niche einfach regulär lassen und einfach subtrahieren, warum invertieren und multiplizieren?

    Weil Matrixtransformationen nunmal so funktionieren!? Du kannst Matritzen auch Addieren und Subtrahieren, nur wird dir das was dabei rauskommt nicht weiterhelfen. Bei normalen Zahlen fragst du ja doch auch nicht warum du a * b rechnest und nicht a + b, oder?



  • dot schrieb:

    Ich versteh nicht was du da jetzt immer noch dauernd mit diesen ganzen Rotationswinkeln willst.

    WeakPeak schrieb:

    Warum kann ich Matritzen niche einfach regulär lassen und einfach subtrahieren, warum invertieren und multiplizieren?

    Weil Matrixtransformationen nunmal so funktionieren!? Du kannst Matritzen auch Addieren und Subtrahieren, nur wird dir das was dabei rauskommt nicht weiterhelfen. Bei normalen Zahlen fragst du ja doch auch nicht warum du a * b rechnest und nicht a + b, oder?

    Das was bei der Multiplikation rauskommt bringt mich aber auch nicht weiter da Turret und Waffe aus 2 verschiedenen Objekten(Mesh´s) bestehen welche jeweils nur auf einer Achse gedreht werden dürfen.

    Turret = Y-Achse
    Waffe = X-Achse
    .. und dies um eine gekippte Achse welche durch die Drehung des parent vorgegeben ist, ich habe zwar hier

    http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToMatrix/index.htm

    eine entsprechende Matrix gefunden mit der ich mich mal neher beschäftigen muss aber mit bisherugen versuchen kam ich nicht auf brauchbare Werte, zudem sind Matrizen auch etwas Rechenintensiver, ich werde mit den Darstellungen aus dem Link oben später mal weiter rum versuchen und auch noch quaternions austesten.

    Aktuelles Problem bei meinen aktuellen Matrix versuchen war halt dass

    1. bei einbeziehung der aktuellen Rotationen sich drehende Turrets rauskamen, aktuell läuft das Projekt auf ca. 35FPS also ca. 30ms pro render-durchgeang in der Zeit werden 8 Turrets sowie 8 Waffen gedreht und ggf. 16 andere aufgrund von Collisionen oder der vorhandensein von bereits maximal zulässigen 8 Waffen 16 andere Turrets/Waffen in die Ursprungsrotation gefahren. Ich weiss nicht ob ich etwas falsch berechnet hatte, die Ursprungsrotation noch nicht wieder hergestellt war oder was sonst passiert ist, jedenfalls kann ich nur Absolute Drehungen berechnen lassen welche das mit einfliessen der aktuellen Rotation nicht mit einbezieht.
    2. ich mit Matritzen noch nicht wirklich sicher rechnen kann und so auch sicherlich Fehler auftreten.
    3. es bisher so aussieht das ich alle 3 Drehungen aus eine Matritzen Mutliplikaton übernehmen muss um verwertbare ergebnisse zu erzielen, allerdings habe ich bisher auch nur standard Matritzen verwendet, evtl würde mir die Matritze aus dem Link oben etwas einringen.

    Danke für die Geduld.



  • Die Irrlicht Engine arbeitet, soweit ich das sehe, sowieso schon auf Basis eines Szenegraphen. D.h. eigentlich sollte da Kaum noch die Notwendigkeit bestehen selbst Hand an Matritzen zu legen. Dein Turret ist einfach ein Child von deinem Ship. Und deine Weapon wiederum ein Child von deinem Turret. D.h. alles was du noch machen musst ist die Absolute von deinem Turret Node zu nehmen und deine Zielposition mit der Inversen davon zu transformieren. Damit kannst du das Turret dann um die lokale Y Achse ausrichten (von mir aus über den Drehwinkel). Und dann kannst du das gleiche nochmal mit der Weapon machen für deren X Rotation. Ich kenn mich jetzt mit Irrlich nicht aus, evtl. kann man das ganze irgendwie noch besser machen, aber das wär mal mein naiver Ansatz...


Anmelden zum Antworten