Browse Source

Add C# Examples for ArrayMesh Tutorial (#6778)

* Create C# Examples for ArrayMesh Tutorial

Shows array types for generating meshes. Provides equivalent C# to existing GDScript examples.

Removes locals that don't need to be locals, and better matches GDScript example.
markawilson 2 years ago
parent
commit
b7c5dfdfcc
1 changed files with 142 additions and 3 deletions
  1. 142 3
      tutorials/3d/procedural_geometry/arraymesh.rst

+ 142 - 3
tutorials/3d/procedural_geometry/arraymesh.rst

@@ -92,6 +92,10 @@ Under ``_ready()``, create a new Array.
   .. code-tab:: gdscript GDScript
 
     var surface_array = []
+  
+  .. code-tab:: csharp C#
+
+    var surfaceArray = new Godot.Collections.Array();
 
 This will be the array that we keep our surface information in - it will hold
 all the arrays of data that the surface needs. Godot will expect it to be of
@@ -102,6 +106,11 @@ size ``Mesh.ARRAY_MAX``, so resize it accordingly.
 
     var surface_array = []
     surface_array.resize(Mesh.ARRAY_MAX)
+  
+ .. code-tab:: csharp C#
+
+    var surfaceArray = new Godot.Collections.Array();
+    surfaceArray.Resize((int)Mesh.ArrayType.Max);
 
 Next create the arrays for each data type you will use.
 
@@ -113,6 +122,13 @@ Next create the arrays for each data type you will use.
     var normals = PackedVector3Array()
     var indices = PackedInt32Array()
 
+ .. code-tab:: csharp C#
+
+    var verts = new List<Vector3>();
+    var uvs = new List<Vector2>();
+    var normals = new List<Vector3>();
+    var indices = new List<int>();
+
 Once you have filled your data arrays with your geometry you can create a mesh
 by adding each array to ``surface_array`` and then committing to the mesh.
 
@@ -124,7 +140,22 @@ by adding each array to ``surface_array`` and then committing to the mesh.
     surface_array[Mesh.ARRAY_NORMAL] = normals
     surface_array[Mesh.ARRAY_INDEX] = indices
 
-    mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, surface_array) # No blendshapes, lods, or compression used.
+    # No blendshapes, lods, or compression used.
+    mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, surface_array)
+
+ .. code-tab:: csharp C#
+
+    surfaceArray[(int)Mesh.ArrayType.Vertex] = verts.ToArray();
+    surfaceArray[(int)Mesh.ArrayType.TexUV] = uvs.ToArray();
+    surfaceArray[(int)Mesh.ArrayType.Normal] = normals.ToArray();
+    surfaceArray[(int)Mesh.ArrayType.Index] = indices.ToArray();
+
+    var arrMesh = Mesh as ArrayMesh;
+    if (arrMesh != null)
+    {
+        // No blendshapes, lods, or compression used.
+        arrMesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, surfaceArray); 
+    }
 
 .. note:: In this example, we used ``Mesh.PRIMITIVE_TRIANGLES``, but you can use any primitive type
           available from mesh.
@@ -157,7 +188,43 @@ Put together, the full code looks like:
         surface_array[Mesh.ARRAY_INDEX] = indices
 
         # Create mesh surface from mesh array.
