| 
									
										
										
										
											2018-05-16 14:19:33 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  csg.h                                                                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							|  |  |  | /*                      https://godotengine.org                          */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2020-01-01 11:16:22 +01:00
										 |  |  | /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */ | 
					
						
							| 
									
										
										
										
											2018-05-16 14:19:33 -03:00
										 |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the       */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including   */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,   */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to    */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to */ | 
					
						
							|  |  |  | /* the following conditions:                                             */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be        */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.       */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | #ifndef CSG_H
 | 
					
						
							|  |  |  | #define CSG_H
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-29 07:34:49 +01:00
										 |  |  | #include "core/list.h"
 | 
					
						
							| 
									
										
										
										
											2018-09-11 18:13:45 +02:00
										 |  |  | #include "core/map.h"
 | 
					
						
							|  |  |  | #include "core/math/aabb.h"
 | 
					
						
							|  |  |  | #include "core/math/plane.h"
 | 
					
						
							|  |  |  | #include "core/math/transform.h"
 | 
					
						
							| 
									
										
										
										
											2019-12-29 07:34:49 +01:00
										 |  |  | #include "core/math/vector2.h"
 | 
					
						
							| 
									
										
										
										
											2018-09-11 18:13:45 +02:00
										 |  |  | #include "core/math/vector3.h"
 | 
					
						
							|  |  |  | #include "core/oa_hash_map.h"
 | 
					
						
							| 
									
										
										
										
											2019-02-12 13:30:56 +01:00
										 |  |  | #include "core/pool_vector.h"
 | 
					
						
							| 
									
										
										
										
											2019-12-29 07:34:49 +01:00
										 |  |  | #include "core/reference.h"
 | 
					
						
							|  |  |  | #include "core/vector.h"
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | #include "scene/resources/material.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct CSGBrush { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	struct Face { | 
					
						
							|  |  |  | 		Vector3 vertices[3]; | 
					
						
							|  |  |  | 		Vector2 uvs[3]; | 
					
						
							|  |  |  | 		AABB aabb; | 
					
						
							|  |  |  | 		bool smooth; | 
					
						
							|  |  |  | 		bool invert; | 
					
						
							|  |  |  | 		int material; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Vector<Face> faces; | 
					
						
							|  |  |  | 	Vector<Ref<Material> > materials; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-29 07:34:49 +01:00
										 |  |  | 	inline void _regen_face_aabbs(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Create a brush from faces.
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 	void build_from_faces(const PoolVector<Vector3> &p_vertices, const PoolVector<Vector2> &p_uvs, const PoolVector<bool> &p_smooth, const PoolVector<Ref<Material> > &p_materials, const PoolVector<bool> &p_invert_faces); | 
					
						
							|  |  |  | 	void copy_from(const CSGBrush &p_brush, const Transform &p_xform); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct CSGBrushOperation { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	enum Operation { | 
					
						
							|  |  |  | 		OPERATION_UNION, | 
					
						
							|  |  |  | 		OPERATION_INTERSECTION, | 
					
						
							|  |  |  | 		OPERATION_SUBSTRACTION, | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-29 07:34:49 +01:00
										 |  |  | 	void merge_brushes(Operation p_operation, const CSGBrush &p_brush_a, const CSGBrush &p_brush_b, CSGBrush &r_merged_brush, float p_vertex_snap); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 	struct MeshMerge { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-29 07:34:49 +01:00
										 |  |  | 		struct Face { | 
					
						
							|  |  |  | 			bool from_b; | 
					
						
							|  |  |  | 			bool inside; | 
					
						
							|  |  |  | 			int points[3]; | 
					
						
							|  |  |  | 			Vector2 uvs[3]; | 
					
						
							|  |  |  | 			bool smooth; | 
					
						
							|  |  |  | 			bool invert; | 
					
						
							|  |  |  | 			int material_idx; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		struct FaceBVH { | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 			int face; | 
					
						
							|  |  |  | 			int left; | 
					
						
							|  |  |  | 			int right; | 
					
						
							|  |  |  | 			int next; | 
					
						
							|  |  |  | 			Vector3 center; | 
					
						
							|  |  |  | 			AABB aabb; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-29 07:34:49 +01:00
										 |  |  | 		struct FaceBVHCmpX { | 
					
						
							|  |  |  | 			_FORCE_INLINE_ bool operator()(const FaceBVH *p_left, const FaceBVH *p_right) const { | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 				return p_left->center.x < p_right->center.x; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-29 07:34:49 +01:00
										 |  |  | 		struct FaceBVHCmpY { | 
					
						
							|  |  |  | 			_FORCE_INLINE_ bool operator()(const FaceBVH *p_left, const FaceBVH *p_right) const { | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 				return p_left->center.y < p_right->center.y; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2019-12-29 07:34:49 +01:00
										 |  |  | 		struct FaceBVHCmpZ { | 
					
						
							|  |  |  | 			_FORCE_INLINE_ bool operator()(const FaceBVH *p_left, const FaceBVH *p_right) const { | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 				return p_left->center.z < p_right->center.z; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		struct VertexKey { | 
					
						
							|  |  |  | 			int32_t x, y, z; | 
					
						
							|  |  |  | 			_FORCE_INLINE_ bool operator<(const VertexKey &p_key) const { | 
					
						
							|  |  |  | 				if (x == p_key.x) { | 
					
						
							|  |  |  | 					if (y == p_key.y) { | 
					
						
							|  |  |  | 						return z < p_key.z; | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						return y < p_key.y; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					return x < p_key.x; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			_FORCE_INLINE_ bool operator==(const VertexKey &p_key) const { | 
					
						
							|  |  |  | 				return (x == p_key.x && y == p_key.y && z == p_key.z); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		struct VertexKeyHash { | 
					
						
							|  |  |  | 			static _FORCE_INLINE_ uint32_t hash(const VertexKey &p_vk) { | 
					
						
							|  |  |  | 				uint32_t h = hash_djb2_one_32(p_vk.x); | 
					
						
							|  |  |  | 				h = hash_djb2_one_32(p_vk.y, h); | 
					
						
							|  |  |  | 				h = hash_djb2_one_32(p_vk.z, h); | 
					
						
							|  |  |  | 				return h; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Vector<Vector3> points; | 
					
						
							|  |  |  | 		Vector<Face> faces; | 
					
						
							|  |  |  | 		Map<Ref<Material>, int> materials; | 
					
						
							|  |  |  | 		Map<Vector3, int> vertex_map; | 
					
						
							| 
									
										
										
										
											2019-12-29 07:34:49 +01:00
										 |  |  | 		OAHashMap<VertexKey, int, VertexKeyHash> snap_cache; | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 		float vertex_snap; | 
					
						
							| 
									
										
										
										
											2019-12-29 07:34:49 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		inline void _add_distance(List<real_t> &r_intersectionsA, List<real_t> &r_intersectionsB, bool p_from_B, real_t p_distance) const; | 
					
						
							|  |  |  | 		inline bool _bvh_inside(FaceBVH *facebvhptr, int p_max_depth, int p_bvh_first, int p_face_idx) const; | 
					
						
							|  |  |  | 		inline int _create_bvh(FaceBVH *facebvhptr, FaceBVH **facebvhptrptr, int p_from, int p_size, int p_depth, int &r_max_depth, int &r_max_alloc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		void add_face(const Vector3 p_points[3], const Vector2 p_uvs[3], bool p_smooth, bool p_invert, const Ref<Material> &p_material, bool p_from_b); | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 		void mark_inside_faces(); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-29 07:34:49 +01:00
										 |  |  | 	struct Build2DFaces { | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-29 07:34:49 +01:00
										 |  |  | 		struct Vertex2D { | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 			Vector2 point; | 
					
						
							|  |  |  | 			Vector2 uv; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-29 07:34:49 +01:00
										 |  |  | 		struct Face2D { | 
					
						
							|  |  |  | 			int vertex_idx[3]; | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-29 07:34:49 +01:00
										 |  |  | 		Vector<Vertex2D> vertices; | 
					
						
							|  |  |  | 		Vector<Face2D> faces; | 
					
						
							|  |  |  | 		Plane plane; | 
					
						
							|  |  |  | 		Transform to_2D; | 
					
						
							|  |  |  | 		Transform to_3D; | 
					
						
							|  |  |  | 		float vertex_snap2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		inline int _get_point_idx(const Vector2 &p_point); | 
					
						
							|  |  |  | 		inline int _add_vertex(const Vertex2D &p_vertex); | 
					
						
							|  |  |  | 		inline void _add_vertex_idx_sorted(Vector<int> &r_vertex_indices, int p_new_vertex_index); | 
					
						
							|  |  |  | 		inline void _merge_faces(const Vector<int> &p_segment_indices); | 
					
						
							|  |  |  | 		inline void _find_edge_intersections(const Vector2 p_segment_points[2], Vector<int> &r_segment_indices); | 
					
						
							|  |  |  | 		inline int _insert_point(const Vector2 &p_point); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		void insert(const CSGBrush &p_brush, int p_brush_face); | 
					
						
							|  |  |  | 		void addFacesToMesh(MeshMerge &r_mesh_merge, bool p_smooth, bool p_invert, const Ref<Material> &p_material, bool p_from_b); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Build2DFaces() {} | 
					
						
							|  |  |  | 		Build2DFaces(const CSGBrush &p_brush, int p_brush_face, float p_vertex_snap2); | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-29 07:34:49 +01:00
										 |  |  | 	struct Build2DFaceCollection { | 
					
						
							|  |  |  | 		Map<int, Build2DFaces> build2DFacesA; | 
					
						
							|  |  |  | 		Map<int, Build2DFaces> build2DFacesB; | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-29 07:34:49 +01:00
										 |  |  | 	void update_faces(const CSGBrush &p_brush_a, const int p_face_idx_a, const CSGBrush &p_brush_b, const int p_face_idx_b, Build2DFaceCollection &p_collection, float p_vertex_snap); | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif // CSG_H
 |