gamnit: 3 Euler rotation angles for actors
authorAlexis Laferrière <alexis.laf@xymus.net>
Wed, 24 May 2017 14:11:10 +0000 (07:11 -0700)
committerAlexis Laferrière <alexis.laf@xymus.net>
Sun, 4 Jun 2017 13:55:52 +0000 (09:55 -0400)
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>

contrib/action_nitro/src/action_nitro.nit
contrib/model_viewer/src/globe.nit
contrib/model_viewer/src/model_viewer.nit
contrib/tinks/src/client/client3d.nit
lib/gamnit/depth/depth_core.nit
lib/gamnit/depth/more_materials.nit
lib/gamnit/depth/selection.nit
lib/matrix/projection.nit

index e5a68f9..a181789 100644 (file)
@@ -507,7 +507,7 @@ end
 redef class Boss
        redef var actor is lazy do
                var actor = new Actor(app.iss_model, center)
-               actor.rotation = pi/2.0
+               actor.yaw = pi/2.0
                return actor
        end
 
@@ -556,7 +556,7 @@ redef class Player
                        var splatter = new Actor(app.splatter_model,
                                new Point3d[Float](center.x, 0.05 & 0.04, center.y))
                        splatter.scale = 32.0
-                       splatter.rotation = 2.0 * pi.rand
+                       splatter.yaw = 2.0*pi.rand
                        app.actors.add splatter
                end
 
index 8fe1158..a5a9a62 100644 (file)
@@ -148,7 +148,7 @@ class GlobeMaterial
 
                # Set uniforms
                program.scale.uniform 1.0
-               program.rotation.uniform new Matrix.rotation(actor.rotation, 0.0, 1.0, 0.0)
+               program.rotation.uniform new Matrix.gamnit_euler_rotation(actor.pitch, actor.yaw, actor.roll)
                program.translation.uniform(actor.center.x, -actor.center.y, actor.center.z, 0.0)
                program.color.uniform(color[0], color[1], color[2], color[3])
                program.is_surface.uniform is_surface
index 9353ef5..347b565 100644 (file)
@@ -146,7 +146,7 @@ redef class App
                var t = clock.total.to_f
 
                # Rotate the model
-               actors.first.rotation = t
+               actors.first.yaw = t
 
                # Move the light source
                var dist_to_light = 20.0
index 5c3d6b9..01b2a25 100644 (file)
@@ -359,7 +359,7 @@ redef class Feature
                # Apply a random model and rotation to new features
                actor = new Actor(rule.models.rand,
                        new Point3d[Float](pos.x, 0.0, pos.y))
-               actor.rotation = 2.0*pi.rand
+               actor.yaw = 2.0*pi.rand
                actor.scale = 0.75
 
                self.actor = actor
@@ -426,7 +426,7 @@ redef class ExplosionEvent
                # Blast mark on the ground
                var blast = new Actor(app.blast_model, new Point3d[Float](pos.x, 0.05 & 0.04, pos.y))
                blast.scale = 3.0
-               blast.rotation = 2.0*pi.rand
+               blast.yaw = 2.0*pi.rand
                app.actors.add blast
 
                # Smoke
@@ -474,8 +474,8 @@ redef class TankMoveEvent
                        actor.center.z = pos.y
                end
 
-               tank.actors[0].rotation = tank.heading + pi
-               tank.actors[1].rotation = tank.turret.heading + pi
+               tank.actors[0].yaw = -tank.heading + pi
+               tank.actors[1].yaw = -tank.turret.heading + pi
 
                # Keep going only for the local tank
                var local_player = app.context.local_player
index 994e8be..db13d81 100644 (file)
@@ -46,8 +46,30 @@ class Actor
        # Position of this sprite in world coordinates
        var center: Point3d[Float] is writable
 
