3d für Anfänger - Transformationen

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • 3d für Anfänger - Transformationen

      Weitere 3d-Anfänger Tutorials gibt's hier:



      Dieses Tutorial basiert teilweise auf meinen Tutorials "3d für Anfänger", "3d für Anfänger - Modelle " und "3d für Anfänger - Outlines ".

      Dieses Tuorial befasst sich mit Transformationen im Game Maker. Inhalt: Rotation und Skalierung

      Seit meinem Basis Tutorial benutze ich einen Code in meinen Examples, welchen ich bis jetzt noch nicht detailliert beschrieben habe.

      GML-Quellcode

      1. d3d_transform_set_identity();
      2. d3d_transform_add_rotation_z(direction);
      3. d3d_transform_add_translation(x,y,0);
      4. d3d_draw_block(-5,-4,0,+5,+4,5,tex,1,1);
      5. d3d_transform_set_identity();

      Zur Erinnerung: Dieser Code bewirkt, dass sich unser Spieler, in diesem Fall ein einfacher Block, immer mit der Direction dreht.
      Um dies zu erklären sollten wir uns endlich von dem öden Block lösen, welchen ich bisher in jedem meiner Examples benutzt habe.

      Für dieses Tutorial werde ich einen "Wobble" benutzen, ein Wesen aus einem alten Projekt. An ihm werde ich Rotation und Skalierung erklären.
      Nehmen wir also am besten das Example meines Modell Tutorial 's zur Hand, da dort bereits die Scripts zum Laden der Modelle enthalten sind.
      Zuerst bearbeiten wir das Objekt "block".
      Da dieses bisher kein Create Event besaß, fügen wir nun eins hinzu und schreiben folgendes:

      GML-Quellcode

      1. mod1=createFromObj('models\mod1.obj');
      2. mod2=createFromObj('models\mod2.obj');
      3. tex=background_get_texture(tex_wobble);
      4. tex2=background_get_texture(tex_black);

      Dieser Code ist zwar selbsterklärend aber ich möchte dennoch kurz darauf eingehen: Es werden zwei Modelle geladen. Einmal das normale Modell des "Wobbles" und die schwarze Kontur welche wir darum zeichnen werden (Das zweite Modell kann weggelassen werden).
      In Zeile 3 wird der Variable "tex" eine Textur zugeschrieben, um sie nacher im Draw-Event abrufen zu lassen.

      Gehen wir nun weiter ins Step-Event:

      GML-Quellcode

      1. if (keyboard_check(vk_up)){speed=2}else{speed=0}
      2. if (keyboard_check(vk_left)){direction+=4}
      3. if (keyboard_check(vk_right)){direction-=4}

      Dies ist der Code welcher bisher für die Bewegung zuständig war. Wir können ihn vorerst unverändert lassen, wichtig ist hier die Variable "direction" welche im nächsten Schritt zum Tragen kommt.

      Rotation:
      Nun wollen wir im Draw-Event das Modell zeichnen, und sich mit der "direction" drehen lassen. Zum Drehen sind nun die Transformationen nötig, fangen wir also an:

      GML-Quellcode

      1. d3d_transform_set_identity();

      Mit diesem Code lassen wir alle anderen Transformationen welche es im Spiel gibt für die nachfolgenden Zeilen deaktivieren. Diesen Code benutzen wir immer vor und nach jeder Transformation.

      GML-Quellcode

      1. d3d_transform_add_rotation_z(direction);

      Mit diesem Code fügen wir eine Rotation zu. Anstatt "d3d_transform_add_rotation_z" könnten wir auch "d3d_transform_add_rotation_y" oder "d3d_transform_add_rotation_x" schreiben. Es ist ebenfalls möglich mehere Rotationen auf einmal zu benutzen.
      Die letze wichtige Zeile bildet:

      GML-Quellcode

      1. d3d_transform_add_translation(x,y,0);

      Dieser Befehl legt fest, an welcher Stelle wir das Objekt rotieren lassen möchten. Lassen wir es an der Stelle (x/y) eines Objekts rotieren sieht das Ganze so aus (Topdown):

      Die Koordinaten x und y befinden sich zentral im Koordinatenkreuz, deswegen wird das Objekt auch an dieser Stelle rotiert.
      Wir können unser Objekt aber auch an einer anderen Stelle rotieren lassen, in dem wir z.B. "d3d_transform_add_translation(x+32,y,0)" schreiben. Hierdurch wird das Objekt um 32 Pixel nach rechts verschoben und dort wie gehabt rotiert. Das sähe so aus:

      Nun folgt die Zeile, in welcher wir das Modell zeichnen lassen:

      GML-Quellcode

      1. d3d_model_draw(mod1,0,0,0,tex);
      2. //d3d_set_culling(true);
      3. //d3d_model_draw(mod2,0,0,0,tex2);
      4. //d3d_set_culling(false);

      Ist eine Rotation eines Körpers um sich selbst erwünscht, so wie wir es bisher hatten, sollten die Koordinaten des Modells 0,0,0 betragen.
      Aber was passiert genau, wenn man z.B. 32,0,0 benutzen würde?
      Das Modell würde seine Position um 32 Pixel nach rechts verschieben, sich dann aber nicht um sich selbst, sondern um den Punkt x,y rotieren.

      In unserem Fall ist dieser Effekt nicht erwünscht, daher benutzen wir weiterhin die Koordinaten 0,0,0.
      Abschließend kommt

      GML-Quellcode

      1. d3d_transform_set_identity();

      in die letzte Zeile, damit unbeteiligte Objekte sicht nicht ebenfalls drehen.
      Komplett sähe der Draw-Code so aus:

      GML-Quellcode

      1. d3d_transform_set_identity();
      2. d3d_transform_add_rotation_z(direction);
      3. d3d_transform_add_translation(x,y,0);
      4. d3d_model_draw(mod1,0,0,0,tex);
      5. //d3d_set_culling(true);
      6. //d3d_model_draw(mod2,0,0,0,tex2);
      7. //d3d_set_culling(false);
      8. d3d_transform_set_identity();


      Das Ganze sieht dann ungefähr so aus.

      Skalierung:

      Nun kann sich der Wobble drehen und bewegen, wackelig sieht es aber noch nicht aus. An dieser Stelle lässt es sich gut mit Skalierungen Arbeiten.
      Mit Skalierungen lässt sich ein Objekt verformen. Um unseren Wobble also zu verformen, brauchen wir nur einen zusätzlichen Befehl.

      GML-Quellcode

      1. d3d_transform_add_scaling(xs,ys,zs)

      Der Gebraucht dieses Befehls ist sehr einfach. Angenommen wir würden

      GML-Quellcode

      1. d3d_transform_add_scaling(1,1,2)

      benutzen, so wäre das Objekt in der Breite unverändert, dafür jedoch doppelt so hoch. Das sähe so aus:



      Erstellen wir also mit dieser Funktion einen Wackel-Effekt:
      Unser Ziel ist es nun, den Wobble in geringer Weise dynamisch größer und wieder kleiner werden zu lassen. Am besten kann man dies mit dem Sinus lösen, welchen ich bereits in meinem Tutorial zu Effekten angesprochen habe.
      Legen wir zunächst zwei Variablen im Create-Event an, z.B. "size" und "size2". Diese bekommen anfänglich den Wert 0.

      GML-Quellcode

      1. size=0;
      2. size2=0;

      Nun kommt das Herzstück des Effekts, das Step-Event:

      GML-Quellcode

      1. size2+=0.2;
      2. size=sin(size2)/10;

      Wir lassen die Variable "size2" pro step um 0.2 anwachsen. Würden wir den Wert z.B. mit 0.3 ersetzen, würde der Effekt schneller ablaufen.
      Die Variable "size" nimm den Wert des Sinus von "size2" an, welcher durch 10 geteilt wird. Würden wir den Wert durch z.B. 5 ersetzen, würde das Objekt um ein vielfaches größer/kleiner werden.

      Setzen wir nun den neu erlernten Code im Draw-Event ein, erhalten wir:

      GML-Quellcode

      1. d3d_transform_set_identity();
      2. d3d_transform_add_rotation_z(direction);
      3. d3d_transform_add_scaling(1+size,1+size,1+size);
      4. d3d_transform_add_translation(x,y,0);
      5. d3d_model_draw(mod1,0,0,0,tex);
      6. //d3d_set_culling(true);
      7. //d3d_model_draw(mod2,0,0,0,tex2);
      8. //d3d_set_culling(false);
      9. d3d_transform_set_identity();

      Der Wobble wird also zusätzlich zu seiner Normalgröße um die Variable "size" gestreckt/gestaucht.

      Am besten ihr schaut euch das Ganze in Bewegung an, das Example ist wie immer angehängt.
      Dateien
    • Oh! Das Tutorial habe ich ja noch gar nicht bemerkt!
      Und wieder mal : TOP! Super beschrieben, leicht zu verstehen und die Zeichnungen und Screens runden das ganze sauber ab...
      Weiter so, und du kriegst - Wie SDX schon angedeutet hat - wohl noch einen eigenen Topic dafür ;)
    • Kann mir bitte jemand erklären warum ...

      GML-Quellcode

      1. d3d_transform_set_identity();
      2. d3d_transform_add_rotation_z(direction);
      3. d3d_transform_add_translation(x,y,0);
      4. d3d_draw_block(-5,-4,0,+5,+4,5,tex,1,1);
      5. d3d_transform_set_identity();


      ... nicht mehr funktioniert wenn ich anstatt d3d_draw_block ein ellipsoid nehme?

      Es dreht sich dann wie in diesem Bild



      EDIT: Hat sich erledigt. Hatte ein Fehler in der Syntax :headtouch:

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von HerzBlatt ()

    • Aber ein Tutorial Thread, weshalb hier jederzeit gefragt werden kann


      In der Tat. Ist ja nicht so, als wenn ich verschollen wäre oder mich für dieses Tutorial schäme.
      Ich hab HerzBlatt schon im Chat gesagt, dass ich sein Problem nicht reproduzieren kann. Ohne weitere Informationen kann ich daher nicht helfen.