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.meta; 17 import godot.core; 18 import godot.c; 19 import godot.d.bind; 20 import godot.d.reference; 21 import godot.object; 22 import godot.classdb; 23 import godot.reference; 24 import godot.material; 25 import godot.mesh; 26 import godot.arraymesh; 27 /** 28 Helper tool to create geometry. 29 30 The `SurfaceTool` is used to construct a $(D Mesh) by specifying vertex attributes individually. It can be used to construct a $(D Mesh) from script. All properties except index need to be added before a call to $(D addVertex). For example adding vertex colors and UVs looks like 31 32 33 var st = SurfaceTool.new() 34 st.begin(Mesh.PRIMITIVE_TRIANGLES) 35 st.add_color(Color(1, 0, 0)) 36 st.add_uv(Vector2(0, 0)) 37 st.add_vertex(Vector3(0, 0, 0)) 38 39 40 The `SurfaceTool` now contains one vertex of a triangle which has a UV coordinate and a specified $(D Color). If another vertex were added without calls to $(D addUv) or $(D addColor) then the last values would be used. 41 It is very important that vertex attributes are passed $(B before) the call to $(D addVertex), failure to do this will result in an error when committing the vertex information to a mesh. 42 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. 43 */ 44 @GodotBaseClass struct SurfaceTool 45 { 46 enum string _GODOT_internal_name = "SurfaceTool"; 47 public: 48 @nogc nothrow: 49 union { godot_object _godot_object; Reference _GODOT_base; } 50 alias _GODOT_base this; 51 alias BaseClasses = AliasSeq!(typeof(_GODOT_base), typeof(_GODOT_base).BaseClasses); 52 package(godot) __gshared bool _classBindingInitialized = false; 53 package(godot) static struct _classBinding 54 { 55 __gshared: 56 @GodotName("begin") GodotMethod!(void, long) begin; 57 @GodotName("add_vertex") GodotMethod!(void, Vector3) addVertex; 58 @GodotName("add_color") GodotMethod!(void, Color) addColor; 59 @GodotName("add_normal") GodotMethod!(void, Vector3) addNormal; 60 @GodotName("add_tangent") GodotMethod!(void, Plane) addTangent; 61 @GodotName("add_uv") GodotMethod!(void, Vector2) addUv; 62 @GodotName("add_uv2") GodotMethod!(void, Vector2) addUv2; 63 @GodotName("add_bones") GodotMethod!(void, PoolIntArray) addBones; 64 @GodotName("add_weights") GodotMethod!(void, PoolRealArray) addWeights; 65 @GodotName("add_smooth_group") GodotMethod!(void, bool) addSmoothGroup; 66 @GodotName("add_triangle_fan") GodotMethod!(void, PoolVector3Array, PoolVector2Array, PoolColorArray, PoolVector2Array, PoolVector3Array, Array) addTriangleFan; 67 @GodotName("add_index") GodotMethod!(void, long) addIndex; 68 @GodotName("index") GodotMethod!(void) index; 69 @GodotName("deindex") GodotMethod!(void) deindex; 70 @GodotName("generate_normals") GodotMethod!(void, bool) generateNormals; 71 @GodotName("generate_tangents") GodotMethod!(void) generateTangents; 72 @GodotName("add_to_format") GodotMethod!(void, long) addToFormat; 73 @GodotName("set_material") GodotMethod!(void, Material) setMaterial; 74 @GodotName("clear") GodotMethod!(void) clear; 75 @GodotName("create_from") GodotMethod!(void, Mesh, long) createFrom; 76 @GodotName("append_from") GodotMethod!(void, Mesh, long, Transform) appendFrom; 77 @GodotName("commit") GodotMethod!(ArrayMesh, ArrayMesh, long) commit; 78 } 79 bool opEquals(in SurfaceTool other) const { return _godot_object.ptr is other._godot_object.ptr; } 80 SurfaceTool opAssign(T : typeof(null))(T n) { _godot_object.ptr = null; } 81 bool opEquals(typeof(null) n) const { return _godot_object.ptr is null; } 82 mixin baseCasts; 83 static SurfaceTool _new() 84 { 85 static godot_class_constructor constructor; 86 if(constructor is null) constructor = _godot_api.godot_get_class_constructor("SurfaceTool"); 87 if(constructor is null) return typeof(this).init; 88 return cast(SurfaceTool)(constructor()); 89 } 90 @disable new(size_t s); 91 /** 92 Called before adding any Vertices. Takes the primitive type as an argument (e.g. Mesh.PRIMITIVE_TRIANGLES). 93 */ 94 void begin(in long primitive) 95 { 96 checkClassBinding!(typeof(this))(); 97 ptrcall!(void)(_classBinding.begin, _godot_object, primitive); 98 } 99 /** 100 Specify position of current Vertex. Should be called after specifying other vertex properties (e.g. Color, UV). 101 */ 102 void addVertex(in Vector3 vertex) 103 { 104 checkClassBinding!(typeof(this))(); 105 ptrcall!(void)(_classBinding.addVertex, _godot_object, vertex); 106 } 107 /** 108 Specify a $(D Color) for the next Vertex to use. 109 */ 110 void addColor(in Color color) 111 { 112 checkClassBinding!(typeof(this))(); 113 ptrcall!(void)(_classBinding.addColor, _godot_object, color); 114 } 115 /** 116 Specify a normal for the next Vertex to use. 117 */ 118 void addNormal(in Vector3 normal) 119 { 120 checkClassBinding!(typeof(this))(); 121 ptrcall!(void)(_classBinding.addNormal, _godot_object, normal); 122 } 123 /** 124 Specify a Tangent for the next Vertex to use. 125 */ 126 void addTangent(in Plane tangent) 127 { 128 checkClassBinding!(typeof(this))(); 129 ptrcall!(void)(_classBinding.addTangent, _godot_object, tangent); 130 } 131 /** 132 Specify UV Coordinate for next Vertex to use. 133 */ 134 void addUv(in Vector2 uv) 135 { 136 checkClassBinding!(typeof(this))(); 137 ptrcall!(void)(_classBinding.addUv, _godot_object, uv); 138 } 139 /** 140 Specify an optional second set of UV coordinates for next Vertex to use. 141 */ 142 void addUv2(in Vector2 uv2) 143 { 144 checkClassBinding!(typeof(this))(); 145 ptrcall!(void)(_classBinding.addUv2, _godot_object, uv2); 146 } 147 /** 148 Add an array of bones for the next Vertex to use. Array must contain 4 integers. 149 */ 150 void addBones(in PoolIntArray bones) 151 { 152 checkClassBinding!(typeof(this))(); 153 ptrcall!(void)(_classBinding.addBones, _godot_object, bones); 154 } 155 /** 156 Specify weight values for next Vertex to use. Array must contain 4 values. 157 */ 158 void addWeights(in PoolRealArray weights) 159 { 160 checkClassBinding!(typeof(this))(); 161 ptrcall!(void)(_classBinding.addWeights, _godot_object, weights); 162 } 163 /** 164 Specify whether current Vertex (if using only Vertex arrays) or current index (if also using index arrays) should utilize smooth normals for normal calculation. 165 */ 166 void addSmoothGroup(in bool smooth) 167 { 168 checkClassBinding!(typeof(this))(); 169 ptrcall!(void)(_classBinding.addSmoothGroup, _godot_object, smooth); 170 } 171 /** 172 Insert a triangle fan made of array data into $(D Mesh) being constructed. 173 Requires primitive type be set to `PRIMITIVE_TRIANGLES`. 174 */ 175 void addTriangleFan(in PoolVector3Array vertexes, in PoolVector2Array uvs = PoolVector2Array.init, in PoolColorArray colors = PoolColorArray.init, in PoolVector2Array uv2s = PoolVector2Array.init, in PoolVector3Array normals = PoolVector3Array.init, in Array tangents = Array.empty_array) 176 { 177 checkClassBinding!(typeof(this))(); 178 ptrcall!(void)(_classBinding.addTriangleFan, _godot_object, vertexes, uvs, colors, uv2s, normals, tangents); 179 } 180 /** 181 Adds an index to index array if you are using indexed Vertices. Does not need to be called before adding Vertex. 182 */ 183 void addIndex(in long index) 184 { 185 checkClassBinding!(typeof(this))(); 186 ptrcall!(void)(_classBinding.addIndex, _godot_object, index); 187 } 188 /** 189 Shrinks Vertex array by creating an index array. Avoids reusing Vertices. 190 */ 191 void index() 192 { 193 checkClassBinding!(typeof(this))(); 194 ptrcall!(void)(_classBinding.index, _godot_object); 195 } 196 /** 197 Removes index array by expanding Vertex array. 198 */ 199 void deindex() 200 { 201 checkClassBinding!(typeof(this))(); 202 ptrcall!(void)(_classBinding.deindex, _godot_object); 203 } 204 /** 205 Generates normals from Vertices so you do not have to do it manually. 206 Setting "flip" `true` inverts resulting normals. 207 Requires primitive type to be set to `PRIMITIVE_TRIANGLES`. 208 */ 209 void generateNormals(in bool flip = false) 210 { 211 checkClassBinding!(typeof(this))(); 212 ptrcall!(void)(_classBinding.generateNormals, _godot_object, flip); 213 } 214 /** 215 Generates a tangent vector for each vertex. 216 Requires that each vertex have UVs and normals set already. 217 */ 218 void generateTangents() 219 { 220 checkClassBinding!(typeof(this))(); 221 ptrcall!(void)(_classBinding.generateTangents, _godot_object); 222 } 223 /** 224 225 */ 226 void addToFormat(in long flags) 227 { 228 checkClassBinding!(typeof(this))(); 229 ptrcall!(void)(_classBinding.addToFormat, _godot_object, flags); 230 } 231 /** 232 Sets $(D Material) to be used by the $(D Mesh) you are constructing. 233 */ 234 void setMaterial(Material material) 235 { 236 checkClassBinding!(typeof(this))(); 237 ptrcall!(void)(_classBinding.setMaterial, _godot_object, material); 238 } 239 /** 240 Clear all information passed into the surface tool so far. 241 */ 242 void clear() 243 { 244 checkClassBinding!(typeof(this))(); 245 ptrcall!(void)(_classBinding.clear, _godot_object); 246 } 247 /** 248 Creates a vertex array from an existing $(D Mesh). 249 */ 250 void createFrom(Mesh existing, in long surface) 251 { 252 checkClassBinding!(typeof(this))(); 253 ptrcall!(void)(_classBinding.createFrom, _godot_object, existing, surface); 254 } 255 /** 256 Append vertices from a given $(D Mesh) surface onto the current vertex array with specified $(D Transform). 257 */ 258 void appendFrom(Mesh existing, in long surface, in Transform transform) 259 { 260 checkClassBinding!(typeof(this))(); 261 ptrcall!(void)(_classBinding.appendFrom, _godot_object, existing, surface, transform); 262 } 263 /** 264 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). 265 */ 266 Ref!ArrayMesh commit(ArrayMesh existing = ArrayMesh.init, in long flags = 97280) 267 { 268 checkClassBinding!(typeof(this))(); 269 return ptrcall!(ArrayMesh)(_classBinding.commit, _godot_object, existing, flags); 270 } 271 }