-       # Rotation on the Z axis
-       var rotation = 0.0 is writable
+       # Rotation around the X axis (+ looks up, - looks down)
+       #
+       # Positive values look up, and negative look down.
+       #
+       # All actor rotations follow the right hand rule.
+       # The default orientation of the model should look towards -Z.
+       var pitch = 0.0 is writable
+
+       # Rotation around the Y axis (+ turns left, - turns right)
+       #
+       # Positive values turn `self` to the left, and negative values to the right.
+       #
+       # All actor rotations follow the right hand rule.
+       # The default orientation of the model should look towards -Z.
+       var yaw = 0.0 is writable
+
+       # Rotation around the Z axis (looking to -Z: + turns counterclockwise, - clockwise)
+       #
+       # From the default camera point of view, looking down on the Z axis,
+       # positive values turn `self` counterclockwise, and negative values clockwise.
+       #
+       # All actor rotations follow the right hand rule.
+       # The default orientation of the model should look towards -Z.
+       var roll = 0.0 is writable
 
        # Scale applied to the model
        var scale = 1.0 is writable
index 4cc8dcb..ec4a3cd 100644 (file)
@@ -49,7 +49,7 @@ class SmoothMaterial
                # Actor specs
                program.translation.uniform(actor.center.x, actor.center.y, actor.center.z, 0.0)
                program.scale.uniform actor.scale
-               program.rotation.uniform new Matrix.rotation(actor.rotation, 0.0, 1.0, 0.0)
+               program.rotation.uniform new Matrix.gamnit_euler_rotation(actor.pitch, actor.yaw, actor.roll)
 
                # From mesh
                program.coord.array_enabled = true
@@ -171,7 +171,8 @@ class TexturedMaterial
 
                program.coord.array_enabled = true
                program.coord.array(mesh.vertices, 3)
-               program.rotation.uniform new Matrix.rotation(actor.rotation, 0.0, 1.0, 0.0)
+
+               program.rotation.uniform new Matrix.gamnit_euler_rotation(actor.pitch, actor.yaw, actor.roll)
 
                program.ambient_color.uniform(ambient_color[0], ambient_color[1], ambient_color[2], ambient_color[3]*actor.alpha)
                program.diffuse_color.uniform(diffuse_color[0], diffuse_color[1], diffuse_color[2], diffuse_color[3]*actor.alpha)
@@ -216,7 +217,8 @@ class NormalsMaterial
 
                program.coord.array_enabled = true
                program.coord.array(mesh.vertices, 3)
-               program.rotation.uniform new Matrix.rotation(actor.rotation, 0.0, 1.0, 0.0)
+
+               program.rotation.uniform new Matrix.gamnit_euler_rotation(actor.pitch, actor.yaw, actor.roll)
 
                program.normal.array_enabled = true
                program.normal.array(mesh.normals, 3)
index 3d0e841..954b962 100644 (file)
@@ -157,7 +157,7 @@ redef class Material
 
                program.coord.array_enabled = true
                program.coord.array(mesh.vertices, 3)
-               program.rotation.uniform new Matrix.rotation(actor.rotation, 0.0, 1.0, 0.0)
+               program.rotation.uniform new Matrix.gamnit_euler_rotation(actor.pitch, actor.yaw, actor.roll)
 
                var display = app.display
                assert display != null
index 908761a..a9bf8b8 100644 (file)
@@ -150,4 +150,27 @@ redef class Matrix
                var rotated = self * rotation
                self.items = rotated.items
        end
+
+       # Rotation matrix from Euler angles `pitch`, `yaw` and `roll` in radians
+       #
+       # Apply a composition of intrinsic rotations around the axes x-y'-z''.
+       # Or `pitch` around the X axis, `yaw` around Y and `roll` around Z,
+       # applied successively. All rotations follow the right hand rule.
+       #
+       # This service aims to respect the world axes and logic of `gamnit`,
+       # it may not correspond to all needs.
+       new gamnit_euler_rotation(pitch, yaw, roll: Float)
+       do
+               var c1 = pitch.cos
+               var s1 = pitch.sin
+               var c2 = yaw.cos
+               var s2 = yaw.sin
+               var c3 = roll.cos
+               var s3 = roll.sin
+               return new Matrix.from(
+                       [[          c2*c3,          -c2*s3,   -s2, 0.0],
+                        [ c1*s3+c3*s1*s2,  c1*c3-s1*s2*s3, c2*s1, 0.0],
+                        [-s1*s3+c1*c3*s2, -c3*s1-c1*s2*s3, c1*c2, 0.0],
+                        [            0.0,             0.0,   0.0, 1.0]])
+       end
 end