1 /*************************************************************************/ 2 /* shape_sw.h */ 3 /*************************************************************************/ 4 /* This file is part of: */ 5 /* GODOT ENGINE */ 6 /* https://godotengine.org */ 7 /*************************************************************************/ 8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ 9 /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ 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 SHAPE_SW_H 31 #define SHAPE_SW_H 32 33 #include "bsp_tree.h" 34 #include "geometry.h" 35 #include "servers/physics_server.h" 36 /* 37 38 SHAPE_LINE, ///< plane:"plane" 39 SHAPE_SEGMENT, ///< float:"length" 40 SHAPE_CIRCLE, ///< float:"radius" 41 SHAPE_RECTANGLE, ///< vec3:"extents" 42 SHAPE_CONVEX_POLYGON, ///< array of planes:"planes" 43 SHAPE_CONCAVE_POLYGON, ///< Vector3 array:"triangles" , or Dictionary with "indices" (int array) and "triangles" (Vector3 array) 44 SHAPE_CUSTOM, ///< Server-Implementation based custom shape, calling shape_create() with this value will result in an error 45 46 */ 47 48 class ShapeSW; 49 50 class ShapeOwnerSW { 51 public: 52 virtual void _shape_changed() = 0; 53 virtual void remove_shape(ShapeSW *p_shape) = 0; 54 ~ShapeOwnerSW()55 virtual ~ShapeOwnerSW() {} 56 }; 57 58 class ShapeSW { 59 60 RID self; 61 AABB aabb; 62 bool configured; 63 real_t custom_bias; 64 65 Map<ShapeOwnerSW *, int> owners; 66 67 protected: 68 void configure(const AABB &p_aabb); 69 70 public: 71 enum { 72 MAX_SUPPORTS = 8 73 }; 74 set_self(const RID & p_self)75 _FORCE_INLINE_ void set_self(const RID &p_self) { self = p_self; } get_self()76 _FORCE_INLINE_ RID get_self() const { return self; } 77 78 virtual PhysicsServer::ShapeType get_type() const = 0; 79 get_aabb()80 _FORCE_INLINE_ AABB get_aabb() const { return aabb; } is_configured()81 _FORCE_INLINE_ bool is_configured() const { return configured; } 82 is_concave()83 virtual bool is_concave() const { return false; } 84 85 virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const = 0; 86 virtual Vector3 get_support(const Vector3 &p_normal) const; 87 virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const = 0; 88 89 virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal) const = 0; 90 virtual Vector3 get_moment_of_inertia(float p_mass) const = 0; 91 92 virtual void set_data(const Variant &p_data) = 0; 93 virtual Variant get_data() const = 0; 94 set_custom_bias(real_t p_bias)95 _FORCE_INLINE_ void set_custom_bias(real_t p_bias) { custom_bias = p_bias; } get_custom_bias()96 _FORCE_INLINE_ real_t get_custom_bias() const { return custom_bias; } 97 98 void add_owner(ShapeOwnerSW *p_owner); 99 void remove_owner(ShapeOwnerSW *p_owner); 100 bool is_owner(ShapeOwnerSW *p_owner) const; 101 const Map<ShapeOwnerSW *, int> &get_owners() const; 102 103 ShapeSW(); 104 virtual ~ShapeSW(); 105 }; 106 107 class ConcaveShapeSW : public ShapeSW { 108 109 public: is_concave()110 virtual bool is_concave() const { return true; } 111 typedef void (*Callback)(void *p_userdata, ShapeSW *p_convex); get_supports(const Vector3 & p_normal,int p_max,Vector3 * r_supports,int & r_amount)112 virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { r_amount = 0; } 113 114 virtual void cull(const AABB &p_local_aabb, Callback p_callback, void *p_userdata) const = 0; 115 ConcaveShapeSW()116 ConcaveShapeSW() {} 117 }; 118 119 class PlaneShapeSW : public ShapeSW { 120 121 Plane plane; 122 123 void _setup(const Plane &p_plane); 124 125 public: 126 Plane get_plane() const; 127 get_type()128 virtual PhysicsServer::ShapeType get_type() const { return PhysicsServer::SHAPE_PLANE; } 129 virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; 130 virtual Vector3 get_support(const Vector3 &p_normal) const; get_supports(const Vector3 & p_normal,int p_max,Vector3 * r_supports,int & r_amount)131 virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { r_amount = 0; } 132 133 virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; 134 135 virtual Vector3 get_moment_of_inertia(float p_mass) const; 136 137 virtual void set_data(const Variant &p_data); 138 virtual Variant get_data() const; 139 140 PlaneShapeSW(); 141 }; 142 143 class RayShapeSW : public ShapeSW { 144 145 float length; 146 147 void _setup(float p_length); 148 149 public: 150 float get_length() const; 151 get_type()152 virtual PhysicsServer::ShapeType get_type() const { return PhysicsServer::SHAPE_RAY; } 153 virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; 154 virtual Vector3 get_support(const Vector3 &p_normal) const; 155 virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const; 156 157 virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; 158 159 virtual Vector3 get_moment_of_inertia(float p_mass) const; 160 161 virtual void set_data(const Variant &p_data); 162 virtual Variant get_data() const; 163 164 RayShapeSW(); 165 }; 166 167 class SphereShapeSW : public ShapeSW { 168 169 real_t radius; 170 171 void _setup(real_t p_radius); 172 173 public: 174 real_t get_radius() const; 175 get_type()176 virtual PhysicsServer::ShapeType get_type() const { return PhysicsServer::SHAPE_SPHERE; } 177 178 virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; 179 virtual Vector3 get_support(const Vector3 &p_normal) const; 180 virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const; 181 virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; 182 183 virtual Vector3 get_moment_of_inertia(float p_mass) const; 184 185 virtual void set_data(const Variant &p_data); 186 virtual Variant get_data() const; 187 188 SphereShapeSW(); 189 }; 190 191 class BoxShapeSW : public ShapeSW { 192 193 Vector3 half_extents; 194 void _setup(const Vector3 &p_half_extents); 195 196 public: get_half_extents()197 _FORCE_INLINE_ Vector3 get_half_extents() const { return half_extents; } 198 get_type()199 virtual PhysicsServer::ShapeType get_type() const { return PhysicsServer::SHAPE_BOX; } 200 201 virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; 202 virtual Vector3 get_support(const Vector3 &p_normal) const; 203 virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const; 204 virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; 205 206 virtual Vector3 get_moment_of_inertia(float p_mass) const; 207 208 virtual void set_data(const Variant &p_data); 209 virtual Variant get_data() const; 210 211 BoxShapeSW(); 212 }; 213 214 class CapsuleShapeSW : public ShapeSW { 215 216 real_t height; 217 real_t radius; 218 219 void _setup(real_t p_height, real_t p_radius); 220 221 public: get_height()222 _FORCE_INLINE_ real_t get_height() const { return height; } get_radius()223 _FORCE_INLINE_ real_t get_radius() const { return radius; } 224 get_type()225 virtual PhysicsServer::ShapeType get_type() const { return PhysicsServer::SHAPE_CAPSULE; } 226 227 virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; 228 virtual Vector3 get_support(const Vector3 &p_normal) const; 229 virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const; 230 virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; 231 232 virtual Vector3 get_moment_of_inertia(float p_mass) const; 233 234 virtual void set_data(const Variant &p_data); 235 virtual Variant get_data() const; 236 237 CapsuleShapeSW(); 238 }; 239 240 struct ConvexPolygonShapeSW : public ShapeSW { 241 242 Geometry::MeshData mesh; 243 244 void _setup(const Vector<Vector3> &p_vertices); 245 246 public: get_meshConvexPolygonShapeSW247 const Geometry::MeshData &get_mesh() const { return mesh; } 248 get_typeConvexPolygonShapeSW249 virtual PhysicsServer::ShapeType get_type() const { return PhysicsServer::SHAPE_CONVEX_POLYGON; } 250 251 virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; 252 virtual Vector3 get_support(const Vector3 &p_normal) const; 253 virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const; 254 virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; 255 256 virtual Vector3 get_moment_of_inertia(float p_mass) const; 257 258 virtual void set_data(const Variant &p_data); 259 virtual Variant get_data() const; 260 261 ConvexPolygonShapeSW(); 262 }; 263 264 struct _VolumeSW_BVH; 265 struct FaceShapeSW; 266 267 struct ConcavePolygonShapeSW : public ConcaveShapeSW { 268 // always a trimesh 269 270 struct Face { 271 272 Vector3 normal; 273 int indices[3]; 274 }; 275 276 DVector<Face> faces; 277 DVector<Vector3> vertices; 278 279 struct BVH { 280 281 AABB aabb; 282 int left; 283 int right; 284 285 int face_index; 286 }; 287 288 DVector<BVH> bvh; 289 290 struct _CullParams { 291 292 AABB aabb; 293 Callback callback; 294 void *userdata; 295 const Face *faces; 296 const Vector3 *vertices; 297 const BVH *bvh; 298 FaceShapeSW *face; 299 }; 300 301 struct _SegmentCullParams { 302 303 Vector3 from; 304 Vector3 to; 305 const Face *faces; 306 const Vector3 *vertices; 307 const BVH *bvh; 308 Vector3 dir; 309 310 Vector3 result; 311 Vector3 normal; 312 real_t min_d; 313 int collisions; 314 }; 315 316 void _cull_segment(int p_idx, _SegmentCullParams *p_params) const; 317 void _cull(int p_idx, _CullParams *p_params) const; 318 319 void _fill_bvh(_VolumeSW_BVH *p_bvh_tree, BVH *p_bvh_array, int &p_idx); 320 321 void _setup(DVector<Vector3> p_faces); 322 323 public: 324 DVector<Vector3> get_faces() const; 325 get_typeConcavePolygonShapeSW326 virtual PhysicsServer::ShapeType get_type() const { return PhysicsServer::SHAPE_CONCAVE_POLYGON; } 327 328 virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; 329 virtual Vector3 get_support(const Vector3 &p_normal) const; 330 331 virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; 332 333 virtual void cull(const AABB &p_local_aabb, Callback p_callback, void *p_userdata) const; 334 335 virtual Vector3 get_moment_of_inertia(float p_mass) const; 336 337 virtual void set_data(const Variant &p_data); 338 virtual Variant get_data() const; 339 340 ConcavePolygonShapeSW(); 341 }; 342 343 struct HeightMapShapeSW : public ConcaveShapeSW { 344 345 DVector<real_t> heights; 346 int width; 347 int depth; 348 float cell_size; 349 350 // void _cull_segment(int p_idx,_SegmentCullParams *p_params) const; 351 // void _cull(int p_idx,_CullParams *p_params) const; 352 353 void _setup(DVector<float> p_heights, int p_width, int p_depth, float p_cell_size); 354 355 public: 356 DVector<real_t> get_heights() const; 357 int get_width() const; 358 int get_depth() const; 359 float get_cell_size() const; 360 get_typeHeightMapShapeSW361 virtual PhysicsServer::ShapeType get_type() const { return PhysicsServer::SHAPE_HEIGHTMAP; } 362 363 virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; 364 virtual Vector3 get_support(const Vector3 &p_normal) const; 365 virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; 366 367 virtual void cull(const AABB &p_local_aabb, Callback p_callback, void *p_userdata) const; 368 369 virtual Vector3 get_moment_of_inertia(float p_mass) const; 370 371 virtual void set_data(const Variant &p_data); 372 virtual Variant get_data() const; 373 374 HeightMapShapeSW(); 375 }; 376 377 //used internally 378 struct FaceShapeSW : public ShapeSW { 379 380 Vector3 normal; //cache 381 Vector3 vertex[3]; 382 get_typeFaceShapeSW383 virtual PhysicsServer::ShapeType get_type() const { return PhysicsServer::SHAPE_CONCAVE_POLYGON; } 384 get_vertexFaceShapeSW385 const Vector3 &get_vertex(int p_idx) const { return vertex[p_idx]; } 386 387 void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; 388 Vector3 get_support(const Vector3 &p_normal) const; 389 virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const; 390 bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const; 391 392 Vector3 get_moment_of_inertia(float p_mass) const; 393 set_dataFaceShapeSW394 virtual void set_data(const Variant &p_data) {} get_dataFaceShapeSW395 virtual Variant get_data() const { return Variant(); } 396 397 FaceShapeSW(); 398 }; 399 400 struct MotionShapeSW : public ShapeSW { 401 402 ShapeSW *shape; 403 Vector3 motion; 404 get_typeMotionShapeSW405 virtual PhysicsServer::ShapeType get_type() const { return PhysicsServer::SHAPE_CONVEX_POLYGON; } 406 project_rangeMotionShapeSW407 void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { 408 409 Vector3 cast = p_transform.basis.xform(motion); 410 real_t mina, maxa; 411 real_t minb, maxb; 412 Transform ofsb = p_transform; 413 ofsb.origin += cast; 414 shape->project_range(p_normal, p_transform, mina, maxa); 415 shape->project_range(p_normal, ofsb, minb, maxb); 416 r_min = MIN(mina, minb); 417 r_max = MAX(maxa, maxb); 418 } 419 get_supportMotionShapeSW420 Vector3 get_support(const Vector3 &p_normal) const { 421 422 Vector3 support = shape->get_support(p_normal); 423 if (p_normal.dot(motion) > 0) { 424 support += motion; 425 } 426 return support; 427 } get_supportsMotionShapeSW428 virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { r_amount = 0; } intersect_segmentMotionShapeSW429 bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { return false; } 430 get_moment_of_inertiaMotionShapeSW431 Vector3 get_moment_of_inertia(float p_mass) const { return Vector3(); } 432 set_dataMotionShapeSW433 virtual void set_data(const Variant &p_data) {} get_dataMotionShapeSW434 virtual Variant get_data() const { return Variant(); } 435 MotionShapeSWMotionShapeSW436 MotionShapeSW() { configure(AABB()); } 437 }; 438 439 struct _ShapeTestConvexBSPSW { 440 441 const BSP_Tree *bsp; 442 const ShapeSW *shape; 443 Transform transform; 444 project_range_ShapeTestConvexBSPSW445 _FORCE_INLINE_ void project_range(const Vector3 &p_normal, real_t &r_min, real_t &r_max) const { 446 447 shape->project_range(p_normal, transform, r_min, r_max); 448 } 449 }; 450 451 #endif // SHAPESW_H 452