convex_hull.cpp 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346
  1. /**************************************************************************/
  2. /* convex_hull.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. /*
  31. * Based on Godot's patched VHACD-version of Bullet's btConvexHullComputer.
  32. * See /thirdparty/vhacd/btConvexHullComputer.cpp at 64403ddcab9f1dca2408f0a412a22d899708bbb1
  33. * In turn, based on /src/LinearMath/btConvexHullComputer.cpp in <https://github.com/bulletphysics/bullet3>
  34. * at 73b217fb07e7e3ce126caeb28ab3c9ddd0718467
  35. *
  36. * Changes:
  37. * - int32_t is consistently used instead of int in some cases
  38. * - integrated patch db0d6c92927f5a1358b887f2645c11f3014f0e8a from Bullet (CWE-190 integer overflow in btConvexHullComputer)
  39. * - adapted to Godot's code style
  40. * - replaced Bullet's types (e.g. vectors) with Godot's
  41. * - replaced custom Pool implementation with PagedAllocator
  42. */
  43. /*
  44. Copyright (c) 2011 Ole Kniemeyer, MAXON, www.maxon.net
  45. This software is provided 'as-is', without any express or implied warranty.
  46. In no event will the authors be held liable for any damages arising from the use of this software.
  47. Permission is granted to anyone to use this software for any purpose,
  48. including commercial applications, and to alter it and redistribute it freely,
  49. subject to the following restrictions:
  50. 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
  51. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
  52. 3. This notice may not be removed or altered from any source distribution.
  53. */
  54. #include "convex_hull.h"
  55. #include "core/error/error_macros.h"
  56. #include "core/math/aabb.h"
  57. #include "core/math/math_defs.h"
  58. #include "core/os/memory.h"
  59. #include "core/templates/oa_hash_map.h"
  60. #include "core/templates/paged_allocator.h"
  61. #include <string.h>
  62. //#define DEBUG_CONVEX_HULL
  63. //#define SHOW_ITERATIONS
  64. // -- GODOT start --
  65. // Assembly optimizations are not used at the moment.
  66. //#define USE_X86_64_ASM
  67. // -- GODOT end --
  68. #ifdef DEBUG_ENABLED
  69. #define CHULL_ASSERT(m_cond) \
  70. do { \
  71. if (unlikely(!(m_cond))) { \
  72. ERR_PRINT("Assertion \"" _STR(m_cond) "\" failed."); \
  73. } \
  74. } while (0)
  75. #else
  76. #define CHULL_ASSERT(m_cond) \
  77. do { \
  78. } while (0)
  79. #endif
  80. #if defined(DEBUG_CONVEX_HULL) || defined(SHOW_ITERATIONS)
  81. #include <stdio.h>
  82. #endif
  83. // Convex hull implementation based on Preparata and Hong
  84. // Ole Kniemeyer, MAXON Computer GmbH
  85. class ConvexHullInternal {
  86. public:
  87. class Point64 {
  88. public:
  89. int64_t x;
  90. int64_t y;
  91. int64_t z;
  92. Point64(int64_t p_x, int64_t p_y, int64_t p_z) {
  93. x = p_x;
  94. y = p_y;
  95. z = p_z;
  96. }
  97. bool is_zero() {
  98. return (x == 0) && (y == 0) && (z == 0);
  99. }
  100. int64_t dot(const Point64 &b) const {
  101. return x * b.x + y * b.y + z * b.z;
  102. }
  103. };
  104. class Point32 {
  105. public:
  106. int32_t x = 0;
  107. int32_t y = 0;
  108. int32_t z = 0;
  109. int32_t index = -1;
  110. Point32() {
  111. }
  112. Point32(int32_t p_x, int32_t p_y, int32_t p_z) {
  113. x = p_x;
  114. y = p_y;
  115. z = p_z;
  116. }
  117. bool operator==(const Point32 &b) const {
  118. return (x == b.x) && (y == b.y) && (z == b.z);
  119. }
  120. bool operator!=(const Point32 &b) const {
  121. return (x != b.x) || (y != b.y) || (z != b.z);
  122. }
  123. bool is_zero() {
  124. return (x == 0) && (y == 0) && (z == 0);
  125. }
  126. Point64 cross(const Point32 &b) const {
  127. return Point64((int64_t)y * b.z - (int64_t)z * b.y, (int64_t)z * b.x - (int64_t)x * b.z, (int64_t)x * b.y - (int64_t)y * b.x);
  128. }
  129. Point64 cross(const Point64 &b) const {
  130. return Point64(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x);
  131. }
  132. int64_t dot(const Point32 &b) const {
  133. return (int64_t)x * b.x + (int64_t)y * b.y + (int64_t)z * b.z;
  134. }
  135. int64_t dot(const Point64 &b) const {
  136. return x * b.x + y * b.y + z * b.z;
  137. }
  138. Point32 operator+(const Point32 &b) const {
  139. return Point32(x + b.x, y + b.y, z + b.z);
  140. }
  141. Point32 operator-(const Point32 &b) const {
  142. return Point32(x - b.x, y - b.y, z - b.z);
  143. }
  144. };
  145. class Int128 {
  146. public:
  147. uint64_t low = 0;
  148. uint64_t high = 0;
  149. Int128() {
  150. }
  151. Int128(uint64_t p_low, uint64_t p_high) {
  152. low = p_low;
  153. high = p_high;
  154. }
  155. Int128(uint64_t p_low) {
  156. low = p_low;
  157. high = 0;
  158. }
  159. Int128(int64_t p_value) {
  160. low = p_value;
  161. if (p_value >= 0) {
  162. high = 0;
  163. } else {
  164. high = (uint64_t)-1LL;
  165. }
  166. }
  167. static Int128 mul(int64_t a, int64_t b);
  168. static Int128 mul(uint64_t a, uint64_t b);
  169. Int128 operator-() const {
  170. return Int128((uint64_t) - (int64_t)low, ~high + (low == 0));
  171. }
  172. Int128 operator+(const Int128 &b) const {
  173. #ifdef USE_X86_64_ASM
  174. Int128 result;
  175. __asm__("addq %[bl], %[rl]\n\t"
  176. "adcq %[bh], %[rh]\n\t"
  177. : [rl] "=r"(result.low), [rh] "=r"(result.high)
  178. : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high)
  179. : "cc");
  180. return result;
  181. #else
  182. uint64_t lo = low + b.low;
  183. return Int128(lo, high + b.high + (lo < low));
  184. #endif
  185. }
  186. Int128 operator-(const Int128 &b) const {
  187. #ifdef USE_X86_64_ASM
  188. Int128 result;
  189. __asm__("subq %[bl], %[rl]\n\t"
  190. "sbbq %[bh], %[rh]\n\t"
  191. : [rl] "=r"(result.low), [rh] "=r"(result.high)
  192. : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high)
  193. : "cc");
  194. return result;
  195. #else
  196. return *this + -b;
  197. #endif
  198. }
  199. Int128 &operator+=(const Int128 &b) {
  200. #ifdef USE_X86_64_ASM
  201. __asm__("addq %[bl], %[rl]\n\t"
  202. "adcq %[bh], %[rh]\n\t"
  203. : [rl] "=r"(low), [rh] "=r"(high)
  204. : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high)
  205. : "cc");
  206. #else
  207. uint64_t lo = low + b.low;
  208. if (lo < low) {
  209. ++high;
  210. }
  211. low = lo;
  212. high += b.high;
  213. #endif
  214. return *this;
  215. }
  216. Int128 &operator++() {
  217. if (++low == 0) {
  218. ++high;
  219. }
  220. return *this;
  221. }
  222. Int128 operator*(int64_t b) const;
  223. real_t to_scalar() const {
  224. return ((int64_t)high >= 0) ? real_t(high) * (real_t(0x100000000LL) * real_t(0x100000000LL)) + real_t(low) : -(-*this).to_scalar();
  225. }
  226. int32_t get_sign() const {
  227. return ((int64_t)high < 0) ? -1 : ((high || low) ? 1 : 0);
  228. }
  229. bool operator<(const Int128 &b) const {
  230. return (high < b.high) || ((high == b.high) && (low < b.low));
  231. }
  232. int32_t ucmp(const Int128 &b) const {
  233. if (high < b.high) {
  234. return -1;
  235. }
  236. if (high > b.high) {
  237. return 1;
  238. }
  239. if (low < b.low) {
  240. return -1;
  241. }
  242. if (low > b.low) {
  243. return 1;
  244. }
  245. return 0;
  246. }
  247. };
  248. class Rational64 {
  249. private:
  250. uint64_t numerator;
  251. uint64_t denominator;
  252. int32_t sign;
  253. public:
  254. Rational64(int64_t p_numerator, int64_t p_denominator) {
  255. if (p_numerator > 0) {
  256. sign = 1;
  257. numerator = (uint64_t)p_numerator;
  258. } else if (p_numerator < 0) {
  259. sign = -1;
  260. numerator = (uint64_t)-p_numerator;
  261. } else {
  262. sign = 0;
  263. numerator = 0;
  264. }
  265. if (p_denominator > 0) {
  266. denominator = (uint64_t)p_denominator;
  267. } else if (p_denominator < 0) {
  268. sign = -sign;
  269. denominator = (uint64_t)-p_denominator;
  270. } else {
  271. denominator = 0;
  272. }
  273. }
  274. bool is_negative_infinity() const {
  275. return (sign < 0) && (denominator == 0);
  276. }
  277. bool is_nan() const {
  278. return (sign == 0) && (denominator == 0);
  279. }
  280. int32_t compare(const Rational64 &b) const;
  281. real_t to_scalar() const {
  282. return sign * ((denominator == 0) ? FLT_MAX : (real_t)numerator / denominator);
  283. }
  284. };
  285. class Rational128 {
  286. private:
  287. Int128 numerator;
  288. Int128 denominator;
  289. int32_t sign;
  290. bool is_int_64;
  291. public:
  292. Rational128(int64_t p_value) {
  293. if (p_value > 0) {
  294. sign = 1;
  295. this->numerator = p_value;
  296. } else if (p_value < 0) {
  297. sign = -1;
  298. this->numerator = -p_value;
  299. } else {
  300. sign = 0;
  301. this->numerator = (uint64_t)0;
  302. }
  303. this->denominator = (uint64_t)1;
  304. is_int_64 = true;
  305. }
  306. Rational128(const Int128 &p_numerator, const Int128 &p_denominator) {
  307. sign = p_numerator.get_sign();
  308. if (sign >= 0) {
  309. this->numerator = p_numerator;
  310. } else {
  311. this->numerator = -p_numerator;
  312. }
  313. int32_t dsign = p_denominator.get_sign();
  314. if (dsign >= 0) {
  315. this->denominator = p_denominator;
  316. } else {
  317. sign = -sign;
  318. this->denominator = -p_denominator;
  319. }
  320. is_int_64 = false;
  321. }
  322. int32_t compare(const Rational128 &b) const;
  323. int32_t compare(int64_t b) const;
  324. real_t to_scalar() const {
  325. return sign * ((denominator.get_sign() == 0) ? FLT_MAX : numerator.to_scalar() / denominator.to_scalar());
  326. }
  327. };
  328. class PointR128 {
  329. public:
  330. Int128 x;
  331. Int128 y;
  332. Int128 z;
  333. Int128 denominator;
  334. PointR128() {
  335. }
  336. PointR128(Int128 p_x, Int128 p_y, Int128 p_z, Int128 p_denominator) {
  337. x = p_x;
  338. y = p_y;
  339. z = p_z;
  340. denominator = p_denominator;
  341. }
  342. real_t xvalue() const {
  343. return x.to_scalar() / denominator.to_scalar();
  344. }
  345. real_t yvalue() const {
  346. return y.to_scalar() / denominator.to_scalar();
  347. }
  348. real_t zvalue() const {
  349. return z.to_scalar() / denominator.to_scalar();
  350. }
  351. };
  352. class Edge;
  353. class Face;
  354. class Vertex {
  355. public:
  356. Vertex *next = nullptr;
  357. Vertex *prev = nullptr;
  358. Edge *edges = nullptr;
  359. Face *first_nearby_face = nullptr;
  360. Face *last_nearby_face = nullptr;
  361. PointR128 point128;
  362. Point32 point;
  363. int32_t copy = -1;
  364. Vertex() {
  365. }
  366. #ifdef DEBUG_CONVEX_HULL
  367. void print() {
  368. printf("V%d (%d, %d, %d)", point.index, point.x, point.y, point.z);
  369. }
  370. void print_graph();
  371. #endif
  372. Point32 operator-(const Vertex &b) const {
  373. return point - b.point;
  374. }
  375. Rational128 dot(const Point64 &b) const {
  376. return (point.index >= 0) ? Rational128(point.dot(b)) : Rational128(point128.x * b.x + point128.y * b.y + point128.z * b.z, point128.denominator);
  377. }
  378. real_t xvalue() const {
  379. return (point.index >= 0) ? real_t(point.x) : point128.xvalue();
  380. }
  381. real_t yvalue() const {
  382. return (point.index >= 0) ? real_t(point.y) : point128.yvalue();
  383. }
  384. real_t zvalue() const {
  385. return (point.index >= 0) ? real_t(point.z) : point128.zvalue();
  386. }
  387. void receive_nearby_faces(Vertex *p_src) {
  388. if (last_nearby_face) {
  389. last_nearby_face->next_with_same_nearby_vertex = p_src->first_nearby_face;
  390. } else {
  391. first_nearby_face = p_src->first_nearby_face;
  392. }
  393. if (p_src->last_nearby_face) {
  394. last_nearby_face = p_src->last_nearby_face;
  395. }
  396. for (Face *f = p_src->first_nearby_face; f; f = f->next_with_same_nearby_vertex) {
  397. CHULL_ASSERT(f->nearby_vertex == p_src);
  398. f->nearby_vertex = this;
  399. }
  400. p_src->first_nearby_face = nullptr;
  401. p_src->last_nearby_face = nullptr;
  402. }
  403. };
  404. class Edge {
  405. public:
  406. Edge *next = nullptr;
  407. Edge *prev = nullptr;
  408. Edge *reverse = nullptr;
  409. Vertex *target = nullptr;
  410. Face *face = nullptr;
  411. int32_t copy = -1;
  412. void link(Edge *n) {
  413. CHULL_ASSERT(reverse->target == n->reverse->target);
  414. next = n;
  415. n->prev = this;
  416. }
  417. #ifdef DEBUG_CONVEX_HULL
  418. void print() {
  419. printf("E%p : %d -> %d, n=%p p=%p (0 %d\t%d\t%d) -> (%d %d %d)", this, reverse->target->point.index, target->point.index, next, prev,
  420. reverse->target->point.x, reverse->target->point.y, reverse->target->point.z, target->point.x, target->point.y, target->point.z);
  421. }
  422. #endif
  423. };
  424. class Face {
  425. public:
  426. Face *next = nullptr;
  427. Vertex *nearby_vertex = nullptr;
  428. Face *next_with_same_nearby_vertex = nullptr;
  429. Point32 origin;
  430. Point32 dir0;
  431. Point32 dir1;
  432. Face() {
  433. }
  434. void init(Vertex *p_a, const Vertex *p_b, const Vertex *p_c) {
  435. nearby_vertex = p_a;
  436. origin = p_a->point;
  437. dir0 = *p_b - *p_a;
  438. dir1 = *p_c - *p_a;
  439. if (p_a->last_nearby_face) {
  440. p_a->last_nearby_face->next_with_same_nearby_vertex = this;
  441. } else {
  442. p_a->first_nearby_face = this;
  443. }
  444. p_a->last_nearby_face = this;
  445. }
  446. Point64 get_normal() {
  447. return dir0.cross(dir1);
  448. }
  449. };
  450. template <typename UWord, typename UHWord>
  451. class DMul {
  452. private:
  453. static uint32_t high(uint64_t p_value) {
  454. return (uint32_t)(p_value >> 32);
  455. }
  456. static uint32_t low(uint64_t p_value) {
  457. return (uint32_t)p_value;
  458. }
  459. static uint64_t mul(uint32_t a, uint32_t b) {
  460. return (uint64_t)a * (uint64_t)b;
  461. }
  462. static void shl_half(uint64_t &p_value) {
  463. p_value <<= 32;
  464. }
  465. static uint64_t high(Int128 p_value) {
  466. return p_value.high;
  467. }
  468. static uint64_t low(Int128 p_value) {
  469. return p_value.low;
  470. }
  471. static Int128 mul(uint64_t a, uint64_t b) {
  472. return Int128::mul(a, b);
  473. }
  474. static void shl_half(Int128 &p_value) {
  475. p_value.high = p_value.low;
  476. p_value.low = 0;
  477. }
  478. public:
  479. static void mul(UWord p_a, UWord p_b, UWord &r_low, UWord &r_high) {
  480. UWord p00 = mul(low(p_a), low(p_b));
  481. UWord p01 = mul(low(p_a), high(p_b));
  482. UWord p10 = mul(high(p_a), low(p_b));
  483. UWord p11 = mul(high(p_a), high(p_b));
  484. UWord p0110 = UWord(low(p01)) + UWord(low(p10));
  485. p11 += high(p01);
  486. p11 += high(p10);
  487. p11 += high(p0110);
  488. shl_half(p0110);
  489. p00 += p0110;
  490. if (p00 < p0110) {
  491. ++p11;
  492. }
  493. r_low = p00;
  494. r_high = p11;
  495. }
  496. };
  497. private:
  498. class IntermediateHull {
  499. public:
  500. Vertex *min_xy = nullptr;
  501. Vertex *max_xy = nullptr;
  502. Vertex *min_yx = nullptr;
  503. Vertex *max_yx = nullptr;
  504. IntermediateHull() {
  505. }
  506. };
  507. enum Orientation { ORIENTATION_NONE,
  508. ORIENTATION_CLOCKWISE,
  509. ORIENTATION_COUNTER_CLOCKWISE };
  510. Vector3 scaling;
  511. Vector3 center;
  512. PagedAllocator<Vertex> vertex_pool;
  513. PagedAllocator<Edge> edge_pool;
  514. PagedAllocator<Face> face_pool;
  515. LocalVector<Vertex *> original_vertices;
  516. int32_t merge_stamp = 0;
  517. Vector3::Axis min_axis = Vector3::Axis::AXIS_X;
  518. Vector3::Axis med_axis = Vector3::Axis::AXIS_X;
  519. Vector3::Axis max_axis = Vector3::Axis::AXIS_X;
  520. int32_t used_edge_pairs = 0;
  521. int32_t max_used_edge_pairs = 0;
  522. static Orientation get_orientation(const Edge *p_prev, const Edge *p_next, const Point32 &p_s, const Point32 &p_t);
  523. Edge *find_max_angle(bool p_ccw, const Vertex *p_start, const Point32 &p_s, const Point64 &p_rxs, const Point64 &p_ssxrxs, Rational64 &p_min_cot);
  524. void find_edge_for_coplanar_faces(Vertex *p_c0, Vertex *p_c1, Edge *&p_e0, Edge *&p_e1, const Vertex *p_stop0, const Vertex *p_stop1);
  525. Edge *new_edge_pair(Vertex *p_from, Vertex *p_to);
  526. void remove_edge_pair(Edge *p_edge) {
  527. Edge *n = p_edge->next;
  528. Edge *r = p_edge->reverse;
  529. CHULL_ASSERT(p_edge->target && r->target);
  530. if (n != p_edge) {
  531. n->prev = p_edge->prev;
  532. p_edge->prev->next = n;
  533. r->target->edges = n;
  534. } else {
  535. r->target->edges = nullptr;
  536. }
  537. n = r->next;
  538. if (n != r) {
  539. n->prev = r->prev;
  540. r->prev->next = n;
  541. p_edge->target->edges = n;
  542. } else {
  543. p_edge->target->edges = nullptr;
  544. }
  545. edge_pool.free(p_edge);
  546. edge_pool.free(r);
  547. used_edge_pairs--;
  548. }
  549. void compute_internal(int32_t p_start, int32_t p_end, IntermediateHull &r_result);
  550. bool merge_projection(IntermediateHull &p_h0, IntermediateHull &p_h1, Vertex *&r_c0, Vertex *&r_c1);
  551. void merge(IntermediateHull &p_h0, IntermediateHull &p_h1);
  552. Vector3 to_gd_vector(const Point32 &p_v);
  553. Vector3 get_gd_normal(Face *p_face);
  554. bool shift_face(Face *p_face, real_t p_amount, LocalVector<Vertex *> &p_stack);
  555. public:
  556. ~ConvexHullInternal() {
  557. vertex_pool.reset(true);
  558. edge_pool.reset(true);
  559. face_pool.reset(true);
  560. }
  561. Vertex *vertex_list = nullptr;
  562. void compute(const Vector3 *p_coords, int32_t p_count);
  563. Vector3 get_coordinates(const Vertex *p_v);
  564. real_t shrink(real_t amount, real_t p_clamp_amount);
  565. };
  566. ConvexHullInternal::Int128 ConvexHullInternal::Int128::operator*(int64_t b) const {
  567. bool negative = (int64_t)high < 0;
  568. Int128 a = negative ? -*this : *this;
  569. if (b < 0) {
  570. negative = !negative;
  571. b = -b;
  572. }
  573. Int128 result = mul(a.low, (uint64_t)b);
  574. result.high += a.high * (uint64_t)b;
  575. return negative ? -result : result;
  576. }
  577. ConvexHullInternal::Int128 ConvexHullInternal::Int128::mul(int64_t a, int64_t b) {
  578. Int128 result;
  579. #ifdef USE_X86_64_ASM
  580. __asm__("imulq %[b]"
  581. : "=a"(result.low), "=d"(result.high)
  582. : "0"(a), [b] "r"(b)
  583. : "cc");
  584. return result;
  585. #else
  586. bool negative = a < 0;
  587. if (negative) {
  588. a = -a;
  589. }
  590. if (b < 0) {
  591. negative = !negative;
  592. b = -b;
  593. }
  594. DMul<uint64_t, uint32_t>::mul((uint64_t)a, (uint64_t)b, result.low, result.high);
  595. return negative ? -result : result;
  596. #endif
  597. }
  598. ConvexHullInternal::Int128 ConvexHullInternal::Int128::mul(uint64_t a, uint64_t b) {
  599. Int128 result;
  600. #ifdef USE_X86_64_ASM
  601. __asm__("mulq %[b]"
  602. : "=a"(result.low), "=d"(result.high)
  603. : "0"(a), [b] "r"(b)
  604. : "cc");
  605. #else
  606. DMul<uint64_t, uint32_t>::mul(a, b, result.low, result.high);
  607. #endif
  608. return result;
  609. }
  610. int32_t ConvexHullInternal::Rational64::compare(const Rational64 &b) const {
  611. if (sign != b.sign) {
  612. return sign - b.sign;
  613. } else if (sign == 0) {
  614. return 0;
  615. }
  616. #ifdef USE_X86_64_ASM
  617. int32_t result;
  618. int64_t tmp;
  619. int64_t dummy;
  620. __asm__("mulq %[bn]\n\t"
  621. "movq %%rax, %[tmp]\n\t"
  622. "movq %%rdx, %%rbx\n\t"
  623. "movq %[tn], %%rax\n\t"
  624. "mulq %[bd]\n\t"
  625. "subq %[tmp], %%rax\n\t"
  626. "sbbq %%rbx, %%rdx\n\t" // rdx:rax contains 128-bit-difference "numerator*b.denominator - b.numerator*denominator"
  627. "setnsb %%bh\n\t" // bh=1 if difference is non-negative, bh=0 otherwise
  628. "orq %%rdx, %%rax\n\t"
  629. "setnzb %%bl\n\t" // bl=1 if difference if non-zero, bl=0 if it is zero
  630. "decb %%bh\n\t" // now bx=0x0000 if difference is zero, 0xff01 if it is negative, 0x0001 if it is positive (i.e., same sign as difference)
  631. "shll $16, %%ebx\n\t" // ebx has same sign as difference
  632. : "=&b"(result), [tmp] "=&r"(tmp), "=a"(dummy)
  633. : "a"(denominator), [bn] "g"(b.numerator), [tn] "g"(numerator), [bd] "g"(b.denominator)
  634. : "%rdx", "cc");
  635. // if sign is +1, only bit 0 of result is inverted, which does not change the sign of result (and cannot result in zero)
  636. // if sign is -1, all bits of result are inverted, which changes the sign of result (and again cannot result in zero)
  637. return result ? result ^ sign : 0;
  638. #else
  639. return sign * Int128::mul(numerator, b.denominator).ucmp(Int128::mul(denominator, b.numerator));
  640. #endif
  641. }
  642. int32_t ConvexHullInternal::Rational128::compare(const Rational128 &b) const {
  643. if (sign != b.sign) {
  644. return sign - b.sign;
  645. } else if (sign == 0) {
  646. return 0;
  647. }
  648. if (is_int_64) {
  649. return -b.compare(sign * (int64_t)numerator.low);
  650. }
  651. Int128 nbd_low, nbd_high, dbn_low, dbn_high;
  652. DMul<Int128, uint64_t>::mul(numerator, b.denominator, nbd_low, nbd_high);
  653. DMul<Int128, uint64_t>::mul(denominator, b.numerator, dbn_low, dbn_high);
  654. int32_t cmp = nbd_high.ucmp(dbn_high);
  655. if (cmp) {
  656. return cmp * sign;
  657. }
  658. return nbd_low.ucmp(dbn_low) * sign;
  659. }
  660. int32_t ConvexHullInternal::Rational128::compare(int64_t b) const {
  661. if (is_int_64) {
  662. int64_t a = sign * (int64_t)numerator.low;
  663. return (a > b) ? 1 : ((a < b) ? -1 : 0);
  664. }
  665. if (b > 0) {
  666. if (sign <= 0) {
  667. return -1;
  668. }
  669. } else if (b < 0) {
  670. if (sign >= 0) {
  671. return 1;
  672. }
  673. b = -b;
  674. } else {
  675. return sign;
  676. }
  677. return numerator.ucmp(denominator * b) * sign;
  678. }
  679. ConvexHullInternal::Edge *ConvexHullInternal::new_edge_pair(Vertex *p_from, Vertex *p_to) {
  680. CHULL_ASSERT(p_from && p_to);
  681. Edge *e = edge_pool.alloc();
  682. Edge *r = edge_pool.alloc();
  683. e->reverse = r;
  684. r->reverse = e;
  685. e->copy = merge_stamp;
  686. r->copy = merge_stamp;
  687. e->target = p_to;
  688. r->target = p_from;
  689. e->face = nullptr;
  690. r->face = nullptr;
  691. used_edge_pairs++;
  692. if (used_edge_pairs > max_used_edge_pairs) {
  693. max_used_edge_pairs = used_edge_pairs;
  694. }
  695. return e;
  696. }
  697. bool ConvexHullInternal::merge_projection(IntermediateHull &r_h0, IntermediateHull &r_h1, Vertex *&r_c0, Vertex *&r_c1) {
  698. Vertex *v0 = r_h0.max_yx;
  699. Vertex *v1 = r_h1.min_yx;
  700. if ((v0->point.x == v1->point.x) && (v0->point.y == v1->point.y)) {
  701. CHULL_ASSERT(v0->point.z < v1->point.z);
  702. Vertex *v1p = v1->prev;
  703. if (v1p == v1) {
  704. r_c0 = v0;
  705. if (v1->edges) {
  706. CHULL_ASSERT(v1->edges->next == v1->edges);
  707. v1 = v1->edges->target;
  708. CHULL_ASSERT(v1->edges->next == v1->edges);
  709. }
  710. r_c1 = v1;
  711. return false;
  712. }
  713. Vertex *v1n = v1->next;
  714. v1p->next = v1n;
  715. v1n->prev = v1p;
  716. if (v1 == r_h1.min_xy) {
  717. if ((v1n->point.x < v1p->point.x) || ((v1n->point.x == v1p->point.x) && (v1n->point.y < v1p->point.y))) {
  718. r_h1.min_xy = v1n;
  719. } else {
  720. r_h1.min_xy = v1p;
  721. }
  722. }
  723. if (v1 == r_h1.max_xy) {
  724. if ((v1n->point.x > v1p->point.x) || ((v1n->point.x == v1p->point.x) && (v1n->point.y > v1p->point.y))) {
  725. r_h1.max_xy = v1n;
  726. } else {
  727. r_h1.max_xy = v1p;
  728. }
  729. }
  730. }
  731. v0 = r_h0.max_xy;
  732. v1 = r_h1.max_xy;
  733. Vertex *v00 = nullptr;
  734. Vertex *v10 = nullptr;
  735. int32_t sign = 1;
  736. for (int32_t side = 0; side <= 1; side++) {
  737. int32_t dx = (v1->point.x - v0->point.x) * sign;
  738. if (dx > 0) {
  739. while (true) {
  740. int32_t dy = v1->point.y - v0->point.y;
  741. Vertex *w0 = side ? v0->next : v0->prev;
  742. if (w0 != v0) {
  743. int32_t dx0 = (w0->point.x - v0->point.x) * sign;
  744. int32_t dy0 = w0->point.y - v0->point.y;
  745. if ((dy0 <= 0) && ((dx0 == 0) || ((dx0 < 0) && (dy0 * dx <= dy * dx0)))) {
  746. v0 = w0;
  747. dx = (v1->point.x - v0->point.x) * sign;
  748. continue;
  749. }
  750. }
  751. Vertex *w1 = side ? v1->next : v1->prev;
  752. if (w1 != v1) {
  753. int32_t dx1 = (w1->point.x - v1->point.x) * sign;
  754. int32_t dy1 = w1->point.y - v1->point.y;
  755. int32_t dxn = (w1->point.x - v0->point.x) * sign;
  756. if ((dxn > 0) && (dy1 < 0) && ((dx1 == 0) || ((dx1 < 0) && (dy1 * dx < dy * dx1)))) {
  757. v1 = w1;
  758. dx = dxn;
  759. continue;
  760. }
  761. }
  762. break;
  763. }
  764. } else if (dx < 0) {
  765. while (true) {
  766. int32_t dy = v1->point.y - v0->point.y;
  767. Vertex *w1 = side ? v1->prev : v1->next;
  768. if (w1 != v1) {
  769. int32_t dx1 = (w1->point.x - v1->point.x) * sign;
  770. int32_t dy1 = w1->point.y - v1->point.y;
  771. if ((dy1 >= 0) && ((dx1 == 0) || ((dx1 < 0) && (dy1 * dx <= dy * dx1)))) {
  772. v1 = w1;
  773. dx = (v1->point.x - v0->point.x) * sign;
  774. continue;
  775. }
  776. }
  777. Vertex *w0 = side ? v0->prev : v0->next;
  778. if (w0 != v0) {
  779. int32_t dx0 = (w0->point.x - v0->point.x) * sign;
  780. int32_t dy0 = w0->point.y - v0->point.y;
  781. int32_t dxn = (v1->point.x - w0->point.x) * sign;
  782. if ((dxn < 0) && (dy0 > 0) && ((dx0 == 0) || ((dx0 < 0) && (dy0 * dx < dy * dx0)))) {
  783. v0 = w0;
  784. dx = dxn;
  785. continue;
  786. }
  787. }
  788. break;
  789. }
  790. } else {
  791. int32_t x = v0->point.x;
  792. int32_t y0 = v0->point.y;
  793. Vertex *w0 = v0;
  794. Vertex *t;
  795. while (((t = side ? w0->next : w0->prev) != v0) && (t->point.x == x) && (t->point.y <= y0)) {
  796. w0 = t;
  797. y0 = t->point.y;
  798. }
  799. v0 = w0;
  800. int32_t y1 = v1->point.y;
  801. Vertex *w1 = v1;
  802. while (((t = side ? w1->prev : w1->next) != v1) && (t->point.x == x) && (t->point.y >= y1)) {
  803. w1 = t;
  804. y1 = t->point.y;
  805. }
  806. v1 = w1;
  807. }
  808. if (side == 0) {
  809. v00 = v0;
  810. v10 = v1;
  811. v0 = r_h0.min_xy;
  812. v1 = r_h1.min_xy;
  813. sign = -1;
  814. }
  815. }
  816. v0->prev = v1;
  817. v1->next = v0;
  818. v00->next = v10;
  819. v10->prev = v00;
  820. if (r_h1.min_xy->point.x < r_h0.min_xy->point.x) {
  821. r_h0.min_xy = r_h1.min_xy;
  822. }
  823. if (r_h1.max_xy->point.x >= r_h0.max_xy->point.x) {
  824. r_h0.max_xy = r_h1.max_xy;
  825. }
  826. r_h0.max_yx = r_h1.max_yx;
  827. r_c0 = v00;
  828. r_c1 = v10;
  829. return true;
  830. }
  831. void ConvexHullInternal::compute_internal(int32_t p_start, int32_t p_end, IntermediateHull &r_result) {
  832. int32_t n = p_end - p_start;
  833. switch (n) {
  834. case 0:
  835. r_result.min_xy = nullptr;
  836. r_result.max_xy = nullptr;
  837. r_result.min_yx = nullptr;
  838. r_result.max_yx = nullptr;
  839. return;
  840. case 2: {
  841. Vertex *v = original_vertices[p_start];
  842. Vertex *w = original_vertices[p_start + 1];
  843. if (v->point != w->point) {
  844. int32_t dx = v->point.x - w->point.x;
  845. int32_t dy = v->point.y - w->point.y;
  846. if ((dx == 0) && (dy == 0)) {
  847. if (v->point.z > w->point.z) {
  848. Vertex *t = w;
  849. w = v;
  850. v = t;
  851. }
  852. CHULL_ASSERT(v->point.z < w->point.z);
  853. v->next = v;
  854. v->prev = v;
  855. r_result.min_xy = v;
  856. r_result.max_xy = v;
  857. r_result.min_yx = v;
  858. r_result.max_yx = v;
  859. } else {
  860. v->next = w;
  861. v->prev = w;
  862. w->next = v;
  863. w->prev = v;
  864. if ((dx < 0) || ((dx == 0) && (dy < 0))) {
  865. r_result.min_xy = v;
  866. r_result.max_xy = w;
  867. } else {
  868. r_result.min_xy = w;
  869. r_result.max_xy = v;
  870. }
  871. if ((dy < 0) || ((dy == 0) && (dx < 0))) {
  872. r_result.min_yx = v;
  873. r_result.max_yx = w;
  874. } else {
  875. r_result.min_yx = w;
  876. r_result.max_yx = v;
  877. }
  878. }
  879. Edge *e = new_edge_pair(v, w);
  880. e->link(e);
  881. v->edges = e;
  882. e = e->reverse;
  883. e->link(e);
  884. w->edges = e;
  885. return;
  886. }
  887. [[fallthrough]];
  888. }
  889. case 1: {
  890. Vertex *v = original_vertices[p_start];
  891. v->edges = nullptr;
  892. v->next = v;
  893. v->prev = v;
  894. r_result.min_xy = v;
  895. r_result.max_xy = v;
  896. r_result.min_yx = v;
  897. r_result.max_yx = v;
  898. return;
  899. }
  900. }
  901. int32_t split0 = p_start + n / 2;
  902. Point32 p = original_vertices[split0 - 1]->point;
  903. int32_t split1 = split0;
  904. while ((split1 < p_end) && (original_vertices[split1]->point == p)) {
  905. split1++;
  906. }
  907. compute_internal(p_start, split0, r_result);
  908. IntermediateHull hull1;
  909. compute_internal(split1, p_end, hull1);
  910. #ifdef DEBUG_CONVEX_HULL
  911. printf("\n\nMerge\n");
  912. r_result.print();
  913. hull1.print();
  914. #endif
  915. merge(r_result, hull1);
  916. #ifdef DEBUG_CONVEX_HULL
  917. printf("\n Result\n");
  918. r_result.print();
  919. #endif
  920. }
  921. #ifdef DEBUG_CONVEX_HULL
  922. void ConvexHullInternal::IntermediateHull::print() {
  923. printf(" Hull\n");
  924. for (Vertex *v = min_xy; v;) {
  925. printf(" ");
  926. v->print();
  927. if (v == max_xy) {
  928. printf(" max_xy");
  929. }
  930. if (v == min_yx) {
  931. printf(" min_yx");
  932. }
  933. if (v == max_yx) {
  934. printf(" max_yx");
  935. }
  936. if (v->next->prev != v) {
  937. printf(" Inconsistency");
  938. }
  939. printf("\n");
  940. v = v->next;
  941. if (v == min_xy) {
  942. break;
  943. }
  944. }
  945. if (min_xy) {
  946. min_xy->copy = (min_xy->copy == -1) ? -2 : -1;
  947. min_xy->print_graph();
  948. }
  949. }
  950. void ConvexHullInternal::Vertex::print_graph() {
  951. print();
  952. printf("\nEdges\n");
  953. Edge *e = edges;
  954. if (e) {
  955. do {
  956. e->print();
  957. printf("\n");
  958. e = e->next;
  959. } while (e != edges);
  960. do {
  961. Vertex *v = e->target;
  962. if (v->copy != copy) {
  963. v->copy = copy;
  964. v->print_graph();
  965. }
  966. e = e->next;
  967. } while (e != edges);
  968. }
  969. }
  970. #endif
  971. ConvexHullInternal::Orientation ConvexHullInternal::get_orientation(const Edge *p_prev, const Edge *p_next, const Point32 &p_s, const Point32 &p_t) {
  972. CHULL_ASSERT(p_prev->reverse->target == p_next->reverse->target);
  973. if (p_prev->next == p_next) {
  974. if (p_prev->prev == p_next) {
  975. Point64 n = p_t.cross(p_s);
  976. Point64 m = (*p_prev->target - *p_next->reverse->target).cross(*p_next->target - *p_next->reverse->target);
  977. CHULL_ASSERT(!m.is_zero());
  978. int64_t dot = n.dot(m);
  979. CHULL_ASSERT(dot != 0);
  980. return (dot > 0) ? ORIENTATION_COUNTER_CLOCKWISE : ORIENTATION_CLOCKWISE;
  981. }
  982. return ORIENTATION_COUNTER_CLOCKWISE;
  983. } else if (p_prev->prev == p_next) {
  984. return ORIENTATION_CLOCKWISE;
  985. } else {
  986. return ORIENTATION_NONE;
  987. }
  988. }
  989. ConvexHullInternal::Edge *ConvexHullInternal::find_max_angle(bool p_ccw, const Vertex *p_start, const Point32 &p_s, const Point64 &p_rxs, const Point64 &p_sxrxs, Rational64 &p_min_cot) {
  990. Edge *min_edge = nullptr;
  991. #ifdef DEBUG_CONVEX_HULL
  992. printf("find max edge for %d\n", p_start->point.index);
  993. #endif
  994. Edge *e = p_start->edges;
  995. if (e) {
  996. do {
  997. if (e->copy > merge_stamp) {
  998. Point32 t = *e->target - *p_start;
  999. Rational64 cot(t.dot(p_sxrxs), t.dot(p_rxs));
  1000. #ifdef DEBUG_CONVEX_HULL
  1001. printf(" Angle is %f (%d) for ", Math::atan(cot.to_scalar()), (int32_t)cot.is_nan());
  1002. e->print();
  1003. #endif
  1004. if (cot.is_nan()) {
  1005. CHULL_ASSERT(p_ccw ? (t.dot(p_s) < 0) : (t.dot(p_s) > 0));
  1006. } else {
  1007. int32_t cmp;
  1008. if (min_edge == nullptr) {
  1009. p_min_cot = cot;
  1010. min_edge = e;
  1011. } else if ((cmp = cot.compare(p_min_cot)) < 0) {
  1012. p_min_cot = cot;
  1013. min_edge = e;
  1014. } else if ((cmp == 0) && (p_ccw == (get_orientation(min_edge, e, p_s, t) == ORIENTATION_COUNTER_CLOCKWISE))) {
  1015. min_edge = e;
  1016. }
  1017. }
  1018. #ifdef DEBUG_CONVEX_HULL
  1019. printf("\n");
  1020. #endif
  1021. }
  1022. e = e->next;
  1023. } while (e != p_start->edges);
  1024. }
  1025. return min_edge;
  1026. }
  1027. void ConvexHullInternal::find_edge_for_coplanar_faces(Vertex *p_c0, Vertex *p_c1, Edge *&p_e0, Edge *&p_e1, const Vertex *p_stop0, const Vertex *p_stop1) {
  1028. Edge *start0 = p_e0;
  1029. Edge *start1 = p_e1;
  1030. Point32 et0 = start0 ? start0->target->point : p_c0->point;
  1031. Point32 et1 = start1 ? start1->target->point : p_c1->point;
  1032. Point32 s = p_c1->point - p_c0->point;
  1033. Point64 normal = ((start0 ? start0 : start1)->target->point - p_c0->point).cross(s);
  1034. int64_t dist = p_c0->point.dot(normal);
  1035. CHULL_ASSERT(!start1 || (start1->target->point.dot(normal) == dist));
  1036. Point64 perp = s.cross(normal);
  1037. CHULL_ASSERT(!perp.is_zero());
  1038. #ifdef DEBUG_CONVEX_HULL
  1039. printf(" Advancing %d %d (%p %p, %d %d)\n", p_c0->point.index, p_c1->point.index, start0, start1, start0 ? start0->target->point.index : -1, start1 ? start1->target->point.index : -1);
  1040. #endif
  1041. int64_t max_dot0 = et0.dot(perp);
  1042. if (p_e0) {
  1043. while (p_e0->target != p_stop0) {
  1044. Edge *e = p_e0->reverse->prev;
  1045. if (e->target->point.dot(normal) < dist) {
  1046. break;
  1047. }
  1048. CHULL_ASSERT(e->target->point.dot(normal) == dist);
  1049. if (e->copy == merge_stamp) {
  1050. break;
  1051. }
  1052. int64_t dot = e->target->point.dot(perp);
  1053. if (dot <= max_dot0) {
  1054. break;
  1055. }
  1056. max_dot0 = dot;
  1057. p_e0 = e;
  1058. et0 = e->target->point;
  1059. }
  1060. }
  1061. int64_t max_dot1 = et1.dot(perp);
  1062. if (p_e1) {
  1063. while (p_e1->target != p_stop1) {
  1064. Edge *e = p_e1->reverse->next;
  1065. if (e->target->point.dot(normal) < dist) {
  1066. break;
  1067. }
  1068. CHULL_ASSERT(e->target->point.dot(normal) == dist);
  1069. if (e->copy == merge_stamp) {
  1070. break;
  1071. }
  1072. int64_t dot = e->target->point.dot(perp);
  1073. if (dot <= max_dot1) {
  1074. break;
  1075. }
  1076. max_dot1 = dot;
  1077. p_e1 = e;
  1078. et1 = e->target->point;
  1079. }
  1080. }
  1081. #ifdef DEBUG_CONVEX_HULL
  1082. printf(" Starting at %d %d\n", et0.index, et1.index);
  1083. #endif
  1084. int64_t dx = max_dot1 - max_dot0;
  1085. if (dx > 0) {
  1086. while (true) {
  1087. int64_t dy = (et1 - et0).dot(s);
  1088. if (p_e0 && (p_e0->target != p_stop0)) {
  1089. Edge *f0 = p_e0->next->reverse;
  1090. if (f0->copy > merge_stamp) {
  1091. int64_t dx0 = (f0->target->point - et0).dot(perp);
  1092. int64_t dy0 = (f0->target->point - et0).dot(s);
  1093. if ((dx0 == 0) ? (dy0 < 0) : ((dx0 < 0) && (Rational64(dy0, dx0).compare(Rational64(dy, dx)) >= 0))) {
  1094. et0 = f0->target->point;
  1095. dx = (et1 - et0).dot(perp);
  1096. p_e0 = (p_e0 == start0) ? nullptr : f0;
  1097. continue;
  1098. }
  1099. }
  1100. }
  1101. if (p_e1 && (p_e1->target != p_stop1)) {
  1102. Edge *f1 = p_e1->reverse->next;
  1103. if (f1->copy > merge_stamp) {
  1104. Point32 d1 = f1->target->point - et1;
  1105. if (d1.dot(normal) == 0) {
  1106. int64_t dx1 = d1.dot(perp);
  1107. int64_t dy1 = d1.dot(s);
  1108. int64_t dxn = (f1->target->point - et0).dot(perp);
  1109. if ((dxn > 0) && ((dx1 == 0) ? (dy1 < 0) : ((dx1 < 0) && (Rational64(dy1, dx1).compare(Rational64(dy, dx)) > 0)))) {
  1110. p_e1 = f1;
  1111. et1 = p_e1->target->point;
  1112. dx = dxn;
  1113. continue;
  1114. }
  1115. } else {
  1116. CHULL_ASSERT((p_e1 == start1) && (d1.dot(normal) < 0));
  1117. }
  1118. }
  1119. }
  1120. break;
  1121. }
  1122. } else if (dx < 0) {
  1123. while (true) {
  1124. int64_t dy = (et1 - et0).dot(s);
  1125. if (p_e1 && (p_e1->target != p_stop1)) {
  1126. Edge *f1 = p_e1->prev->reverse;
  1127. if (f1->copy > merge_stamp) {
  1128. int64_t dx1 = (f1->target->point - et1).dot(perp);
  1129. int64_t dy1 = (f1->target->point - et1).dot(s);
  1130. if ((dx1 == 0) ? (dy1 > 0) : ((dx1 < 0) && (Rational64(dy1, dx1).compare(Rational64(dy, dx)) <= 0))) {
  1131. et1 = f1->target->point;
  1132. dx = (et1 - et0).dot(perp);
  1133. p_e1 = (p_e1 == start1) ? nullptr : f1;
  1134. continue;
  1135. }
  1136. }
  1137. }
  1138. if (p_e0 && (p_e0->target != p_stop0)) {
  1139. Edge *f0 = p_e0->reverse->prev;
  1140. if (f0->copy > merge_stamp) {
  1141. Point32 d0 = f0->target->point - et0;
  1142. if (d0.dot(normal) == 0) {
  1143. int64_t dx0 = d0.dot(perp);
  1144. int64_t dy0 = d0.dot(s);
  1145. int64_t dxn = (et1 - f0->target->point).dot(perp);
  1146. if ((dxn < 0) && ((dx0 == 0) ? (dy0 > 0) : ((dx0 < 0) && (Rational64(dy0, dx0).compare(Rational64(dy, dx)) < 0)))) {
  1147. p_e0 = f0;
  1148. et0 = p_e0->target->point;
  1149. dx = dxn;
  1150. continue;
  1151. }
  1152. } else {
  1153. CHULL_ASSERT((p_e0 == start0) && (d0.dot(normal) < 0));
  1154. }
  1155. }
  1156. }
  1157. break;
  1158. }
  1159. }
  1160. #ifdef DEBUG_CONVEX_HULL
  1161. printf(" Advanced edges to %d %d\n", et0.index, et1.index);
  1162. #endif
  1163. }
  1164. void ConvexHullInternal::merge(IntermediateHull &p_h0, IntermediateHull &p_h1) {
  1165. if (!p_h1.max_xy) {
  1166. return;
  1167. }
  1168. if (!p_h0.max_xy) {
  1169. p_h0 = p_h1;
  1170. return;
  1171. }
  1172. merge_stamp--;
  1173. Vertex *c0 = nullptr;
  1174. Edge *to_prev0 = nullptr;
  1175. Edge *first_new0 = nullptr;
  1176. Edge *pending_head0 = nullptr;
  1177. Edge *pending_tail0 = nullptr;
  1178. Vertex *c1 = nullptr;
  1179. Edge *to_prev1 = nullptr;
  1180. Edge *first_new1 = nullptr;
  1181. Edge *pending_head1 = nullptr;
  1182. Edge *pending_tail1 = nullptr;
  1183. Point32 prev_point;
  1184. if (merge_projection(p_h0, p_h1, c0, c1)) {
  1185. Point32 s = *c1 - *c0;
  1186. Point64 normal = Point32(0, 0, -1).cross(s);
  1187. Point64 t = s.cross(normal);
  1188. CHULL_ASSERT(!t.is_zero());
  1189. Edge *e = c0->edges;
  1190. Edge *start0 = nullptr;
  1191. if (e) {
  1192. do {
  1193. int64_t dot = (*e->target - *c0).dot(normal);
  1194. CHULL_ASSERT(dot <= 0);
  1195. if ((dot == 0) && ((*e->target - *c0).dot(t) > 0)) {
  1196. if (!start0 || (get_orientation(start0, e, s, Point32(0, 0, -1)) == ORIENTATION_CLOCKWISE)) {
  1197. start0 = e;
  1198. }
  1199. }
  1200. e = e->next;
  1201. } while (e != c0->edges);
  1202. }
  1203. e = c1->edges;
  1204. Edge *start1 = nullptr;
  1205. if (e) {
  1206. do {
  1207. int64_t dot = (*e->target - *c1).dot(normal);
  1208. CHULL_ASSERT(dot <= 0);
  1209. if ((dot == 0) && ((*e->target - *c1).dot(t) > 0)) {
  1210. if (!start1 || (get_orientation(start1, e, s, Point32(0, 0, -1)) == ORIENTATION_COUNTER_CLOCKWISE)) {
  1211. start1 = e;
  1212. }
  1213. }
  1214. e = e->next;
  1215. } while (e != c1->edges);
  1216. }
  1217. if (start0 || start1) {
  1218. find_edge_for_coplanar_faces(c0, c1, start0, start1, nullptr, nullptr);
  1219. if (start0) {
  1220. c0 = start0->target;
  1221. }
  1222. if (start1) {
  1223. c1 = start1->target;
  1224. }
  1225. }
  1226. prev_point = c1->point;
  1227. prev_point.z++;
  1228. } else {
  1229. prev_point = c1->point;
  1230. prev_point.x++;
  1231. }
  1232. Vertex *first0 = c0;
  1233. Vertex *first1 = c1;
  1234. bool first_run = true;
  1235. while (true) {
  1236. Point32 s = *c1 - *c0;
  1237. Point32 r = prev_point - c0->point;
  1238. Point64 rxs = r.cross(s);
  1239. Point64 sxrxs = s.cross(rxs);
  1240. #ifdef DEBUG_CONVEX_HULL
  1241. printf("\n Checking %d %d\n", c0->point.index, c1->point.index);
  1242. #endif
  1243. Rational64 min_cot0(0, 0);
  1244. Edge *min0 = find_max_angle(false, c0, s, rxs, sxrxs, min_cot0);
  1245. Rational64 min_cot1(0, 0);
  1246. Edge *min1 = find_max_angle(true, c1, s, rxs, sxrxs, min_cot1);
  1247. if (!min0 && !min1) {
  1248. Edge *e = new_edge_pair(c0, c1);
  1249. e->link(e);
  1250. c0->edges = e;
  1251. e = e->reverse;
  1252. e->link(e);
  1253. c1->edges = e;
  1254. return;
  1255. } else {
  1256. int32_t cmp = !min0 ? 1 : (!min1 ? -1 : min_cot0.compare(min_cot1));
  1257. #ifdef DEBUG_CONVEX_HULL
  1258. printf(" -> Result %d\n", cmp);
  1259. #endif
  1260. if (first_run || ((cmp >= 0) ? !min_cot1.is_negative_infinity() : !min_cot0.is_negative_infinity())) {
  1261. Edge *e = new_edge_pair(c0, c1);
  1262. if (pending_tail0) {
  1263. pending_tail0->prev = e;
  1264. } else {
  1265. pending_head0 = e;
  1266. }
  1267. e->next = pending_tail0;
  1268. pending_tail0 = e;
  1269. e = e->reverse;
  1270. if (pending_tail1) {
  1271. pending_tail1->next = e;
  1272. } else {
  1273. pending_head1 = e;
  1274. }
  1275. e->prev = pending_tail1;
  1276. pending_tail1 = e;
  1277. }
  1278. Edge *e0 = min0;
  1279. Edge *e1 = min1;
  1280. #ifdef DEBUG_CONVEX_HULL
  1281. printf(" Found min edges to %d %d\n", e0 ? e0->target->point.index : -1, e1 ? e1->target->point.index : -1);
  1282. #endif
  1283. if (cmp == 0) {
  1284. find_edge_for_coplanar_faces(c0, c1, e0, e1, nullptr, nullptr);
  1285. }
  1286. if ((cmp >= 0) && e1) {
  1287. if (to_prev1) {
  1288. for (Edge *e = to_prev1->next, *n = nullptr; e != min1; e = n) {
  1289. n = e->next;
  1290. remove_edge_pair(e);
  1291. }
  1292. }
  1293. if (pending_tail1) {
  1294. if (to_prev1) {
  1295. to_prev1->link(pending_head1);
  1296. } else {
  1297. min1->prev->link(pending_head1);
  1298. first_new1 = pending_head1;
  1299. }
  1300. pending_tail1->link(min1);
  1301. pending_head1 = nullptr;
  1302. pending_tail1 = nullptr;
  1303. } else if (!to_prev1) {
  1304. first_new1 = min1;
  1305. }
  1306. prev_point = c1->point;
  1307. c1 = e1->target;
  1308. to_prev1 = e1->reverse;
  1309. }
  1310. if ((cmp <= 0) && e0) {
  1311. if (to_prev0) {
  1312. for (Edge *e = to_prev0->prev, *n = nullptr; e != min0; e = n) {
  1313. n = e->prev;
  1314. remove_edge_pair(e);
  1315. }
  1316. }
  1317. if (pending_tail0) {
  1318. if (to_prev0) {
  1319. pending_head0->link(to_prev0);
  1320. } else {
  1321. pending_head0->link(min0->next);
  1322. first_new0 = pending_head0;
  1323. }
  1324. min0->link(pending_tail0);
  1325. pending_head0 = nullptr;
  1326. pending_tail0 = nullptr;
  1327. } else if (!to_prev0) {
  1328. first_new0 = min0;
  1329. }
  1330. prev_point = c0->point;
  1331. c0 = e0->target;
  1332. to_prev0 = e0->reverse;
  1333. }
  1334. }
  1335. if ((c0 == first0) && (c1 == first1)) {
  1336. if (to_prev0 == nullptr) {
  1337. pending_head0->link(pending_tail0);
  1338. c0->edges = pending_tail0;
  1339. } else {
  1340. for (Edge *e = to_prev0->prev, *n = nullptr; e != first_new0; e = n) {
  1341. n = e->prev;
  1342. remove_edge_pair(e);
  1343. }
  1344. if (pending_tail0) {
  1345. pending_head0->link(to_prev0);
  1346. first_new0->link(pending_tail0);
  1347. }
  1348. }
  1349. if (to_prev1 == nullptr) {
  1350. pending_tail1->link(pending_head1);
  1351. c1->edges = pending_tail1;
  1352. } else {
  1353. for (Edge *e = to_prev1->next, *n = nullptr; e != first_new1; e = n) {
  1354. n = e->next;
  1355. remove_edge_pair(e);
  1356. }
  1357. if (pending_tail1) {
  1358. to_prev1->link(pending_head1);
  1359. pending_tail1->link(first_new1);
  1360. }
  1361. }
  1362. return;
  1363. }
  1364. first_run = false;
  1365. }
  1366. }
  1367. struct PointComparator {
  1368. _FORCE_INLINE_ bool operator()(const ConvexHullInternal::Point32 &p, const ConvexHullInternal::Point32 &q) const {
  1369. return (p.y < q.y) || ((p.y == q.y) && ((p.x < q.x) || ((p.x == q.x) && (p.z < q.z))));
  1370. }
  1371. };
  1372. void ConvexHullInternal::compute(const Vector3 *p_coords, int32_t p_count) {
  1373. AABB aabb;
  1374. for (int32_t i = 0; i < p_count; i++) {
  1375. Vector3 p = p_coords[i];
  1376. if (i == 0) {
  1377. aabb.position = p;
  1378. } else {
  1379. aabb.expand_to(p);
  1380. }
  1381. }
  1382. Vector3 s = aabb.size;
  1383. max_axis = s.max_axis_index();
  1384. min_axis = s.min_axis_index();
  1385. if (min_axis == max_axis) {
  1386. min_axis = Vector3::Axis((max_axis + 1) % 3);
  1387. }
  1388. med_axis = Vector3::Axis(3 - max_axis - min_axis);
  1389. s /= real_t(10216);
  1390. if (((med_axis + 1) % 3) != max_axis) {
  1391. s *= -1;
  1392. }
  1393. scaling = s;
  1394. if (s[0] != 0) {
  1395. s[0] = real_t(1) / s[0];
  1396. }
  1397. if (s[1] != 0) {
  1398. s[1] = real_t(1) / s[1];
  1399. }
  1400. if (s[2] != 0) {
  1401. s[2] = real_t(1) / s[2];
  1402. }
  1403. center = aabb.position;
  1404. LocalVector<Point32> points;
  1405. points.resize(p_count);
  1406. for (int32_t i = 0; i < p_count; i++) {
  1407. Vector3 p = p_coords[i];
  1408. p = (p - center) * s;
  1409. points[i].x = (int32_t)p[med_axis];
  1410. points[i].y = (int32_t)p[max_axis];
  1411. points[i].z = (int32_t)p[min_axis];
  1412. points[i].index = i;
  1413. }
  1414. points.sort_custom<PointComparator>();
  1415. vertex_pool.reset(true);
  1416. original_vertices.resize(p_count);
  1417. for (int32_t i = 0; i < p_count; i++) {
  1418. Vertex *v = vertex_pool.alloc();
  1419. v->edges = nullptr;
  1420. v->point = points[i];
  1421. v->copy = -1;
  1422. original_vertices[i] = v;
  1423. }
  1424. points.clear();
  1425. edge_pool.reset(true);
  1426. used_edge_pairs = 0;
  1427. max_used_edge_pairs = 0;
  1428. merge_stamp = -3;
  1429. IntermediateHull hull;
  1430. compute_internal(0, p_count, hull);
  1431. vertex_list = hull.min_xy;
  1432. #ifdef DEBUG_CONVEX_HULL
  1433. printf("max. edges %d (3v = %d)", max_used_edge_pairs, 3 * p_count);
  1434. #endif
  1435. }
  1436. Vector3 ConvexHullInternal::to_gd_vector(const Point32 &p_v) {
  1437. Vector3 p;
  1438. p[med_axis] = real_t(p_v.x);
  1439. p[max_axis] = real_t(p_v.y);
  1440. p[min_axis] = real_t(p_v.z);
  1441. return p * scaling;
  1442. }
  1443. Vector3 ConvexHullInternal::get_gd_normal(Face *p_face) {
  1444. return to_gd_vector(p_face->dir0).cross(to_gd_vector(p_face->dir1)).normalized();
  1445. }
  1446. Vector3 ConvexHullInternal::get_coordinates(const Vertex *p_v) {
  1447. Vector3 p;
  1448. p[med_axis] = p_v->xvalue();
  1449. p[max_axis] = p_v->yvalue();
  1450. p[min_axis] = p_v->zvalue();
  1451. return p * scaling + center;
  1452. }
  1453. real_t ConvexHullInternal::shrink(real_t p_amount, real_t p_clamp_amount) {
  1454. if (!vertex_list) {
  1455. return 0;
  1456. }
  1457. int32_t stamp = --merge_stamp;
  1458. LocalVector<Vertex *> stack;
  1459. vertex_list->copy = stamp;
  1460. stack.push_back(vertex_list);
  1461. LocalVector<Face *> faces;
  1462. Point32 ref = vertex_list->point;
  1463. Int128 hull_center_x(0, 0);
  1464. Int128 hull_center_y(0, 0);
  1465. Int128 hull_center_z(0, 0);
  1466. Int128 volume(0, 0);
  1467. while (stack.size() > 0) {
  1468. Vertex *v = stack[stack.size() - 1];
  1469. stack.remove_at(stack.size() - 1);
  1470. Edge *e = v->edges;
  1471. if (e) {
  1472. do {
  1473. if (e->target->copy != stamp) {
  1474. e->target->copy = stamp;
  1475. stack.push_back(e->target);
  1476. }
  1477. if (e->copy != stamp) {
  1478. Face *face = face_pool.alloc();
  1479. face->init(e->target, e->reverse->prev->target, v);
  1480. faces.push_back(face);
  1481. Edge *f = e;
  1482. Vertex *a = nullptr;
  1483. Vertex *b = nullptr;
  1484. do {
  1485. if (a && b) {
  1486. int64_t vol = (v->point - ref).dot((a->point - ref).cross(b->point - ref));
  1487. CHULL_ASSERT(vol >= 0);
  1488. Point32 c = v->point + a->point + b->point + ref;
  1489. hull_center_x += vol * c.x;
  1490. hull_center_y += vol * c.y;
  1491. hull_center_z += vol * c.z;
  1492. volume += vol;
  1493. }
  1494. CHULL_ASSERT(f->copy != stamp);
  1495. f->copy = stamp;
  1496. f->face = face;
  1497. a = b;
  1498. b = f->target;
  1499. f = f->reverse->prev;
  1500. } while (f != e);
  1501. }
  1502. e = e->next;
  1503. } while (e != v->edges);
  1504. }
  1505. }
  1506. if (volume.get_sign() <= 0) {
  1507. return 0;
  1508. }
  1509. Vector3 hull_center;
  1510. hull_center[med_axis] = hull_center_x.to_scalar();
  1511. hull_center[max_axis] = hull_center_y.to_scalar();
  1512. hull_center[min_axis] = hull_center_z.to_scalar();
  1513. hull_center /= 4 * volume.to_scalar();
  1514. hull_center *= scaling;
  1515. int32_t face_count = faces.size();
  1516. if (p_clamp_amount > 0) {
  1517. real_t min_dist = FLT_MAX;
  1518. for (int32_t i = 0; i < face_count; i++) {
  1519. Vector3 normal = get_gd_normal(faces[i]);
  1520. real_t dist = normal.dot(to_gd_vector(faces[i]->origin) - hull_center);
  1521. if (dist < min_dist) {
  1522. min_dist = dist;
  1523. }
  1524. }
  1525. if (min_dist <= 0) {
  1526. return 0;
  1527. }
  1528. p_amount = MIN(p_amount, min_dist * p_clamp_amount);
  1529. }
  1530. uint32_t seed = 243703;
  1531. for (int32_t i = 0; i < face_count; i++, seed = 1664525 * seed + 1013904223) {
  1532. SWAP(faces[i], faces[seed % face_count]);
  1533. }
  1534. for (int32_t i = 0; i < face_count; i++) {
  1535. if (!shift_face(faces[i], p_amount, stack)) {
  1536. return -p_amount;
  1537. }
  1538. }
  1539. return p_amount;
  1540. }
  1541. bool ConvexHullInternal::shift_face(Face *p_face, real_t p_amount, LocalVector<Vertex *> &p_stack) {
  1542. Vector3 orig_shift = get_gd_normal(p_face) * -p_amount;
  1543. if (scaling[0] != 0) {
  1544. orig_shift[0] /= scaling[0];
  1545. }
  1546. if (scaling[1] != 0) {
  1547. orig_shift[1] /= scaling[1];
  1548. }
  1549. if (scaling[2] != 0) {
  1550. orig_shift[2] /= scaling[2];
  1551. }
  1552. Point32 shift((int32_t)orig_shift[med_axis], (int32_t)orig_shift[max_axis], (int32_t)orig_shift[min_axis]);
  1553. if (shift.is_zero()) {
  1554. return true;
  1555. }
  1556. Point64 normal = p_face->get_normal();
  1557. #ifdef DEBUG_CONVEX_HULL
  1558. printf("\nShrinking p_face (%d %d %d) (%d %d %d) (%d %d %d) by (%d %d %d)\n",
  1559. p_face->origin.x, p_face->origin.y, p_face->origin.z, p_face->dir0.x, p_face->dir0.y, p_face->dir0.z, p_face->dir1.x, p_face->dir1.y, p_face->dir1.z, shift.x, shift.y, shift.z);
  1560. #endif
  1561. int64_t orig_dot = p_face->origin.dot(normal);
  1562. Point32 shifted_origin = p_face->origin + shift;
  1563. int64_t shifted_dot = shifted_origin.dot(normal);
  1564. CHULL_ASSERT(shifted_dot <= orig_dot);
  1565. if (shifted_dot >= orig_dot) {
  1566. return false;
  1567. }
  1568. Edge *intersection = nullptr;
  1569. Edge *start_edge = p_face->nearby_vertex->edges;
  1570. #ifdef DEBUG_CONVEX_HULL
  1571. printf("Start edge is ");
  1572. start_edge->print();
  1573. printf(", normal is (%lld %lld %lld), shifted dot is %lld\n", normal.x, normal.y, normal.z, shifted_dot);
  1574. #endif
  1575. Rational128 opt_dot = p_face->nearby_vertex->dot(normal);
  1576. int32_t cmp = opt_dot.compare(shifted_dot);
  1577. #ifdef SHOW_ITERATIONS
  1578. int32_t n = 0;
  1579. #endif
  1580. if (cmp >= 0) {
  1581. Edge *e = start_edge;
  1582. do {
  1583. #ifdef SHOW_ITERATIONS
  1584. n++;
  1585. #endif
  1586. Rational128 dot = e->target->dot(normal);
  1587. CHULL_ASSERT(dot.compare(orig_dot) <= 0);
  1588. #ifdef DEBUG_CONVEX_HULL
  1589. printf("Moving downwards, edge is ");
  1590. e->print();
  1591. printf(", dot is %f (%f %lld)\n", (float)dot.to_scalar(), (float)opt_dot.to_scalar(), shifted_dot);
  1592. #endif
  1593. if (dot.compare(opt_dot) < 0) {
  1594. int32_t c = dot.compare(shifted_dot);
  1595. opt_dot = dot;
  1596. e = e->reverse;
  1597. start_edge = e;
  1598. if (c < 0) {
  1599. intersection = e;
  1600. break;
  1601. }
  1602. cmp = c;
  1603. }
  1604. e = e->prev;
  1605. } while (e != start_edge);
  1606. if (!intersection) {
  1607. return false;
  1608. }
  1609. } else {
  1610. Edge *e = start_edge;
  1611. do {
  1612. #ifdef SHOW_ITERATIONS
  1613. n++;
  1614. #endif
  1615. Rational128 dot = e->target->dot(normal);
  1616. CHULL_ASSERT(dot.compare(orig_dot) <= 0);
  1617. #ifdef DEBUG_CONVEX_HULL
  1618. printf("Moving upwards, edge is ");
  1619. e->print();
  1620. printf(", dot is %f (%f %lld)\n", (float)dot.to_scalar(), (float)opt_dot.to_scalar(), shifted_dot);
  1621. #endif
  1622. if (dot.compare(opt_dot) > 0) {
  1623. cmp = dot.compare(shifted_dot);
  1624. if (cmp >= 0) {
  1625. intersection = e;
  1626. break;
  1627. }
  1628. opt_dot = dot;
  1629. e = e->reverse;
  1630. start_edge = e;
  1631. }
  1632. e = e->prev;
  1633. } while (e != start_edge);
  1634. if (!intersection) {
  1635. return true;
  1636. }
  1637. }
  1638. #ifdef SHOW_ITERATIONS
  1639. printf("Needed %d iterations to find initial intersection\n", n);
  1640. #endif
  1641. if (cmp == 0) {
  1642. Edge *e = intersection->reverse->next;
  1643. #ifdef SHOW_ITERATIONS
  1644. n = 0;
  1645. #endif
  1646. while (e->target->dot(normal).compare(shifted_dot) <= 0) {
  1647. #ifdef SHOW_ITERATIONS
  1648. n++;
  1649. #endif
  1650. e = e->next;
  1651. if (e == intersection->reverse) {
  1652. return true;
  1653. }
  1654. #ifdef DEBUG_CONVEX_HULL
  1655. printf("Checking for outwards edge, current edge is ");
  1656. e->print();
  1657. printf("\n");
  1658. #endif
  1659. }
  1660. #ifdef SHOW_ITERATIONS
  1661. printf("Needed %d iterations to check for complete containment\n", n);
  1662. #endif
  1663. }
  1664. Edge *first_intersection = nullptr;
  1665. Edge *face_edge = nullptr;
  1666. Edge *first_face_edge = nullptr;
  1667. #ifdef SHOW_ITERATIONS
  1668. int32_t m = 0;
  1669. #endif
  1670. while (true) {
  1671. #ifdef SHOW_ITERATIONS
  1672. m++;
  1673. #endif
  1674. #ifdef DEBUG_CONVEX_HULL
  1675. printf("Intersecting edge is ");
  1676. intersection->print();
  1677. printf("\n");
  1678. #endif
  1679. if (cmp == 0) {
  1680. Edge *e = intersection->reverse->next;
  1681. start_edge = e;
  1682. #ifdef SHOW_ITERATIONS
  1683. n = 0;
  1684. #endif
  1685. while (true) {
  1686. #ifdef SHOW_ITERATIONS
  1687. n++;
  1688. #endif
  1689. if (e->target->dot(normal).compare(shifted_dot) >= 0) {
  1690. break;
  1691. }
  1692. intersection = e->reverse;
  1693. e = e->next;
  1694. if (e == start_edge) {
  1695. return true;
  1696. }
  1697. }
  1698. #ifdef SHOW_ITERATIONS
  1699. printf("Needed %d iterations to advance intersection\n", n);
  1700. #endif
  1701. }
  1702. #ifdef DEBUG_CONVEX_HULL
  1703. printf("Advanced intersecting edge to ");
  1704. intersection->print();
  1705. printf(", cmp = %d\n", cmp);
  1706. #endif
  1707. if (!first_intersection) {
  1708. first_intersection = intersection;
  1709. } else if (intersection == first_intersection) {
  1710. break;
  1711. }
  1712. int32_t prev_cmp = cmp;
  1713. Edge *prev_intersection = intersection;
  1714. Edge *prev_face_edge = face_edge;
  1715. Edge *e = intersection->reverse;
  1716. #ifdef SHOW_ITERATIONS
  1717. n = 0;
  1718. #endif
  1719. while (true) {
  1720. #ifdef SHOW_ITERATIONS
  1721. n++;
  1722. #endif
  1723. e = e->reverse->prev;
  1724. CHULL_ASSERT(e != intersection->reverse);
  1725. cmp = e->target->dot(normal).compare(shifted_dot);
  1726. #ifdef DEBUG_CONVEX_HULL
  1727. printf("Testing edge ");
  1728. e->print();
  1729. printf(" -> cmp = %d\n", cmp);
  1730. #endif
  1731. if (cmp >= 0) {
  1732. intersection = e;
  1733. break;
  1734. }
  1735. }
  1736. #ifdef SHOW_ITERATIONS
  1737. printf("Needed %d iterations to find other intersection of p_face\n", n);
  1738. #endif
  1739. if (cmp > 0) {
  1740. Vertex *removed = intersection->target;
  1741. e = intersection->reverse;
  1742. if (e->prev == e) {
  1743. removed->edges = nullptr;
  1744. } else {
  1745. removed->edges = e->prev;
  1746. e->prev->link(e->next);
  1747. e->link(e);
  1748. }
  1749. #ifdef DEBUG_CONVEX_HULL
  1750. printf("1: Removed part contains (%d %d %d)\n", removed->point.x, removed->point.y, removed->point.z);
  1751. #endif
  1752. Point64 n0 = intersection->face->get_normal();
  1753. Point64 n1 = intersection->reverse->face->get_normal();
  1754. int64_t m00 = p_face->dir0.dot(n0);
  1755. int64_t m01 = p_face->dir1.dot(n0);
  1756. int64_t m10 = p_face->dir0.dot(n1);
  1757. int64_t m11 = p_face->dir1.dot(n1);
  1758. int64_t r0 = (intersection->face->origin - shifted_origin).dot(n0);
  1759. int64_t r1 = (intersection->reverse->face->origin - shifted_origin).dot(n1);
  1760. Int128 det = Int128::mul(m00, m11) - Int128::mul(m01, m10);
  1761. CHULL_ASSERT(det.get_sign() != 0);
  1762. Vertex *v = vertex_pool.alloc();
  1763. v->point.index = -1;
  1764. v->copy = -1;
  1765. v->point128 = PointR128(Int128::mul(p_face->dir0.x * r0, m11) - Int128::mul(p_face->dir0.x * r1, m01) + Int128::mul(p_face->dir1.x * r1, m00) - Int128::mul(p_face->dir1.x * r0, m10) + det * shifted_origin.x,
  1766. Int128::mul(p_face->dir0.y * r0, m11) - Int128::mul(p_face->dir0.y * r1, m01) + Int128::mul(p_face->dir1.y * r1, m00) - Int128::mul(p_face->dir1.y * r0, m10) + det * shifted_origin.y,
  1767. Int128::mul(p_face->dir0.z * r0, m11) - Int128::mul(p_face->dir0.z * r1, m01) + Int128::mul(p_face->dir1.z * r1, m00) - Int128::mul(p_face->dir1.z * r0, m10) + det * shifted_origin.z,
  1768. det);
  1769. v->point.x = (int32_t)v->point128.xvalue();
  1770. v->point.y = (int32_t)v->point128.yvalue();
  1771. v->point.z = (int32_t)v->point128.zvalue();
  1772. intersection->target = v;
  1773. v->edges = e;
  1774. p_stack.push_back(v);
  1775. p_stack.push_back(removed);
  1776. p_stack.push_back(nullptr);
  1777. }
  1778. if (cmp || prev_cmp || (prev_intersection->reverse->next->target != intersection->target)) {
  1779. face_edge = new_edge_pair(prev_intersection->target, intersection->target);
  1780. if (prev_cmp == 0) {
  1781. face_edge->link(prev_intersection->reverse->next);
  1782. }
  1783. if ((prev_cmp == 0) || prev_face_edge) {
  1784. prev_intersection->reverse->link(face_edge);
  1785. }
  1786. if (cmp == 0) {
  1787. intersection->reverse->prev->link(face_edge->reverse);
  1788. }
  1789. face_edge->reverse->link(intersection->reverse);
  1790. } else {
  1791. face_edge = prev_intersection->reverse->next;
  1792. }
  1793. if (prev_face_edge) {
  1794. if (prev_cmp > 0) {
  1795. face_edge->link(prev_face_edge->reverse);
  1796. } else if (face_edge != prev_face_edge->reverse) {
  1797. p_stack.push_back(prev_face_edge->target);
  1798. while (face_edge->next != prev_face_edge->reverse) {
  1799. Vertex *removed = face_edge->next->target;
  1800. remove_edge_pair(face_edge->next);
  1801. p_stack.push_back(removed);
  1802. #ifdef DEBUG_CONVEX_HULL
  1803. printf("2: Removed part contains (%d %d %d)\n", removed->point.x, removed->point.y, removed->point.z);
  1804. #endif
  1805. }
  1806. p_stack.push_back(nullptr);
  1807. }
  1808. }
  1809. face_edge->face = p_face;
  1810. face_edge->reverse->face = intersection->face;
  1811. if (!first_face_edge) {
  1812. first_face_edge = face_edge;
  1813. }
  1814. }
  1815. #ifdef SHOW_ITERATIONS
  1816. printf("Needed %d iterations to process all intersections\n", m);
  1817. #endif
  1818. if (cmp > 0) {
  1819. first_face_edge->reverse->target = face_edge->target;
  1820. first_intersection->reverse->link(first_face_edge);
  1821. first_face_edge->link(face_edge->reverse);
  1822. } else if (first_face_edge != face_edge->reverse) {
  1823. p_stack.push_back(face_edge->target);
  1824. while (first_face_edge->next != face_edge->reverse) {
  1825. Vertex *removed = first_face_edge->next->target;
  1826. remove_edge_pair(first_face_edge->next);
  1827. p_stack.push_back(removed);
  1828. #ifdef DEBUG_CONVEX_HULL
  1829. printf("3: Removed part contains (%d %d %d)\n", removed->point.x, removed->point.y, removed->point.z);
  1830. #endif
  1831. }
  1832. p_stack.push_back(nullptr);
  1833. }
  1834. CHULL_ASSERT(p_stack.size() > 0);
  1835. vertex_list = p_stack[0];
  1836. #ifdef DEBUG_CONVEX_HULL
  1837. printf("Removing part\n");
  1838. #endif
  1839. #ifdef SHOW_ITERATIONS
  1840. n = 0;
  1841. #endif
  1842. uint32_t pos = 0;
  1843. while (pos < p_stack.size()) {
  1844. uint32_t end = p_stack.size();
  1845. while (pos < end) {
  1846. Vertex *kept = p_stack[pos++];
  1847. #ifdef DEBUG_CONVEX_HULL
  1848. kept->print();
  1849. #endif
  1850. bool deeper = false;
  1851. Vertex *removed;
  1852. while ((removed = p_stack[pos++]) != nullptr) {
  1853. #ifdef SHOW_ITERATIONS
  1854. n++;
  1855. #endif
  1856. kept->receive_nearby_faces(removed);
  1857. while (removed->edges) {
  1858. if (!deeper) {
  1859. deeper = true;
  1860. p_stack.push_back(kept);
  1861. }
  1862. p_stack.push_back(removed->edges->target);
  1863. remove_edge_pair(removed->edges);
  1864. }
  1865. }
  1866. if (deeper) {
  1867. p_stack.push_back(nullptr);
  1868. }
  1869. }
  1870. }
  1871. #ifdef SHOW_ITERATIONS
  1872. printf("Needed %d iterations to remove part\n", n);
  1873. #endif
  1874. p_stack.clear();
  1875. p_face->origin = shifted_origin;
  1876. return true;
  1877. }
  1878. static int32_t get_vertex_copy(ConvexHullInternal::Vertex *p_vertex, LocalVector<ConvexHullInternal::Vertex *> &p_vertices) {
  1879. int32_t index = p_vertex->copy;
  1880. if (index < 0) {
  1881. index = p_vertices.size();
  1882. p_vertex->copy = index;
  1883. p_vertices.push_back(p_vertex);
  1884. #ifdef DEBUG_CONVEX_HULL
  1885. printf("Vertex %d gets index *%d\n", p_vertex->point.index, index);
  1886. #endif
  1887. }
  1888. return index;
  1889. }
  1890. real_t ConvexHullComputer::compute(const Vector3 *p_coords, int32_t p_count, real_t p_shrink, real_t p_shrink_clamp) {
  1891. if (p_count <= 0) {
  1892. vertices.clear();
  1893. edges.clear();
  1894. faces.clear();
  1895. return 0;
  1896. }
  1897. ConvexHullInternal hull;
  1898. hull.compute(p_coords, p_count);
  1899. real_t shift = 0;
  1900. if ((p_shrink > 0) && ((shift = hull.shrink(p_shrink, p_shrink_clamp)) < 0)) {
  1901. vertices.clear();
  1902. edges.clear();
  1903. faces.clear();
  1904. return shift;
  1905. }
  1906. vertices.clear();
  1907. edges.clear();
  1908. faces.clear();
  1909. LocalVector<ConvexHullInternal::Vertex *> old_vertices;
  1910. get_vertex_copy(hull.vertex_list, old_vertices);
  1911. int32_t copied = 0;
  1912. while (copied < (int32_t)old_vertices.size()) {
  1913. ConvexHullInternal::Vertex *v = old_vertices[copied];
  1914. vertices.push_back(hull.get_coordinates(v));
  1915. ConvexHullInternal::Edge *first_edge = v->edges;
  1916. if (first_edge) {
  1917. int32_t first_copy = -1;
  1918. int32_t prev_copy = -1;
  1919. ConvexHullInternal::Edge *e = first_edge;
  1920. do {
  1921. if (e->copy < 0) {
  1922. int32_t s = edges.size();
  1923. edges.push_back(Edge());
  1924. edges.push_back(Edge());
  1925. Edge *c = &edges[s];
  1926. Edge *r = &edges[s + 1];
  1927. e->copy = s;
  1928. e->reverse->copy = s + 1;
  1929. c->reverse = 1;
  1930. r->reverse = -1;
  1931. c->target_vertex = get_vertex_copy(e->target, old_vertices);
  1932. r->target_vertex = copied;
  1933. #ifdef DEBUG_CONVEX_HULL
  1934. printf(" CREATE: Vertex *%d has edge to *%d\n", copied, c->get_target_vertex());
  1935. #endif
  1936. }
  1937. if (prev_copy >= 0) {
  1938. edges[e->copy].next = prev_copy - e->copy;
  1939. } else {
  1940. first_copy = e->copy;
  1941. }
  1942. prev_copy = e->copy;
  1943. e = e->next;
  1944. } while (e != first_edge);
  1945. edges[first_copy].next = prev_copy - first_copy;
  1946. }
  1947. copied++;
  1948. }
  1949. for (int32_t i = 0; i < copied; i++) {
  1950. ConvexHullInternal::Vertex *v = old_vertices[i];
  1951. ConvexHullInternal::Edge *first_edge = v->edges;
  1952. if (first_edge) {
  1953. ConvexHullInternal::Edge *e = first_edge;
  1954. do {
  1955. if (e->copy >= 0) {
  1956. #ifdef DEBUG_CONVEX_HULL
  1957. printf("Vertex *%d has edge to *%d\n", i, edges[e->copy].get_target_vertex());
  1958. #endif
  1959. faces.push_back(e->copy);
  1960. ConvexHullInternal::Edge *f = e;
  1961. do {
  1962. #ifdef DEBUG_CONVEX_HULL
  1963. printf(" Face *%d\n", edges[f->copy].get_target_vertex());
  1964. #endif
  1965. f->copy = -1;
  1966. f = f->reverse->prev;
  1967. } while (f != e);
  1968. }
  1969. e = e->next;
  1970. } while (e != first_edge);
  1971. }
  1972. }
  1973. return shift;
  1974. }
  1975. Error ConvexHullComputer::convex_hull(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_mesh) {
  1976. r_mesh = Geometry3D::MeshData(); // clear
  1977. if (p_points.size() == 0) {
  1978. return FAILED; // matches QuickHull
  1979. }
  1980. ConvexHullComputer ch;
  1981. ch.compute(p_points.ptr(), p_points.size(), -1.0, -1.0);
  1982. r_mesh.vertices = ch.vertices;
  1983. // Tag which face each edge belongs to
  1984. LocalVector<int32_t> edge_faces;
  1985. edge_faces.resize(ch.edges.size());
  1986. for (uint32_t i = 0; i < ch.edges.size(); i++) {
  1987. edge_faces[i] = -1;
  1988. }
  1989. for (uint32_t i = 0; i < ch.faces.size(); i++) {
  1990. const Edge *e_start = &ch.edges[ch.faces[i]];
  1991. const Edge *e = e_start;
  1992. do {
  1993. int64_t ofs = e - ch.edges.ptr();
  1994. edge_faces[ofs] = i;
  1995. e = e->get_next_edge_of_face();
  1996. } while (e != e_start);
  1997. }
  1998. // Copy the edges over. There's two "half-edges" for every edge, so we pick only one of them.
  1999. r_mesh.edges.resize(ch.edges.size() / 2);
  2000. OAHashMap<uint64_t, int32_t> edge_map(ch.edges.size() * 4); // The higher the capacity, the faster the insert
  2001. uint32_t edges_copied = 0;
  2002. for (uint32_t i = 0; i < ch.edges.size(); i++) {
  2003. ERR_CONTINUE(edge_faces[i] == -1); // Sanity check
  2004. uint32_t a = (&ch.edges[i])->get_source_vertex();
  2005. uint32_t b = (&ch.edges[i])->get_target_vertex();
  2006. if (a < b) { // Copy only the "canonical" edge. For the reverse edge, this will be false.
  2007. ERR_BREAK(edges_copied >= (uint32_t)r_mesh.edges.size());
  2008. r_mesh.edges[edges_copied].vertex_a = a;
  2009. r_mesh.edges[edges_copied].vertex_b = b;
  2010. r_mesh.edges[edges_copied].face_a = edge_faces[i];
  2011. r_mesh.edges[edges_copied].face_b = -1;
  2012. uint64_t key = a;
  2013. key <<= 32;
  2014. key |= b;
  2015. edge_map.insert(key, edges_copied);
  2016. edges_copied++;
  2017. } else {
  2018. uint64_t key = b;
  2019. key <<= 32;
  2020. key |= a;
  2021. int32_t index;
  2022. if (!edge_map.lookup(key, index)) {
  2023. ERR_PRINT("Invalid edge");
  2024. } else {
  2025. r_mesh.edges[index].face_b = edge_faces[i];
  2026. }
  2027. }
  2028. }
  2029. if (edges_copied != (uint32_t)r_mesh.edges.size()) {
  2030. ERR_PRINT("Invalid edge count.");
  2031. }
  2032. r_mesh.faces.resize(ch.faces.size());
  2033. for (uint32_t i = 0; i < ch.faces.size(); i++) {
  2034. const Edge *e_start = &ch.edges[ch.faces[i]];
  2035. const Edge *e = e_start;
  2036. Geometry3D::MeshData::Face &face = r_mesh.faces[i];
  2037. do {
  2038. face.indices.push_back(e->get_target_vertex());
  2039. e = e->get_next_edge_of_face();
  2040. } while (e != e_start);
  2041. // reverse indices: Godot wants clockwise, but this is counter-clockwise
  2042. if (face.indices.size() > 2) {
  2043. // reverse all but the first index.
  2044. int *indices = face.indices.ptr();
  2045. for (uint32_t c = 0; c < (face.indices.size() - 1) / 2; c++) {
  2046. SWAP(indices[c + 1], indices[face.indices.size() - 1 - c]);
  2047. }
  2048. }
  2049. // compute normal
  2050. if (face.indices.size() >= 3) {
  2051. face.plane = Plane(r_mesh.vertices[face.indices[0]], r_mesh.vertices[face.indices[1]], r_mesh.vertices[face.indices[2]]);
  2052. } else {
  2053. WARN_PRINT("Too few vertices per face.");
  2054. }
  2055. }
  2056. return OK;
  2057. }