1 /**
2 Provides high-performance mesh instancing.
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.multimesh;
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.resource;
25 import godot.mesh;
26 /**
27 Provides high-performance mesh instancing.
28 
29 MultiMesh provides low-level mesh instancing. Drawing thousands of $(D MeshInstance) nodes can be slow, since each object is submitted to the GPU then drawn individually.
30 MultiMesh is much faster as it can draw thousands of instances with a single draw call, resulting in less API overhead.
31 As a drawback, if the instances are too far away from each other, performance may be reduced as every single instance will always render (they are spatially indexed as one, for the whole object).
32 Since instances may have any behavior, the AABB used for visibility must be provided by the user.
33 */
34 @GodotBaseClass struct MultiMesh
35 {
36 	package(godot) enum string _GODOT_internal_name = "MultiMesh";
37 public:
38 @nogc nothrow:
39 	union { /** */ godot_object _godot_object; /** */ Resource _GODOT_base; }
40 	alias _GODOT_base this;
41 	alias BaseClasses = AliasSeq!(typeof(_GODOT_base), typeof(_GODOT_base).BaseClasses);
42 	package(godot) __gshared bool _classBindingInitialized = false;
43 	package(godot) static struct GDNativeClassBinding
44 	{
45 		__gshared:
46 		@GodotName("_get_color_array") GodotMethod!(PoolColorArray) _getColorArray;
47 		@GodotName("_get_custom_data_array") GodotMethod!(PoolColorArray) _getCustomDataArray;
48 		@GodotName("_get_transform_2d_array") GodotMethod!(PoolVector2Array) _getTransform2dArray;
49 		@GodotName("_get_transform_array") GodotMethod!(PoolVector3Array) _getTransformArray;
50 		@GodotName("_set_color_array") GodotMethod!(void, PoolColorArray) _setColorArray;
51 		@GodotName("_set_custom_data_array") GodotMethod!(void, PoolColorArray) _setCustomDataArray;
52 		@GodotName("_set_transform_2d_array") GodotMethod!(void, PoolVector2Array) _setTransform2dArray;
53 		@GodotName("_set_transform_array") GodotMethod!(void, PoolVector3Array) _setTransformArray;
54 		@GodotName("get_aabb") GodotMethod!(AABB) getAabb;
55 		@GodotName("get_color_format") GodotMethod!(MultiMesh.ColorFormat) getColorFormat;
56 		@GodotName("get_custom_data_format") GodotMethod!(MultiMesh.CustomDataFormat) getCustomDataFormat;
57 		@GodotName("get_instance_color") GodotMethod!(Color, long) getInstanceColor;
58 		@GodotName("get_instance_count") GodotMethod!(long) getInstanceCount;
59 		@GodotName("get_instance_custom_data") GodotMethod!(Color, long) getInstanceCustomData;
60 		@GodotName("get_instance_transform") GodotMethod!(Transform, long) getInstanceTransform;
61 		@GodotName("get_instance_transform_2d") GodotMethod!(Transform2D, long) getInstanceTransform2d;
62 		@GodotName("get_mesh") GodotMethod!(Mesh) getMesh;
63 		@GodotName("get_transform_format") GodotMethod!(MultiMesh.TransformFormat) getTransformFormat;
64 		@GodotName("get_visible_instance_count") GodotMethod!(long) getVisibleInstanceCount;
65 		@GodotName("set_as_bulk_array") GodotMethod!(void, PoolRealArray) setAsBulkArray;
66 		@GodotName("set_color_format") GodotMethod!(void, long) setColorFormat;
67 		@GodotName("set_custom_data_format") GodotMethod!(void, long) setCustomDataFormat;
68 		@GodotName("set_instance_color") GodotMethod!(void, long, Color) setInstanceColor;
69 		@GodotName("set_instance_count") GodotMethod!(void, long) setInstanceCount;
70 		@GodotName("set_instance_custom_data") GodotMethod!(void, long, Color) setInstanceCustomData;
71 		@GodotName("set_instance_transform") GodotMethod!(void, long, Transform) setInstanceTransform;
72 		@GodotName("set_instance_transform_2d") GodotMethod!(void, long, Transform2D) setInstanceTransform2d;
73 		@GodotName("set_mesh") GodotMethod!(void, Mesh) setMesh;
74 		@GodotName("set_transform_format") GodotMethod!(void, long) setTransformFormat;
75 		@GodotName("set_visible_instance_count") GodotMethod!(void, long) setVisibleInstanceCount;
76 	}
77 	/// 
78 	pragma(inline, true) bool opEquals(in MultiMesh other) const
79 	{ return _godot_object.ptr is other._godot_object.ptr; }
80 	/// 
81 	pragma(inline, true) typeof(null) opAssign(typeof(null) n)
82 	{ _godot_object.ptr = n; return null; }
83 	/// 
84 	pragma(inline, true) bool opEquals(typeof(null) n) const
85 	{ return _godot_object.ptr is n; }
86 	/// 
87 	size_t toHash() const @trusted { return cast(size_t)_godot_object.ptr; }
88 	mixin baseCasts;
89 	/// Construct a new instance of MultiMesh.
90 	/// Note: use `memnew!MultiMesh` instead.
91 	static MultiMesh _new()
92 	{
93 		static godot_class_constructor constructor;
94 		if(constructor is null) constructor = _godot_api.godot_get_class_constructor("MultiMesh");
95 		if(constructor is null) return typeof(this).init;
96 		return cast(MultiMesh)(constructor());
97 	}
98 	@disable new(size_t s);
99 	/// 
100 	enum TransformFormat : int
101 	{
102 		/**
103 		Use this when using 2D transforms.
104 		*/
105 		transform2d = 0,
106 		/**
107 		Use this when using 3D transforms.
108 		*/
109 		transform3d = 1,
110 	}
111 	/// 
112 	enum CustomDataFormat : int
113 	{
114 		/**
115 		Use when you are not using per-instance custom data.
116 		*/
117 		customDataNone = 0,
118 		/**
119 		Compress custom_data into 8 bits when passing to shader. This uses less memory and can be faster, but loses precision and range. Floats packed into 8 bits can only represent values between 0 and 1, numbers outside that range will be clamped.
120 		*/
121 		customData8bit = 1,
122 		/**
123 		The $(D Color) passed into $(D setInstanceCustomData) will use 4 floats. Use this for highest precision.
124 		*/
125 		customDataFloat = 2,
126 	}
127 	/// 
128 	enum ColorFormat : int
129 	{
130 		/**
131 		Use when you are not using per-instance $(D Color)s.
132 		*/
133 		colorNone = 0,
134 		/**
135 		Compress $(D Color) data into 8 bits when passing to shader. This uses less memory and can be faster, but the $(D Color) loses precision.
136 		*/
137 		color8bit = 1,
138 		/**
139 		The $(D Color) passed into $(D setInstanceColor) will use 4 floats. Use this for highest precision $(D Color).
140 		*/
141 		colorFloat = 2,
142 	}
143 	/// 
144 	enum Constants : int
145 	{
146 		colorNone = 0,
147 		transform2d = 0,
148 		customDataNone = 0,
149 		customData8bit = 1,
150 		transform3d = 1,
151 		color8bit = 1,
152 		colorFloat = 2,
153 		customDataFloat = 2,
154 	}
155 	/**
156 	
157 	*/
158 	PoolColorArray _getColorArray() const
159 	{
160 		Array _GODOT_args = Array.make();
161 		String _GODOT_method_name = String("_get_color_array");
162 		return this.callv(_GODOT_method_name, _GODOT_args).as!(RefOrT!PoolColorArray);
163 	}
164 	/**
165 	
166 	*/
167 	PoolColorArray _getCustomDataArray() const
168 	{
169 		Array _GODOT_args = Array.make();
170 		String _GODOT_method_name = String("_get_custom_data_array");
171 		return this.callv(_GODOT_method_name, _GODOT_args).as!(RefOrT!PoolColorArray);
172 	}
173 	/**
174 	
175 	*/
176 	PoolVector2Array _getTransform2dArray() const
177 	{
178 		Array _GODOT_args = Array.make();
179 		String _GODOT_method_name = String("_get_transform_2d_array");
180 		return this.callv(_GODOT_method_name, _GODOT_args).as!(RefOrT!PoolVector2Array);
181 	}
182 	/**
183 	
184 	*/
185 	PoolVector3Array _getTransformArray() const
186 	{
187 		Array _GODOT_args = Array.make();
188 		String _GODOT_method_name = String("_get_transform_array");
189 		return this.callv(_GODOT_method_name, _GODOT_args).as!(RefOrT!PoolVector3Array);
190 	}
191 	/**
192 	
193 	*/
194 	void _setColorArray(in PoolColorArray arg0)
195 	{
196 		Array _GODOT_args = Array.make();
197 		_GODOT_args.append(arg0);
198 		String _GODOT_method_name = String("_set_color_array");
199 		this.callv(_GODOT_method_name, _GODOT_args);
200 	}
201 	/**
202 	
203 	*/
204 	void _setCustomDataArray(in PoolColorArray arg0)
205 	{
206 		Array _GODOT_args = Array.make();
207 		_GODOT_args.append(arg0);
208 		String _GODOT_method_name = String("_set_custom_data_array");
209 		this.callv(_GODOT_method_name, _GODOT_args);
210 	}
211 	/**
212 	
213 	*/
214 	void _setTransform2dArray(in PoolVector2Array arg0)
215 	{
216 		Array _GODOT_args = Array.make();
217 		_GODOT_args.append(arg0);
218 		String _GODOT_method_name = String("_set_transform_2d_array");
219 		this.callv(_GODOT_method_name, _GODOT_args);
220 	}
221 	/**
222 	
223 	*/
224 	void _setTransformArray(in PoolVector3Array arg0)
225 	{
226 		Array _GODOT_args = Array.make();
227 		_GODOT_args.append(arg0);
228 		String _GODOT_method_name = String("_set_transform_array");
229 		this.callv(_GODOT_method_name, _GODOT_args);
230 	}
231 	/**
232 	Returns the visibility axis-aligned bounding box in local space. See also $(D VisualInstance.getTransformedAabb).
233 	*/
234 	AABB getAabb() const
235 	{
236 		checkClassBinding!(typeof(this))();
237 		return ptrcall!(AABB)(GDNativeClassBinding.getAabb, _godot_object);
238 	}
239 	/**
240 	
241 	*/
242 	MultiMesh.ColorFormat getColorFormat() const
243 	{
244 		checkClassBinding!(typeof(this))();
245 		return ptrcall!(MultiMesh.ColorFormat)(GDNativeClassBinding.getColorFormat, _godot_object);
246 	}
247 	/**
248 	
249 	*/
250 	MultiMesh.CustomDataFormat getCustomDataFormat() const
251 	{
252 		checkClassBinding!(typeof(this))();
253 		return ptrcall!(MultiMesh.CustomDataFormat)(GDNativeClassBinding.getCustomDataFormat, _godot_object);
254 	}
255 	/**
256 	Gets a specific instance's color.
257 	*/
258 	Color getInstanceColor(in long instance) const
259 	{
260 		checkClassBinding!(typeof(this))();
261 		return ptrcall!(Color)(GDNativeClassBinding.getInstanceColor, _godot_object, instance);
262 	}
263 	/**
264 	
265 	*/
266 	long getInstanceCount() const
267 	{
268 		checkClassBinding!(typeof(this))();
269 		return ptrcall!(long)(GDNativeClassBinding.getInstanceCount, _godot_object);
270 	}
271 	/**
272 	Returns the custom data that has been set for a specific instance.
273 	*/
274 	Color getInstanceCustomData(in long instance) const
275 	{
276 		checkClassBinding!(typeof(this))();
277 		return ptrcall!(Color)(GDNativeClassBinding.getInstanceCustomData, _godot_object, instance);
278 	}
279 	/**
280 	Returns the $(D Transform) of a specific instance.
281 	*/
282 	Transform getInstanceTransform(in long instance) const
283 	{
284 		checkClassBinding!(typeof(this))();
285 		return ptrcall!(Transform)(GDNativeClassBinding.getInstanceTransform, _godot_object, instance);
286 	}
287 	/**
288 	Returns the $(D Transform2D) of a specific instance.
289 	*/
290 	Transform2D getInstanceTransform2d(in long instance) const
291 	{
292 		checkClassBinding!(typeof(this))();
293 		return ptrcall!(Transform2D)(GDNativeClassBinding.getInstanceTransform2d, _godot_object, instance);
294 	}
295 	/**
296 	
297 	*/
298 	Ref!Mesh getMesh() const
299 	{
300 		checkClassBinding!(typeof(this))();
301 		return ptrcall!(Mesh)(GDNativeClassBinding.getMesh, _godot_object);
302 	}
303 	/**
304 	
305 	*/
306 	MultiMesh.TransformFormat getTransformFormat() const
307 	{
308 		checkClassBinding!(typeof(this))();
309 		return ptrcall!(MultiMesh.TransformFormat)(GDNativeClassBinding.getTransformFormat, _godot_object);
310 	}
311 	/**
312 	
313 	*/
314 	long getVisibleInstanceCount() const
315 	{
316 		checkClassBinding!(typeof(this))();
317 		return ptrcall!(long)(GDNativeClassBinding.getVisibleInstanceCount, _godot_object);
318 	}
319 	/**
320 	Sets all data related to the instances in one go. This is especially useful when loading the data from disk or preparing the data from GDNative.
321 	All data is packed in one large float array. An array may look like this: Transform for instance 1, color data for instance 1, custom data for instance 1, transform for instance 2, color data for instance 2, etc...
322 	$(D Transform) is stored as 12 floats, $(D Transform2D) is stored as 8 floats, `COLOR_8BIT` / `CUSTOM_DATA_8BIT` is stored as 1 float (4 bytes as is) and `COLOR_FLOAT` / `CUSTOM_DATA_FLOAT` is stored as 4 floats.
323 	*/
324 	void setAsBulkArray(in PoolRealArray array)
325 	{
326 		checkClassBinding!(typeof(this))();
327 		ptrcall!(void)(GDNativeClassBinding.setAsBulkArray, _godot_object, array);
328 	}
329 	/**
330 	
331 	*/
332 	void setColorFormat(in long format)
333 	{
334 		checkClassBinding!(typeof(this))();
335 		ptrcall!(void)(GDNativeClassBinding.setColorFormat, _godot_object, format);
336 	}
337 	/**
338 	
339 	*/
340 	void setCustomDataFormat(in long format)
341 	{
342 		checkClassBinding!(typeof(this))();
343 		ptrcall!(void)(GDNativeClassBinding.setCustomDataFormat, _godot_object, format);
344 	}
345 	/**
346 	Sets the color of a specific instance by $(I multiplying) the mesh's existing vertex colors.
347 	For the color to take effect, ensure that $(D colorFormat) is non-`null` on the $(D MultiMesh) and $(D SpatialMaterial.vertexColorUseAsAlbedo) is `true` on the material.
348 	*/
349 	void setInstanceColor(in long instance, in Color color)
350 	{
351 		checkClassBinding!(typeof(this))();
352 		ptrcall!(void)(GDNativeClassBinding.setInstanceColor, _godot_object, instance, color);
353 	}
354 	/**
355 	
356 	*/
357 	void setInstanceCount(in long count)
358 	{
359 		checkClassBinding!(typeof(this))();
360 		ptrcall!(void)(GDNativeClassBinding.setInstanceCount, _godot_object, count);
361 	}
362 	/**
363 	Sets custom data for a specific instance. Although $(D Color) is used, it is just a container for 4 floating point numbers. The format of the number can change depending on the $(D customdataformat) used.
364 	*/
365 	void setInstanceCustomData(in long instance, in Color custom_data)
366 	{
367 		checkClassBinding!(typeof(this))();
368 		ptrcall!(void)(GDNativeClassBinding.setInstanceCustomData, _godot_object, instance, custom_data);
369 	}
370 	/**
371 	Sets the $(D Transform) for a specific instance.
372 	*/
373 	void setInstanceTransform(in long instance, in Transform transform)
374 	{
375 		checkClassBinding!(typeof(this))();
376 		ptrcall!(void)(GDNativeClassBinding.setInstanceTransform, _godot_object, instance, transform);
377 	}
378 	/**
379 	Sets the $(D Transform2D) for a specific instance.
380 	*/
381 	void setInstanceTransform2d(in long instance, in Transform2D transform)
382 	{
383 		checkClassBinding!(typeof(this))();
384 		ptrcall!(void)(GDNativeClassBinding.setInstanceTransform2d, _godot_object, instance, transform);
385 	}
386 	/**
387 	
388 	*/
389 	void setMesh(Mesh mesh)
390 	{
391 		checkClassBinding!(typeof(this))();
392 		ptrcall!(void)(GDNativeClassBinding.setMesh, _godot_object, mesh);
393 	}
394 	/**
395 	
396 	*/
397 	void setTransformFormat(in long format)
398 	{
399 		checkClassBinding!(typeof(this))();
400 		ptrcall!(void)(GDNativeClassBinding.setTransformFormat, _godot_object, format);
401 	}
402 	/**
403 	
404 	*/
405 	void setVisibleInstanceCount(in long count)
406 	{
407 		checkClassBinding!(typeof(this))();
408 		ptrcall!(void)(GDNativeClassBinding.setVisibleInstanceCount, _godot_object, count);
409 	}
410 	/**
411 	
412 	*/
413 	@property PoolColorArray colorArray()
414 	{
415 		return _getColorArray();
416 	}
417 	/// ditto
418 	@property void colorArray(PoolColorArray v)
419 	{
420 		_setColorArray(v);
421 	}
422 	/**
423 	Format of colors in color array that gets passed to shader.
424 	*/
425 	@property MultiMesh.ColorFormat colorFormat()
426 	{
427 		return getColorFormat();
428 	}
429 	/// ditto
430 	@property void colorFormat(long v)
431 	{
432 		setColorFormat(v);
433 	}
434 	/**
435 	
436 	*/
437 	@property PoolColorArray customDataArray()
438 	{
439 		return _getCustomDataArray();
440 	}
441 	/// ditto
442 	@property void customDataArray(PoolColorArray v)
443 	{
444 		_setCustomDataArray(v);
445 	}
446 	/**
447 	Format of custom data in custom data array that gets passed to shader.
448 	*/
449 	@property MultiMesh.CustomDataFormat customDataFormat()
450 	{
451 		return getCustomDataFormat();
452 	}
453 	/// ditto
454 	@property void customDataFormat(long v)
455 	{
456 		setCustomDataFormat(v);
457 	}
458 	/**
459 	Number of instances that will get drawn. This clears and (re)sizes the buffers. By default, all instances are drawn but you can limit this with $(D visibleInstanceCount).
460 	*/
461 	@property long instanceCount()
462 	{
463 		return getInstanceCount();
464 	}
465 	/// ditto
466 	@property void instanceCount(long v)
467 	{
468 		setInstanceCount(v);
469 	}
470 	/**
471 	Mesh to be drawn.
472 	*/
473 	@property Mesh mesh()
474 	{
475 		return getMesh();
476 	}
477 	/// ditto
478 	@property void mesh(Mesh v)
479 	{
480 		setMesh(v);
481 	}
482 	/**
483 	
484 	*/
485 	@property PoolVector2Array transform2dArray()
486 	{
487 		return _getTransform2dArray();
488 	}
489 	/// ditto
490 	@property void transform2dArray(PoolVector2Array v)
491 	{
492 		_setTransform2dArray(v);
493 	}
494 	/**
495 	
496 	*/
497 	@property PoolVector3Array transformArray()
498 	{
499 		return _getTransformArray();
500 	}
501 	/// ditto
502 	@property void transformArray(PoolVector3Array v)
503 	{
504 		_setTransformArray(v);
505 	}
506 	/**
507 	Format of transform used to transform mesh, either 2D or 3D.
508 	*/
509 	@property MultiMesh.TransformFormat transformFormat()
510 	{
511 		return getTransformFormat();
512 	}
513 	/// ditto
514 	@property void transformFormat(long v)
515 	{
516 		setTransformFormat(v);
517 	}
518 	/**
519 	Limits the number of instances drawn, -1 draws all instances. Changing this does not change the sizes of the buffers.
520 	*/
521 	@property long visibleInstanceCount()
522 	{
523 		return getVisibleInstanceCount();
524 	}
525 	/// ditto
526 	@property void visibleInstanceCount(long v)
527 	{
528 		setVisibleInstanceCount(v);
529 	}
530 }