1 /** 2 Helper tool to create geometry. 3 4 Copyright: 5 Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. 6 Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) 7 Copyright (c) 2017-2018 Godot-D contributors 8 9 License: $(LINK2 https://opensource.org/licenses/MIT, MIT License) 10 11 12 */ 13 module godot.surfacetool; 14 import std.meta : AliasSeq, staticIndexOf; 15 import std.traits : Unqual; 16 import godot.d.traits; 17 import godot.core; 18 import godot.c; 19 import godot.d.bind; 20 import godot.d.reference; 21 import godot.globalenums; 22 import godot.object; 23 import godot.classdb; 24 import godot.reference; 25 import godot.mesh; 26 import godot.arraymesh; 27 import godot.material; 28 /** 29 Helper tool to create geometry. 30 31 The $(D SurfaceTool) is used to construct a $(D Mesh) by specifying vertex attributes individually. It can be used to construct a $(D Mesh) from a script. All properties except indices need to be added before calling $(D addVertex). For example, to add vertex colors and UVs: 32 33 34 var st = SurfaceTool.new() 35 st.begin(Mesh.PRIMITIVE_TRIANGLES) 36 st.add_color(Color(1, 0, 0)) 37 st.add_uv(Vector2(0, 0)) 38 st.add_vertex(Vector3(0, 0, 0)) 39 40 41 The above $(D SurfaceTool) now contains one vertex of a triangle which has a UV coordinate and a specified $(D Color). If another vertex were added without calling $(D addUv) or $(D addColor), then the last values would be used. 42 Vertex attributes must be passed $(B before) calling $(D addVertex). Failure to do so will result in an error when committing the vertex information to a mesh. 43 Additionally, the attributes used before the first vertex is added determine the format of the mesh. For example, if you only add UVs to the first vertex, you cannot add color to any of the subsequent vertices. 44 See also $(D ArrayMesh), $(D ImmediateGeometry) and $(D MeshDataTool) for procedural geometry generation. 45 $(B Note:) Godot uses clockwise $(D url=https://learnopengl.com/Advanced-OpenGL/Face-culling)winding order$(D /url) for front faces of triangle primitive modes. 46 */ 47 @GodotBaseClass struct SurfaceTool 48 { 49 package(godot) enum string _GODOT_internal_name = "SurfaceTool"; 50 public: 51 @nogc nothrow: 52 union { /** */ godot_object _godot_object; /** */ Reference _GODOT_base; } 53 alias _GODOT_base this; 54 alias BaseClasses = AliasSeq!(typeof(_GODOT_base), typeof(_GODOT_base).BaseClasses); 55 package(godot) __gshared bool _classBindingInitialized = false; 56 package(godot) static struct GDNativeClassBinding 57 { 58 __gshared: 59 @GodotName("add_bones") GodotMethod!(void, PoolIntArray) addBones; 60 @GodotName("add_color") GodotMethod!(void, Color) addColor; 61 @GodotName("add_index") GodotMethod!(void, long) addIndex; 62 @GodotName("add_normal") GodotMethod!(void, Vector3) addNormal; 63 @GodotName("add_smooth_group") GodotMethod!(void, bool) addSmoothGroup; 64 @GodotName("add_tangent") GodotMethod!(void, Plane) addTangent; 65 @GodotName("add_triangle_fan") GodotMethod!(void, PoolVector3Array, PoolVector2Array, PoolColorArray, PoolVector2Array, PoolVector3Array, Array) addTriangleFan; 66 @GodotName("add_uv") GodotMethod!(void, Vector2) addUv; 67 @GodotName("add_uv2") GodotMethod!(void, Vector2) addUv2; 68 @GodotName("add_vertex") GodotMethod!(void, Vector3) addVertex; 69 @GodotName("add_weights") GodotMethod!(void, PoolRealArray) addWeights; 70 @GodotName("append_from") GodotMethod!(void, Mesh, long, Transform) appendFrom; 71 @GodotName("begin") GodotMethod!(void, long) begin; 72 @GodotName("clear") GodotMethod!(void) clear; 73 @GodotName("commit") GodotMethod!(ArrayMesh, ArrayMesh, long) commit; 74 @GodotName("commit_to_arrays") GodotMethod!(Array) commitToArrays; 75 @GodotName("create_from") GodotMethod!(void, Mesh, long) createFrom; 76 @GodotName("create_from_blend_shape") GodotMethod!(void, Mesh, long, String) createFromBlendShape; 77 @GodotName("deindex") GodotMethod!(void) deindex; 78 @GodotName("generate_normals") GodotMethod!(void, bool) generateNormals; 79 @GodotName("generate_tangents") GodotMethod!(void) generateTangents; 80 @GodotName("index") GodotMethod!(void) index; 81 @GodotName("set_material") GodotMethod!(void, Material) setMaterial; 82 } 83 /// 84 pragma(inline, true) bool opEquals(in SurfaceTool other) const 85 { return _godot_object.ptr is other._godot_object.ptr; } 86 /// 87 pragma(inline, true) typeof(null) opAssign(typeof(null) n) 88 { _godot_object.ptr = n; return null; } 89 /// 90 pragma(inline, true) bool opEquals(typeof(null) n) const 91 { return _godot_object.ptr is n; } 92 /// 93 size_t toHash() const @trusted { return cast(size_t)_godot_object.ptr; } 94 mixin baseCasts; 95 /// Construct a new instance of SurfaceTool. 96 /// Note: use `memnew!SurfaceTool` instead. 97 static SurfaceTool _new() 98 { 99 static godot_class_constructor constructor; 100 if(constructor is null) constructor = _godot_api.godot_get_class_constructor("SurfaceTool"); 101 if(constructor is null) return typeof(this).init; 102 return cast(SurfaceTool)(constructor()); 103 } 104 @disable new(size_t s); 105 /** 106 Specifies an array of bones to use for the $(I next) vertex. `bones` must contain 4 integers. 107 */ 108 void addBones(in PoolIntArray bones) 109 { 110 checkClassBinding!(typeof(this))(); 111 ptrcall!(void)(GDNativeClassBinding.addBones, _godot_object, bones); 112 } 113 /** 114 Specifies a $(D Color) to use for the $(I next) vertex. If every vertex needs to have this information set and you fail to submit it for the first vertex, this information may not be used at all. 115 $(B Note:) The material must have $(D SpatialMaterial.vertexColorUseAsAlbedo) enabled for the vertex color to be visible. 116 */ 117 void addColor(in Color color) 118 { 119 checkClassBinding!(typeof(this))(); 120 ptrcall!(void)(GDNativeClassBinding.addColor, _godot_object, color); 121 } 122 /** 123 Adds an index to index array if you are using indexed vertices. Does not need to be called before adding vertices. 124 */ 125 void addIndex(in long index) 126 { 127 checkClassBinding!(typeof(this))(); 128 ptrcall!(void)(GDNativeClassBinding.addIndex, _godot_object, index); 129 } 130 /** 131 Specifies a normal to use for the $(I next) vertex. If every vertex needs to have this information set and you fail to submit it for the first vertex, this information may not be used at all. 132 */ 133 void addNormal(in Vector3 normal) 134 { 135 checkClassBinding!(typeof(this))(); 136 ptrcall!(void)(GDNativeClassBinding.addNormal, _godot_object, normal); 137 } 138 /** 139 Specifies whether the current vertex (if using only vertex arrays) or current index (if also using index arrays) should use smooth normals for normal calculation. 140 */ 141 void addSmoothGroup(in bool smooth) 142 { 143 checkClassBinding!(typeof(this))(); 144 ptrcall!(void)(GDNativeClassBinding.addSmoothGroup, _godot_object, smooth); 145 } 146 /** 147 Specifies a tangent to use for the $(I next) vertex. If every vertex needs to have this information set and you fail to submit it for the first vertex, this information may not be used at all. 148 */ 149 void addTangent(in Plane tangent) 150 { 151 checkClassBinding!(typeof(this))(); 152 ptrcall!(void)(GDNativeClassBinding.addTangent, _godot_object, tangent); 153 } 154 /** 155 Inserts a triangle fan made of array data into $(D Mesh) being constructed. 156 Requires the primitive type be set to $(D constant Mesh.PRIMITIVE_TRIANGLES). 157 */ 158 void addTriangleFan(in PoolVector3Array vertices, in PoolVector2Array uvs = PoolVector2Array.init, in PoolColorArray colors = PoolColorArray.init, in PoolVector2Array uv2s = PoolVector2Array.init, in PoolVector3Array normals = PoolVector3Array.init, in Array tangents = Array.make()) 159 { 160 checkClassBinding!(typeof(this))(); 161 ptrcall!(void)(GDNativeClassBinding.addTriangleFan, _godot_object, vertices, uvs, colors, uv2s, normals, tangents); 162 } 163 /** 164 Specifies a set of UV coordinates to use for the $(I next) vertex. If every vertex needs to have this information set and you fail to submit it for the first vertex, this information may not be used at all. 165 */ 166 void addUv(in Vector2 uv) 167 { 168 checkClassBinding!(typeof(this))(); 169 ptrcall!(void)(GDNativeClassBinding.addUv, _godot_object, uv); 170 } 171 /** 172 Specifies an optional second set of UV coordinates to use for the $(I next) vertex. If every vertex needs to have this information set and you fail to submit it for the first vertex, this information may not be used at all. 173 */ 174 void addUv2(in Vector2 uv2) 175 { 176 checkClassBinding!(typeof(this))(); 177 ptrcall!(void)(GDNativeClassBinding.addUv2, _godot_object, uv2); 178 } 179 /** 180 Specifies the position of current vertex. Should be called after specifying other vertex properties (e.g. Color, UV). 181 */ 182 void addVertex(in Vector3 vertex) 183 { 184 checkClassBinding!(typeof(this))(); 185 ptrcall!(void)(GDNativeClassBinding.addVertex, _godot_object, vertex); 186 } 187 /** 188 Specifies weight values to use for the $(I next) vertex. `weights` must contain 4 values. If every vertex needs to have this information set and you fail to submit it for the first vertex, this information may not be used at all. 189 */ 190 void addWeights(in PoolRealArray weights) 191 { 192 checkClassBinding!(typeof(this))(); 193 ptrcall!(void)(GDNativeClassBinding.addWeights, _godot_object, weights); 194 } 195 /** 196 Append vertices from a given $(D Mesh) surface onto the current vertex array with specified $(D Transform). 197 */ 198 void appendFrom(Mesh existing, in long surface, in Transform transform) 199 { 200 checkClassBinding!(typeof(this))(); 201 ptrcall!(void)(GDNativeClassBinding.appendFrom, _godot_object, existing, surface, transform); 202 } 203 /** 204 Called before adding any vertices. Takes the primitive type as an argument (e.g. $(D constant Mesh.PRIMITIVE_TRIANGLES)). 205 */ 206 void begin(in long primitive) 207 { 208 checkClassBinding!(typeof(this))(); 209 ptrcall!(void)(GDNativeClassBinding.begin, _godot_object, primitive); 210 } 211 /** 212 Clear all information passed into the surface tool so far. 213 */ 214 void clear() 215 { 216 checkClassBinding!(typeof(this))(); 217 ptrcall!(void)(GDNativeClassBinding.clear, _godot_object); 218 } 219 /** 220 Returns a constructed $(D ArrayMesh) from current information passed in. If an existing $(D ArrayMesh) is passed in as an argument, will add an extra surface to the existing $(D ArrayMesh). 221 Default flag is $(D constant Mesh.ARRAY_COMPRESS_DEFAULT). See `ARRAY_COMPRESS_*` constants in $(D Mesh.arrayformat) for other flags. 222 */ 223 Ref!ArrayMesh commit(ArrayMesh existing = ArrayMesh.init, in long flags = 97280) 224 { 225 checkClassBinding!(typeof(this))(); 226 return ptrcall!(ArrayMesh)(GDNativeClassBinding.commit, _godot_object, existing, flags); 227 } 228 /** 229 Commits the data to the same format used by $(D ArrayMesh.addSurfaceFromArrays). This way you can further process the mesh data using the $(D ArrayMesh) API. 230 */ 231 Array commitToArrays() 232 { 233 checkClassBinding!(typeof(this))(); 234 return ptrcall!(Array)(GDNativeClassBinding.commitToArrays, _godot_object); 235 } 236 /** 237 Creates a vertex array from an existing $(D Mesh). 238 */ 239 void createFrom(Mesh existing, in long surface) 240 { 241 checkClassBinding!(typeof(this))(); 242 ptrcall!(void)(GDNativeClassBinding.createFrom, _godot_object, existing, surface); 243 } 244 /** 245 Creates a vertex array from the specified blend shape of an existing $(D Mesh). This can be used to extract a specific pose from a blend shape. 246 */ 247 void createFromBlendShape(Mesh existing, in long surface, in String blend_shape) 248 { 249 checkClassBinding!(typeof(this))(); 250 ptrcall!(void)(GDNativeClassBinding.createFromBlendShape, _godot_object, existing, surface, blend_shape); 251 } 252 /** 253 Removes the index array by expanding the vertex array. 254 */ 255 void deindex() 256 { 257 checkClassBinding!(typeof(this))(); 258 ptrcall!(void)(GDNativeClassBinding.deindex, _godot_object); 259 } 260 /** 261 Generates normals from vertices so you do not have to do it manually. If `flip` is `true`, the resulting normals will be inverted. $(D generateNormals) should be called $(I after) generating geometry and $(I before) committing the mesh using $(D commit) or $(D commitToArrays). 262 $(B Note:) $(D generateNormals) only works if the primitive type to be set to $(D constant Mesh.PRIMITIVE_TRIANGLES). 263 */ 264 void generateNormals(in bool flip = false) 265 { 266 checkClassBinding!(typeof(this))(); 267 ptrcall!(void)(GDNativeClassBinding.generateNormals, _godot_object, flip); 268 } 269 /** 270 Generates a tangent vector for each vertex. Requires that each vertex have UVs and normals set already. 271 */ 272 void generateTangents() 273 { 274 checkClassBinding!(typeof(this))(); 275 ptrcall!(void)(GDNativeClassBinding.generateTangents, _godot_object); 276 } 277 /** 278 Shrinks the vertex array by creating an index array. This can improve performance by avoiding vertex reuse. 279 */ 280 void index() 281 { 282 checkClassBinding!(typeof(this))(); 283 ptrcall!(void)(GDNativeClassBinding.index, _godot_object); 284 } 285 /** 286 Sets $(D Material) to be used by the $(D Mesh) you are constructing. 287 */ 288 void setMaterial(Material material) 289 { 290 checkClassBinding!(typeof(this))(); 291 ptrcall!(void)(GDNativeClassBinding.setMaterial, _godot_object, material); 292 } 293 }