Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/scene/resources/3d/primitive_meshes.h
9898 views
1
/**************************************************************************/
2
/* primitive_meshes.h */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#pragma once
32
33
#include "scene/resources/font.h"
34
#include "scene/resources/mesh.h"
35
#include "servers/text_server.h"
36
37
///@TODO probably should change a few integers to unsigned integers...
38
39
/**
40
Base class for all the classes in this file, handles a number of code functions that are shared among all meshes.
41
This class is set apart that it assumes a single surface is always generated for our mesh.
42
*/
43
44
class PrimitiveMesh : public Mesh {
45
GDCLASS(PrimitiveMesh, Mesh);
46
47
private:
48
RID mesh;
49
mutable AABB aabb;
50
AABB custom_aabb;
51
52
mutable int array_len = 0;
53
mutable int index_array_len = 0;
54
55
Ref<Material> material;
56
bool flip_faces = false;
57
58
bool add_uv2 = false;
59
float uv2_padding = 2.0;
60
61
// make sure we do an update after we've finished constructing our object
62
mutable bool pending_request = true;
63
void _update() const;
64
65
protected:
66
// assume primitive triangles as the type, correct for all but one and it will change this :)
67
Mesh::PrimitiveType primitive_type = Mesh::PRIMITIVE_TRIANGLES;
68
69
// Copy of our texel_size project setting.
70
float texel_size = 0.2;
71
72
static void _bind_methods();
73
74
virtual void _create_mesh_array(Array &p_arr) const {}
75
GDVIRTUAL0RC(Array, _create_mesh_array)
76
77
Vector2 get_uv2_scale(Vector2 p_margin_scale = Vector2(1.0, 1.0)) const;
78
float get_lightmap_texel_size() const;
79
virtual void _update_lightmap_size() {}
80
81
void _on_settings_changed();
82
83
public:
84
virtual int get_surface_count() const override;
85
virtual int surface_get_array_len(int p_idx) const override;
86
virtual int surface_get_array_index_len(int p_idx) const override;
87
virtual Array surface_get_arrays(int p_surface) const override;
88
virtual TypedArray<Array> surface_get_blend_shape_arrays(int p_surface) const override;
89
virtual Dictionary surface_get_lods(int p_surface) const override;
90
virtual BitField<ArrayFormat> surface_get_format(int p_idx) const override;
91
virtual Mesh::PrimitiveType surface_get_primitive_type(int p_idx) const override;
92
virtual void surface_set_material(int p_idx, const Ref<Material> &p_material) override;
93
virtual Ref<Material> surface_get_material(int p_idx) const override;
94
virtual int get_blend_shape_count() const override;
95
virtual StringName get_blend_shape_name(int p_index) const override;
96
virtual void set_blend_shape_name(int p_index, const StringName &p_name) override;
97
virtual AABB get_aabb() const override;
98
virtual RID get_rid() const override;
99
100
void set_material(const Ref<Material> &p_material);
101
Ref<Material> get_material() const;
102
103
Array get_mesh_arrays() const;
104
105
void set_custom_aabb(const AABB &p_custom);
106
AABB get_custom_aabb() const;
107
108
void set_flip_faces(bool p_enable);
109
bool get_flip_faces() const;
110
111
void set_add_uv2(bool p_enable);
112
bool get_add_uv2() const { return add_uv2; }
113
114
void set_uv2_padding(float p_padding);
115
float get_uv2_padding() const { return uv2_padding; }
116
117
void request_update();
118
119
PrimitiveMesh();
120
~PrimitiveMesh();
121
};
122
123
/**
124
Mesh for a simple capsule
125
*/
126
class CapsuleMesh : public PrimitiveMesh {
127
GDCLASS(CapsuleMesh, PrimitiveMesh);
128
129
private:
130
float radius = 0.5;
131
float height = 2.0;
132
int radial_segments = 64;
133
int rings = 8;
134
135
protected:
136
static void _bind_methods();
137
virtual void _create_mesh_array(Array &p_arr) const override;
138
139
virtual void _update_lightmap_size() override;
140
141
public:
142
static void create_mesh_array(Array &p_arr, float radius, float height, int radial_segments = 64, int rings = 8, bool p_add_uv2 = false, const float p_uv2_padding = 1.0);
143
144
void set_radius(const float p_radius);
145
float get_radius() const;
146
147
void set_height(const float p_height);
148
float get_height() const;
149
150
void set_radial_segments(const int p_segments);
151
int get_radial_segments() const;
152
153
void set_rings(const int p_rings);
154
int get_rings() const;
155
};
156
157
/**
158
A box
159
*/
160
class BoxMesh : public PrimitiveMesh {
161
GDCLASS(BoxMesh, PrimitiveMesh);
162
163
private:
164
Vector3 size = Vector3(1, 1, 1);
165
int subdivide_w = 0;
166
int subdivide_h = 0;
167
int subdivide_d = 0;
168
169
protected:
170
static void _bind_methods();
171
virtual void _create_mesh_array(Array &p_arr) const override;
172
173
virtual void _update_lightmap_size() override;
174
175
public:
176
static void create_mesh_array(Array &p_arr, Vector3 size, int subdivide_w = 0, int subdivide_h = 0, int subdivide_d = 0, bool p_add_uv2 = false, const float p_uv2_padding = 1.0);
177
178
void set_size(const Vector3 &p_size);
179
Vector3 get_size() const;
180
181
void set_subdivide_width(const int p_divisions);
182
int get_subdivide_width() const;
183
184
void set_subdivide_height(const int p_divisions);
185
int get_subdivide_height() const;
186
187
void set_subdivide_depth(const int p_divisions);
188
int get_subdivide_depth() const;
189
};
190
191
/**
192
A cylinder
193
*/
194
195
class CylinderMesh : public PrimitiveMesh {
196
GDCLASS(CylinderMesh, PrimitiveMesh);
197
198
private:
199
float top_radius = 0.5;
200
float bottom_radius = 0.5;
201
float height = 2.0;
202
int radial_segments = 64;
203
int rings = 4;
204
bool cap_top = true;
205
bool cap_bottom = true;
206
207
protected:
208
static void _bind_methods();
209
virtual void _create_mesh_array(Array &p_arr) const override;
210
211
virtual void _update_lightmap_size() override;
212
213
public:
214
static void create_mesh_array(Array &p_arr, float top_radius, float bottom_radius, float height, int radial_segments = 64, int rings = 4, bool cap_top = true, bool cap_bottom = true, bool p_add_uv2 = false, const float p_uv2_padding = 1.0);
215
216
void set_top_radius(const float p_radius);
217
float get_top_radius() const;
218
219
void set_bottom_radius(const float p_radius);
220
float get_bottom_radius() const;
221
222
void set_height(const float p_height);
223
float get_height() const;
224
225
void set_radial_segments(const int p_segments);
226
int get_radial_segments() const;
227
228
void set_rings(const int p_rings);
229
int get_rings() const;
230
231
void set_cap_top(bool p_cap_top);
232
bool is_cap_top() const;
233
234
void set_cap_bottom(bool p_cap_bottom);
235
bool is_cap_bottom() const;
236
};
237
238
/*
239
A flat rectangle, can be used as quad or heightmap.
240
*/
241
class PlaneMesh : public PrimitiveMesh {
242
GDCLASS(PlaneMesh, PrimitiveMesh);
243
244
public:
245
enum Orientation {
246
FACE_X,
247
FACE_Y,
248
FACE_Z,
249
};
250
251
private:
252
Size2 size = Size2(2.0, 2.0);
253
int subdivide_w = 0;
254
int subdivide_d = 0;
255
Vector3 center_offset;
256
Orientation orientation = FACE_Y;
257
258
protected:
259
static void _bind_methods();
260
virtual void _create_mesh_array(Array &p_arr) const override;
261
262
virtual void _update_lightmap_size() override;
263
264
public:
265
void set_size(const Size2 &p_size);
266
Size2 get_size() const;
267
268
void set_subdivide_width(const int p_divisions);
269
int get_subdivide_width() const;
270
271
void set_subdivide_depth(const int p_divisions);
272
int get_subdivide_depth() const;
273
274
void set_center_offset(const Vector3 p_offset);
275
Vector3 get_center_offset() const;
276
277
void set_orientation(const Orientation p_orientation);
278
Orientation get_orientation() const;
279
};
280
281
VARIANT_ENUM_CAST(PlaneMesh::Orientation)
282
283
/*
284
A flat rectangle, inherits from PlaneMesh but defaults to facing the Z-plane.
285
*/
286
class QuadMesh : public PlaneMesh {
287
GDCLASS(QuadMesh, PlaneMesh);
288
289
public:
290
QuadMesh() {
291
set_orientation(FACE_Z);
292
set_size(Size2(1, 1));
293
}
294
};
295
296
/**
297
A prism shapen, handy for ramps, triangles, etc.
298
*/
299
class PrismMesh : public PrimitiveMesh {
300
GDCLASS(PrismMesh, PrimitiveMesh);
301
302
private:
303
float left_to_right = 0.5;
304
Vector3 size = Vector3(1.0, 1.0, 1.0);
305
int subdivide_w = 0;
306
int subdivide_h = 0;
307
int subdivide_d = 0;
308
309
protected:
310
static void _bind_methods();
311
virtual void _create_mesh_array(Array &p_arr) const override;
312
313
virtual void _update_lightmap_size() override;
314
315
public:
316
void set_left_to_right(const float p_left_to_right);
317
float get_left_to_right() const;
318
319
void set_size(const Vector3 &p_size);
320
Vector3 get_size() const;
321
322
void set_subdivide_width(const int p_divisions);
323
int get_subdivide_width() const;
324
325
void set_subdivide_height(const int p_divisions);
326
int get_subdivide_height() const;
327
328
void set_subdivide_depth(const int p_divisions);
329
int get_subdivide_depth() const;
330
};
331
332
/**
333
A sphere..
334
*/
335
class SphereMesh : public PrimitiveMesh {
336
GDCLASS(SphereMesh, PrimitiveMesh);
337
338
private:
339
float radius = 0.5;
340
float height = 1.0;
341
int radial_segments = 64;
342
int rings = 32;
343
bool is_hemisphere = false;
344
345
protected:
346
static void _bind_methods();
347
virtual void _create_mesh_array(Array &p_arr) const override;
348
349
virtual void _update_lightmap_size() override;
350
351
public:
352
static void create_mesh_array(Array &p_arr, float radius, float height, int radial_segments = 64, int rings = 32, bool is_hemisphere = false, bool p_add_uv2 = false, const float p_uv2_padding = 1.0);
353
354
void set_radius(const float p_radius);
355
float get_radius() const;
356
357
void set_height(const float p_height);
358
float get_height() const;
359
360
void set_radial_segments(const int p_radial_segments);
361
int get_radial_segments() const;
362
363
void set_rings(const int p_rings);
364
int get_rings() const;
365
366
void set_is_hemisphere(const bool p_is_hemisphere);
367
bool get_is_hemisphere() const;
368
};
369
370
/**
371
Big donut
372
*/
373
class TorusMesh : public PrimitiveMesh {
374
GDCLASS(TorusMesh, PrimitiveMesh);
375
376
private:
377
float inner_radius = 0.5;
378
float outer_radius = 1.0;
379
int rings = 64;
380
int ring_segments = 32;
381
382
protected:
383
static void _bind_methods();
384
virtual void _create_mesh_array(Array &p_arr) const override;
385
386
virtual void _update_lightmap_size() override;
387
388
public:
389
void set_inner_radius(const float p_inner_radius);
390
float get_inner_radius() const;
391
392
void set_outer_radius(const float p_outer_radius);
393
float get_outer_radius() const;
394
395
void set_rings(const int p_rings);
396
int get_rings() const;
397
398
void set_ring_segments(const int p_ring_segments);
399
int get_ring_segments() const;
400
};
401
402
/**
403
A single point for use in particle systems
404
*/
405
406
class PointMesh : public PrimitiveMesh {
407
GDCLASS(PointMesh, PrimitiveMesh)
408
409
protected:
410
virtual void _create_mesh_array(Array &p_arr) const override;
411
412
public:
413
PointMesh();
414
};
415
416
class TubeTrailMesh : public PrimitiveMesh {
417
GDCLASS(TubeTrailMesh, PrimitiveMesh);
418
419
private:
420
float radius = 0.5;
421
int radial_steps = 8;
422
int sections = 5;
423
float section_length = 0.2;
424
int section_rings = 3;
425
bool cap_top = true;
426
bool cap_bottom = true;
427
428
Ref<Curve> curve;
429
430
void _curve_changed();
431
432
protected:
433
static void _bind_methods();
434
virtual void _create_mesh_array(Array &p_arr) const override;
435
436
public:
437
void set_radius(const float p_radius);
438
float get_radius() const;
439
440
void set_radial_steps(const int p_radial_steps);
441
int get_radial_steps() const;
442
443
void set_sections(const int p_sections);
444
int get_sections() const;
445
446
void set_section_length(float p_sectionlength);
447
float get_section_length() const;
448
449
void set_section_rings(const int p_section_rings);
450
int get_section_rings() const;
451
452
void set_cap_top(bool p_cap_top);
453
bool is_cap_top() const;
454
455
void set_cap_bottom(bool p_cap_bottom);
456
bool is_cap_bottom() const;
457
458
void set_curve(const Ref<Curve> &p_curve);
459
Ref<Curve> get_curve() const;
460
461
virtual int get_builtin_bind_pose_count() const override;
462
virtual Transform3D get_builtin_bind_pose(int p_index) const override;
463
464
TubeTrailMesh();
465
};
466
467
class RibbonTrailMesh : public PrimitiveMesh {
468
GDCLASS(RibbonTrailMesh, PrimitiveMesh);
469
470
public:
471
enum Shape {
472
SHAPE_FLAT,
473
SHAPE_CROSS
474
};
475
476
private:
477
float size = 1.0;
478
int sections = 5;
479
float section_length = 0.2;
480
int section_segments = 3;
481
482
Shape shape = SHAPE_CROSS;
483
484
Ref<Curve> curve;
485
486
void _curve_changed();
487
488
protected:
489
static void _bind_methods();
490
virtual void _create_mesh_array(Array &p_arr) const override;
491
492
public:
493
void set_shape(Shape p_shape);
494
Shape get_shape() const;
495
496
void set_size(const float p_size);
497
float get_size() const;
498
499
void set_sections(const int p_sections);
500
int get_sections() const;
501
502
void set_section_length(float p_sectionlength);
503
float get_section_length() const;
504
505
void set_section_segments(const int p_section_segments);
506
int get_section_segments() const;
507
508
void set_curve(const Ref<Curve> &p_curve);
509
Ref<Curve> get_curve() const;
510
511
virtual int get_builtin_bind_pose_count() const override;
512
virtual Transform3D get_builtin_bind_pose(int p_index) const override;
513
514
RibbonTrailMesh();
515
};
516
517
/**
518
Text...
519
*/
520
521
class TextMesh : public PrimitiveMesh {
522
GDCLASS(TextMesh, PrimitiveMesh);
523
524
private:
525
struct ContourPoint {
526
Vector2 point;
527
bool sharp = false;
528
529
ContourPoint() {}
530
ContourPoint(const Vector2 &p_pt, bool p_sharp) {
531
point = p_pt;
532
sharp = p_sharp;
533
}
534
};
535
536
struct ContourInfo {
537
real_t length = 0.0;
538
bool ccw = true;
539
ContourInfo() {}
540
ContourInfo(real_t p_len, bool p_ccw) {
541
length = p_len;
542
ccw = p_ccw;
543
}
544
};
545
546
struct GlyphMeshKey {
547
uint64_t font_id;
548
uint32_t gl_id;
549
550
bool operator==(const GlyphMeshKey &p_b) const {
551
return (font_id == p_b.font_id) && (gl_id == p_b.gl_id);
552
}
553
554
GlyphMeshKey(uint64_t p_font_id, uint32_t p_gl_id) {
555
font_id = p_font_id;
556
gl_id = p_gl_id;
557
}
558
};
559
560
struct GlyphMeshKeyHasher {
561
_FORCE_INLINE_ static uint32_t hash(const GlyphMeshKey &p_a) {
562
return hash_murmur3_buffer(&p_a, sizeof(GlyphMeshKey));
563
}
564
};
565
566
struct GlyphMeshData {
567
Vector<Vector2> triangles;
568
Vector<Vector<ContourPoint>> contours;
569
Vector<ContourInfo> contours_info;
570
Vector2 min_p = Vector2(Math::INF, Math::INF);
571
Vector2 max_p = Vector2(-Math::INF, -Math::INF);
572
};
573
mutable HashMap<GlyphMeshKey, GlyphMeshData, GlyphMeshKeyHasher> cache;
574
575
RID text_rid;
576
mutable Vector<RID> lines_rid;
577
578
String text;
579
String xl_text;
580
581
int font_size = 16;
582
Ref<Font> font_override;
583
584
TextServer::AutowrapMode autowrap_mode = TextServer::AUTOWRAP_OFF;
585
BitField<TextServer::JustificationFlag> jst_flags = TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_SKIP_LAST_LINE | TextServer::JUSTIFICATION_DO_NOT_SKIP_SINGLE_LINE;
586
float width = 500.0;
587
float line_spacing = 0.f;
588
Point2 lbl_offset;
589
590
HorizontalAlignment horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER;
591
VerticalAlignment vertical_alignment = VERTICAL_ALIGNMENT_CENTER;
592
bool uppercase = false;
593
String language;
594
TextServer::Direction text_direction = TextServer::DIRECTION_AUTO;
595
TextServer::StructuredTextParser st_parser = TextServer::STRUCTURED_TEXT_DEFAULT;
596
Array st_args;
597
598
real_t depth = 0.05;
599
real_t pixel_size = 0.01;
600
real_t curve_step = 0.5;
601
602
mutable bool dirty_lines = true;
603
mutable bool dirty_text = true;
604
mutable bool dirty_font = true;
605
mutable bool dirty_cache = true;
606
607
void _generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph &p_glyph) const;
608
void _font_changed();
609
610
protected:
611
static void _bind_methods();
612
void _notification(int p_what);
613
614
virtual void _create_mesh_array(Array &p_arr) const override;
615
616
public:
617
GDVIRTUAL2RC(TypedArray<Vector3i>, _structured_text_parser, Array, String)
618
619
TextMesh();
620
~TextMesh();
621
622
void set_horizontal_alignment(HorizontalAlignment p_alignment);
623
HorizontalAlignment get_horizontal_alignment() const;
624
625
void set_vertical_alignment(VerticalAlignment p_alignment);
626
VerticalAlignment get_vertical_alignment() const;
627
628
void set_text(const String &p_string);
629
String get_text() const;
630
631
void set_font(const Ref<Font> &p_font);
632
Ref<Font> get_font() const;
633
Ref<Font> _get_font_or_default() const;
634
635
void set_font_size(int p_size);
636
int get_font_size() const;
637
638
void set_line_spacing(float p_size);
639
float get_line_spacing() const;
640
641
void set_autowrap_mode(TextServer::AutowrapMode p_mode);
642
TextServer::AutowrapMode get_autowrap_mode() const;
643
644
void set_justification_flags(BitField<TextServer::JustificationFlag> p_flags);
645
BitField<TextServer::JustificationFlag> get_justification_flags() const;
646
647
void set_text_direction(TextServer::Direction p_text_direction);
648
TextServer::Direction get_text_direction() const;
649
650
void set_language(const String &p_language);
651
String get_language() const;
652
653
void set_structured_text_bidi_override(TextServer::StructuredTextParser p_parser);
654
TextServer::StructuredTextParser get_structured_text_bidi_override() const;
655
656
void set_structured_text_bidi_override_options(Array p_args);
657
Array get_structured_text_bidi_override_options() const;
658
659
void set_uppercase(bool p_uppercase);
660
bool is_uppercase() const;
661
662
void set_width(real_t p_width);
663
real_t get_width() const;
664
665
void set_depth(real_t p_depth);
666
real_t get_depth() const;
667
668
void set_curve_step(real_t p_step);
669
real_t get_curve_step() const;
670
671
void set_pixel_size(real_t p_amount);
672
real_t get_pixel_size() const;
673
674
void set_offset(const Point2 &p_offset);
675
Point2 get_offset() const;
676
};
677
678
VARIANT_ENUM_CAST(RibbonTrailMesh::Shape)
679
680