primitive_meshes.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  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. #ifndef PRIMITIVE_MESHES_H
  31. #define PRIMITIVE_MESHES_H
  32. #include "scene/resources/font.h"
  33. #include "scene/resources/mesh.h"
  34. #include "servers/text_server.h"
  35. ///@TODO probably should change a few integers to unsigned integers...
  36. /**
  37. Base class for all the classes in this file, handles a number of code functions that are shared among all meshes.
  38. This class is set apart that it assumes a single surface is always generated for our mesh.
  39. */
  40. class PrimitiveMesh : public Mesh {
  41. GDCLASS(PrimitiveMesh, Mesh);
  42. private:
  43. RID mesh;
  44. mutable AABB aabb;
  45. AABB custom_aabb;
  46. mutable int array_len = 0;
  47. mutable int index_array_len = 0;
  48. Ref<Material> material;
  49. bool flip_faces = false;
  50. bool add_uv2 = false;
  51. float uv2_padding = 2.0;
  52. // make sure we do an update after we've finished constructing our object
  53. mutable bool pending_request = true;
  54. void _update() const;
  55. protected:
  56. // assume primitive triangles as the type, correct for all but one and it will change this :)
  57. Mesh::PrimitiveType primitive_type = Mesh::PRIMITIVE_TRIANGLES;
  58. // Copy of our texel_size project setting.
  59. float texel_size = 0.2;
  60. static void _bind_methods();
  61. virtual void _create_mesh_array(Array &p_arr) const {}
  62. GDVIRTUAL0RC(Array, _create_mesh_array)
  63. Vector2 get_uv2_scale(Vector2 p_margin_scale = Vector2(1.0, 1.0)) const;
  64. float get_lightmap_texel_size() const;
  65. virtual void _update_lightmap_size() {}
  66. void _on_settings_changed();
  67. public:
  68. virtual int get_surface_count() const override;
  69. virtual int surface_get_array_len(int p_idx) const override;
  70. virtual int surface_get_array_index_len(int p_idx) const override;
  71. virtual Array surface_get_arrays(int p_surface) const override;
  72. virtual TypedArray<Array> surface_get_blend_shape_arrays(int p_surface) const override;
  73. virtual Dictionary surface_get_lods(int p_surface) const override;
  74. virtual BitField<ArrayFormat> surface_get_format(int p_idx) const override;
  75. virtual Mesh::PrimitiveType surface_get_primitive_type(int p_idx) const override;
  76. virtual void surface_set_material(int p_idx, const Ref<Material> &p_material) override;
  77. virtual Ref<Material> surface_get_material(int p_idx) const override;
  78. virtual int get_blend_shape_count() const override;
  79. virtual StringName get_blend_shape_name(int p_index) const override;
  80. virtual void set_blend_shape_name(int p_index, const StringName &p_name) override;
  81. virtual AABB get_aabb() const override;
  82. virtual RID get_rid() const override;
  83. void set_material(const Ref<Material> &p_material);
  84. Ref<Material> get_material() const;
  85. Array get_mesh_arrays() const;
  86. void set_custom_aabb(const AABB &p_custom);
  87. AABB get_custom_aabb() const;
  88. void set_flip_faces(bool p_enable);
  89. bool get_flip_faces() const;
  90. void set_add_uv2(bool p_enable);
  91. bool get_add_uv2() const { return add_uv2; }
  92. void set_uv2_padding(float p_padding);
  93. float get_uv2_padding() const { return uv2_padding; }
  94. void request_update();
  95. PrimitiveMesh();
  96. ~PrimitiveMesh();
  97. };
  98. /**
  99. Mesh for a simple capsule
  100. */
  101. class CapsuleMesh : public PrimitiveMesh {
  102. GDCLASS(CapsuleMesh, PrimitiveMesh);
  103. private:
  104. float radius = 0.5;
  105. float height = 2.0;
  106. int radial_segments = 64;
  107. int rings = 8;
  108. protected:
  109. static void _bind_methods();
  110. virtual void _create_mesh_array(Array &p_arr) const override;
  111. virtual void _update_lightmap_size() override;
  112. public:
  113. 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);
  114. void set_radius(const float p_radius);
  115. float get_radius() const;
  116. void set_height(const float p_height);
  117. float get_height() const;
  118. void set_radial_segments(const int p_segments);
  119. int get_radial_segments() const;
  120. void set_rings(const int p_rings);
  121. int get_rings() const;
  122. CapsuleMesh();
  123. };
  124. /**
  125. A box
  126. */
  127. class BoxMesh : public PrimitiveMesh {
  128. GDCLASS(BoxMesh, PrimitiveMesh);
  129. private:
  130. Vector3 size = Vector3(1, 1, 1);
  131. int subdivide_w = 0;
  132. int subdivide_h = 0;
  133. int subdivide_d = 0;
  134. protected:
  135. static void _bind_methods();
  136. virtual void _create_mesh_array(Array &p_arr) const override;
  137. virtual void _update_lightmap_size() override;
  138. public:
  139. 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);
  140. void set_size(const Vector3 &p_size);
  141. Vector3 get_size() const;
  142. void set_subdivide_width(const int p_divisions);
  143. int get_subdivide_width() const;
  144. void set_subdivide_height(const int p_divisions);
  145. int get_subdivide_height() const;
  146. void set_subdivide_depth(const int p_divisions);
  147. int get_subdivide_depth() const;
  148. BoxMesh();
  149. };
  150. /**
  151. A cylinder
  152. */
  153. class CylinderMesh : public PrimitiveMesh {
  154. GDCLASS(CylinderMesh, PrimitiveMesh);
  155. private:
  156. float top_radius = 0.5;
  157. float bottom_radius = 0.5;
  158. float height = 2.0;
  159. int radial_segments = 64;
  160. int rings = 4;
  161. bool cap_top = true;
  162. bool cap_bottom = true;
  163. protected:
  164. static void _bind_methods();
  165. virtual void _create_mesh_array(Array &p_arr) const override;
  166. virtual void _update_lightmap_size() override;
  167. public:
  168. 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);
  169. void set_top_radius(const float p_radius);
  170. float get_top_radius() const;
  171. void set_bottom_radius(const float p_radius);
  172. float get_bottom_radius() const;
  173. void set_height(const float p_height);
  174. float get_height() const;
  175. void set_radial_segments(const int p_segments);
  176. int get_radial_segments() const;
  177. void set_rings(const int p_rings);
  178. int get_rings() const;
  179. void set_cap_top(bool p_cap_top);
  180. bool is_cap_top() const;
  181. void set_cap_bottom(bool p_cap_bottom);
  182. bool is_cap_bottom() const;
  183. CylinderMesh();
  184. };
  185. /*
  186. A flat rectangle, can be used as quad or heightmap.
  187. */
  188. class PlaneMesh : public PrimitiveMesh {
  189. GDCLASS(PlaneMesh, PrimitiveMesh);
  190. public:
  191. enum Orientation {
  192. FACE_X,
  193. FACE_Y,
  194. FACE_Z,
  195. };
  196. private:
  197. Size2 size = Size2(2.0, 2.0);
  198. int subdivide_w = 0;
  199. int subdivide_d = 0;
  200. Vector3 center_offset;
  201. Orientation orientation = FACE_Y;
  202. protected:
  203. static void _bind_methods();
  204. virtual void _create_mesh_array(Array &p_arr) const override;
  205. virtual void _update_lightmap_size() override;
  206. public:
  207. void set_size(const Size2 &p_size);
  208. Size2 get_size() const;
  209. void set_subdivide_width(const int p_divisions);
  210. int get_subdivide_width() const;
  211. void set_subdivide_depth(const int p_divisions);
  212. int get_subdivide_depth() const;
  213. void set_center_offset(const Vector3 p_offset);
  214. Vector3 get_center_offset() const;
  215. void set_orientation(const Orientation p_orientation);
  216. Orientation get_orientation() const;
  217. PlaneMesh();
  218. };
  219. VARIANT_ENUM_CAST(PlaneMesh::Orientation)
  220. /*
  221. A flat rectangle, inherits from PlaneMesh but defaults to facing the Z-plane.
  222. */
  223. class QuadMesh : public PlaneMesh {
  224. GDCLASS(QuadMesh, PlaneMesh);
  225. public:
  226. QuadMesh() {
  227. set_orientation(FACE_Z);
  228. set_size(Size2(1, 1));
  229. }
  230. };
  231. /**
  232. A prism shapen, handy for ramps, triangles, etc.
  233. */
  234. class PrismMesh : public PrimitiveMesh {
  235. GDCLASS(PrismMesh, PrimitiveMesh);
  236. private:
  237. float left_to_right = 0.5;
  238. Vector3 size = Vector3(1.0, 1.0, 1.0);
  239. int subdivide_w = 0;
  240. int subdivide_h = 0;
  241. int subdivide_d = 0;
  242. protected:
  243. static void _bind_methods();
  244. virtual void _create_mesh_array(Array &p_arr) const override;
  245. virtual void _update_lightmap_size() override;
  246. public:
  247. void set_left_to_right(const float p_left_to_right);
  248. float get_left_to_right() const;
  249. void set_size(const Vector3 &p_size);
  250. Vector3 get_size() const;
  251. void set_subdivide_width(const int p_divisions);
  252. int get_subdivide_width() const;
  253. void set_subdivide_height(const int p_divisions);
  254. int get_subdivide_height() const;
  255. void set_subdivide_depth(const int p_divisions);
  256. int get_subdivide_depth() const;
  257. PrismMesh();
  258. };
  259. /**
  260. A sphere..
  261. */
  262. class SphereMesh : public PrimitiveMesh {
  263. GDCLASS(SphereMesh, PrimitiveMesh);
  264. private:
  265. float radius = 0.5;
  266. float height = 1.0;
  267. int radial_segments = 64;
  268. int rings = 32;
  269. bool is_hemisphere = false;
  270. protected:
  271. static void _bind_methods();
  272. virtual void _create_mesh_array(Array &p_arr) const override;
  273. virtual void _update_lightmap_size() override;
  274. public:
  275. 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);
  276. void set_radius(const float p_radius);
  277. float get_radius() const;
  278. void set_height(const float p_height);
  279. float get_height() const;
  280. void set_radial_segments(const int p_radial_segments);
  281. int get_radial_segments() const;
  282. void set_rings(const int p_rings);
  283. int get_rings() const;
  284. void set_is_hemisphere(const bool p_is_hemisphere);
  285. bool get_is_hemisphere() const;
  286. SphereMesh();
  287. };
  288. /**
  289. Big donut
  290. */
  291. class TorusMesh : public PrimitiveMesh {
  292. GDCLASS(TorusMesh, PrimitiveMesh);
  293. private:
  294. float inner_radius = 0.5;
  295. float outer_radius = 1.0;
  296. int rings = 64;
  297. int ring_segments = 32;
  298. protected:
  299. static void _bind_methods();
  300. virtual void _create_mesh_array(Array &p_arr) const override;
  301. virtual void _update_lightmap_size() override;
  302. public:
  303. void set_inner_radius(const float p_inner_radius);
  304. float get_inner_radius() const;
  305. void set_outer_radius(const float p_outer_radius);
  306. float get_outer_radius() const;
  307. void set_rings(const int p_rings);
  308. int get_rings() const;
  309. void set_ring_segments(const int p_ring_segments);
  310. int get_ring_segments() const;
  311. TorusMesh();
  312. };
  313. /**
  314. A single point for use in particle systems
  315. */
  316. class PointMesh : public PrimitiveMesh {
  317. GDCLASS(PointMesh, PrimitiveMesh)
  318. protected:
  319. virtual void _create_mesh_array(Array &p_arr) const override;
  320. public:
  321. PointMesh();
  322. };
  323. class TubeTrailMesh : public PrimitiveMesh {
  324. GDCLASS(TubeTrailMesh, PrimitiveMesh);
  325. private:
  326. float radius = 0.5;
  327. int radial_steps = 8;
  328. int sections = 5;
  329. float section_length = 0.2;
  330. int section_rings = 3;
  331. bool cap_top = true;
  332. bool cap_bottom = true;
  333. Ref<Curve> curve;
  334. void _curve_changed();
  335. protected:
  336. static void _bind_methods();
  337. virtual void _create_mesh_array(Array &p_arr) const override;
  338. public:
  339. void set_radius(const float p_radius);
  340. float get_radius() const;
  341. void set_radial_steps(const int p_radial_steps);
  342. int get_radial_steps() const;
  343. void set_sections(const int p_sections);
  344. int get_sections() const;
  345. void set_section_length(float p_sectionlength);
  346. float get_section_length() const;
  347. void set_section_rings(const int p_section_rings);
  348. int get_section_rings() const;
  349. void set_cap_top(bool p_cap_top);
  350. bool is_cap_top() const;
  351. void set_cap_bottom(bool p_cap_bottom);
  352. bool is_cap_bottom() const;
  353. void set_curve(const Ref<Curve> &p_curve);
  354. Ref<Curve> get_curve() const;
  355. virtual int get_builtin_bind_pose_count() const override;
  356. virtual Transform3D get_builtin_bind_pose(int p_index) const override;
  357. TubeTrailMesh();
  358. };
  359. class RibbonTrailMesh : public PrimitiveMesh {
  360. GDCLASS(RibbonTrailMesh, PrimitiveMesh);
  361. public:
  362. enum Shape {
  363. SHAPE_FLAT,
  364. SHAPE_CROSS
  365. };
  366. private:
  367. float size = 1.0;
  368. int sections = 5;
  369. float section_length = 0.2;
  370. int section_segments = 3;
  371. Shape shape = SHAPE_CROSS;
  372. Ref<Curve> curve;
  373. void _curve_changed();
  374. protected:
  375. static void _bind_methods();
  376. virtual void _create_mesh_array(Array &p_arr) const override;
  377. public:
  378. void set_shape(Shape p_shape);
  379. Shape get_shape() const;
  380. void set_size(const float p_size);
  381. float get_size() const;
  382. void set_sections(const int p_sections);
  383. int get_sections() const;
  384. void set_section_length(float p_sectionlength);
  385. float get_section_length() const;
  386. void set_section_segments(const int p_section_segments);
  387. int get_section_segments() const;
  388. void set_curve(const Ref<Curve> &p_curve);
  389. Ref<Curve> get_curve() const;
  390. virtual int get_builtin_bind_pose_count() const override;
  391. virtual Transform3D get_builtin_bind_pose(int p_index) const override;
  392. RibbonTrailMesh();
  393. };
  394. /**
  395. Text...
  396. */
  397. class TextMesh : public PrimitiveMesh {
  398. GDCLASS(TextMesh, PrimitiveMesh);
  399. private:
  400. struct ContourPoint {
  401. Vector2 point;
  402. bool sharp = false;
  403. ContourPoint() {}
  404. ContourPoint(const Vector2 &p_pt, bool p_sharp) {
  405. point = p_pt;
  406. sharp = p_sharp;
  407. }
  408. };
  409. struct ContourInfo {
  410. real_t length = 0.0;
  411. bool ccw = true;
  412. ContourInfo() {}
  413. ContourInfo(real_t p_len, bool p_ccw) {
  414. length = p_len;
  415. ccw = p_ccw;
  416. }
  417. };
  418. struct GlyphMeshKey {
  419. uint64_t font_id;
  420. uint32_t gl_id;
  421. bool operator==(const GlyphMeshKey &p_b) const {
  422. return (font_id == p_b.font_id) && (gl_id == p_b.gl_id);
  423. }
  424. GlyphMeshKey(uint64_t p_font_id, uint32_t p_gl_id) {
  425. font_id = p_font_id;
  426. gl_id = p_gl_id;
  427. }
  428. };
  429. struct GlyphMeshKeyHasher {
  430. _FORCE_INLINE_ static uint32_t hash(const GlyphMeshKey &p_a) {
  431. return hash_murmur3_buffer(&p_a, sizeof(GlyphMeshKey));
  432. }
  433. };
  434. struct GlyphMeshData {
  435. Vector<Vector2> triangles;
  436. Vector<Vector<ContourPoint>> contours;
  437. Vector<ContourInfo> contours_info;
  438. Vector2 min_p = Vector2(INFINITY, INFINITY);
  439. Vector2 max_p = Vector2(-INFINITY, -INFINITY);
  440. };
  441. mutable HashMap<GlyphMeshKey, GlyphMeshData, GlyphMeshKeyHasher> cache;
  442. RID text_rid;
  443. mutable Vector<RID> lines_rid;
  444. String text;
  445. String xl_text;
  446. int font_size = 16;
  447. Ref<Font> font_override;
  448. TextServer::AutowrapMode autowrap_mode = TextServer::AUTOWRAP_OFF;
  449. BitField<TextServer::JustificationFlag> jst_flags = TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_SKIP_LAST_LINE | TextServer::JUSTIFICATION_DO_NOT_SKIP_SINGLE_LINE;
  450. float width = 500.0;
  451. float line_spacing = 0.f;
  452. Point2 lbl_offset;
  453. HorizontalAlignment horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER;
  454. VerticalAlignment vertical_alignment = VERTICAL_ALIGNMENT_CENTER;
  455. bool uppercase = false;
  456. String language;
  457. TextServer::Direction text_direction = TextServer::DIRECTION_AUTO;
  458. TextServer::StructuredTextParser st_parser = TextServer::STRUCTURED_TEXT_DEFAULT;
  459. Array st_args;
  460. real_t depth = 0.05;
  461. real_t pixel_size = 0.01;
  462. real_t curve_step = 0.5;
  463. mutable bool dirty_lines = true;
  464. mutable bool dirty_text = true;
  465. mutable bool dirty_font = true;
  466. mutable bool dirty_cache = true;
  467. void _generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph &p_glyph) const;
  468. void _font_changed();
  469. protected:
  470. static void _bind_methods();
  471. void _notification(int p_what);
  472. virtual void _create_mesh_array(Array &p_arr) const override;
  473. public:
  474. GDVIRTUAL2RC(TypedArray<Vector3i>, _structured_text_parser, Array, String)
  475. TextMesh();
  476. ~TextMesh();
  477. void set_horizontal_alignment(HorizontalAlignment p_alignment);
  478. HorizontalAlignment get_horizontal_alignment() const;
  479. void set_vertical_alignment(VerticalAlignment p_alignment);
  480. VerticalAlignment get_vertical_alignment() const;
  481. void set_text(const String &p_string);
  482. String get_text() const;
  483. void set_font(const Ref<Font> &p_font);
  484. Ref<Font> get_font() const;
  485. Ref<Font> _get_font_or_default() const;
  486. void set_font_size(int p_size);
  487. int get_font_size() const;
  488. void set_line_spacing(float p_size);
  489. float get_line_spacing() const;
  490. void set_autowrap_mode(TextServer::AutowrapMode p_mode);
  491. TextServer::AutowrapMode get_autowrap_mode() const;
  492. void set_justification_flags(BitField<TextServer::JustificationFlag> p_flags);
  493. BitField<TextServer::JustificationFlag> get_justification_flags() const;
  494. void set_text_direction(TextServer::Direction p_text_direction);
  495. TextServer::Direction get_text_direction() const;
  496. void set_language(const String &p_language);
  497. String get_language() const;
  498. void set_structured_text_bidi_override(TextServer::StructuredTextParser p_parser);
  499. TextServer::StructuredTextParser get_structured_text_bidi_override() const;
  500. void set_structured_text_bidi_override_options(Array p_args);
  501. Array get_structured_text_bidi_override_options() const;
  502. void set_uppercase(bool p_uppercase);
  503. bool is_uppercase() const;
  504. void set_width(real_t p_width);
  505. real_t get_width() const;
  506. void set_depth(real_t p_depth);
  507. real_t get_depth() const;
  508. void set_curve_step(real_t p_step);
  509. real_t get_curve_step() const;
  510. void set_pixel_size(real_t p_amount);
  511. real_t get_pixel_size() const;
  512. void set_offset(const Point2 &p_offset);
  513. Point2 get_offset() const;
  514. };
  515. VARIANT_ENUM_CAST(RibbonTrailMesh::Shape)
  516. #endif // PRIMITIVE_MESHES_H