bsp_tree.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. /**************************************************************************/
  2. /* bsp_tree.cpp */
  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. #include "bsp_tree.h"
  31. #include "core/error_macros.h"
  32. #include "core/print_string.h"
  33. void BSP_Tree::from_aabb(const AABB &p_aabb) {
  34. planes.clear();
  35. for (int i = 0; i < 3; i++) {
  36. Vector3 n;
  37. n[i] = 1;
  38. planes.push_back(Plane(n, p_aabb.position[i] + p_aabb.size[i]));
  39. planes.push_back(Plane(-n, -p_aabb.position[i]));
  40. }
  41. nodes.clear();
  42. for (int i = 0; i < 6; i++) {
  43. Node n;
  44. n.plane = i;
  45. n.under = (i == 0) ? UNDER_LEAF : i - 1;
  46. n.over = OVER_LEAF;
  47. nodes.push_back(n);
  48. }
  49. aabb = p_aabb;
  50. error_radius = 0;
  51. }
  52. Vector<BSP_Tree::Node> BSP_Tree::get_nodes() const {
  53. return nodes;
  54. }
  55. Vector<Plane> BSP_Tree::get_planes() const {
  56. return planes;
  57. }
  58. AABB BSP_Tree::get_aabb() const {
  59. return aabb;
  60. }
  61. int BSP_Tree::_get_points_inside(int p_node, const Vector3 *p_points, int *p_indices, const Vector3 &p_center, const Vector3 &p_half_extents, int p_indices_count) const {
  62. const Node *node = &nodes[p_node];
  63. const Plane &p = planes[node->plane];
  64. Vector3 min(
  65. (p.normal.x > 0) ? -p_half_extents.x : p_half_extents.x,
  66. (p.normal.y > 0) ? -p_half_extents.y : p_half_extents.y,
  67. (p.normal.z > 0) ? -p_half_extents.z : p_half_extents.z);
  68. Vector3 max = -min;
  69. max += p_center;
  70. min += p_center;
  71. real_t dist_min = p.distance_to(min);
  72. real_t dist_max = p.distance_to(max);
  73. if ((dist_min * dist_max) < (real_t)CMP_EPSILON) { //intersection, test point by point
  74. int under_count = 0;
  75. //sort points, so the are under first, over last
  76. for (int i = 0; i < p_indices_count; i++) {
  77. int index = p_indices[i];
  78. if (p.is_point_over(p_points[index])) {
  79. // kind of slow (but cache friendly), should try something else,
  80. // but this is a corner case most of the time
  81. for (int j = index; j < p_indices_count - 1; j++) {
  82. p_indices[j] = p_indices[j + 1];
  83. }
  84. p_indices[p_indices_count - 1] = index;
  85. } else {
  86. under_count++;
  87. }
  88. }
  89. int total = 0;
  90. if (under_count > 0) {
  91. if (node->under == UNDER_LEAF) {
  92. total += under_count;
  93. } else {
  94. total += _get_points_inside(node->under, p_points, p_indices, p_center, p_half_extents, under_count);
  95. }
  96. }
  97. if (under_count != p_indices_count) {
  98. if (node->over == OVER_LEAF) {
  99. //total+=0 //if they are over an OVER_LEAF, they are outside the model
  100. } else {
  101. total += _get_points_inside(node->over, p_points, &p_indices[under_count], p_center, p_half_extents, p_indices_count - under_count);
  102. }
  103. }
  104. return total;
  105. } else if (dist_min > 0) { //all points over plane
  106. if (node->over == OVER_LEAF) {
  107. return 0; // all these points are not visible
  108. }
  109. return _get_points_inside(node->over, p_points, p_indices, p_center, p_half_extents, p_indices_count);
  110. } else { //all points behind plane
  111. if (node->under == UNDER_LEAF) {
  112. return p_indices_count; // all these points are visible
  113. }
  114. return _get_points_inside(node->under, p_points, p_indices, p_center, p_half_extents, p_indices_count);
  115. }
  116. }
  117. int BSP_Tree::get_points_inside(const Vector3 *p_points, int p_point_count) const {
  118. if (nodes.size() == 0) {
  119. return 0;
  120. }
  121. #if 1
  122. //this version is easier to debug, and and MUCH faster in real world cases
  123. int pass_count = 0;
  124. const Node *nodesptr = &nodes[0];
  125. const Plane *planesptr = &planes[0];
  126. int node_count = nodes.size();
  127. if (node_count == 0) { // no nodes!
  128. return 0;
  129. }
  130. for (int i = 0; i < p_point_count; i++) {
  131. const Vector3 &point = p_points[i];
  132. if (!aabb.has_point(point)) {
  133. continue;
  134. }
  135. int idx = node_count - 1;
  136. bool pass = false;
  137. while (true) {
  138. if (idx == OVER_LEAF) {
  139. pass = false;
  140. break;
  141. } else if (idx == UNDER_LEAF) {
  142. pass = true;
  143. break;
  144. }
  145. #ifdef DEBUG_ENABLED
  146. int plane_count = planes.size();
  147. uint16_t plane = nodesptr[idx].plane;
  148. ERR_FAIL_UNSIGNED_INDEX_V(plane, plane_count, 0);
  149. #endif
  150. idx = planesptr[nodesptr[idx].plane].is_point_over(point) ? nodes[idx].over : nodes[idx].under;
  151. #ifdef DEBUG_ENABLED
  152. ERR_FAIL_COND_V(idx < MAX_NODES && idx >= node_count, 0);
  153. #endif
  154. }
  155. if (pass) {
  156. pass_count++;
  157. }
  158. }
  159. return pass_count;
  160. #else
  161. //this version scales better but it's slower for real world cases
  162. int *indices = (int *)alloca(p_point_count * sizeof(int));
  163. AABB bounds;
  164. for (int i = 0; i < p_point_count; i++) {
  165. indices[i] = i;
  166. if (i == 0)
  167. bounds.pos = p_points[i];
  168. else
  169. bounds.expand_to(p_points[i]);
  170. }
  171. Vector3 half_extents = bounds.size / 2;
  172. return _get_points_inside(nodes.size() + 1, p_points, indices, bounds.pos + half_extents, half_extents, p_point_count);
  173. #endif
  174. }
  175. bool BSP_Tree::point_is_inside(const Vector3 &p_point) const {
  176. if (!aabb.has_point(p_point)) {
  177. return false;
  178. }
  179. int node_count = nodes.size();
  180. if (node_count == 0) { // no nodes!
  181. return false;
  182. }
  183. const Node *nodesptr = &nodes[0];
  184. const Plane *planesptr = &planes[0];
  185. int idx = node_count - 1;
  186. while (true) {
  187. if (idx == OVER_LEAF) {
  188. return false;
  189. }
  190. if (idx == UNDER_LEAF) {
  191. return true;
  192. }
  193. #ifdef DEBUG_ENABLED
  194. int plane_count = planes.size();
  195. uint16_t plane = nodesptr[idx].plane;
  196. ERR_FAIL_UNSIGNED_INDEX_V(plane, plane_count, false);
  197. #endif
  198. bool over = planesptr[nodesptr[idx].plane].is_point_over(p_point);
  199. idx = over ? nodes[idx].over : nodes[idx].under;
  200. #ifdef DEBUG_ENABLED
  201. ERR_FAIL_COND_V(idx < MAX_NODES && idx >= node_count, false);
  202. #endif
  203. }
  204. }
  205. static int _bsp_find_best_half_plane(const Face3 *p_faces, const Vector<int> &p_indices, real_t p_tolerance) {
  206. int ic = p_indices.size();
  207. const int *indices = p_indices.ptr();
  208. int best_plane = -1;
  209. real_t best_plane_cost = 1e20;
  210. // Loop to find the polygon that best divides the set.
  211. for (int i = 0; i < ic; i++) {
  212. const Face3 &f = p_faces[indices[i]];
  213. Plane p = f.get_plane();
  214. int num_over = 0, num_under = 0; //num_spanning = 0;
  215. for (int j = 0; j < ic; j++) {
  216. if (i == j) {
  217. continue;
  218. }
  219. const Face3 &g = p_faces[indices[j]];
  220. int over = 0, under = 0;
  221. for (int k = 0; k < 3; k++) {
  222. real_t d = p.distance_to(g.vertex[j]);
  223. if (Math::abs(d) > p_tolerance) {
  224. if (d > 0) {
  225. over++;
  226. } else {
  227. under++;
  228. }
  229. }
  230. }
  231. if (over && under) {
  232. //num_spanning++;
  233. } else if (over) {
  234. num_over++;
  235. } else {
  236. num_under++;
  237. }
  238. }
  239. //real_t split_cost = num_spanning / (real_t) face_count;
  240. real_t relation = Math::abs(num_over - num_under) / (real_t)ic;
  241. // being honest, i never found a way to add split cost to the mix in a meaninguful way
  242. // in this engine, also, will likely be ignored anyway
  243. real_t plane_cost = /*split_cost +*/ relation;
  244. //printf("plane %i, %i over, %i under, %i spanning, cost is %g\n",i,num_over,num_under,num_spanning,plane_cost);
  245. if (plane_cost < best_plane_cost) {
  246. best_plane = i;
  247. best_plane_cost = plane_cost;
  248. }
  249. }
  250. return best_plane;
  251. }
  252. static int _bsp_create_node(const Face3 *p_faces, const Vector<int> &p_indices, Vector<Plane> &p_planes, Vector<BSP_Tree::Node> &p_nodes, real_t p_tolerance) {
  253. ERR_FAIL_COND_V(p_nodes.size() == BSP_Tree::MAX_NODES, -1);
  254. // should not reach here
  255. ERR_FAIL_COND_V(p_indices.size() == 0, -1);
  256. int ic = p_indices.size();
  257. const int *indices = p_indices.ptr();
  258. int divisor_idx = _bsp_find_best_half_plane(p_faces, p_indices, p_tolerance);
  259. // returned error
  260. ERR_FAIL_COND_V(divisor_idx < 0, -1);
  261. Vector<int> faces_over;
  262. Vector<int> faces_under;
  263. Plane divisor_plane = p_faces[indices[divisor_idx]].get_plane();
  264. for (int i = 0; i < ic; i++) {
  265. if (i == divisor_idx) {
  266. continue;
  267. }
  268. const Face3 &f = p_faces[indices[i]];
  269. /*
  270. if (f.get_plane().is_equal_approx(divisor_plane))
  271. continue;
  272. */
  273. int over_count = 0;
  274. int under_count = 0;
  275. for (int j = 0; j < 3; j++) {
  276. real_t d = divisor_plane.distance_to(f.vertex[j]);
  277. if (Math::abs(d) > p_tolerance) {
  278. if (d > 0) {
  279. over_count++;
  280. } else {
  281. under_count++;
  282. }
  283. }
  284. }
  285. if (over_count) {
  286. faces_over.push_back(indices[i]);
  287. }
  288. if (under_count) {
  289. faces_under.push_back(indices[i]);
  290. }
  291. }
  292. uint16_t over_idx = BSP_Tree::OVER_LEAF, under_idx = BSP_Tree::UNDER_LEAF;
  293. if (faces_over.size() > 0) { //have facess above?
  294. int idx = _bsp_create_node(p_faces, faces_over, p_planes, p_nodes, p_tolerance);
  295. if (idx >= 0) {
  296. over_idx = idx;
  297. }
  298. }
  299. if (faces_under.size() > 0) { //have facess above?
  300. int idx = _bsp_create_node(p_faces, faces_under, p_planes, p_nodes, p_tolerance);
  301. if (idx >= 0) {
  302. under_idx = idx;
  303. }
  304. }
  305. /* Create the node */
  306. // find existing divisor plane
  307. int divisor_plane_idx = -1;
  308. for (int i = 0; i < p_planes.size(); i++) {
  309. if (p_planes[i].is_equal_approx(divisor_plane)) {
  310. divisor_plane_idx = i;
  311. break;
  312. }
  313. }
  314. if (divisor_plane_idx == -1) {
  315. ERR_FAIL_COND_V(p_planes.size() == BSP_Tree::MAX_PLANES, -1);
  316. divisor_plane_idx = p_planes.size();
  317. p_planes.push_back(divisor_plane);
  318. }
  319. BSP_Tree::Node node;
  320. node.plane = divisor_plane_idx;
  321. node.under = under_idx;
  322. node.over = over_idx;
  323. p_nodes.push_back(node);
  324. return p_nodes.size() - 1;
  325. }
  326. BSP_Tree::operator Variant() const {
  327. Dictionary d;
  328. d["error_radius"] = error_radius;
  329. Vector<real_t> plane_values;
  330. plane_values.resize(planes.size() * 4);
  331. for (int i = 0; i < planes.size(); i++) {
  332. plane_values.write[i * 4 + 0] = planes[i].normal.x;
  333. plane_values.write[i * 4 + 1] = planes[i].normal.y;
  334. plane_values.write[i * 4 + 2] = planes[i].normal.z;
  335. plane_values.write[i * 4 + 3] = planes[i].d;
  336. }
  337. d["planes"] = plane_values;
  338. PoolVector<int> dst_nodes;
  339. dst_nodes.resize(nodes.size() * 3);
  340. for (int i = 0; i < nodes.size(); i++) {
  341. dst_nodes.set(i * 3 + 0, nodes[i].over);
  342. dst_nodes.set(i * 3 + 1, nodes[i].under);
  343. dst_nodes.set(i * 3 + 2, nodes[i].plane);
  344. }
  345. d["nodes"] = dst_nodes;
  346. d["aabb"] = aabb;
  347. return Variant(d);
  348. }
  349. BSP_Tree::BSP_Tree() {
  350. }
  351. BSP_Tree::BSP_Tree(const Variant &p_variant) {
  352. Dictionary d = p_variant;
  353. ERR_FAIL_COND(!d.has("nodes"));
  354. ERR_FAIL_COND(!d.has("planes"));
  355. ERR_FAIL_COND(!d.has("aabb"));
  356. ERR_FAIL_COND(!d.has("error_radius"));
  357. PoolVector<int> src_nodes = d["nodes"];
  358. ERR_FAIL_COND(src_nodes.size() % 3);
  359. if (d["planes"].get_type() == Variant::POOL_REAL_ARRAY) {
  360. PoolVector<real_t> src_planes = d["planes"];
  361. int plane_count = src_planes.size();
  362. ERR_FAIL_COND(plane_count % 4);
  363. planes.resize(plane_count / 4);
  364. if (plane_count) {
  365. PoolVector<real_t>::Read r = src_planes.read();
  366. for (int i = 0; i < plane_count / 4; i++) {
  367. planes.write[i].normal.x = r[i * 4 + 0];
  368. planes.write[i].normal.y = r[i * 4 + 1];
  369. planes.write[i].normal.z = r[i * 4 + 2];
  370. planes.write[i].d = r[i * 4 + 3];
  371. }
  372. }
  373. } else {
  374. planes = d["planes"];
  375. }
  376. error_radius = d["error"];
  377. aabb = d["aabb"];
  378. //int node_count = src_nodes.size();
  379. nodes.resize(src_nodes.size() / 3);
  380. PoolVector<int>::Read r = src_nodes.read();
  381. for (int i = 0; i < nodes.size(); i++) {
  382. nodes.write[i].over = r[i * 3 + 0];
  383. nodes.write[i].under = r[i * 3 + 1];
  384. nodes.write[i].plane = r[i * 3 + 2];
  385. }
  386. }
  387. BSP_Tree::BSP_Tree(const PoolVector<Face3> &p_faces, real_t p_error_radius) {
  388. // compute aabb
  389. int face_count = p_faces.size();
  390. PoolVector<Face3>::Read faces_r = p_faces.read();
  391. const Face3 *facesptr = faces_r.ptr();
  392. bool first = true;
  393. Vector<int> indices;
  394. for (int i = 0; i < face_count; i++) {
  395. const Face3 &f = facesptr[i];
  396. if (f.is_degenerate()) {
  397. continue;
  398. }
  399. for (int j = 0; j < 3; j++) {
  400. if (first) {
  401. aabb.position = f.vertex[0];
  402. first = false;
  403. } else {
  404. aabb.expand_to(f.vertex[j]);
  405. }
  406. }
  407. indices.push_back(i);
  408. }
  409. ERR_FAIL_COND(aabb.has_no_area());
  410. int top = _bsp_create_node(faces_r.ptr(), indices, planes, nodes, aabb.get_longest_axis_size() * 0.0001f);
  411. if (top < 0) {
  412. nodes.clear();
  413. planes.clear();
  414. ERR_FAIL_COND(top < 0);
  415. }
  416. error_radius = p_error_radius;
  417. }
  418. BSP_Tree::BSP_Tree(const Vector<Node> &p_nodes, const Vector<Plane> &p_planes, const AABB &p_aabb, real_t p_error_radius) :
  419. nodes(p_nodes),
  420. planes(p_planes),
  421. aabb(p_aabb),
  422. error_radius(p_error_radius) {
  423. }
  424. BSP_Tree::~BSP_Tree() {
  425. }