convex_hull.cpp 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298
  1. /*************************************************************************/
  2. /* convex_hull.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /*************************************************************************/
  30. /*
  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_macros.h"
  56. #include "core/math/aabb.h"
  57. #include "core/math/math_defs.h"
  58. #include "core/os/memory.h"
  59. #include "core/paged_allocator.h"
  60. #include <string.h>
  61. //#define DEBUG_CONVEX_HULL
  62. //#define SHOW_ITERATIONS
  63. // -- GODOT start --
  64. // Assembly optimizations are not used at the moment.
  65. //#define USE_X86_64_ASM
  66. // -- GODOT end --
  67. #ifdef DEBUG_ENABLED
  68. #define CHULL_ASSERT(m_cond) \
  69. do { \
  70. if (unlikely(!(m_cond))) { \
  71. ERR_PRINT("Assertion \"" _STR(m_cond) "\" failed.") \
  72. } \
  73. } while (0)
  74. #else
  75. #define CHULL_ASSERT(m_cond) \
  76. do { \
  77. } while (0)
  78. #endif
  79. #if defined(DEBUG_CONVEX_HULL) || defined(SHOW_ITERATIONS)
  80. #include <stdio.h>
  81. #endif
  82. // Convex hull implementation based on Preparata and Hong
  83. // Ole Kniemeyer, MAXON Computer GmbH
  84. class ConvexHullInternal {
  85. public:
  86. class Point64 {
  87. public:
  88. int64_t x;
  89. int64_t y;
  90. int64_t z;
  91. Point64(int64_t p_x, int64_t p_y, int64_t p_z) {
  92. x = p_x;
  93. y = p_y;
  94. z = p_z;
  95. }
  96. bool is_zero() {
  97. return (x == 0) && (y == 0) && (z == 0);
  98. }
  99. int64_t dot(const Point64 &b) const {
  100. return x * b.x + y * b.y + z * b.z;
  101. }
  102. };
  103. class Point32 {
  104. public:
  105. int32_t x = 0;
  106. int32_t y = 0;
  107. int32_t z = 0;
  108. int32_t index = -1;
  109. Point32() {
  110. }
  111. Point32(int32_t p_x, int32_t p_y, int32_t p_z) {
  112. x = p_x;
  113. y = p_y;
  114. z = p_z;
  115. }
  116. bool operator==(const Point32 &b) const {
  117. return (x == b.x) && (y == b.y) && (z == b.z);
  118. }
  119. bool operator!=(const Point32 &b) const {
  120. return (x != b.x) || (y != b.y) || (z != b.z);
  121. }
  122. bool is_zero() {
  123. return (x == 0) && (y == 0) && (z == 0);
  124. }
  125. Point64 cross(const Point32 &b) const {
  126. 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);
  127. }
  128. Point64 cross(const Point64 &b) const {
  129. return Point64(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x);
  130. }
  131. int64_t dot(const Point32 &b) const {
  132. return (int64_t)x * b.x + (int64_t)y * b.y + (int64_t)z * b.z;
  133. }
  134. int64_t dot(const Point64 &b) const {
  135. return x * b.x + y * b.y + z * b.z;
  136. }
  137. Point32 operator+(const Point32 &b) const {
  138. return Point32(x + b.x, y + b.y, z + b.z);
  139. }
  140. Point32 operator-(const Point32 &b) const {
  141. return Point32(x - b.x, y - b.y, z - b.z);
  142. }
  143. };
  144. class Int128 {
  145. public:
  146. uint64_t low = 0;
  147. uint64_t high = 0;
  148. Int128() {
  149. }
  150. Int128(uint64_t p_low, uint64_t p_high) {
  151. low = p_low;
  152. high = p_high;
  153. }
  154. Int128(uint64_t p_low) {
  155. low = p_low;
  156. high = 0;
  157. }
  158. Int128(int64_t p_value) {
  159. low = p_value;
  160. if (p_value >= 0) {
  161. high = 0;
  162. } else {
  163. high = (uint64_t)-1LL;
  164. }
  165. }
  166. static Int128 mul(int64_t a, int64_t b);
  167. static Int128 mul(uint64_t a, uint64_t b);
  168. Int128 operator-() const {
  169. return Int128((uint64_t) - (int64_t)low, ~high + (low == 0));
  170. }
  171. Int128 operator+(const Int128 &b) const {
  172. #ifdef USE_X86_64_ASM
  173. Int128 result;
  174. __asm__("addq %[bl], %[rl]\n\t"
  175. "adcq %[bh], %[rh]\n\t"
  176. : [rl] "=r"(result.low), [rh] "=r"(result.high)
  177. : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high)
  178. : "cc");
  179. return result;
  180. #else
  181. uint64_t lo = low + b.low;
  182. return Int128(lo, high + b.high + (lo < low));
  183. #endif
  184. }
  185. Int128 operator-(const Int128 &b) const {
  186. #ifdef USE_X86_64_ASM
  187. Int128 result;
  188. __asm__("subq %[bl], %[rl]\n\t"
  189. "sbbq %[bh], %[rh]\n\t"
  190. : [rl] "=r"(result.low), [rh] "=r"(result.high)
  191. : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high)
  192. : "cc");
  193. return result;
  194. #else
  195. return *this + -b;
  196. #endif
  197. }
  198. Int128 &operator+=(const Int128 &b) {
  199. #ifdef USE_X86_64_ASM
  200. __asm__("addq %[bl], %[rl]\n\t"
  201. "adcq %[bh], %[rh]\n\t"
  202. : [rl] "=r"(low), [rh] "=r"(high)
  203. : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high)
  204. : "cc");
  205. #else
  206. uint64_t lo = low + b.low;
  207. if (lo < low) {
  208. ++high;
  209. }
  210. low = lo;
  211. high += b.high;
  212. #endif
  213. return *this;
  214. }
  215. Int128 &operator++() {
  216. if (++low == 0) {
  217. ++high;
  218. }
  219. return *this;
  220. }
  221. Int128 operator*(int64_t b) const;
  222. real_t to_scalar() const {
  223. return ((int64_t)high >= 0) ? real_t(high) * (real_t(0x100000000LL) * real_t(0x100000000LL)) + real_t(low) : -(-*this).to_scalar();
  224. }
  225. int32_t get_sign() const {
  226. return ((int64_t)high < 0) ? -1 : (high || low) ? 1 :
  227. 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, Vertex *p_b, 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. void print();
  507. };
  508. enum Orientation { NONE,
  509. CLOCKWISE,
  510. COUNTER_CLOCKWISE };
  511. Vector3 scaling;
  512. Vector3 center;
  513. PagedAllocator<Vertex> vertex_pool;
  514. PagedAllocator<Edge> edge_pool;
  515. PagedAllocator<Face> face_pool;
  516. LocalVector<Vertex *> original_vertices;
  517. int32_t merge_stamp = 0;
  518. int32_t min_axis = 0;
  519. int32_t med_axis = 0;
  520. int32_t max_axis = 0;
  521. int32_t used_edge_pairs = 0;
  522. int32_t max_used_edge_pairs = 0;
  523. static Orientation get_orientation(const Edge *p_prev, const Edge *p_next, const Point32 &p_s, const Point32 &p_t);
  524. 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);
  525. void find_edge_for_coplanar_faces(Vertex *p_c0, Vertex *p_c1, Edge *&p_e0, Edge *&p_e1, Vertex *p_stop0, Vertex *p_stop1);
  526. Edge *new_edge_pair(Vertex *p_from, Vertex *p_to);
  527. void remove_edge_pair(Edge *p_edge) {
  528. Edge *n = p_edge->next;
  529. Edge *r = p_edge->reverse;
  530. CHULL_ASSERT(p_edge->target && r->target);
  531. if (n != p_edge) {
  532. n->prev = p_edge->prev;
  533. p_edge->prev->next = n;
  534. r->target->edges = n;
  535. } else {
  536. r->target->edges = nullptr;
  537. }
  538. n = r->next;
  539. if (n != r) {
  540. n->prev = r->prev;
  541. r->prev->next = n;
  542. p_edge->target->edges = n;
  543. } else {
  544. p_edge->target->edges = nullptr;
  545. }
  546. edge_pool.free(p_edge);
  547. edge_pool.free(r);
  548. used_edge_pairs--;
  549. }
  550. void compute_internal(int32_t p_start, int32_t p_end, IntermediateHull &r_result);
  551. bool merge_projection(IntermediateHull &p_h0, IntermediateHull &p_h1, Vertex *&r_c0, Vertex *&r_c1);
  552. void merge(IntermediateHull &p_h0, IntermediateHull &p_h1);
  553. Vector3 to_gd_vector(const Point32 &p_v);
  554. Vector3 get_gd_normal(Face *p_face);
  555. bool shift_face(Face *p_face, real_t p_amount, LocalVector<Vertex *> p_stack);
  556. public:
  557. ~ConvexHullInternal() {
  558. vertex_pool.reset(true);
  559. edge_pool.reset(true);
  560. face_pool.reset(true);
  561. }
  562. Vertex *vertex_list;
  563. void compute(const Vector3 *p_coords, int32_t p_count);
  564. Vector3 get_coordinates(const Vertex *p_v);
  565. real_t shrink(real_t amount, real_t p_clamp_amount);
  566. };
  567. ConvexHullInternal::Int128 ConvexHullInternal::Int128::operator*(int64_t b) const {
  568. bool negative = (int64_t)high < 0;
  569. Int128 a = negative ? -*this : *this;
  570. if (b < 0) {
  571. negative = !negative;
  572. b = -b;
  573. }
  574. Int128 result = mul(a.low, (uint64_t)b);
  575. result.high += a.high * (uint64_t)b;
  576. return negative ? -result : result;
  577. }
  578. ConvexHullInternal::Int128 ConvexHullInternal::Int128::mul(int64_t a, int64_t b) {
  579. Int128 result;
  580. #ifdef USE_X86_64_ASM
  581. __asm__("imulq %[b]"
  582. : "=a"(result.low), "=d"(result.high)
  583. : "0"(a), [b] "r"(b)
  584. : "cc");
  585. return result;
  586. #else
  587. bool negative = a < 0;
  588. if (negative) {
  589. a = -a;
  590. }
  591. if (b < 0) {
  592. negative = !negative;
  593. b = -b;
  594. }
  595. DMul<uint64_t, uint32_t>::mul((uint64_t)a, (uint64_t)b, result.low, result.high);
  596. return negative ? -result : result;
  597. #endif
  598. }
  599. ConvexHullInternal::Int128 ConvexHullInternal::Int128::mul(uint64_t a, uint64_t b) {
  600. Int128 result;
  601. #ifdef USE_X86_64_ASM
  602. __asm__("mulq %[b]"
  603. : "=a"(result.low), "=d"(result.high)
  604. : "0"(a), [b] "r"(b)
  605. : "cc");
  606. #else
  607. DMul<uint64_t, uint32_t>::mul(a, b, result.low, result.high);
  608. #endif
  609. return result;
  610. }
  611. int32_t ConvexHullInternal::Rational64::compare(const Rational64 &b) const {
  612. if (sign != b.sign) {
  613. return sign - b.sign;
  614. } else if (sign == 0) {
  615. return 0;
  616. }
  617. // return (numerator * b.denominator > b.numerator * denominator) ? sign : (numerator * b.denominator < b.numerator * denominator) ? -sign : 0;
  618. #ifdef USE_X86_64_ASM
  619. int32_t result;
  620. int64_t tmp;
  621. int64_t dummy;
  622. __asm__("mulq %[bn]\n\t"
  623. "movq %%rax, %[tmp]\n\t"
  624. "movq %%rdx, %%rbx\n\t"
  625. "movq %[tn], %%rax\n\t"
  626. "mulq %[bd]\n\t"
  627. "subq %[tmp], %%rax\n\t"
  628. "sbbq %%rbx, %%rdx\n\t" // rdx:rax contains 128-bit-difference "numerator*b.denominator - b.numerator*denominator"
  629. "setnsb %%bh\n\t" // bh=1 if difference is non-negative, bh=0 otherwise
  630. "orq %%rdx, %%rax\n\t"
  631. "setnzb %%bl\n\t" // bl=1 if difference if non-zero, bl=0 if it is zero
  632. "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)
  633. "shll $16, %%ebx\n\t" // ebx has same sign as difference
  634. : "=&b"(result), [tmp] "=&r"(tmp), "=a"(dummy)
  635. : "a"(denominator), [bn] "g"(b.numerator), [tn] "g"(numerator), [bd] "g"(b.denominator)
  636. : "%rdx", "cc");
  637. return result ? result ^ sign // if sign is +1, only bit 0 of result is inverted, which does not change the sign of result (and cannot result in zero)
  638. // if sign is -1, all bits of result are inverted, which changes the sign of result (and again cannot result in zero)
  639. :
  640. 0;
  641. #else
  642. return sign * Int128::mul(numerator, b.denominator).ucmp(Int128::mul(denominator, b.numerator));
  643. #endif
  644. }
  645. int32_t ConvexHullInternal::Rational128::compare(const Rational128 &b) const {
  646. if (sign != b.sign) {
  647. return sign - b.sign;
  648. } else if (sign == 0) {
  649. return 0;
  650. }
  651. if (is_int_64) {
  652. return -b.compare(sign * (int64_t)numerator.low);
  653. }
  654. Int128 nbd_low, nbd_high, dbn_low, dbn_high;
  655. DMul<Int128, uint64_t>::mul(numerator, b.denominator, nbd_low, nbd_high);
  656. DMul<Int128, uint64_t>::mul(denominator, b.numerator, dbn_low, dbn_high);
  657. int32_t cmp = nbd_high.ucmp(dbn_high);
  658. if (cmp) {
  659. return cmp * sign;
  660. }
  661. return nbd_low.ucmp(dbn_low) * sign;
  662. }
  663. int32_t ConvexHullInternal::Rational128::compare(int64_t b) const {
  664. if (is_int_64) {
  665. int64_t a = sign * (int64_t)numerator.low;
  666. return (a > b) ? 1 : (a < b) ? -1 :
  667. 0;
  668. }
  669. if (b > 0) {
  670. if (sign <= 0) {
  671. return -1;
  672. }
  673. } else if (b < 0) {
  674. if (sign >= 0) {
  675. return 1;
  676. }
  677. b = -b;
  678. } else {
  679. return sign;
  680. }
  681. return numerator.ucmp(denominator * b) * sign;
  682. }
  683. ConvexHullInternal::Edge *ConvexHullInternal::new_edge_pair(Vertex *p_from, Vertex *p_to) {
  684. CHULL_ASSERT(p_from && p_to);
  685. Edge *e = edge_pool.alloc();
  686. Edge *r = edge_pool.alloc();
  687. e->reverse = r;
  688. r->reverse = e;
  689. e->copy = merge_stamp;
  690. r->copy = merge_stamp;
  691. e->target = p_to;
  692. r->target = p_from;
  693. e->face = nullptr;
  694. r->face = nullptr;
  695. used_edge_pairs++;
  696. if (used_edge_pairs > max_used_edge_pairs) {
  697. max_used_edge_pairs = used_edge_pairs;
  698. }
  699. return e;
  700. }
  701. bool ConvexHullInternal::merge_projection(IntermediateHull &r_h0, IntermediateHull &r_h1, Vertex *&r_c0, Vertex *&r_c1) {
  702. Vertex *v0 = r_h0.max_yx;
  703. Vertex *v1 = r_h1.min_yx;
  704. if ((v0->point.x == v1->point.x) && (v0->point.y == v1->point.y)) {
  705. CHULL_ASSERT(v0->point.z < v1->point.z);
  706. Vertex *v1p = v1->prev;
  707. if (v1p == v1) {
  708. r_c0 = v0;
  709. if (v1->edges) {
  710. CHULL_ASSERT(v1->edges->next == v1->edges);
  711. v1 = v1->edges->target;
  712. CHULL_ASSERT(v1->edges->next == v1->edges);
  713. }
  714. r_c1 = v1;
  715. return false;
  716. }
  717. Vertex *v1n = v1->next;
  718. v1p->next = v1n;
  719. v1n->prev = v1p;
  720. if (v1 == r_h1.min_xy) {
  721. if ((v1n->point.x < v1p->point.x) || ((v1n->point.x == v1p->point.x) && (v1n->point.y < v1p->point.y))) {
  722. r_h1.min_xy = v1n;
  723. } else {
  724. r_h1.min_xy = v1p;
  725. }
  726. }
  727. if (v1 == r_h1.max_xy) {
  728. if ((v1n->point.x > v1p->point.x) || ((v1n->point.x == v1p->point.x) && (v1n->point.y > v1p->point.y))) {
  729. r_h1.max_xy = v1n;
  730. } else {
  731. r_h1.max_xy = v1p;
  732. }
  733. }
  734. }
  735. v0 = r_h0.max_xy;
  736. v1 = r_h1.max_xy;
  737. Vertex *v00 = nullptr;
  738. Vertex *v10 = nullptr;
  739. int32_t sign = 1;
  740. for (int32_t side = 0; side <= 1; side++) {
  741. int32_t dx = (v1->point.x - v0->point.x) * sign;
  742. if (dx > 0) {
  743. while (true) {
  744. int32_t dy = v1->point.y - v0->point.y;
  745. Vertex *w0 = side ? v0->next : v0->prev;
  746. if (w0 != v0) {
  747. int32_t dx0 = (w0->point.x - v0->point.x) * sign;
  748. int32_t dy0 = w0->point.y - v0->point.y;
  749. if ((dy0 <= 0) && ((dx0 == 0) || ((dx0 < 0) && (dy0 * dx <= dy * dx0)))) {
  750. v0 = w0;
  751. dx = (v1->point.x - v0->point.x) * sign;
  752. continue;
  753. }
  754. }
  755. Vertex *w1 = side ? v1->next : v1->prev;
  756. if (w1 != v1) {
  757. int32_t dx1 = (w1->point.x - v1->point.x) * sign;
  758. int32_t dy1 = w1->point.y - v1->point.y;
  759. int32_t dxn = (w1->point.x - v0->point.x) * sign;
  760. if ((dxn > 0) && (dy1 < 0) && ((dx1 == 0) || ((dx1 < 0) && (dy1 * dx < dy * dx1)))) {
  761. v1 = w1;
  762. dx = dxn;
  763. continue;
  764. }
  765. }
  766. break;
  767. }
  768. } else if (dx < 0) {
  769. while (true) {
  770. int32_t dy = v1->point.y - v0->point.y;
  771. Vertex *w1 = side ? v1->prev : v1->next;
  772. if (w1 != v1) {
  773. int32_t dx1 = (w1->point.x - v1->point.x) * sign;
  774. int32_t dy1 = w1->point.y - v1->point.y;
  775. if ((dy1 >= 0) && ((dx1 == 0) || ((dx1 < 0) && (dy1 * dx <= dy * dx1)))) {
  776. v1 = w1;
  777. dx = (v1->point.x - v0->point.x) * sign;
  778. continue;
  779. }
  780. }
  781. Vertex *w0 = side ? v0->prev : v0->next;
  782. if (w0 != v0) {
  783. int32_t dx0 = (w0->point.x - v0->point.x) * sign;
  784. int32_t dy0 = w0->point.y - v0->point.y;
  785. int32_t dxn = (v1->point.x - w0->point.x) * sign;
  786. if ((dxn < 0) && (dy0 > 0) && ((dx0 == 0) || ((dx0 < 0) && (dy0 * dx < dy * dx0)))) {
  787. v0 = w0;
  788. dx = dxn;
  789. continue;
  790. }
  791. }
  792. break;
  793. }
  794. } else {
  795. int32_t x = v0->point.x;
  796. int32_t y0 = v0->point.y;
  797. Vertex *w0 = v0;
  798. Vertex *t;
  799. while (((t = side ? w0->next : w0->prev) != v0) && (t->point.x == x) && (t->point.y <= y0)) {
  800. w0 = t;
  801. y0 = t->point.y;
  802. }
  803. v0 = w0;
  804. int32_t y1 = v1->point.y;
  805. Vertex *w1 = v1;
  806. while (((t = side ? w1->prev : w1->next) != v1) && (t->point.x == x) && (t->point.y >= y1)) {
  807. w1 = t;
  808. y1 = t->point.y;
  809. }
  810. v1 = w1;
  811. }
  812. if (side == 0) {
  813. v00 = v0;
  814. v10 = v1;
  815. v0 = r_h0.min_xy;
  816. v1 = r_h1.min_xy;
  817. sign = -1;
  818. }
  819. }
  820. v0->prev = v1;
  821. v1->next = v0;
  822. v00->next = v10;
  823. v10->prev = v00;
  824. if (r_h1.min_xy->point.x < r_h0.min_xy->point.x) {
  825. r_h0.min_xy = r_h1.min_xy;
  826. }
  827. if (r_h1.max_xy->point.x >= r_h0.max_xy->point.x) {
  828. r_h0.max_xy = r_h1.max_xy;
  829. }
  830. r_h0.max_yx = r_h1.max_yx;
  831. r_c0 = v00;
  832. r_c1 = v10;
  833. return true;
  834. }
  835. void ConvexHullInternal::compute_internal(int32_t p_start, int32_t p_end, IntermediateHull &r_result) {
  836. int32_t n = p_end - p_start;
  837. switch (n) {
  838. case 0:
  839. r_result.min_xy = nullptr;
  840. r_result.max_xy = nullptr;
  841. r_result.min_yx = nullptr;
  842. r_result.max_yx = nullptr;
  843. return;
  844. case 2: {
  845. Vertex *v = original_vertices[p_start];
  846. Vertex *w = original_vertices[p_start + 1];
  847. if (v->point != w->point) {
  848. int32_t dx = v->point.x - w->point.x;
  849. int32_t dy = v->point.y - w->point.y;
  850. if ((dx == 0) && (dy == 0)) {
  851. if (v->point.z > w->point.z) {
  852. Vertex *t = w;
  853. w = v;
  854. v = t;
  855. }
  856. CHULL_ASSERT(v->point.z < w->point.z);
  857. v->next = v;
  858. v->prev = v;
  859. r_result.min_xy = v;
  860. r_result.max_xy = v;
  861. r_result.min_yx = v;
  862. r_result.max_yx = v;
  863. } else {
  864. v->next = w;
  865. v->prev = w;
  866. w->next = v;
  867. w->prev = v;
  868. if ((dx < 0) || ((dx == 0) && (dy < 0))) {
  869. r_result.min_xy = v;
  870. r_result.max_xy = w;
  871. } else {
  872. r_result.min_xy = w;
  873. r_result.max_xy = v;
  874. }
  875. if ((dy < 0) || ((dy == 0) && (dx < 0))) {
  876. r_result.min_yx = v;
  877. r_result.max_yx = w;
  878. } else {
  879. r_result.min_yx = w;
  880. r_result.max_yx = v;
  881. }
  882. }
  883. Edge *e = new_edge_pair(v, w);
  884. e->link(e);
  885. v->edges = e;
  886. e = e->reverse;
  887. e->link(e);
  888. w->edges = e;
  889. return;
  890. }
  891. }
  892. // lint -fallthrough
  893. case 1: {
  894. Vertex *v = original_vertices[p_start];
  895. v->edges = nullptr;
  896. v->next = v;
  897. v->prev = v;
  898. r_result.min_xy = v;
  899. r_result.max_xy = v;
  900. r_result.min_yx = v;
  901. r_result.max_yx = v;
  902. return;
  903. }
  904. }
  905. int32_t split0 = p_start + n / 2;
  906. Point32 p = original_vertices[split0 - 1]->point;
  907. int32_t split1 = split0;
  908. while ((split1 < p_end) && (original_vertices[split1]->point == p)) {
  909. split1++;
  910. }
  911. compute_internal(p_start, split0, r_result);
  912. IntermediateHull hull1;
  913. compute_internal(split1, p_end, hull1);
  914. #ifdef DEBUG_CONVEX_HULL
  915. printf("\n\nMerge\n");
  916. r_result.print();
  917. hull1.print();
  918. #endif
  919. merge(r_result, hull1);
  920. #ifdef DEBUG_CONVEX_HULL
  921. printf("\n Result\n");
  922. r_result.print();
  923. #endif
  924. }
  925. #ifdef DEBUG_CONVEX_HULL
  926. void ConvexHullInternal::IntermediateHull::print() {
  927. printf(" Hull\n");
  928. for (Vertex *v = min_xy; v;) {
  929. printf(" ");
  930. v->print();
  931. if (v == max_xy) {
  932. printf(" max_xy");
  933. }
  934. if (v == min_yx) {
  935. printf(" min_yx");
  936. }
  937. if (v == max_yx) {
  938. printf(" max_yx");
  939. }
  940. if (v->next->prev != v) {
  941. printf(" Inconsistency");
  942. }
  943. printf("\n");
  944. v = v->next;
  945. if (v == min_xy) {
  946. break;
  947. }
  948. }
  949. if (min_xy) {
  950. min_xy->copy = (min_xy->copy == -1) ? -2 : -1;
  951. min_xy->print_graph();
  952. }
  953. }
  954. void ConvexHullInternal::Vertex::print_graph() {
  955. print();
  956. printf("\nEdges\n");
  957. Edge *e = edges;
  958. if (e) {
  959. do {
  960. e->print();
  961. printf("\n");
  962. e = e->next;
  963. } while (e != edges);
  964. do {
  965. Vertex *v = e->target;
  966. if (v->copy != copy) {
  967. v->copy = copy;
  968. v->print_graph();
  969. }
  970. e = e->next;
  971. } while (e != edges);
  972. }
  973. }
  974. #endif
  975. ConvexHullInternal::Orientation ConvexHullInternal::get_orientation(const Edge *p_prev, const Edge *p_next, const Point32 &p_s, const Point32 &p_t) {
  976. CHULL_ASSERT(p_prev->reverse->target == p_next->reverse->target);
  977. if (p_prev->next == p_next) {
  978. if (p_prev->prev == p_next) {
  979. Point64 n = p_t.cross(p_s);
  980. Point64 m = (*p_prev->target - *p_next->reverse->target).cross(*p_next->target - *p_next->reverse->target);
  981. CHULL_ASSERT(!m.is_zero());
  982. int64_t dot = n.dot(m);
  983. CHULL_ASSERT(dot != 0);
  984. return (dot > 0) ? COUNTER_CLOCKWISE : CLOCKWISE;
  985. }
  986. return COUNTER_CLOCKWISE;
  987. } else if (p_prev->prev == p_next) {
  988. return CLOCKWISE;
  989. } else {
  990. return NONE;
  991. }
  992. }
  993. 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) {
  994. Edge *min_edge = nullptr;
  995. #ifdef DEBUG_CONVEX_HULL
  996. printf("find max edge for %d\n", p_start->point.index);
  997. #endif
  998. Edge *e = p_start->edges;
  999. if (e) {
  1000. do {
  1001. if (e->copy > merge_stamp) {
  1002. Point32 t = *e->target - *p_start;
  1003. Rational64 cot(t.dot(p_sxrxs), t.dot(p_rxs));
  1004. #ifdef DEBUG_CONVEX_HULL
  1005. printf(" Angle is %f (%d) for ", Math::atan(cot.to_scalar()), (int32_t)cot.is_nan());
  1006. e->print();
  1007. #endif
  1008. if (cot.is_nan()) {
  1009. CHULL_ASSERT(p_ccw ? (t.dot(p_s) < 0) : (t.dot(p_s) > 0));
  1010. } else {
  1011. int32_t cmp;
  1012. if (min_edge == nullptr) {
  1013. p_min_cot = cot;
  1014. min_edge = e;
  1015. } else if ((cmp = cot.compare(p_min_cot)) < 0) {
  1016. p_min_cot = cot;
  1017. min_edge = e;
  1018. } else if ((cmp == 0) && (p_ccw == (get_orientation(min_edge, e, p_s, t) == COUNTER_CLOCKWISE))) {
  1019. min_edge = e;
  1020. }
  1021. }
  1022. #ifdef DEBUG_CONVEX_HULL
  1023. printf("\n");
  1024. #endif
  1025. }
  1026. e = e->next;
  1027. } while (e != p_start->edges);
  1028. }
  1029. return min_edge;
  1030. }
  1031. void ConvexHullInternal::find_edge_for_coplanar_faces(Vertex *p_c0, Vertex *p_c1, Edge *&p_e0, Edge *&p_e1, Vertex *p_stop0, Vertex *p_stop1) {
  1032. Edge *start0 = p_e0;
  1033. Edge *start1 = p_e1;
  1034. Point32 et0 = start0 ? start0->target->point : p_c0->point;
  1035. Point32 et1 = start1 ? start1->target->point : p_c1->point;
  1036. Point32 s = p_c1->point - p_c0->point;
  1037. Point64 normal = ((start0 ? start0 : start1)->target->point - p_c0->point).cross(s);
  1038. int64_t dist = p_c0->point.dot(normal);
  1039. CHULL_ASSERT(!start1 || (start1->target->point.dot(normal) == dist));
  1040. Point64 perp = s.cross(normal);
  1041. CHULL_ASSERT(!perp.is_zero());
  1042. #ifdef DEBUG_CONVEX_HULL
  1043. 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);
  1044. #endif
  1045. int64_t max_dot0 = et0.dot(perp);
  1046. if (p_e0) {
  1047. while (p_e0->target != p_stop0) {
  1048. Edge *e = p_e0->reverse->prev;
  1049. if (e->target->point.dot(normal) < dist) {
  1050. break;
  1051. }
  1052. CHULL_ASSERT(e->target->point.dot(normal) == dist);
  1053. if (e->copy == merge_stamp) {
  1054. break;
  1055. }
  1056. int64_t dot = e->target->point.dot(perp);
  1057. if (dot <= max_dot0) {
  1058. break;
  1059. }
  1060. max_dot0 = dot;
  1061. p_e0 = e;
  1062. et0 = e->target->point;
  1063. }
  1064. }
  1065. int64_t max_dot1 = et1.dot(perp);
  1066. if (p_e1) {
  1067. while (p_e1->target != p_stop1) {
  1068. Edge *e = p_e1->reverse->next;
  1069. if (e->target->point.dot(normal) < dist) {
  1070. break;
  1071. }
  1072. CHULL_ASSERT(e->target->point.dot(normal) == dist);
  1073. if (e->copy == merge_stamp) {
  1074. break;
  1075. }
  1076. int64_t dot = e->target->point.dot(perp);
  1077. if (dot <= max_dot1) {
  1078. break;
  1079. }
  1080. max_dot1 = dot;
  1081. p_e1 = e;
  1082. et1 = e->target->point;
  1083. }
  1084. }
  1085. #ifdef DEBUG_CONVEX_HULL
  1086. printf(" Starting at %d %d\n", et0.index, et1.index);
  1087. #endif
  1088. int64_t dx = max_dot1 - max_dot0;
  1089. if (dx > 0) {
  1090. while (true) {
  1091. int64_t dy = (et1 - et0).dot(s);
  1092. if (p_e0 && (p_e0->target != p_stop0)) {
  1093. Edge *f0 = p_e0->next->reverse;
  1094. if (f0->copy > merge_stamp) {
  1095. int64_t dx0 = (f0->target->point - et0).dot(perp);
  1096. int64_t dy0 = (f0->target->point - et0).dot(s);
  1097. if ((dx0 == 0) ? (dy0 < 0) : ((dx0 < 0) && (Rational64(dy0, dx0).compare(Rational64(dy, dx)) >= 0))) {
  1098. et0 = f0->target->point;
  1099. dx = (et1 - et0).dot(perp);
  1100. p_e0 = (p_e0 == start0) ? nullptr : f0;
  1101. continue;
  1102. }
  1103. }
  1104. }
  1105. if (p_e1 && (p_e1->target != p_stop1)) {
  1106. Edge *f1 = p_e1->reverse->next;
  1107. if (f1->copy > merge_stamp) {
  1108. Point32 d1 = f1->target->point - et1;
  1109. if (d1.dot(normal) == 0) {
  1110. int64_t dx1 = d1.dot(perp);
  1111. int64_t dy1 = d1.dot(s);
  1112. int64_t dxn = (f1->target->point - et0).dot(perp);
  1113. if ((dxn > 0) && ((dx1 == 0) ? (dy1 < 0) : ((dx1 < 0) && (Rational64(dy1, dx1).compare(Rational64(dy, dx)) > 0)))) {
  1114. p_e1 = f1;
  1115. et1 = p_e1->target->point;
  1116. dx = dxn;
  1117. continue;
  1118. }
  1119. } else {
  1120. CHULL_ASSERT((p_e1 == start1) && (d1.dot(normal) < 0));
  1121. }
  1122. }
  1123. }
  1124. break;
  1125. }
  1126. } else if (dx < 0) {
  1127. while (true) {
  1128. int64_t dy = (et1 - et0).dot(s);
  1129. if (p_e1 && (p_e1->target != p_stop1)) {
  1130. Edge *f1 = p_e1->prev->reverse;
  1131. if (f1->copy > merge_stamp) {
  1132. int64_t dx1 = (f1->target->point - et1).dot(perp);
  1133. int64_t dy1 = (f1->target->point - et1).dot(s);
  1134. if ((dx1 == 0) ? (dy1 > 0) : ((dx1 < 0) && (Rational64(dy1, dx1).compare(Rational64(dy, dx)) <= 0))) {
  1135. et1 = f1->target->point;
  1136. dx = (et1 - et0).dot(perp);
  1137. p_e1 = (p_e1 == start1) ? nullptr : f1;
  1138. continue;
  1139. }
  1140. }
  1141. }
  1142. if (p_e0 && (p_e0->target != p_stop0)) {
  1143. Edge *f0 = p_e0->reverse->prev;
  1144. if (f0->copy > merge_stamp) {
  1145. Point32 d0 = f0->target->point - et0;
  1146. if (d0.dot(normal) == 0) {
  1147. int64_t dx0 = d0.dot(perp);
  1148. int64_t dy0 = d0.dot(s);
  1149. int64_t dxn = (et1 - f0->target->point).dot(perp);
  1150. if ((dxn < 0) && ((dx0 == 0) ? (dy0 > 0) : ((dx0 < 0) && (Rational64(dy0, dx0).compare(Rational64(dy, dx)) < 0)))) {
  1151. p_e0 = f0;
  1152. et0 = p_e0->target->point;
  1153. dx = dxn;
  1154. continue;
  1155. }
  1156. } else {
  1157. CHULL_ASSERT((p_e0 == start0) && (d0.dot(normal) < 0));
  1158. }
  1159. }
  1160. }
  1161. break;
  1162. }
  1163. }
  1164. #ifdef DEBUG_CONVEX_HULL
  1165. printf(" Advanced edges to %d %d\n", et0.index, et1.index);
  1166. #endif
  1167. }
  1168. void ConvexHullInternal::merge(IntermediateHull &p_h0, IntermediateHull &p_h1) {
  1169. if (!p_h1.max_xy) {
  1170. return;
  1171. }
  1172. if (!p_h0.max_xy) {
  1173. p_h0 = p_h1;
  1174. return;
  1175. }
  1176. merge_stamp--;
  1177. Vertex *c0 = nullptr;
  1178. Edge *to_prev0 = nullptr;
  1179. Edge *first_new0 = nullptr;
  1180. Edge *pending_head0 = nullptr;
  1181. Edge *pending_tail0 = nullptr;
  1182. Vertex *c1 = nullptr;
  1183. Edge *to_prev1 = nullptr;
  1184. Edge *first_new1 = nullptr;
  1185. Edge *pending_head1 = nullptr;
  1186. Edge *pending_tail1 = nullptr;
  1187. Point32 prev_point;
  1188. if (merge_projection(p_h0, p_h1, c0, c1)) {
  1189. Point32 s = *c1 - *c0;
  1190. Point64 normal = Point32(0, 0, -1).cross(s);
  1191. Point64 t = s.cross(normal);
  1192. CHULL_ASSERT(!t.is_zero());
  1193. Edge *e = c0->edges;
  1194. Edge *start0 = nullptr;
  1195. if (e) {
  1196. do {
  1197. int64_t dot = (*e->target - *c0).dot(normal);
  1198. CHULL_ASSERT(dot <= 0);
  1199. if ((dot == 0) && ((*e->target - *c0).dot(t) > 0)) {
  1200. if (!start0 || (get_orientation(start0, e, s, Point32(0, 0, -1)) == CLOCKWISE)) {
  1201. start0 = e;
  1202. }
  1203. }
  1204. e = e->next;
  1205. } while (e != c0->edges);
  1206. }
  1207. e = c1->edges;
  1208. Edge *start1 = nullptr;
  1209. if (e) {
  1210. do {
  1211. int64_t dot = (*e->target - *c1).dot(normal);
  1212. CHULL_ASSERT(dot <= 0);
  1213. if ((dot == 0) && ((*e->target - *c1).dot(t) > 0)) {
  1214. if (!start1 || (get_orientation(start1, e, s, Point32(0, 0, -1)) == COUNTER_CLOCKWISE)) {
  1215. start1 = e;
  1216. }
  1217. }
  1218. e = e->next;
  1219. } while (e != c1->edges);
  1220. }
  1221. if (start0 || start1) {
  1222. find_edge_for_coplanar_faces(c0, c1, start0, start1, nullptr, nullptr);
  1223. if (start0) {
  1224. c0 = start0->target;
  1225. }
  1226. if (start1) {
  1227. c1 = start1->target;
  1228. }
  1229. }
  1230. prev_point = c1->point;
  1231. prev_point.z++;
  1232. } else {
  1233. prev_point = c1->point;
  1234. prev_point.x++;
  1235. }
  1236. Vertex *first0 = c0;
  1237. Vertex *first1 = c1;
  1238. bool first_run = true;
  1239. while (true) {
  1240. Point32 s = *c1 - *c0;
  1241. Point32 r = prev_point - c0->point;
  1242. Point64 rxs = r.cross(s);
  1243. Point64 sxrxs = s.cross(rxs);
  1244. #ifdef DEBUG_CONVEX_HULL
  1245. printf("\n Checking %d %d\n", c0->point.index, c1->point.index);
  1246. #endif
  1247. Rational64 min_cot0(0, 0);
  1248. Edge *min0 = find_max_angle(false, c0, s, rxs, sxrxs, min_cot0);
  1249. Rational64 min_cot1(0, 0);
  1250. Edge *min1 = find_max_angle(true, c1, s, rxs, sxrxs, min_cot1);
  1251. if (!min0 && !min1) {
  1252. Edge *e = new_edge_pair(c0, c1);
  1253. e->link(e);
  1254. c0->edges = e;
  1255. e = e->reverse;
  1256. e->link(e);
  1257. c1->edges = e;
  1258. return;
  1259. } else {
  1260. int32_t cmp = !min0 ? 1 : !min1 ? -1 :
  1261. min_cot0.compare(min_cot1);
  1262. #ifdef DEBUG_CONVEX_HULL
  1263. printf(" -> Result %d\n", cmp);
  1264. #endif
  1265. if (first_run || ((cmp >= 0) ? !min_cot1.is_negative_infinity() : !min_cot0.is_negative_infinity())) {
  1266. Edge *e = new_edge_pair(c0, c1);
  1267. if (pending_tail0) {
  1268. pending_tail0->prev = e;
  1269. } else {
  1270. pending_head0 = e;
  1271. }
  1272. e->next = pending_tail0;
  1273. pending_tail0 = e;
  1274. e = e->reverse;
  1275. if (pending_tail1) {
  1276. pending_tail1->next = e;
  1277. } else {
  1278. pending_head1 = e;
  1279. }
  1280. e->prev = pending_tail1;
  1281. pending_tail1 = e;
  1282. }
  1283. Edge *e0 = min0;
  1284. Edge *e1 = min1;
  1285. #ifdef DEBUG_CONVEX_HULL
  1286. printf(" Found min edges to %d %d\n", e0 ? e0->target->point.index : -1, e1 ? e1->target->point.index : -1);
  1287. #endif
  1288. if (cmp == 0) {
  1289. find_edge_for_coplanar_faces(c0, c1, e0, e1, nullptr, nullptr);
  1290. }
  1291. if ((cmp >= 0) && e1) {
  1292. if (to_prev1) {
  1293. for (Edge *e = to_prev1->next, *n = nullptr; e != min1; e = n) {
  1294. n = e->next;
  1295. remove_edge_pair(e);
  1296. }
  1297. }
  1298. if (pending_tail1) {
  1299. if (to_prev1) {
  1300. to_prev1->link(pending_head1);
  1301. } else {
  1302. min1->prev->link(pending_head1);
  1303. first_new1 = pending_head1;
  1304. }
  1305. pending_tail1->link(min1);
  1306. pending_head1 = nullptr;
  1307. pending_tail1 = nullptr;
  1308. } else if (!to_prev1) {
  1309. first_new1 = min1;
  1310. }
  1311. prev_point = c1->point;
  1312. c1 = e1->target;
  1313. to_prev1 = e1->reverse;
  1314. }
  1315. if ((cmp <= 0) && e0) {
  1316. if (to_prev0) {
  1317. for (Edge *e = to_prev0->prev, *n = nullptr; e != min0; e = n) {
  1318. n = e->prev;
  1319. remove_edge_pair(e);
  1320. }
  1321. }
  1322. if (pending_tail0) {
  1323. if (to_prev0) {
  1324. pending_head0->link(to_prev0);
  1325. } else {
  1326. pending_head0->link(min0->next);
  1327. first_new0 = pending_head0;
  1328. }
  1329. min0->link(pending_tail0);
  1330. pending_head0 = nullptr;
  1331. pending_tail0 = nullptr;
  1332. } else if (!to_prev0) {
  1333. first_new0 = min0;
  1334. }
  1335. prev_point = c0->point;
  1336. c0 = e0->target;
  1337. to_prev0 = e0->reverse;
  1338. }
  1339. }
  1340. if ((c0 == first0) && (c1 == first1)) {
  1341. if (to_prev0 == nullptr) {
  1342. pending_head0->link(pending_tail0);
  1343. c0->edges = pending_tail0;
  1344. } else {
  1345. for (Edge *e = to_prev0->prev, *n = nullptr; e != first_new0; e = n) {
  1346. n = e->prev;
  1347. remove_edge_pair(e);
  1348. }
  1349. if (pending_tail0) {
  1350. pending_head0->link(to_prev0);
  1351. first_new0->link(pending_tail0);
  1352. }
  1353. }
  1354. if (to_prev1 == nullptr) {
  1355. pending_tail1->link(pending_head1);
  1356. c1->edges = pending_tail1;
  1357. } else {
  1358. for (Edge *e = to_prev1->next, *n = nullptr; e != first_new1; e = n) {
  1359. n = e->next;
  1360. remove_edge_pair(e);
  1361. }
  1362. if (pending_tail1) {
  1363. to_prev1->link(pending_head1);
  1364. pending_tail1->link(first_new1);
  1365. }
  1366. }
  1367. return;
  1368. }
  1369. first_run = false;
  1370. }
  1371. }
  1372. struct PointComparator {
  1373. _FORCE_INLINE_ bool operator()(const ConvexHullInternal::Point32 &p, const ConvexHullInternal::Point32 &q) const {
  1374. return (p.y < q.y) || ((p.y == q.y) && ((p.x < q.x) || ((p.x == q.x) && (p.z < q.z))));
  1375. }
  1376. };
  1377. void ConvexHullInternal::compute(const Vector3 *p_coords, int32_t p_count) {
  1378. AABB aabb;
  1379. for (int32_t i = 0; i < p_count; i++) {
  1380. Vector3 p = p_coords[i];
  1381. if (i == 0) {
  1382. aabb.position = p;
  1383. } else {
  1384. aabb.expand_to(p);
  1385. }
  1386. }
  1387. Vector3 s = aabb.size;
  1388. max_axis = s.max_axis();
  1389. min_axis = s.min_axis();
  1390. if (min_axis == max_axis) {
  1391. min_axis = (max_axis + 1) % 3;
  1392. }
  1393. med_axis = 3 - max_axis - min_axis;
  1394. s /= real_t(10216);
  1395. if (((med_axis + 1) % 3) != max_axis) {
  1396. s *= -1;
  1397. }
  1398. scaling = s;
  1399. if (s[0] != 0) {
  1400. s[0] = real_t(1) / s[0];
  1401. }
  1402. if (s[1] != 0) {
  1403. s[1] = real_t(1) / s[1];
  1404. }
  1405. if (s[2] != 0) {
  1406. s[2] = real_t(1) / s[2];
  1407. }
  1408. center = aabb.position;
  1409. LocalVector<Point32> points;
  1410. points.resize(p_count);
  1411. for (int32_t i = 0; i < p_count; i++) {
  1412. Vector3 p = p_coords[i];
  1413. p = (p - center) * s;
  1414. points[i].x = (int32_t)p[med_axis];
  1415. points[i].y = (int32_t)p[max_axis];
  1416. points[i].z = (int32_t)p[min_axis];
  1417. points[i].index = i;
  1418. }
  1419. points.sort_custom<PointComparator>();
  1420. vertex_pool.reset(true);
  1421. original_vertices.resize(p_count);
  1422. for (int32_t i = 0; i < p_count; i++) {
  1423. Vertex *v = vertex_pool.alloc();
  1424. v->edges = nullptr;
  1425. v->point = points[i];
  1426. v->copy = -1;
  1427. original_vertices[i] = v;
  1428. }
  1429. points.clear();
  1430. edge_pool.reset(true);
  1431. used_edge_pairs = 0;
  1432. max_used_edge_pairs = 0;
  1433. merge_stamp = -3;
  1434. IntermediateHull hull;
  1435. compute_internal(0, p_count, hull);
  1436. vertex_list = hull.min_xy;
  1437. #ifdef DEBUG_CONVEX_HULL
  1438. printf("max. edges %d (3v = %d)", max_used_edge_pairs, 3 * p_count);
  1439. #endif
  1440. }
  1441. Vector3 ConvexHullInternal::to_gd_vector(const Point32 &p_v) {
  1442. Vector3 p;
  1443. p[med_axis] = real_t(p_v.x);
  1444. p[max_axis] = real_t(p_v.y);
  1445. p[min_axis] = real_t(p_v.z);
  1446. return p * scaling;
  1447. }
  1448. Vector3 ConvexHullInternal::get_gd_normal(Face *p_face) {
  1449. return to_gd_vector(p_face->dir0).cross(to_gd_vector(p_face->dir1)).normalized();
  1450. }
  1451. Vector3 ConvexHullInternal::get_coordinates(const Vertex *p_v) {
  1452. Vector3 p;
  1453. p[med_axis] = p_v->xvalue();
  1454. p[max_axis] = p_v->yvalue();
  1455. p[min_axis] = p_v->zvalue();
  1456. return p * scaling + center;
  1457. }
  1458. real_t ConvexHullInternal::shrink(real_t p_amount, real_t p_clamp_amount) {
  1459. if (!vertex_list) {
  1460. return 0;
  1461. }
  1462. int32_t stamp = --merge_stamp;
  1463. LocalVector<Vertex *> stack;
  1464. vertex_list->copy = stamp;
  1465. stack.push_back(vertex_list);
  1466. LocalVector<Face *> faces;
  1467. Point32 ref = vertex_list->point;
  1468. Int128 hull_center_x(0, 0);
  1469. Int128 hull_center_y(0, 0);
  1470. Int128 hull_center_z(0, 0);
  1471. Int128 volume(0, 0);
  1472. while (stack.size() > 0) {
  1473. Vertex *v = stack[stack.size() - 1];
  1474. stack.remove(stack.size() - 1);
  1475. Edge *e = v->edges;
  1476. if (e) {
  1477. do {
  1478. if (e->target->copy != stamp) {
  1479. e->target->copy = stamp;
  1480. stack.push_back(e->target);
  1481. }
  1482. if (e->copy != stamp) {
  1483. Face *face = face_pool.alloc();
  1484. face->init(e->target, e->reverse->prev->target, v);
  1485. faces.push_back(face);
  1486. Edge *f = e;
  1487. Vertex *a = nullptr;
  1488. Vertex *b = nullptr;
  1489. do {
  1490. if (a && b) {
  1491. int64_t vol = (v->point - ref).dot((a->point - ref).cross(b->point - ref));
  1492. CHULL_ASSERT(vol >= 0);
  1493. Point32 c = v->point + a->point + b->point + ref;
  1494. hull_center_x += vol * c.x;
  1495. hull_center_y += vol * c.y;
  1496. hull_center_z += vol * c.z;
  1497. volume += vol;
  1498. }
  1499. CHULL_ASSERT(f->copy != stamp);
  1500. f->copy = stamp;
  1501. f->face = face;
  1502. a = b;
  1503. b = f->target;
  1504. f = f->reverse->prev;
  1505. } while (f != e);
  1506. }
  1507. e = e->next;
  1508. } while (e != v->edges);
  1509. }
  1510. }
  1511. if (volume.get_sign() <= 0) {
  1512. return 0;
  1513. }
  1514. Vector3 hull_center;
  1515. hull_center[med_axis] = hull_center_x.to_scalar();
  1516. hull_center[max_axis] = hull_center_y.to_scalar();
  1517. hull_center[min_axis] = hull_center_z.to_scalar();
  1518. hull_center /= 4 * volume.to_scalar();
  1519. hull_center *= scaling;
  1520. int32_t face_count = faces.size();
  1521. if (p_clamp_amount > 0) {
  1522. real_t min_dist = FLT_MAX;
  1523. for (int32_t i = 0; i < face_count; i++) {
  1524. Vector3 normal = get_gd_normal(faces[i]);
  1525. real_t dist = normal.dot(to_gd_vector(faces[i]->origin) - hull_center);
  1526. if (dist < min_dist) {
  1527. min_dist = dist;
  1528. }
  1529. }
  1530. if (min_dist <= 0) {
  1531. return 0;
  1532. }
  1533. p_amount = MIN(p_amount, min_dist * p_clamp_amount);
  1534. }
  1535. uint32_t seed = 243703;
  1536. for (int32_t i = 0; i < face_count; i++, seed = 1664525 * seed + 1013904223) {
  1537. SWAP(faces[i], faces[seed % face_count]);
  1538. }
  1539. for (int32_t i = 0; i < face_count; i++) {
  1540. if (!shift_face(faces[i], p_amount, stack)) {
  1541. return -p_amount;
  1542. }
  1543. }
  1544. return p_amount;
  1545. }
  1546. bool ConvexHullInternal::shift_face(Face *p_face, real_t p_amount, LocalVector<Vertex *> p_stack) {
  1547. Vector3 orig_shift = get_gd_normal(p_face) * -p_amount;
  1548. if (scaling[0] != 0) {
  1549. orig_shift[0] /= scaling[0];
  1550. }
  1551. if (scaling[1] != 0) {
  1552. orig_shift[1] /= scaling[1];
  1553. }
  1554. if (scaling[2] != 0) {
  1555. orig_shift[2] /= scaling[2];
  1556. }
  1557. Point32 shift((int32_t)orig_shift[med_axis], (int32_t)orig_shift[max_axis], (int32_t)orig_shift[min_axis]);
  1558. if (shift.is_zero()) {
  1559. return true;
  1560. }
  1561. Point64 normal = p_face->get_normal();
  1562. #ifdef DEBUG_CONVEX_HULL
  1563. printf("\nShrinking p_face (%d %d %d) (%d %d %d) (%d %d %d) by (%d %d %d)\n",
  1564. 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);
  1565. #endif
  1566. int64_t orig_dot = p_face->origin.dot(normal);
  1567. Point32 shifted_origin = p_face->origin + shift;
  1568. int64_t shifted_dot = shifted_origin.dot(normal);
  1569. CHULL_ASSERT(shifted_dot <= orig_dot);
  1570. if (shifted_dot >= orig_dot) {
  1571. return false;
  1572. }
  1573. Edge *intersection = nullptr;
  1574. Edge *start_edge = p_face->nearby_vertex->edges;
  1575. #ifdef DEBUG_CONVEX_HULL
  1576. printf("Start edge is ");
  1577. start_edge->print();
  1578. printf(", normal is (%lld %lld %lld), shifted dot is %lld\n", normal.x, normal.y, normal.z, shifted_dot);
  1579. #endif
  1580. Rational128 opt_dot = p_face->nearby_vertex->dot(normal);
  1581. int32_t cmp = opt_dot.compare(shifted_dot);
  1582. #ifdef SHOW_ITERATIONS
  1583. int32_t n = 0;
  1584. #endif
  1585. if (cmp >= 0) {
  1586. Edge *e = start_edge;
  1587. do {
  1588. #ifdef SHOW_ITERATIONS
  1589. n++;
  1590. #endif
  1591. Rational128 dot = e->target->dot(normal);
  1592. CHULL_ASSERT(dot.compare(orig_dot) <= 0);
  1593. #ifdef DEBUG_CONVEX_HULL
  1594. printf("Moving downwards, edge is ");
  1595. e->print();
  1596. printf(", dot is %f (%f %lld)\n", (float)dot.to_scalar(), (float)opt_dot.to_scalar(), shifted_dot);
  1597. #endif
  1598. if (dot.compare(opt_dot) < 0) {
  1599. int32_t c = dot.compare(shifted_dot);
  1600. opt_dot = dot;
  1601. e = e->reverse;
  1602. start_edge = e;
  1603. if (c < 0) {
  1604. intersection = e;
  1605. break;
  1606. }
  1607. cmp = c;
  1608. }
  1609. e = e->prev;
  1610. } while (e != start_edge);
  1611. if (!intersection) {
  1612. return false;
  1613. }
  1614. } else {
  1615. Edge *e = start_edge;
  1616. do {
  1617. #ifdef SHOW_ITERATIONS
  1618. n++;
  1619. #endif
  1620. Rational128 dot = e->target->dot(normal);
  1621. CHULL_ASSERT(dot.compare(orig_dot) <= 0);
  1622. #ifdef DEBUG_CONVEX_HULL
  1623. printf("Moving upwards, edge is ");
  1624. e->print();
  1625. printf(", dot is %f (%f %lld)\n", (float)dot.to_scalar(), (float)opt_dot.to_scalar(), shifted_dot);
  1626. #endif
  1627. if (dot.compare(opt_dot) > 0) {
  1628. cmp = dot.compare(shifted_dot);
  1629. if (cmp >= 0) {
  1630. intersection = e;
  1631. break;
  1632. }
  1633. opt_dot = dot;
  1634. e = e->reverse;
  1635. start_edge = e;
  1636. }
  1637. e = e->prev;
  1638. } while (e != start_edge);
  1639. if (!intersection) {
  1640. return true;
  1641. }
  1642. }
  1643. #ifdef SHOW_ITERATIONS
  1644. printf("Needed %d iterations to find initial intersection\n", n);
  1645. #endif
  1646. if (cmp == 0) {
  1647. Edge *e = intersection->reverse->next;
  1648. #ifdef SHOW_ITERATIONS
  1649. n = 0;
  1650. #endif
  1651. while (e->target->dot(normal).compare(shifted_dot) <= 0) {
  1652. #ifdef SHOW_ITERATIONS
  1653. n++;
  1654. #endif
  1655. e = e->next;
  1656. if (e == intersection->reverse) {
  1657. return true;
  1658. }
  1659. #ifdef DEBUG_CONVEX_HULL
  1660. printf("Checking for outwards edge, current edge is ");
  1661. e->print();
  1662. printf("\n");
  1663. #endif
  1664. }
  1665. #ifdef SHOW_ITERATIONS
  1666. printf("Needed %d iterations to check for complete containment\n", n);
  1667. #endif
  1668. }
  1669. Edge *first_intersection = nullptr;
  1670. Edge *face_edge = nullptr;
  1671. Edge *first_face_edge = nullptr;
  1672. #ifdef SHOW_ITERATIONS
  1673. int32_t m = 0;
  1674. #endif
  1675. while (true) {
  1676. #ifdef SHOW_ITERATIONS
  1677. m++;
  1678. #endif
  1679. #ifdef DEBUG_CONVEX_HULL
  1680. printf("Intersecting edge is ");
  1681. intersection->print();
  1682. printf("\n");
  1683. #endif
  1684. if (cmp == 0) {
  1685. Edge *e = intersection->reverse->next;
  1686. start_edge = e;
  1687. #ifdef SHOW_ITERATIONS
  1688. n = 0;
  1689. #endif
  1690. while (true) {
  1691. #ifdef SHOW_ITERATIONS
  1692. n++;
  1693. #endif
  1694. if (e->target->dot(normal).compare(shifted_dot) >= 0) {
  1695. break;
  1696. }
  1697. intersection = e->reverse;
  1698. e = e->next;
  1699. if (e == start_edge) {
  1700. return true;
  1701. }
  1702. }
  1703. #ifdef SHOW_ITERATIONS
  1704. printf("Needed %d iterations to advance intersection\n", n);
  1705. #endif
  1706. }
  1707. #ifdef DEBUG_CONVEX_HULL
  1708. printf("Advanced intersecting edge to ");
  1709. intersection->print();
  1710. printf(", cmp = %d\n", cmp);
  1711. #endif
  1712. if (!first_intersection) {
  1713. first_intersection = intersection;
  1714. } else if (intersection == first_intersection) {
  1715. break;
  1716. }
  1717. int32_t prev_cmp = cmp;
  1718. Edge *prev_intersection = intersection;
  1719. Edge *prev_face_edge = face_edge;
  1720. Edge *e = intersection->reverse;
  1721. #ifdef SHOW_ITERATIONS
  1722. n = 0;
  1723. #endif
  1724. while (true) {
  1725. #ifdef SHOW_ITERATIONS
  1726. n++;
  1727. #endif
  1728. e = e->reverse->prev;
  1729. CHULL_ASSERT(e != intersection->reverse);
  1730. cmp = e->target->dot(normal).compare(shifted_dot);
  1731. #ifdef DEBUG_CONVEX_HULL
  1732. printf("Testing edge ");
  1733. e->print();
  1734. printf(" -> cmp = %d\n", cmp);
  1735. #endif
  1736. if (cmp >= 0) {
  1737. intersection = e;
  1738. break;
  1739. }
  1740. }
  1741. #ifdef SHOW_ITERATIONS
  1742. printf("Needed %d iterations to find other intersection of p_face\n", n);
  1743. #endif
  1744. if (cmp > 0) {
  1745. Vertex *removed = intersection->target;
  1746. e = intersection->reverse;
  1747. if (e->prev == e) {
  1748. removed->edges = nullptr;
  1749. } else {
  1750. removed->edges = e->prev;
  1751. e->prev->link(e->next);
  1752. e->link(e);
  1753. }
  1754. #ifdef DEBUG_CONVEX_HULL
  1755. printf("1: Removed part contains (%d %d %d)\n", removed->point.x, removed->point.y, removed->point.z);
  1756. #endif
  1757. Point64 n0 = intersection->face->get_normal();
  1758. Point64 n1 = intersection->reverse->face->get_normal();
  1759. int64_t m00 = p_face->dir0.dot(n0);
  1760. int64_t m01 = p_face->dir1.dot(n0);
  1761. int64_t m10 = p_face->dir0.dot(n1);
  1762. int64_t m11 = p_face->dir1.dot(n1);
  1763. int64_t r0 = (intersection->face->origin - shifted_origin).dot(n0);
  1764. int64_t r1 = (intersection->reverse->face->origin - shifted_origin).dot(n1);
  1765. Int128 det = Int128::mul(m00, m11) - Int128::mul(m01, m10);
  1766. CHULL_ASSERT(det.get_sign() != 0);
  1767. Vertex *v = vertex_pool.alloc();
  1768. v->point.index = -1;
  1769. v->copy = -1;
  1770. 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,
  1771. 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,
  1772. 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,
  1773. det);
  1774. v->point.x = (int32_t)v->point128.xvalue();
  1775. v->point.y = (int32_t)v->point128.yvalue();
  1776. v->point.z = (int32_t)v->point128.zvalue();
  1777. intersection->target = v;
  1778. v->edges = e;
  1779. p_stack.push_back(v);
  1780. p_stack.push_back(removed);
  1781. p_stack.push_back(nullptr);
  1782. }
  1783. if (cmp || prev_cmp || (prev_intersection->reverse->next->target != intersection->target)) {
  1784. face_edge = new_edge_pair(prev_intersection->target, intersection->target);
  1785. if (prev_cmp == 0) {
  1786. face_edge->link(prev_intersection->reverse->next);
  1787. }
  1788. if ((prev_cmp == 0) || prev_face_edge) {
  1789. prev_intersection->reverse->link(face_edge);
  1790. }
  1791. if (cmp == 0) {
  1792. intersection->reverse->prev->link(face_edge->reverse);
  1793. }
  1794. face_edge->reverse->link(intersection->reverse);
  1795. } else {
  1796. face_edge = prev_intersection->reverse->next;
  1797. }
  1798. if (prev_face_edge) {
  1799. if (prev_cmp > 0) {
  1800. face_edge->link(prev_face_edge->reverse);
  1801. } else if (face_edge != prev_face_edge->reverse) {
  1802. p_stack.push_back(prev_face_edge->target);
  1803. while (face_edge->next != prev_face_edge->reverse) {
  1804. Vertex *removed = face_edge->next->target;
  1805. remove_edge_pair(face_edge->next);
  1806. p_stack.push_back(removed);
  1807. #ifdef DEBUG_CONVEX_HULL
  1808. printf("2: Removed part contains (%d %d %d)\n", removed->point.x, removed->point.y, removed->point.z);
  1809. #endif
  1810. }
  1811. p_stack.push_back(nullptr);
  1812. }
  1813. }
  1814. face_edge->face = p_face;
  1815. face_edge->reverse->face = intersection->face;
  1816. if (!first_face_edge) {
  1817. first_face_edge = face_edge;
  1818. }
  1819. }
  1820. #ifdef SHOW_ITERATIONS
  1821. printf("Needed %d iterations to process all intersections\n", m);
  1822. #endif
  1823. if (cmp > 0) {
  1824. first_face_edge->reverse->target = face_edge->target;
  1825. first_intersection->reverse->link(first_face_edge);
  1826. first_face_edge->link(face_edge->reverse);
  1827. } else if (first_face_edge != face_edge->reverse) {
  1828. p_stack.push_back(face_edge->target);
  1829. while (first_face_edge->next != face_edge->reverse) {
  1830. Vertex *removed = first_face_edge->next->target;
  1831. remove_edge_pair(first_face_edge->next);
  1832. p_stack.push_back(removed);
  1833. #ifdef DEBUG_CONVEX_HULL
  1834. printf("3: Removed part contains (%d %d %d)\n", removed->point.x, removed->point.y, removed->point.z);
  1835. #endif
  1836. }
  1837. p_stack.push_back(nullptr);
  1838. }
  1839. CHULL_ASSERT(p_stack.size() > 0);
  1840. vertex_list = p_stack[0];
  1841. #ifdef DEBUG_CONVEX_HULL
  1842. printf("Removing part\n");
  1843. #endif
  1844. #ifdef SHOW_ITERATIONS
  1845. n = 0;
  1846. #endif
  1847. uint32_t pos = 0;
  1848. while (pos < p_stack.size()) {
  1849. uint32_t end = p_stack.size();
  1850. while (pos < end) {
  1851. Vertex *kept = p_stack[pos++];
  1852. #ifdef DEBUG_CONVEX_HULL
  1853. kept->print();
  1854. #endif
  1855. bool deeper = false;
  1856. Vertex *removed;
  1857. while ((removed = p_stack[pos++]) != nullptr) {
  1858. #ifdef SHOW_ITERATIONS
  1859. n++;
  1860. #endif
  1861. kept->receive_nearby_faces(removed);
  1862. while (removed->edges) {
  1863. if (!deeper) {
  1864. deeper = true;
  1865. p_stack.push_back(kept);
  1866. }
  1867. p_stack.push_back(removed->edges->target);
  1868. remove_edge_pair(removed->edges);
  1869. }
  1870. }
  1871. if (deeper) {
  1872. p_stack.push_back(nullptr);
  1873. }
  1874. }
  1875. }
  1876. #ifdef SHOW_ITERATIONS
  1877. printf("Needed %d iterations to remove part\n", n);
  1878. #endif
  1879. p_stack.resize(0);
  1880. p_face->origin = shifted_origin;
  1881. return true;
  1882. }
  1883. static int32_t get_vertex_copy(ConvexHullInternal::Vertex *p_vertex, LocalVector<ConvexHullInternal::Vertex *> &p_vertices) {
  1884. int32_t index = p_vertex->copy;
  1885. if (index < 0) {
  1886. index = p_vertices.size();
  1887. p_vertex->copy = index;
  1888. p_vertices.push_back(p_vertex);
  1889. #ifdef DEBUG_CONVEX_HULL
  1890. printf("Vertex %d gets index *%d\n", p_vertex->point.index, index);
  1891. #endif
  1892. }
  1893. return index;
  1894. }
  1895. real_t ConvexHullComputer::compute(const Vector3 *p_coords, int32_t p_count, real_t p_shrink, real_t p_shrink_clamp) {
  1896. if (p_count <= 0) {
  1897. vertices.clear();
  1898. edges.clear();
  1899. faces.clear();
  1900. return 0;
  1901. }
  1902. ConvexHullInternal hull;
  1903. hull.compute(p_coords, p_count);
  1904. real_t shift = 0;
  1905. if ((p_shrink > 0) && ((shift = hull.shrink(p_shrink, p_shrink_clamp)) < 0)) {
  1906. vertices.clear();
  1907. edges.clear();
  1908. faces.clear();
  1909. return shift;
  1910. }
  1911. vertices.resize(0);
  1912. edges.resize(0);
  1913. faces.resize(0);
  1914. LocalVector<ConvexHullInternal::Vertex *> old_vertices;
  1915. get_vertex_copy(hull.vertex_list, old_vertices);
  1916. int32_t copied = 0;
  1917. while (copied < (int32_t)old_vertices.size()) {
  1918. ConvexHullInternal::Vertex *v = old_vertices[copied];
  1919. vertices.push_back(hull.get_coordinates(v));
  1920. ConvexHullInternal::Edge *first_edge = v->edges;
  1921. if (first_edge) {
  1922. int32_t first_copy = -1;
  1923. int32_t prev_copy = -1;
  1924. ConvexHullInternal::Edge *e = first_edge;
  1925. do {
  1926. if (e->copy < 0) {
  1927. int32_t s = edges.size();
  1928. edges.push_back(Edge());
  1929. edges.push_back(Edge());
  1930. Edge *c = &edges[s];
  1931. Edge *r = &edges[s + 1];
  1932. e->copy = s;
  1933. e->reverse->copy = s + 1;
  1934. c->reverse = 1;
  1935. r->reverse = -1;
  1936. c->target_vertex = get_vertex_copy(e->target, old_vertices);
  1937. r->target_vertex = copied;
  1938. #ifdef DEBUG_CONVEX_HULL
  1939. printf(" CREATE: Vertex *%d has edge to *%d\n", copied, c->get_target_vertex());
  1940. #endif
  1941. }
  1942. if (prev_copy >= 0) {
  1943. edges[e->copy].next = prev_copy - e->copy;
  1944. } else {
  1945. first_copy = e->copy;
  1946. }
  1947. prev_copy = e->copy;
  1948. e = e->next;
  1949. } while (e != first_edge);
  1950. edges[first_copy].next = prev_copy - first_copy;
  1951. }
  1952. copied++;
  1953. }
  1954. for (int32_t i = 0; i < copied; i++) {
  1955. ConvexHullInternal::Vertex *v = old_vertices[i];
  1956. ConvexHullInternal::Edge *first_edge = v->edges;
  1957. if (first_edge) {
  1958. ConvexHullInternal::Edge *e = first_edge;
  1959. do {
  1960. if (e->copy >= 0) {
  1961. #ifdef DEBUG_CONVEX_HULL
  1962. printf("Vertex *%d has edge to *%d\n", i, edges[e->copy].get_target_vertex());
  1963. #endif
  1964. faces.push_back(e->copy);
  1965. ConvexHullInternal::Edge *f = e;
  1966. do {
  1967. #ifdef DEBUG_CONVEX_HULL
  1968. printf(" Face *%d\n", edges[f->copy].get_target_vertex());
  1969. #endif
  1970. f->copy = -1;
  1971. f = f->reverse->prev;
  1972. } while (f != e);
  1973. }
  1974. e = e->next;
  1975. } while (e != first_edge);
  1976. }
  1977. }
  1978. return shift;
  1979. }
  1980. Error ConvexHullComputer::convex_hull(const Vector<Vector3> &p_points, Geometry::MeshData &r_mesh) {
  1981. return convex_hull(p_points.ptr(), p_points.size(), r_mesh);
  1982. }
  1983. Error ConvexHullComputer::convex_hull(const PoolVector<Vector3> &p_points, Geometry::MeshData &r_mesh) {
  1984. return convex_hull(p_points.read().ptr(), p_points.size(), r_mesh);
  1985. }
  1986. Error ConvexHullComputer::convex_hull(const Vector3 *p_points, int32_t p_point_count, Geometry::MeshData &r_mesh) {
  1987. r_mesh = Geometry::MeshData(); // clear
  1988. if (p_point_count == 0) {
  1989. return FAILED; // matches QuickHull
  1990. }
  1991. ConvexHullComputer ch;
  1992. ch.compute(p_points, p_point_count, -1.0, -1.0);
  1993. r_mesh.vertices = ch.vertices;
  1994. r_mesh.edges.resize(ch.edges.size());
  1995. for (uint32_t i = 0; i < ch.edges.size(); i++) {
  1996. r_mesh.edges.write[i].a = (&ch.edges[i])->get_source_vertex();
  1997. r_mesh.edges.write[i].b = (&ch.edges[i])->get_target_vertex();
  1998. }
  1999. r_mesh.faces.resize(ch.faces.size());
  2000. for (uint32_t i = 0; i < ch.faces.size(); i++) {
  2001. const Edge *e_start = &ch.edges[ch.faces[i]];
  2002. const Edge *e = e_start;
  2003. Geometry::MeshData::Face &face = r_mesh.faces.write[i];
  2004. do {
  2005. face.indices.push_back(e->get_target_vertex());
  2006. e = e->get_next_edge_of_face();
  2007. } while (e != e_start);
  2008. // compute normal
  2009. if (face.indices.size() >= 3) {
  2010. face.plane = Plane(r_mesh.vertices[face.indices[0]], r_mesh.vertices[face.indices[2]], r_mesh.vertices[face.indices[1]]);
  2011. } else {
  2012. WARN_PRINT("Too few vertices per face.");
  2013. }
  2014. }
  2015. return OK;
  2016. }