-        mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, surface_array) # No blendshapes, lods, or compression used.
+        # No blendshapes, lods, or compression used.
+        mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, surface_array)
+
+ .. code-tab:: csharp C#
+
+    public partial class MyMeshInstance3D : MeshInstance3D
+    {
+        public override void _Ready()
+        {
+            var surfaceArray = new Godot.Collections.Array();
+            surfaceArray.Resize((int)Mesh.ArrayType.Max);
+
+            // C# arrays cannot be resized or expanded, so use Lists to create geometry.
+            var verts = new List<Vector3>();
+            var uvs = new List<Vector2>();
+            var normals = new List<Vector3>();
+            var indices = new List<int>();
+
+            /***********************************
+            * Insert code here to generate mesh.
+            * *********************************/
+
+            // Convert Lists to arrays and assign to surface array
+            surfaceArray[(int)Mesh.ArrayType.Vertex] = verts.ToArray();
+            surfaceArray[(int)Mesh.ArrayType.TexUV] = uvs.ToArray();
+            surfaceArray[(int)Mesh.ArrayType.Normal] = normals.ToArray();
+            surfaceArray[(int)Mesh.ArrayType.Index] = indices.ToArray();
+
+            var arrMesh = Mesh as ArrayMesh;
+            if (arrMesh != null)
+            {
+                // Create mesh surface from mesh array
+                // No blendshapes, lods, or compression used.
+                arrMesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, surfaceArray);
+            }
+        }
+    }
 
 
 The code that goes in the middle can be whatever you want. Below we will present some
@@ -180,7 +247,6 @@ that you find online.
 
     var rings = 50
     var radial_segments = 50
-    var height = 1
     var radius = 1
 
     func _ready():
@@ -233,6 +299,74 @@ that you find online.
 
       # Insert committing to the ArrayMesh here.
 
+ .. code-tab:: csharp C#
+
+    public partial class MyMeshInstance3D : MeshInstance3D
+    {
+        private int _rings = 50;
+        private int _radialSegments = 50;
+        private float _radius = 1;
+
+        public override void _Ready()
+        {
+            // Insert setting up the surface array and lists here.
+
+            // Vertex indices.
+            var thisRow = 0;
+            var prevRow = 0;
+            var point = 0;
+
+            // Loop over rings.
+            for (var i = 0; i < _rings + 1; i++)
+            {
+                var v = ((float)i) / _rings;
+                var w = Mathf.Sin(Mathf.Pi * v);
+                var y = Mathf.Cos(Mathf.Pi * v);
+
+                // Loop over segments in ring.
+                for (var j = 0; j < _radialSegments; j++)
+                {
+                    var u = ((float)j) / _radialSegments;
+                    var x = Mathf.Sin(u * Mathf.Pi * 2);
+                    var z = Mathf.Cos(u * Mathf.Pi * 2);
+                    var vert = new Vector3(x * _radius * w, y, z * _radius * w);
+                    verts.Add(vert);
+                    normals.Add(vert.Normalized());
+                    uvs.Add(new Vector2(u, v));
+                    point += 1;
+
+                    // Create triangles in ring using indices.
+                    if (i > 0 && j > 0)
+                    {
+                        indices.Add(prevRow + j - 1);
+                        indices.Add(prevRow + j);
+                        indices.Add(thisRow + j - 1);
+
+                        indices.Add(prevRow + j);
+                        indices.Add(thisRow + j);
+                        indices.Add(thisRow + j - 1);
+                    }
+                }
+
+                if (i > 0)
+                {
+                    indices.Add(prevRow + _radialSegments - 1);
+                    indices.Add(prevRow);
+                    indices.Add(thisRow + _radialSegments - 1);
+
+                    indices.Add(prevRow);
+                    indices.Add(prevRow + _radialSegments);
+                    indices.Add(thisRow + _radialSegments - 1);
+                }
+
+                prevRow = thisRow;
+                thisRow = point;
+            }
+
+            // Insert committing to the ArrayMesh here.
+        }
+    }
+
 Saving
 ------
 
@@ -244,3 +378,8 @@ This is useful when you want to generate a mesh and then use it later without ha
 
     # Saves mesh to a .tres file with compression enabled.
     ResourceSaver.save(mesh, "res://sphere.tres", ResourceSaver.FLAG_COMPRESS)
+
+ .. code-tab:: csharp C#
+
+    // Saves mesh to a .tres file with compression enabled.
+    ResourceSaver.Save(Mesh, "res://sphere.tres", ResourceSaver.SaverFlags.Compress);