24 #elif defined(_MSC_VER)
46 #if defined(DEBUG_CONVEX_HULL) || defined(SHOW_ITERATIONS)
69 return (
x == 0) && (
y == 0) && (
z == 0);
74 return x * b.
x +
y * b.
y +
z * b.
z;
96 return (
x == b.
x) && (
y == b.
y) && (
z == b.
z);
101 return (
x != b.
x) || (
y != b.
y) || (
z != b.
z);
106 return (
x == 0) && (
y == 0) && (
z == 0);
121 return x * b.
x +
y * b.
y +
z * b.
z;
126 return x * b.
x +
y * b.
y +
z * b.
z;
173 #ifdef USE_X86_64_ASM
175 __asm__ (
"addq %[bl], %[rl]\n\t"
176 "adcq %[bh], %[rh]\n\t"
177 : [rl]
"=r" (result.
low), [rh]
"=r" (result.
high)
189 #ifdef USE_X86_64_ASM
191 __asm__ (
"subq %[bl], %[rl]\n\t"
192 "sbbq %[bh], %[rh]\n\t"
193 : [rl]
"=r" (result.
low), [rh]
"=r" (result.
high)
204 #ifdef USE_X86_64_ASM
205 __asm__ (
"addq %[bl], %[rl]\n\t"
206 "adcq %[bh], %[rh]\n\t"
207 : [rl]
"=r" (
low), [rh]
"=r" (
high)
287 else if (numerator < 0)
301 else if (denominator < 0)
372 int dsign = denominator.
getSign();
447 #ifdef DEBUG_CONVEX_HULL
499 f->nearbyVertex =
this;
533 #ifdef DEBUG_CONVEX_HULL
562 if (a->lastNearbyFace)
568 a->firstNearbyFace =
this;
570 a->lastNearbyFace =
this;
579 template<
typename UWord,
typename UHWord>
class DMul
625 static void mul(UWord a, UWord b, UWord& resLow, UWord& resHigh)
631 UWord p0110 = UWord(
low(p01)) + UWord(
low(p10));
687 for (
int i = 0; i <
size; i++, o++)
689 o->next = (i+1 <
size) ? o + 1 : NULL;
695 template <
typename T>
class Pool
817 bool mergeProjection(IntermediateHull& h0, IntermediateHull& h1, Vertex*& c0, Vertex*& c1);
819 void merge(IntermediateHull& h0, IntermediateHull& h1);
830 void compute(
const void* coords,
bool doubleCoords,
int stride,
int count);
841 Int128 a = negative ? -*
this : *
this;
844 negative = !negative;
849 return negative ? -result : result;
856 #ifdef USE_X86_64_ASM
857 __asm__ (
"imulq %[b]"
858 :
"=a" (result.
low),
"=d" (result.
high)
864 bool negative = a < 0;
871 negative = !negative;
875 return negative ? -result : result;
883 #ifdef USE_X86_64_ASM
885 :
"=a" (result.
low),
"=d" (result.
high)
900 return sign - b.
sign;
909 #ifdef USE_X86_64_ASM
914 __asm__ (
"mulq %[bn]\n\t"
915 "movq %%rax, %[tmp]\n\t"
916 "movq %%rdx, %%rbx\n\t"
917 "movq %[tn], %%rax\n\t"
919 "subq %[tmp], %%rax\n\t"
920 "sbbq %%rbx, %%rdx\n\t"
922 "orq %%rdx, %%rax\n\t"
925 "shll $16, %%ebx\n\t"
926 :
"=&b"(result), [tmp]
"=&r"(tmp),
"=a"(dummy)
927 :
"a"(denominator), [bn]
"g"(b.numerator), [tn]
"g"(numerator), [bd]
"g"(b.denominator)
929 return result ? result ^ sign
944 return sign - b.
sign;
955 Int128 nbdLow, nbdHigh, dbnLow, dbnHigh;
959 int cmp = nbdHigh.
ucmp(dbnHigh);
964 return nbdLow.
ucmp(dbnLow) * sign;
972 return (a > b) ? 1 : (a < b) ? -1 : 0;
994 return numerator.ucmp(denominator * b) * sign;
1072 for (
int side = 0; side <= 1; side++)
1086 if ((dy0 <= 0) && ((dx0 == 0) || ((dx0 < 0) && (dy0 * dx <= dy * dx0))))
1100 if ((dxn > 0) && (dy1 < 0) && ((dx1 == 0) || ((dx1 < 0) && (dy1 * dx < dy * dx1))))
1122 if ((dy1 >= 0) && ((dx1 == 0) || ((dx1 < 0) && (dy1 * dx <= dy * dx1))))
1136 if ((dxn < 0) && (dy0 > 0) && ((dx0 == 0) || ((dx0 < 0) && (dy0 * dx < dy * dx0))))
1206 int n = end - start;
1210 result.
minXy = NULL;
1211 result.
maxXy = NULL;
1212 result.
minYx = NULL;
1213 result.
maxYx = NULL;
1224 if ((dx == 0) && (dy == 0))
1247 if ((dx < 0) || ((dx == 0) && (dy < 0)))
1258 if ((dy < 0) || ((dy == 0) && (dx < 0)))
1298 int split0 = start + n / 2;
1300 int split1 = split0;
1308 #ifdef DEBUG_CONVEX_HULL
1309 printf(
"\n\nMerge\n");
1313 merge(result, hull1);
1314 #ifdef DEBUG_CONVEX_HULL
1315 printf(
"\n Result\n");
1320 #ifdef DEBUG_CONVEX_HULL
1324 for (Vertex* v = minXy; v; )
1340 if (v->next->prev != v)
1342 printf(
" Inconsistency");
1353 minXy->copy = (minXy->copy == -1) ? -2 : -1;
1354 minXy->printGraph();
1358 void btConvexHullInternal::Vertex::printGraph()
1361 printf(
"\nEdges\n");
1370 }
while (e != edges);
1373 Vertex* v = e->target;
1374 if (v->copy != copy)
1380 }
while (e != edges);
1388 if (prev->
next == next)
1390 if (prev->
prev == next)
1401 else if (prev->
prev == next)
1413 Edge* minEdge = NULL;
1415 #ifdef DEBUG_CONVEX_HULL
1416 printf(
"find max edge for %d\n", start->
point.
index);
1427 #ifdef DEBUG_CONVEX_HULL
1428 printf(
" Angle is %f (%d) for ", (
float)
btAtan(cot.toScalar()), (
int) cot.isNaN());
1438 if (minEdge == NULL)
1443 else if ((cmp = cot.compare(minCot)) < 0)
1453 #ifdef DEBUG_CONVEX_HULL
1458 }
while (e != start->
edges);
1470 Point64 normal = ((start0 ? start0 : start1)->target->point - c0->
point).cross(s);
1476 #ifdef DEBUG_CONVEX_HULL
1483 while (e0->
target != stop0)
1509 while (e1->
target != stop1)
1532 #ifdef DEBUG_CONVEX_HULL
1533 printf(
" Starting at %d %d\n", et0.
index, et1.
index);
1536 int64_t dx = maxDot1 - maxDot0;
1543 if (e0 && (e0->
target != stop0))
1553 dx = (et1 - et0).
dot(perp);
1554 e0 = (e0 == start0) ? NULL : f0;
1560 if (e1 && (e1->
target != stop1))
1566 if (d1.
dot(normal) == 0)
1595 if (e1 && (e1->
target != stop1))
1605 dx = (et1 - et0).
dot(perp);
1606 e1 = (e1 == start1) ? NULL : f1;
1612 if (e0 && (e0->
target != stop0))
1618 if (d0.
dot(normal) == 0)
1641 #ifdef DEBUG_CONVEX_HULL
1642 printf(
" Advanced edges to %d %d\n", et0.
index, et1.
index);
1662 Edge* toPrev0 = NULL;
1663 Edge* firstNew0 = NULL;
1664 Edge* pendingHead0 = NULL;
1665 Edge* pendingTail0 = NULL;
1667 Edge* toPrev1 = NULL;
1668 Edge* firstNew1 = NULL;
1669 Edge* pendingHead1 = NULL;
1670 Edge* pendingTail1 = NULL;
1680 Edge* e = c0->edges;
1681 Edge* start0 = NULL;
1688 if ((dot == 0) && ((*e->target - *c0).dot(t) > 0))
1696 }
while (e != c0->edges);
1700 Edge* start1 = NULL;
1707 if ((dot == 0) && ((*e->target - *c1).dot(t) > 0))
1715 }
while (e != c1->
edges);
1718 if (start0 || start1)
1731 prevPoint = c1->
point;
1736 prevPoint = c1->
point;
1742 bool firstRun =
true;
1747 Point32 r = prevPoint - c0->point;
1751 #ifdef DEBUG_CONVEX_HULL
1752 printf(
"\n Checking %d %d\n", c0->point.index, c1->
point.
index);
1771 int cmp = !min0 ? 1 : !min1 ? -1 : minCot0.
compare(minCot1);
1772 #ifdef DEBUG_CONVEX_HULL
1773 printf(
" -> Result %d\n", cmp);
1780 pendingTail0->
prev = e;
1786 e->
next = pendingTail0;
1792 pendingTail1->
next = e;
1798 e->
prev = pendingTail1;
1805 #ifdef DEBUG_CONVEX_HULL
1814 if ((cmp >= 0) && e1)
1818 for (
Edge* e = toPrev1->
next, *n = NULL; e != min1; e = n)
1829 toPrev1->
link(pendingHead1);
1834 firstNew1 = pendingHead1;
1836 pendingTail1->
link(min1);
1837 pendingHead1 = NULL;
1838 pendingTail1 = NULL;
1845 prevPoint = c1->
point;
1850 if ((cmp <= 0) && e0)
1854 for (
Edge* e = toPrev0->
prev, *n = NULL; e != min0; e = n)
1865 pendingHead0->
link(toPrev0);
1870 firstNew0 = pendingHead0;
1872 min0->
link(pendingTail0);
1873 pendingHead0 = NULL;
1874 pendingTail0 = NULL;
1881 prevPoint = c0->point;
1887 if ((c0 == first0) && (c1 == first1))
1889 if (toPrev0 == NULL)
1891 pendingHead0->
link(pendingTail0);
1892 c0->edges = pendingTail0;
1896 for (
Edge* e = toPrev0->
prev, *n = NULL; e != firstNew0; e = n)
1903 pendingHead0->
link(toPrev0);
1904 firstNew0->
link(pendingTail0);
1908 if (toPrev1 == NULL)
1910 pendingTail1->
link(pendingHead1);
1911 c1->
edges = pendingTail1;
1915 for (
Edge* e = toPrev1->
next, *n = NULL; e != firstNew1; e = n)
1922 toPrev1->
link(pendingHead1);
1923 pendingTail1->
link(firstNew1);
1937 return (p.
y < q.
y) || ((p.
y == q.
y) && ((p.
x < q.
x) || ((p.
x == q.
x) && (p.
z < q.
z))));
1943 const char* ptr = (
const char*) coords;
1946 for (
int i = 0; i < count; i++)
1948 const double* v = (
const double*) ptr;
1957 for (
int i = 0; i < count; i++)
1959 const float* v = (
const float*) ptr;
2000 ptr = (
const char*) coords;
2003 for (
int i = 0; i < count; i++)
2005 const double* v = (
const double*) ptr;
2011 points[i].z = (
int32_t) p[minAxis];
2012 points[i].index = i;
2017 for (
int i = 0; i < count; i++)
2019 const float* v = (
const float*) ptr;
2025 points[i].z = (
int32_t) p[minAxis];
2026 points[i].index = i;
2034 for (
int i = 0; i < count; i++)
2038 v->
point = points[i];
2056 #ifdef DEBUG_CONVEX_HULL
2097 Int128 hullCenterX(0, 0);
2098 Int128 hullCenterY(0, 0);
2099 Int128 hullCenterZ(0, 0);
2102 while (stack.
size() > 0)
2116 if (e->
copy != stamp)
2132 hullCenterX += vol * c.
x;
2133 hullCenterY += vol * c.
y;
2134 hullCenterZ += vol * c.
z;
2149 }
while (e != v->
edges);
2162 hullCenter /= 4 * volume.
toScalar();
2165 int faceCount = faces.
size();
2167 if (clampAmount > 0)
2170 for (
int i = 0; i < faceCount; i++)
2185 amount =
btMin(amount, minDist * clampAmount);
2188 unsigned int seed = 243703;
2189 for (
int i = 0; i < faceCount; i++, seed = 1664525 * seed + 1013904223)
2191 btSwap(faces[i], faces[seed % faceCount]);
2194 for (
int i = 0; i < faceCount; i++)
2196 if (!
shiftFace(faces[i], amount, stack))
2226 #ifdef DEBUG_CONVEX_HULL
2227 printf(
"\nShrinking face (%d %d %d) (%d %d %d) (%d %d %d) by (%d %d %d)\n",
2228 face->
origin.
x, face->
origin.
y, face->
origin.
z, face->
dir0.
x, face->
dir0.
y, face->
dir0.
z, face->
dir1.
x, face->
dir1.
y, face->
dir1.
z, shift.
x, shift.
y, shift.
z);
2232 int64_t shiftedDot = shiftedOrigin.
dot(normal);
2234 if (shiftedDot >= origDot)
2239 Edge* intersection = NULL;
2242 #ifdef DEBUG_CONVEX_HULL
2243 printf(
"Start edge is ");
2245 printf(
", normal is (%lld %lld %lld), shifted dot is %lld\n", normal.
x, normal.
y, normal.
z, shiftedDot);
2248 int cmp = optDot.
compare(shiftedDot);
2249 #ifdef SHOW_ITERATIONS
2254 Edge* e = startEdge;
2257 #ifdef SHOW_ITERATIONS
2262 #ifdef DEBUG_CONVEX_HULL
2263 printf(
"Moving downwards, edge is ");
2265 printf(
", dot is %f (%f %lld)\n", (
float) dot.
toScalar(), (float) optDot.
toScalar(), shiftedDot);
2269 int c = dot.
compare(shiftedDot);
2281 }
while (e != startEdge);
2290 Edge* e = startEdge;
2293 #ifdef SHOW_ITERATIONS
2298 #ifdef DEBUG_CONVEX_HULL
2299 printf(
"Moving upwards, edge is ");
2301 printf(
", dot is %f (%f %lld)\n", (
float) dot.
toScalar(), (float) optDot.
toScalar(), shiftedDot);
2305 cmp = dot.
compare(shiftedDot);
2316 }
while (e != startEdge);
2324 #ifdef SHOW_ITERATIONS
2325 printf(
"Needed %d iterations to find initial intersection\n", n);
2331 #ifdef SHOW_ITERATIONS
2336 #ifdef SHOW_ITERATIONS
2340 if (e == intersection->
reverse)
2344 #ifdef DEBUG_CONVEX_HULL
2345 printf(
"Checking for outwards edge, current edge is ");
2350 #ifdef SHOW_ITERATIONS
2351 printf(
"Needed %d iterations to check for complete containment\n", n);
2355 Edge* firstIntersection = NULL;
2356 Edge* faceEdge = NULL;
2357 Edge* firstFaceEdge = NULL;
2359 #ifdef SHOW_ITERATIONS
2364 #ifdef SHOW_ITERATIONS
2367 #ifdef DEBUG_CONVEX_HULL
2368 printf(
"Intersecting edge is ");
2369 intersection->print();
2376 #ifdef SHOW_ITERATIONS
2381 #ifdef SHOW_ITERATIONS
2395 #ifdef SHOW_ITERATIONS
2396 printf(
"Needed %d iterations to advance intersection\n", n);
2400 #ifdef DEBUG_CONVEX_HULL
2401 printf(
"Advanced intersecting edge to ");
2402 intersection->print();
2403 printf(
", cmp = %d\n", cmp);
2406 if (!firstIntersection)
2408 firstIntersection = intersection;
2410 else if (intersection == firstIntersection)
2416 Edge* prevIntersection = intersection;
2417 Edge* prevFaceEdge = faceEdge;
2420 #ifdef SHOW_ITERATIONS
2425 #ifdef SHOW_ITERATIONS
2431 #ifdef DEBUG_CONVEX_HULL
2432 printf(
"Testing edge ");
2434 printf(
" -> cmp = %d\n", cmp);
2442 #ifdef SHOW_ITERATIONS
2443 printf(
"Needed %d iterations to find other intersection of face\n", n);
2452 removed->
edges = NULL;
2460 #ifdef DEBUG_CONVEX_HULL
2461 printf(
"1: Removed part contains (%d %d %d)\n", removed->
point.
x, removed->
point.
y, removed->
point.
z);
2475 v->point.index = -1;
2484 v->point.x = (
int32_t) v->point128.xvalue();
2485 v->point.y = (
int32_t) v->point128.yvalue();
2486 v->point.z = (
int32_t) v->point128.zvalue();
2487 intersection->
target = v;
2502 if ((prevCmp == 0) || prevFaceEdge)
2523 else if (faceEdge != prevFaceEdge->
reverse)
2531 #ifdef DEBUG_CONVEX_HULL
2532 printf(
"2: Removed part contains (%d %d %d)\n", removed->
point.
x, removed->
point.
y, removed->
point.
z);
2538 faceEdge->
face = face;
2543 firstFaceEdge = faceEdge;
2546 #ifdef SHOW_ITERATIONS
2547 printf(
"Needed %d iterations to process all intersections\n", m);
2556 else if (firstFaceEdge != faceEdge->
reverse)
2564 #ifdef DEBUG_CONVEX_HULL
2565 printf(
"3: Removed part contains (%d %d %d)\n", removed->
point.
x, removed->
point.
y, removed->
point.
z);
2574 #ifdef DEBUG_CONVEX_HULL
2575 printf(
"Removing part\n");
2577 #ifdef SHOW_ITERATIONS
2581 while (pos < stack.
size())
2583 int end = stack.
size();
2586 Vertex* kept = stack[pos++];
2587 #ifdef DEBUG_CONVEX_HULL
2590 bool deeper =
false;
2592 while ((removed = stack[pos++]) != NULL)
2594 #ifdef SHOW_ITERATIONS
2598 while (removed->
edges)
2615 #ifdef SHOW_ITERATIONS
2616 printf(
"Needed %d iterations to remove part\n", n);
2620 face->
origin = shiftedOrigin;
2628 int index = vertex->
copy;
2631 index = vertices.
size();
2632 vertex->
copy = index;
2634 #ifdef DEBUG_CONVEX_HULL
2635 printf(
"Vertex %d gets index *%d\n", vertex->
point.
index, index);
2652 hull.
compute(coords, doubleCoords, stride, count);
2655 if ((shrink > 0) && ((shift = hull.
shrink(shrink, shrinkClamp)) < 0))
2670 while (copied < oldVertices.
size())
2684 int s = edges.size();
2685 edges.push_back(
Edge());
2686 edges.push_back(
Edge());
2687 Edge* c = &edges[s];
2688 Edge* r = &edges[s + 1];
2695 #ifdef DEBUG_CONVEX_HULL
2696 printf(
" CREATE: Vertex *%d has edge to *%d\n", copied, c->
getTargetVertex());
2701 edges[e->
copy].next = prevCopy - e->
copy;
2705 firstCopy = e->
copy;
2709 }
while (e != firstEdge);
2710 edges[firstCopy].
next = prevCopy - firstCopy;
2715 for (
int i = 0; i < copied; i++)
2726 #ifdef DEBUG_CONVEX_HULL
2727 printf(
"Vertex *%d has edge to *%d\n", i, edges[e->
copy].getTargetVertex());
2729 faces.push_back(e->
copy);
2733 #ifdef DEBUG_CONVEX_HULL
2734 printf(
" Face *%d\n", edges[f->
copy].getTargetVertex());
2741 }
while (e != firstEdge);