فهرست منبع

c sharp samples for using 3D transforms

Kelly thomas 7 سال پیش
والد
کامیت
bf817ddfc3
1فایلهای تغییر یافته به همراه141 افزوده شده و 23 حذف شده
  1. 141 23
      tutorials/3d/using_transforms.rst

+ 141 - 23
tutorials/3d/using_transforms.rst

@@ -95,7 +95,8 @@ A transform has a :ref:`class_Basis` (transform.basis sub-property), which consi
 
 
 A default basis (unmodified) is akin to:
 A default basis (unmodified) is akin to:
 
 
-.. code-block:: python
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
 
     var basis = Basis()
     var basis = Basis()
     # Contains the following default values:
     # Contains the following default values:
@@ -103,6 +104,23 @@ A default basis (unmodified) is akin to:
     basis.y = Vector3(0, 1, 0) # Vector pointing along the Y axis
     basis.y = Vector3(0, 1, 0) # Vector pointing along the Y axis
     basis.z = Vector3(0, 0, 1) # Vector pointing along the Z axis
     basis.z = Vector3(0, 0, 1) # Vector pointing along the Z axis
 
 
+ .. code-tab:: csharp
+
+    // Due to technical limitations on structs in C# the default
+    // constructor will contain zero values for all fields.
+    var defaultBasis = new Basis();
+    GD.Print(defaultBasis); // prints: ((0, 0, 0), (0, 0, 0), (0, 0, 0))
+
+    // Instead we can use the Identity property.
+    var identityBasis = Basis.Identity;
+    GD.Print(identityBasis.x); // prints: (1, 0, 0)
+    GD.Print(identityBasis.y); // prints: (0, 1, 0)
+    GD.Print(identityBasis.z); // prints: (0, 0, 1)
+
+    // The Identity basis is equivalent to: 
+    var basis = new Basis(Vector3.Right, Vector3.Up, Vector3.Back);
+    GD.Print(basis); // prints: ((1, 0, 0), (0, 1, 0), (0, 0, 1))
+
 This is also an analog to a 3x3 identity matrix.
 This is also an analog to a 3x3 identity matrix.
 
 
 Following the OpenGL convention, ``X`` is the *Right* axis, ``Y`` is the *Up* axis and ``Z`` is the *Forward* axis.
 Following the OpenGL convention, ``X`` is the *Right* axis, ``Y`` is the *Up* axis and ``Z`` is the *Forward* axis.
@@ -129,34 +147,53 @@ Of course, transforms are not as straightforward to manipulate as angles and hav
 
 
 It is possible to rotate a transform, either by multiplying its basis by another (this is called accumulation), or by using the rotation methods.
 It is possible to rotate a transform, either by multiplying its basis by another (this is called accumulation), or by using the rotation methods.
 
 
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
 
-.. code-block:: python
-
-    # Rotate the transform in X axis
+    # Rotate the transform about the X axis
     transform.basis = Basis(Vector3(1, 0, 0), PI) * transform.basis
     transform.basis = Basis(Vector3(1, 0, 0), PI) * transform.basis
     # shortened
     # shortened
     transform.basis = transform.basis.rotated(Vector3(1, 0, 0), PI)
     transform.basis = transform.basis.rotated(Vector3(1, 0, 0), PI)
 
 
+ .. code-tab:: csharp
+
+    // rotate the transform about the X axis
+    transform.basis = new Basis(Vector3.Right, Mathf.Pi) * transform.basis;
+    // shortened
+    transform.basis = transform.basis.Rotated(Vector3.Right, Mathf.Pi);
+
 A method in Spatial simplifies this:
 A method in Spatial simplifies this:
 
 
-.. code-block:: python
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
 
     # Rotate the transform in X axis
     # Rotate the transform in X axis
     rotate(Vector3(1, 0, 0), PI)
     rotate(Vector3(1, 0, 0), PI)
     # shortened
     # shortened
     rotate_x(PI)
     rotate_x(PI)
 
 
