summaryrefslogtreecommitdiff
path: root/modules/csg/csg_shape.h
blob: c1d2cce60600ebfaa118ca040e5f8999e38af58d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
#ifndef CSG_SHAPE_H
#define CSG_SHAPE_H

#define CSGJS_HEADER_ONLY

#include "csg.h"
#include "scene/3d/visual_instance.h"
#include "scene/resources/concave_polygon_shape.h"

class CSGShape : public VisualInstance {
	GDCLASS(CSGShape, VisualInstance);

public:
	enum Operation {
		OPERATION_UNION,
		OPERATION_INTERSECTION,
		OPERATION_SUBTRACTION,

	};

private:
	Operation operation;
	CSGShape *parent;

	CSGBrush *brush;

	AABB node_aabb;

	bool dirty;
	float snap;

	bool use_collision;
	Ref<ConcavePolygonShape> root_collision_shape;
	RID root_collision_instance;

	Ref<ArrayMesh> root_mesh;

	struct Vector3Hasher {
		_ALWAYS_INLINE_ uint32_t hash(const Vector3 &p_vec3) const {
			uint32_t h = hash_djb2_one_float(p_vec3.x);
			h = hash_djb2_one_float(p_vec3.y, h);
			h = hash_djb2_one_float(p_vec3.z, h);
			return h;
		}
	};

	struct ShapeUpdateSurface {
		PoolVector<Vector3> vertices;
		PoolVector<Vector3> normals;
		PoolVector<Vector2> uvs;
		Ref<Material> material;
		int last_added;

		PoolVector<Vector3>::Write verticesw;
		PoolVector<Vector3>::Write normalsw;
		PoolVector<Vector2>::Write uvsw;
	};

	void _update_shape();

protected:
	void _notification(int p_what);
	virtual CSGBrush *_build_brush() = 0;
	void _make_dirty();

	static void _bind_methods();

	friend class CSGCombiner;
	CSGBrush *_get_brush();

	virtual void _validate_property(PropertyInfo &property) const;

public:
	void set_operation(Operation p_operation);
	Operation get_operation() const;

	virtual PoolVector<Vector3> get_brush_faces();

	virtual AABB get_aabb() const;
	virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const;

	void set_use_collision(bool p_enable);
	bool is_using_collision() const;

	void set_snap(float p_snap);
	float get_snap() const;

	bool is_root_shape() const;
	CSGShape();
	~CSGShape();
};

VARIANT_ENUM_CAST(CSGShape::Operation)

class CSGCombiner : public CSGShape {
	GDCLASS(CSGCombiner, CSGShape)
private:
	virtual CSGBrush *_build_brush();

public:
	CSGCombiner();
};

class CSGPrimitive : public CSGShape {
	GDCLASS(CSGPrimitive, CSGShape)

private:
	bool invert_faces;

protected:
	CSGBrush *_create_brush_from_arrays(const PoolVector<Vector3> &p_vertices, const PoolVector<Vector2> &p_uv, const PoolVector<bool> &p_smooth, const PoolVector<Ref<Material> > &p_materials);
	static void _bind_methods();

public:
	void set_invert_faces(bool p_invert);
	bool is_inverting_faces();

	CSGPrimitive();
};

class CSGMesh : public CSGPrimitive {
	GDCLASS(CSGMesh, CSGPrimitive)

	virtual CSGBrush *_build_brush();

	Ref<Mesh> mesh;

	void _mesh_changed();

protected:
	static void _bind_methods();

public:
	void set_mesh(const Ref<Mesh> &p_mesh);
	Ref<Mesh> get_mesh();
};

class CSGSphere : public CSGPrimitive {

	GDCLASS(CSGSphere, CSGPrimitive)
	virtual CSGBrush *_build_brush();

	Ref<Material> material;
	bool smooth_faces;
	float radius;
	int radial_segments;
	int rings;

protected:
	static void _bind_methods();

public:
	void set_radius(const float p_radius);
	float get_radius() const;

	void set_radial_segments(const int p_radial_segments);
	int get_radial_segments() const;

	void set_rings(const int p_rings);
	int get_rings() const;

	void set_material(const Ref<Material> &p_material);
	Ref<Material> get_material() const;

	void set_smooth_faces(bool p_smooth_faces);
	bool get_smooth_faces() const;

	CSGSphere();
};

class CSGBox : public CSGPrimitive {

	GDCLASS(CSGBox, CSGPrimitive)
	virtual CSGBrush *_build_brush();

	Ref<Material> material;
	float width;
	float height;
	float depth;

protected:
	static void _bind_methods();

public:
	void set_width(const float p_width);
	float get_width() const;

	void set_height(const float p_height);
	float get_height() const;

	void set_depth(const float p_depth);
	float get_depth() const;

	void set_material(const Ref<Material> &p_material);
	Ref<Material> get_material() const;

	CSGBox();
};

class CSGCylinder : public CSGPrimitive {

	GDCLASS(CSGCylinder, CSGPrimitive)
	virtual CSGBrush *_build_brush();

	Ref<Material> material;
	float radius;
	float height;
	int sides;
	bool cone;
	bool smooth_faces;

protected:
	static void _bind_methods();

public:
	void set_radius(const float p_radius);
	float get_radius() const;

	void set_height(const float p_height);
	float get_height() const;

	void set_sides(const int p_sides);
	int get_sides() const;

	void set_cone(const bool p_cone);
	bool is_cone() const;

	void set_smooth_faces(bool p_smooth_faces);
	bool get_smooth_faces() const;

	void set_material(const Ref<Material> &p_material);
	Ref<Material> get_material() const;

	CSGCylinder();
};

class CSGTorus : public CSGPrimitive {

	GDCLASS(CSGTorus, CSGPrimitive)
	virtual CSGBrush *_build_brush();

	Ref<Material> material;
	float inner_radius;
	float outer_radius;
	int sides;
	int ring_sides;
	bool smooth_faces;

protected:
	static void _bind_methods();

public:
	void set_inner_radius(const float p_inner_radius);
	float get_inner_radius() const;

	void set_outer_radius(const float p_outer_radius);
	float get_outer_radius() const;

	void set_sides(const int p_sides);
	int get_sides() const;

	void set_ring_sides(const int p_ring_sides);
	int get_ring_sides() const;

	void set_smooth_faces(bool p_smooth_faces);
	bool get_smooth_faces() const;

	void set_material(const Ref<Material> &p_material);
	Ref<Material> get_material() const;

	CSGTorus();
};

class CSGPolygon : public CSGPrimitive {

	GDCLASS(CSGPolygon, CSGPrimitive)

public:
	enum Mode {
		MODE_DEPTH,
		MODE_SPIN,
		MODE_PATH
	};

	enum PathRotation {
		PATH_ROTATION_POLYGON,
		PATH_ROTATION_PATH,
		PATH_ROTATION_PATH_FOLLOW,
	};

private:
	virtual CSGBrush *_build_brush();

	Vector<Vector2> polygon;
	Ref<Material> material;

	Mode mode;

	float depth;

	float spin_degrees;
	int spin_sides;

	NodePath path_node;
	float path_interval;
	PathRotation path_rotation;

	Node *path_cache;

	bool smooth_faces;

	bool _is_editable_3d_polygon() const;
	bool _has_editable_3d_polygon_no_depth() const;

	void _path_changed();
	void _path_exited();

protected:
	static void _bind_methods();
	virtual void _validate_property(PropertyInfo &property) const;
	void _notification(int p_what);

public:
	void set_polygon(const Vector<Vector2> &p_polygon);
	Vector<Vector2> get_polygon() const;

	void set_mode(Mode p_mode);
	Mode get_mode() const;

	void set_depth(float p_depth);
	float get_depth() const;

	void set_spin_degrees(float p_spin_degrees);
	float get_spin_degrees() const;

	void set_spin_sides(int p_sides);
	int get_spin_sides() const;

	void set_path_node(const NodePath &p_path);
	NodePath get_path_node() const;

	void set_path_interval(float p_interval);
	float get_path_interval() const;

	void set_path_rotation(PathRotation p_rotation);
	PathRotation get_path_rotation() const;

	void set_smooth_faces(bool p_smooth_faces);
	bool get_smooth_faces() const;

	void set_material(const Ref<Material> &p_material);
	Ref<Material> get_material() const;

	CSGPolygon();
};

VARIANT_ENUM_CAST(CSGPolygon::Mode)
VARIANT_ENUM_CAST(CSGPolygon::PathRotation)

#endif // CSG_SHAPE_H