+ .. code-tab:: csharp
+
+    // Rotate the transform about the X axis
+    Rotate(Vector3.Right, Mathf.Pi);
+    // shortened
+    RotateX(Mathf.Pi);
+
 This rotates the node relative to the parent node.
 This rotates the node relative to the parent node.
 
 
 To rotate relative to object space (the node's own transform) use the following:
 To rotate relative to object space (the node's own transform) use the following:
 
 
-.. code-block:: python
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
 
-    # Rotate locally, notice multiplication order is inverted
-    transform = transform * Basis(Vector3(1, 0, 0), PI)
-    # shortened
+    # Rotate locally
     rotate_object_local(Vector3(1, 0, 0), PI)
     rotate_object_local(Vector3(1, 0, 0), PI)
 
 
+ .. code-tab:: csharp
+    
+    // Rotate locally
+    RotateObjectLocal(Vector3.Right, Mathf.Pi);
+
 Precision Errors
 Precision Errors
 ================
 ================
 
 
@@ -166,19 +203,29 @@ If a transform is rotated every frame, it will eventually start deforming over t
 
 
 There are two different ways to handle this. The first is to *orthonormalize* the transform after some time (maybe once per frame if you modify it every frame):
 There are two different ways to handle this. The first is to *orthonormalize* the transform after some time (maybe once per frame if you modify it every frame):
 
 
-.. code-block:: python
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
 
     transform = transform.orthonormalized()
     transform = transform.orthonormalized()
 
 
+ .. code-tab:: csharp
+
+    transform = transform.Orthonormalized();
+
 This will make all axes have ``1.0`` length again and be ``90`` degrees from each other. However, any scale applied to the transform will be lost.
 This will make all axes have ``1.0`` length again and be ``90`` degrees from each other. However, any scale applied to the transform will be lost.
 
 
 It is recommended you don't scale nodes that are going to be manipulated. Scale their children nodes instead (such as MeshInstance). If you absolutely must scale the node, then re-apply it at the end:
 It is recommended you don't scale nodes that are going to be manipulated. Scale their children nodes instead (such as MeshInstance). If you absolutely must scale the node, then re-apply it at the end:
 
 
-.. code-block:: python
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
 
     transform = transform.orthonormalized()
     transform = transform.orthonormalized()
     transform = transform.scaled(scale)
     transform = transform.scaled(scale)
 
 
+ .. code-tab:: csharp
+
+    transform = transform.Orthonormalized();
+    transform = transform.Scaled(scale);
 
 
 Obtaining Information
 Obtaining Information
 =====================
 =====================
@@ -187,31 +234,57 @@ You might be thinking at this point: **"Ok, but how do I get angles from a trans
 
 
 Imagine you need to shoot a bullet in the direction your player is facing. Just use the forward axis (commonly ``Z`` or ``-Z``).
 Imagine you need to shoot a bullet in the direction your player is facing. Just use the forward axis (commonly ``Z`` or ``-Z``).
 
 
-.. code-block:: python
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
 
     bullet.transform = transform
     bullet.transform = transform
     bullet.speed = transform.basis.z * BULLET_SPEED
     bullet.speed = transform.basis.z * BULLET_SPEED
 
 
+ .. code-tab:: csharp
+
+    bullet.Transform = transform;
+    bullet.LinearVelocity = transform.basis.z * BulletSpeed;
+
 Is the enemy looking at the player? Use the dot product for this (see the :ref:`doc_vector_math` tutorial for an explanation of the dot product):
 Is the enemy looking at the player? Use the dot product for this (see the :ref:`doc_vector_math` tutorial for an explanation of the dot product):
 
 
-.. code-block:: python
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
 
     # Get the direction vector from player to enemy
     # Get the direction vector from player to enemy
     var direction = enemy.transform.origin - player.transform.origin
     var direction = enemy.transform.origin - player.transform.origin
     if direction.dot(enemy.transform.basis.z) > 0:
     if direction.dot(enemy.transform.basis.z) > 0:
-	enemy.im_watching_you(player)
+        enemy.im_watching_you(player)
+
+ .. code-tab:: csharp
+
+    // Get the direction vector from player to enemy
+    Vector3 direction = enemy.Transform.origin - player.Transform.origin;
+    if (direction.Dot(enemy.Transform.basis.z) > 0)
+    {
+        enemy.ImWatchingYou(player);
+    }
 
 
 Strafe left:
 Strafe left:
 
 
-.. code-block:: python
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
 
     # Remember that +X is right
     # Remember that +X is right
     if Input.is_action_pressed("strafe_left"):
     if Input.is_action_pressed("strafe_left"):
-	translate_object_local(-transform.basis.x)
+        translate_object_local(-transform.basis.x)
+
+ .. code-tab:: csharp
+
+    // Remember that +X is right
+    if (Input.IsActionPressed("strafe_left"))
+    {
+        TranslateObjectLocal(-Transform.basis.x);
+    }
 
 
 Jump:
 Jump:
 
 
-.. code-block:: python
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
 
     # Keep in mind Y is up-axis
     # Keep in mind Y is up-axis
     if Input.is_action_just_pressed("jump"):
     if Input.is_action_just_pressed("jump"):
@@ -219,6 +292,15 @@ Jump:
 
 
     velocity = move_and_slide(velocity)
     velocity = move_and_slide(velocity)
 
 
+ .. code-tab:: csharp
+
+    // Keep in mind Y is up-axis
+    if (Input.IsActionJustPressed("jump"))
+    {
+        velocity.y = JumpSpeed;
+    }
+    velocity = MoveAndSlide(velocity);
+
 All common behaviors and logic can be done with just vectors.
 All common behaviors and logic can be done with just vectors.
 
 
 Setting Information
 Setting Information
@@ -230,22 +312,47 @@ For such cases, keep the angles and rotations *outside* the transform and set th
 
 
 Example of looking around, FPS style:
 Example of looking around, FPS style:
 
 
-.. code-block:: python
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
 
     # accumulators
     # accumulators
     var rot_x = 0
     var rot_x = 0
     var rot_y = 0
     var rot_y = 0
 
 
     func _input(event):
     func _input(event):
-
-        if event is InputEventMouseMotion and ev.button_mask & 1:
+        if event is InputEventMouseMotion and event.button_mask & 1:
             # modify accumulated mouse rotation
             # modify accumulated mouse rotation
-            rot_x += ev.relative.x * LOOKAROUND_SPEED
-            rot_y += ev.relative.y * LOOKAROUND_SPEED
+            rot_x += event.relative.x * LOOKAROUND_SPEED
+            rot_y += event.relative.y * LOOKAROUND_SPEED
             transform.basis = Basis() # reset rotation
             transform.basis = Basis() # reset rotation
             rotate_object_local(Vector3(0, 1, 0), rot_x) # first rotate in Y
             rotate_object_local(Vector3(0, 1, 0), rot_x) # first rotate in Y
             rotate_object_local(Vector3(1, 0, 0), rot_y) # then rotate in X
             rotate_object_local(Vector3(1, 0, 0), rot_y) # then rotate in X
 
 
+ .. code-tab:: csharp
+
+    // accumulators
+    private float _rotationX = 0f;
+    private float _rotationY = 0f;
+
+    public override void _Input(InputEvent @event)
+    {
+        var mouseMotion = @event as InputEventMouseMotion;
+        if (mouseMotion != null)
+        {
+            // modify accumulated mouse rotation
+            _rotationX += mouseMotion.Relative.x * LookAroundSpeed;
+            _rotationY += mouseMotion.Relative.y * LookAroundSpeed;
+            
+            // reset rotation
+            Transform transform = Transform;
+            transform.basis = Basis.Identity;
+            Transform = transform;
+
+            RotateObjectLocal(Vector3.Up, _rotationX); // first rotate about Y
+            RotateObjectLocal(Vector3.Right, _rotationY); // then rotate about X
+        }
+    }
+
 As you can see, in such cases it's even simpler to keep the rotation outside, then use the transform as the *final* orientation.
 As you can see, in such cases it's even simpler to keep the rotation outside, then use the transform as the *final* orientation.
 
 
 Interpolating with Quaternions
 Interpolating with Quaternions
@@ -255,7 +362,8 @@ Interpolating between two transforms can efficiently be done with quaternions. M
 
 
 Converting a rotation to quaternion is straightforward.
 Converting a rotation to quaternion is straightforward.
 
 
-.. code-block:: python
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
 
     # Convert basis to quaternion, keep in mind scale is lost
     # Convert basis to quaternion, keep in mind scale is lost
     var a = Quat(transform.basis)
     var a = Quat(transform.basis)
@@ -265,6 +373,16 @@ Converting a rotation to quaternion is straightforward.
     # Apply back
     # Apply back
     transform.basis = Basis(c)
     transform.basis = Basis(c)
 
 
+ .. code-tab:: csharp
+
+    // Convert basis to quaternion, keep in mind scale is lost
+    var a = transform.basis.Quat();
+    var b = transform.basis.Quat();
+    // Interpolate using spherical-linear interpolation (SLERP).
+    var c = a.Slerp(b, 0.5f); // find halfway point between a and b
+    // Apply back
+    transform.basis = new Basis(c);
+
 The :ref:`class_Quat` type reference has more information on the datatype (it can also do transform accumulation, transform points, etc. though this is used less often). If you interpolate or apply operations to quaternions many times, keep in mind they need to be eventually normalized or they also may suffer from numerical precision errors.
 The :ref:`class_Quat` type reference has more information on the datatype (it can also do transform accumulation, transform points, etc. though this is used less often). If you interpolate or apply operations to quaternions many times, keep in mind they need to be eventually normalized or they also may suffer from numerical precision errors.
 
 
 Quaternions are very useful when doing camera/path/etc. interpolations, as the result will be always correct and smooth.
 Quaternions are very useful when doing camera/path/etc. interpolations, as the result will be always correct and smooth.