b3ConvexHullContact.cpp 149 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409
  1. /*
  2. Bullet Continuous Collision Detection and Physics Library
  3. Copyright (c) 2011 Advanced Micro Devices, Inc. http://bulletphysics.org
  4. This software is provided 'as-is', without any express or implied warranty.
  5. In no event will the authors be held liable for any damages arising from the use of this software.
  6. Permission is granted to anyone to use this software for any purpose,
  7. including commercial applications, and to alter it and redistribute it freely,
  8. subject to the following restrictions:
  9. 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.
  10. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
  11. 3. This notice may not be removed or altered from any source distribution.
  12. */
  13. bool findSeparatingAxisOnGpu = true;
  14. bool splitSearchSepAxisConcave = false;
  15. bool splitSearchSepAxisConvex = true;
  16. bool useMprGpu = true; //use mpr for edge-edge (+contact point) or sat. Needs testing on main OpenCL platforms, before enabling...
  17. bool bvhTraversalKernelGPU = true;
  18. bool findConcaveSeparatingAxisKernelGPU = true;
  19. bool clipConcaveFacesAndFindContactsCPU = false; //false;//true;
  20. bool clipConvexFacesAndFindContactsCPU = false; //false;//true;
  21. bool reduceConcaveContactsOnGPU = true; //false;
  22. bool reduceConvexContactsOnGPU = true; //false;
  23. bool findConvexClippingFacesGPU = true;
  24. bool useGjk = false; ///option for CPU/host testing, when findSeparatingAxisOnGpu = false
  25. bool useGjkContacts = false; //////option for CPU/host testing when findSeparatingAxisOnGpu = false
  26. static int myframecount = 0; ///for testing
  27. ///This file was written by Erwin Coumans
  28. ///Separating axis rest based on work from Pierre Terdiman, see
  29. ///And contact clipping based on work from Simon Hobbs
  30. //#define B3_DEBUG_SAT_FACE
  31. //#define CHECK_ON_HOST
  32. #ifdef CHECK_ON_HOST
  33. //#define PERSISTENT_CONTACTS_HOST
  34. #endif
  35. int b3g_actualSATPairTests = 0;
  36. #include "b3ConvexHullContact.h"
  37. #include <string.h> //memcpy
  38. #include "Bullet3Collision/NarrowPhaseCollision/shared/b3ConvexPolyhedronData.h"
  39. #include "Bullet3Collision/NarrowPhaseCollision/shared/b3MprPenetration.h"
  40. #include "Bullet3OpenCL/NarrowphaseCollision/b3ContactCache.h"
  41. #include "Bullet3Geometry/b3AabbUtil.h"
  42. typedef b3AlignedObjectArray<b3Vector3> b3VertexArray;
  43. #include <float.h> //for FLT_MAX
  44. #include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h"
  45. #include "Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.h"
  46. //#include "AdlQuaternion.h"
  47. #include "kernels/satKernels.h"
  48. #include "kernels/mprKernels.h"
  49. #include "kernels/satConcaveKernels.h"
  50. #include "kernels/satClipHullContacts.h"
  51. #include "kernels/bvhTraversal.h"
  52. #include "kernels/primitiveContacts.h"
  53. #include "Bullet3Geometry/b3AabbUtil.h"
  54. #define BT_NARROWPHASE_SAT_PATH "src/Bullet3OpenCL/NarrowphaseCollision/kernels/sat.cl"
  55. #define BT_NARROWPHASE_SAT_CONCAVE_PATH "src/Bullet3OpenCL/NarrowphaseCollision/kernels/satConcave.cl"
  56. #define BT_NARROWPHASE_MPR_PATH "src/Bullet3OpenCL/NarrowphaseCollision/kernels/mpr.cl"
  57. #define BT_NARROWPHASE_CLIPHULL_PATH "src/Bullet3OpenCL/NarrowphaseCollision/kernels/satClipHullContacts.cl"
  58. #define BT_NARROWPHASE_BVH_TRAVERSAL_PATH "src/Bullet3OpenCL/NarrowphaseCollision/kernels/bvhTraversal.cl"
  59. #define BT_NARROWPHASE_PRIMITIVE_CONTACT_PATH "src/Bullet3OpenCL/NarrowphaseCollision/kernels/primitiveContacts.cl"
  60. #ifndef __global
  61. #define __global
  62. #endif
  63. #ifndef __kernel
  64. #define __kernel
  65. #endif
  66. #include "Bullet3Collision/NarrowPhaseCollision/shared/b3BvhTraversal.h"
  67. #include "Bullet3Collision/NarrowPhaseCollision/shared/b3FindConcaveSatAxis.h"
  68. #include "Bullet3Collision/NarrowPhaseCollision/shared/b3ClipFaces.h"
  69. #include "Bullet3Collision/NarrowPhaseCollision/shared/b3NewContactReduction.h"
  70. #define dot3F4 b3Dot
  71. GpuSatCollision::GpuSatCollision(cl_context ctx, cl_device_id device, cl_command_queue q)
  72. : m_context(ctx),
  73. m_device(device),
  74. m_queue(q),
  75. m_findSeparatingAxisKernel(0),
  76. m_findSeparatingAxisVertexFaceKernel(0),
  77. m_findSeparatingAxisEdgeEdgeKernel(0),
  78. m_unitSphereDirections(m_context, m_queue),
  79. m_totalContactsOut(m_context, m_queue),
  80. m_sepNormals(m_context, m_queue),
  81. m_dmins(m_context, m_queue),
  82. m_hasSeparatingNormals(m_context, m_queue),
  83. m_concaveSepNormals(m_context, m_queue),
  84. m_concaveHasSeparatingNormals(m_context, m_queue),
  85. m_numConcavePairsOut(m_context, m_queue),
  86. m_gpuCompoundPairs(m_context, m_queue),
  87. m_gpuCompoundSepNormals(m_context, m_queue),
  88. m_gpuHasCompoundSepNormals(m_context, m_queue),
  89. m_numCompoundPairsOut(m_context, m_queue)
  90. {
  91. m_totalContactsOut.push_back(0);
  92. cl_int errNum = 0;
  93. if (1)
  94. {
  95. const char* mprSrc = mprKernelsCL;
  96. const char* srcConcave = satConcaveKernelsCL;
  97. char flags[1024] = {0};
  98. //#ifdef CL_PLATFORM_INTEL
  99. // sprintf(flags,"-g -s \"%s\"","C:/develop/bullet3_experiments2/opencl/gpu_narrowphase/kernels/sat.cl");
  100. //#endif
  101. m_mprPenetrationKernel = 0;
  102. m_findSeparatingAxisUnitSphereKernel = 0;
  103. if (useMprGpu)
  104. {
  105. cl_program mprProg = b3OpenCLUtils::compileCLProgramFromString(m_context, m_device, mprSrc, &errNum, flags, BT_NARROWPHASE_MPR_PATH);
  106. b3Assert(errNum == CL_SUCCESS);
  107. m_mprPenetrationKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, mprSrc, "mprPenetrationKernel", &errNum, mprProg);
  108. b3Assert(m_mprPenetrationKernel);
  109. b3Assert(errNum == CL_SUCCESS);
  110. m_findSeparatingAxisUnitSphereKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, mprSrc, "findSeparatingAxisUnitSphereKernel", &errNum, mprProg);
  111. b3Assert(m_findSeparatingAxisUnitSphereKernel);
  112. b3Assert(errNum == CL_SUCCESS);
  113. int numDirections = sizeof(unitSphere162) / sizeof(b3Vector3);
  114. m_unitSphereDirections.resize(numDirections);
  115. m_unitSphereDirections.copyFromHostPointer(unitSphere162, numDirections, 0, true);
  116. }
  117. cl_program satProg = b3OpenCLUtils::compileCLProgramFromString(m_context, m_device, satKernelsCL, &errNum, flags, BT_NARROWPHASE_SAT_PATH);
  118. b3Assert(errNum == CL_SUCCESS);
  119. cl_program satConcaveProg = b3OpenCLUtils::compileCLProgramFromString(m_context, m_device, srcConcave, &errNum, flags, BT_NARROWPHASE_SAT_CONCAVE_PATH);
  120. b3Assert(errNum == CL_SUCCESS);
  121. m_findSeparatingAxisKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, satKernelsCL, "findSeparatingAxisKernel", &errNum, satProg);
  122. b3Assert(m_findSeparatingAxisKernel);
  123. b3Assert(errNum == CL_SUCCESS);
  124. m_findSeparatingAxisVertexFaceKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, satKernelsCL, "findSeparatingAxisVertexFaceKernel", &errNum, satProg);
  125. b3Assert(m_findSeparatingAxisVertexFaceKernel);
  126. m_findSeparatingAxisEdgeEdgeKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, satKernelsCL, "findSeparatingAxisEdgeEdgeKernel", &errNum, satProg);
  127. b3Assert(m_findSeparatingAxisVertexFaceKernel);
  128. m_findConcaveSeparatingAxisKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, satKernelsCL, "findConcaveSeparatingAxisKernel", &errNum, satProg);
  129. b3Assert(m_findConcaveSeparatingAxisKernel);
  130. b3Assert(errNum == CL_SUCCESS);
  131. m_findConcaveSeparatingAxisVertexFaceKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, srcConcave, "findConcaveSeparatingAxisVertexFaceKernel", &errNum, satConcaveProg);
  132. b3Assert(m_findConcaveSeparatingAxisVertexFaceKernel);
  133. b3Assert(errNum == CL_SUCCESS);
  134. m_findConcaveSeparatingAxisEdgeEdgeKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, srcConcave, "findConcaveSeparatingAxisEdgeEdgeKernel", &errNum, satConcaveProg);
  135. b3Assert(m_findConcaveSeparatingAxisEdgeEdgeKernel);
  136. b3Assert(errNum == CL_SUCCESS);
  137. m_findCompoundPairsKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, satKernelsCL, "findCompoundPairsKernel", &errNum, satProg);
  138. b3Assert(m_findCompoundPairsKernel);
  139. b3Assert(errNum == CL_SUCCESS);
  140. m_processCompoundPairsKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, satKernelsCL, "processCompoundPairsKernel", &errNum, satProg);
  141. b3Assert(m_processCompoundPairsKernel);
  142. b3Assert(errNum == CL_SUCCESS);
  143. }
  144. if (1)
  145. {
  146. const char* srcClip = satClipKernelsCL;
  147. char flags[1024] = {0};
  148. //#ifdef CL_PLATFORM_INTEL
  149. // sprintf(flags,"-g -s \"%s\"","C:/develop/bullet3_experiments2/opencl/gpu_narrowphase/kernels/satClipHullContacts.cl");
  150. //#endif
  151. cl_program satClipContactsProg = b3OpenCLUtils::compileCLProgramFromString(m_context, m_device, srcClip, &errNum, flags, BT_NARROWPHASE_CLIPHULL_PATH);
  152. b3Assert(errNum == CL_SUCCESS);
  153. m_clipHullHullKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, srcClip, "clipHullHullKernel", &errNum, satClipContactsProg);
  154. b3Assert(errNum == CL_SUCCESS);
  155. m_clipCompoundsHullHullKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, srcClip, "clipCompoundsHullHullKernel", &errNum, satClipContactsProg);
  156. b3Assert(errNum == CL_SUCCESS);
  157. m_findClippingFacesKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, srcClip, "findClippingFacesKernel", &errNum, satClipContactsProg);
  158. b3Assert(errNum == CL_SUCCESS);
  159. m_clipFacesAndFindContacts = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, srcClip, "clipFacesAndFindContactsKernel", &errNum, satClipContactsProg);
  160. b3Assert(errNum == CL_SUCCESS);
  161. m_clipHullHullConcaveConvexKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, srcClip, "clipHullHullConcaveConvexKernel", &errNum, satClipContactsProg);
  162. b3Assert(errNum == CL_SUCCESS);
  163. // m_extractManifoldAndAddContactKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,srcClip, "extractManifoldAndAddContactKernel",&errNum,satClipContactsProg);
  164. // b3Assert(errNum==CL_SUCCESS);
  165. m_newContactReductionKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, srcClip,
  166. "newContactReductionKernel", &errNum, satClipContactsProg);
  167. b3Assert(errNum == CL_SUCCESS);
  168. }
  169. else
  170. {
  171. m_clipHullHullKernel = 0;
  172. m_clipCompoundsHullHullKernel = 0;
  173. m_findClippingFacesKernel = 0;
  174. m_newContactReductionKernel = 0;
  175. m_clipFacesAndFindContacts = 0;
  176. m_clipHullHullConcaveConvexKernel = 0;
  177. // m_extractManifoldAndAddContactKernel = 0;
  178. }
  179. if (1)
  180. {
  181. const char* srcBvh = bvhTraversalKernelCL;
  182. cl_program bvhTraversalProg = b3OpenCLUtils::compileCLProgramFromString(m_context, m_device, srcBvh, &errNum, "", BT_NARROWPHASE_BVH_TRAVERSAL_PATH);
  183. b3Assert(errNum == CL_SUCCESS);
  184. m_bvhTraversalKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, srcBvh, "bvhTraversalKernel", &errNum, bvhTraversalProg, "");
  185. b3Assert(errNum == CL_SUCCESS);
  186. }
  187. {
  188. const char* primitiveContactsSrc = primitiveContactsKernelsCL;
  189. cl_program primitiveContactsProg = b3OpenCLUtils::compileCLProgramFromString(m_context, m_device, primitiveContactsSrc, &errNum, "", BT_NARROWPHASE_PRIMITIVE_CONTACT_PATH);
  190. b3Assert(errNum == CL_SUCCESS);
  191. m_primitiveContactsKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, primitiveContactsSrc, "primitiveContactsKernel", &errNum, primitiveContactsProg, "");
  192. b3Assert(errNum == CL_SUCCESS);
  193. m_findConcaveSphereContactsKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, primitiveContactsSrc, "findConcaveSphereContactsKernel", &errNum, primitiveContactsProg);
  194. b3Assert(errNum == CL_SUCCESS);
  195. b3Assert(m_findConcaveSphereContactsKernel);
  196. m_processCompoundPairsPrimitivesKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, primitiveContactsSrc, "processCompoundPairsPrimitivesKernel", &errNum, primitiveContactsProg, "");
  197. b3Assert(errNum == CL_SUCCESS);
  198. b3Assert(m_processCompoundPairsPrimitivesKernel);
  199. }
  200. }
  201. GpuSatCollision::~GpuSatCollision()
  202. {
  203. if (m_findSeparatingAxisVertexFaceKernel)
  204. clReleaseKernel(m_findSeparatingAxisVertexFaceKernel);
  205. if (m_findSeparatingAxisEdgeEdgeKernel)
  206. clReleaseKernel(m_findSeparatingAxisEdgeEdgeKernel);
  207. if (m_findSeparatingAxisUnitSphereKernel)
  208. clReleaseKernel(m_findSeparatingAxisUnitSphereKernel);
  209. if (m_mprPenetrationKernel)
  210. clReleaseKernel(m_mprPenetrationKernel);
  211. if (m_findSeparatingAxisKernel)
  212. clReleaseKernel(m_findSeparatingAxisKernel);
  213. if (m_findConcaveSeparatingAxisVertexFaceKernel)
  214. clReleaseKernel(m_findConcaveSeparatingAxisVertexFaceKernel);
  215. if (m_findConcaveSeparatingAxisEdgeEdgeKernel)
  216. clReleaseKernel(m_findConcaveSeparatingAxisEdgeEdgeKernel);
  217. if (m_findConcaveSeparatingAxisKernel)
  218. clReleaseKernel(m_findConcaveSeparatingAxisKernel);
  219. if (m_findCompoundPairsKernel)
  220. clReleaseKernel(m_findCompoundPairsKernel);
  221. if (m_processCompoundPairsKernel)
  222. clReleaseKernel(m_processCompoundPairsKernel);
  223. if (m_findClippingFacesKernel)
  224. clReleaseKernel(m_findClippingFacesKernel);
  225. if (m_clipFacesAndFindContacts)
  226. clReleaseKernel(m_clipFacesAndFindContacts);
  227. if (m_newContactReductionKernel)
  228. clReleaseKernel(m_newContactReductionKernel);
  229. if (m_primitiveContactsKernel)
  230. clReleaseKernel(m_primitiveContactsKernel);
  231. if (m_findConcaveSphereContactsKernel)
  232. clReleaseKernel(m_findConcaveSphereContactsKernel);
  233. if (m_processCompoundPairsPrimitivesKernel)
  234. clReleaseKernel(m_processCompoundPairsPrimitivesKernel);
  235. if (m_clipHullHullKernel)
  236. clReleaseKernel(m_clipHullHullKernel);
  237. if (m_clipCompoundsHullHullKernel)
  238. clReleaseKernel(m_clipCompoundsHullHullKernel);
  239. if (m_clipHullHullConcaveConvexKernel)
  240. clReleaseKernel(m_clipHullHullConcaveConvexKernel);
  241. // if (m_extractManifoldAndAddContactKernel)
  242. // clReleaseKernel(m_extractManifoldAndAddContactKernel);
  243. if (m_bvhTraversalKernel)
  244. clReleaseKernel(m_bvhTraversalKernel);
  245. }
  246. struct MyTriangleCallback : public b3NodeOverlapCallback
  247. {
  248. int m_bodyIndexA;
  249. int m_bodyIndexB;
  250. virtual void processNode(int subPart, int triangleIndex)
  251. {
  252. printf("bodyIndexA %d, bodyIndexB %d\n", m_bodyIndexA, m_bodyIndexB);
  253. printf("triangleIndex %d\n", triangleIndex);
  254. }
  255. };
  256. #define float4 b3Vector3
  257. #define make_float4(x, y, z, w) b3MakeVector3(x, y, z, w)
  258. float signedDistanceFromPointToPlane(const float4& point, const float4& planeEqn, float4* closestPointOnFace)
  259. {
  260. float4 n = planeEqn;
  261. n[3] = 0.f;
  262. float dist = dot3F4(n, point) + planeEqn[3];
  263. *closestPointOnFace = point - dist * n;
  264. return dist;
  265. }
  266. #define cross3(a, b) (a.cross(b))
  267. b3Vector3 transform(const b3Vector3* v, const b3Vector3* pos, const b3Quaternion* orn)
  268. {
  269. b3Transform tr;
  270. tr.setIdentity();
  271. tr.setOrigin(*pos);
  272. tr.setRotation(*orn);
  273. b3Vector3 res = tr(*v);
  274. return res;
  275. }
  276. inline bool IsPointInPolygon(const float4& p,
  277. const b3GpuFace* face,
  278. const float4* baseVertex,
  279. const int* convexIndices,
  280. float4* out)
  281. {
  282. float4 a;
  283. float4 b;
  284. float4 ab;
  285. float4 ap;
  286. float4 v;
  287. float4 plane = b3MakeVector3(face->m_plane.x, face->m_plane.y, face->m_plane.z, 0.f);
  288. if (face->m_numIndices < 2)
  289. return false;
  290. float4 v0 = baseVertex[convexIndices[face->m_indexOffset + face->m_numIndices - 1]];
  291. b = v0;
  292. for (unsigned i = 0; i != face->m_numIndices; ++i)
  293. {
  294. a = b;
  295. float4 vi = baseVertex[convexIndices[face->m_indexOffset + i]];
  296. b = vi;
  297. ab = b - a;
  298. ap = p - a;
  299. v = cross3(ab, plane);
  300. if (b3Dot(ap, v) > 0.f)
  301. {
  302. float ab_m2 = b3Dot(ab, ab);
  303. float rt = ab_m2 != 0.f ? b3Dot(ab, ap) / ab_m2 : 0.f;
  304. if (rt <= 0.f)
  305. {
  306. *out = a;
  307. }
  308. else if (rt >= 1.f)
  309. {
  310. *out = b;
  311. }
  312. else
  313. {
  314. float s = 1.f - rt;
  315. out[0].x = s * a.x + rt * b.x;
  316. out[0].y = s * a.y + rt * b.y;
  317. out[0].z = s * a.z + rt * b.z;
  318. }
  319. return false;
  320. }
  321. }
  322. return true;
  323. }
  324. #define normalize3(a) (a.normalize())
  325. int extractManifoldSequentialGlobal(const float4* p, int nPoints, const float4& nearNormal, b3Int4* contactIdx)
  326. {
  327. if (nPoints == 0)
  328. return 0;
  329. if (nPoints <= 4)
  330. return nPoints;
  331. if (nPoints > 64)
  332. nPoints = 64;
  333. float4 center = b3MakeVector3(0, 0, 0, 0);
  334. {
  335. for (int i = 0; i < nPoints; i++)
  336. center += p[i];
  337. center /= (float)nPoints;
  338. }
  339. // sample 4 directions
  340. float4 aVector = p[0] - center;
  341. float4 u = cross3(nearNormal, aVector);
  342. float4 v = cross3(nearNormal, u);
  343. u = normalize3(u);
  344. v = normalize3(v);
  345. //keep point with deepest penetration
  346. float minW = FLT_MAX;
  347. int minIndex = -1;
  348. float4 maxDots;
  349. maxDots.x = FLT_MIN;
  350. maxDots.y = FLT_MIN;
  351. maxDots.z = FLT_MIN;
  352. maxDots.w = FLT_MIN;
  353. // idx, distance
  354. for (int ie = 0; ie < nPoints; ie++)
  355. {
  356. if (p[ie].w < minW)
  357. {
  358. minW = p[ie].w;
  359. minIndex = ie;
  360. }
  361. float f;
  362. float4 r = p[ie] - center;
  363. f = dot3F4(u, r);
  364. if (f < maxDots.x)
  365. {
  366. maxDots.x = f;
  367. contactIdx[0].x = ie;
  368. }
  369. f = dot3F4(-u, r);
  370. if (f < maxDots.y)
  371. {
  372. maxDots.y = f;
  373. contactIdx[0].y = ie;
  374. }
  375. f = dot3F4(v, r);
  376. if (f < maxDots.z)
  377. {
  378. maxDots.z = f;
  379. contactIdx[0].z = ie;
  380. }
  381. f = dot3F4(-v, r);
  382. if (f < maxDots.w)
  383. {
  384. maxDots.w = f;
  385. contactIdx[0].w = ie;
  386. }
  387. }
  388. if (contactIdx[0].x != minIndex && contactIdx[0].y != minIndex && contactIdx[0].z != minIndex && contactIdx[0].w != minIndex)
  389. {
  390. //replace the first contact with minimum (todo: replace contact with least penetration)
  391. contactIdx[0].x = minIndex;
  392. }
  393. return 4;
  394. }
  395. #define MAX_VERTS 1024
  396. inline void project(const b3ConvexPolyhedronData& hull, const float4& pos, const b3Quaternion& orn, const float4& dir, const b3AlignedObjectArray<b3Vector3>& vertices, b3Scalar& min, b3Scalar& max)
  397. {
  398. min = FLT_MAX;
  399. max = -FLT_MAX;
  400. int numVerts = hull.m_numVertices;
  401. const float4 localDir = b3QuatRotate(orn.inverse(), dir);
  402. b3Scalar offset = dot3F4(pos, dir);
  403. for (int i = 0; i < numVerts; i++)
  404. {
  405. //b3Vector3 pt = trans * vertices[m_vertexOffset+i];
  406. //b3Scalar dp = pt.dot(dir);
  407. //b3Vector3 vertex = vertices[hull.m_vertexOffset+i];
  408. b3Scalar dp = dot3F4((float4&)vertices[hull.m_vertexOffset + i], localDir);
  409. //b3Assert(dp==dpL);
  410. if (dp < min) min = dp;
  411. if (dp > max) max = dp;
  412. }
  413. if (min > max)
  414. {
  415. b3Scalar tmp = min;
  416. min = max;
  417. max = tmp;
  418. }
  419. min += offset;
  420. max += offset;
  421. }
  422. static bool TestSepAxis(const b3ConvexPolyhedronData& hullA, const b3ConvexPolyhedronData& hullB,
  423. const float4& posA, const b3Quaternion& ornA,
  424. const float4& posB, const b3Quaternion& ornB,
  425. const float4& sep_axis, const b3AlignedObjectArray<b3Vector3>& verticesA, const b3AlignedObjectArray<b3Vector3>& verticesB, b3Scalar& depth)
  426. {
  427. b3Scalar Min0, Max0;
  428. b3Scalar Min1, Max1;
  429. project(hullA, posA, ornA, sep_axis, verticesA, Min0, Max0);
  430. project(hullB, posB, ornB, sep_axis, verticesB, Min1, Max1);
  431. if (Max0 < Min1 || Max1 < Min0)
  432. return false;
  433. b3Scalar d0 = Max0 - Min1;
  434. assert(d0 >= 0.0f);
  435. b3Scalar d1 = Max1 - Min0;
  436. assert(d1 >= 0.0f);
  437. depth = d0 < d1 ? d0 : d1;
  438. return true;
  439. }
  440. inline bool IsAlmostZero(const b3Vector3& v)
  441. {
  442. if (fabsf(v.x) > 1e-6 || fabsf(v.y) > 1e-6 || fabsf(v.z) > 1e-6) return false;
  443. return true;
  444. }
  445. static bool findSeparatingAxis(const b3ConvexPolyhedronData& hullA, const b3ConvexPolyhedronData& hullB,
  446. const float4& posA1,
  447. const b3Quaternion& ornA,
  448. const float4& posB1,
  449. const b3Quaternion& ornB,
  450. const b3AlignedObjectArray<b3Vector3>& verticesA,
  451. const b3AlignedObjectArray<b3Vector3>& uniqueEdgesA,
  452. const b3AlignedObjectArray<b3GpuFace>& facesA,
  453. const b3AlignedObjectArray<int>& indicesA,
  454. const b3AlignedObjectArray<b3Vector3>& verticesB,
  455. const b3AlignedObjectArray<b3Vector3>& uniqueEdgesB,
  456. const b3AlignedObjectArray<b3GpuFace>& facesB,
  457. const b3AlignedObjectArray<int>& indicesB,
  458. b3Vector3& sep)
  459. {
  460. B3_PROFILE("findSeparatingAxis");
  461. b3g_actualSATPairTests++;
  462. float4 posA = posA1;
  463. posA.w = 0.f;
  464. float4 posB = posB1;
  465. posB.w = 0.f;
  466. //#ifdef TEST_INTERNAL_OBJECTS
  467. float4 c0local = (float4&)hullA.m_localCenter;
  468. float4 c0 = transform(&c0local, &posA, &ornA);
  469. float4 c1local = (float4&)hullB.m_localCenter;
  470. float4 c1 = transform(&c1local, &posB, &ornB);
  471. const float4 deltaC2 = c0 - c1;
  472. //#endif
  473. b3Scalar dmin = FLT_MAX;
  474. int curPlaneTests = 0;
  475. int numFacesA = hullA.m_numFaces;
  476. // Test normals from hullA
  477. for (int i = 0; i < numFacesA; i++)
  478. {
  479. const float4& normal = (float4&)facesA[hullA.m_faceOffset + i].m_plane;
  480. float4 faceANormalWS = b3QuatRotate(ornA, normal);
  481. if (dot3F4(deltaC2, faceANormalWS) < 0)
  482. faceANormalWS *= -1.f;
  483. curPlaneTests++;
  484. #ifdef TEST_INTERNAL_OBJECTS
  485. gExpectedNbTests++;
  486. if (gUseInternalObject && !TestInternalObjects(transA, transB, DeltaC2, faceANormalWS, hullA, hullB, dmin))
  487. continue;
  488. gActualNbTests++;
  489. #endif
  490. b3Scalar d;
  491. if (!TestSepAxis(hullA, hullB, posA, ornA, posB, ornB, faceANormalWS, verticesA, verticesB, d))
  492. return false;
  493. if (d < dmin)
  494. {
  495. dmin = d;
  496. sep = (b3Vector3&)faceANormalWS;
  497. }
  498. }
  499. int numFacesB = hullB.m_numFaces;
  500. // Test normals from hullB
  501. for (int i = 0; i < numFacesB; i++)
  502. {
  503. float4 normal = (float4&)facesB[hullB.m_faceOffset + i].m_plane;
  504. float4 WorldNormal = b3QuatRotate(ornB, normal);
  505. if (dot3F4(deltaC2, WorldNormal) < 0)
  506. {
  507. WorldNormal *= -1.f;
  508. }
  509. curPlaneTests++;
  510. #ifdef TEST_INTERNAL_OBJECTS
  511. gExpectedNbTests++;
  512. if (gUseInternalObject && !TestInternalObjects(transA, transB, DeltaC2, WorldNormal, hullA, hullB, dmin))
  513. continue;
  514. gActualNbTests++;
  515. #endif
  516. b3Scalar d;
  517. if (!TestSepAxis(hullA, hullB, posA, ornA, posB, ornB, WorldNormal, verticesA, verticesB, d))
  518. return false;
  519. if (d < dmin)
  520. {
  521. dmin = d;
  522. sep = (b3Vector3&)WorldNormal;
  523. }
  524. }
  525. int curEdgeEdge = 0;
  526. // Test edges
  527. for (int e0 = 0; e0 < hullA.m_numUniqueEdges; e0++)
  528. {
  529. const float4& edge0 = (float4&)uniqueEdgesA[hullA.m_uniqueEdgesOffset + e0];
  530. float4 edge0World = b3QuatRotate(ornA, (float4&)edge0);
  531. for (int e1 = 0; e1 < hullB.m_numUniqueEdges; e1++)
  532. {
  533. const b3Vector3 edge1 = uniqueEdgesB[hullB.m_uniqueEdgesOffset + e1];
  534. float4 edge1World = b3QuatRotate(ornB, (float4&)edge1);
  535. float4 crossje = cross3(edge0World, edge1World);
  536. curEdgeEdge++;
  537. if (!IsAlmostZero((b3Vector3&)crossje))
  538. {
  539. crossje = normalize3(crossje);
  540. if (dot3F4(deltaC2, crossje) < 0)
  541. crossje *= -1.f;
  542. #ifdef TEST_INTERNAL_OBJECTS
  543. gExpectedNbTests++;
  544. if (gUseInternalObject && !TestInternalObjects(transA, transB, DeltaC2, Cross, hullA, hullB, dmin))
  545. continue;
  546. gActualNbTests++;
  547. #endif
  548. b3Scalar dist;
  549. if (!TestSepAxis(hullA, hullB, posA, ornA, posB, ornB, crossje, verticesA, verticesB, dist))
  550. return false;
  551. if (dist < dmin)
  552. {
  553. dmin = dist;
  554. sep = (b3Vector3&)crossje;
  555. }
  556. }
  557. }
  558. }
  559. if ((dot3F4(-deltaC2, (float4&)sep)) > 0.0f)
  560. sep = -sep;
  561. return true;
  562. }
  563. bool findSeparatingAxisEdgeEdge(__global const b3ConvexPolyhedronData* hullA, __global const b3ConvexPolyhedronData* hullB,
  564. const b3Float4& posA1,
  565. const b3Quat& ornA,
  566. const b3Float4& posB1,
  567. const b3Quat& ornB,
  568. const b3Float4& DeltaC2,
  569. __global const b3AlignedObjectArray<float4>& vertices,
  570. __global const b3AlignedObjectArray<float4>& uniqueEdges,
  571. __global const b3AlignedObjectArray<b3GpuFace>& faces,
  572. __global const b3AlignedObjectArray<int>& indices,
  573. float4* sep,
  574. float* dmin)
  575. {
  576. // int i = get_global_id(0);
  577. float4 posA = posA1;
  578. posA.w = 0.f;
  579. float4 posB = posB1;
  580. posB.w = 0.f;
  581. //int curPlaneTests=0;
  582. int curEdgeEdge = 0;
  583. // Test edges
  584. for (int e0 = 0; e0 < hullA->m_numUniqueEdges; e0++)
  585. {
  586. const float4 edge0 = uniqueEdges[hullA->m_uniqueEdgesOffset + e0];
  587. float4 edge0World = b3QuatRotate(ornA, edge0);
  588. for (int e1 = 0; e1 < hullB->m_numUniqueEdges; e1++)
  589. {
  590. const float4 edge1 = uniqueEdges[hullB->m_uniqueEdgesOffset + e1];
  591. float4 edge1World = b3QuatRotate(ornB, edge1);
  592. float4 crossje = cross3(edge0World, edge1World);
  593. curEdgeEdge++;
  594. if (!IsAlmostZero(crossje))
  595. {
  596. crossje = normalize3(crossje);
  597. if (dot3F4(DeltaC2, crossje) < 0)
  598. crossje *= -1.f;
  599. float dist;
  600. bool result = true;
  601. {
  602. float Min0, Max0;
  603. float Min1, Max1;
  604. project(*hullA, posA, ornA, crossje, vertices, Min0, Max0);
  605. project(*hullB, posB, ornB, crossje, vertices, Min1, Max1);
  606. if (Max0 < Min1 || Max1 < Min0)
  607. result = false;
  608. float d0 = Max0 - Min1;
  609. float d1 = Max1 - Min0;
  610. dist = d0 < d1 ? d0 : d1;
  611. result = true;
  612. }
  613. if (dist < *dmin)
  614. {
  615. *dmin = dist;
  616. *sep = crossje;
  617. }
  618. }
  619. }
  620. }
  621. if ((dot3F4(-DeltaC2, *sep)) > 0.0f)
  622. {
  623. *sep = -(*sep);
  624. }
  625. return true;
  626. }
  627. __inline float4 lerp3(const float4& a, const float4& b, float t)
  628. {
  629. return b3MakeVector3(a.x + (b.x - a.x) * t,
  630. a.y + (b.y - a.y) * t,
  631. a.z + (b.z - a.z) * t,
  632. 0.f);
  633. }
  634. // Clips a face to the back of a plane, return the number of vertices out, stored in ppVtxOut
  635. int clipFace(const float4* pVtxIn, int numVertsIn, float4& planeNormalWS, float planeEqWS, float4* ppVtxOut)
  636. {
  637. int ve;
  638. float ds, de;
  639. int numVertsOut = 0;
  640. if (numVertsIn < 2)
  641. return 0;
  642. float4 firstVertex = pVtxIn[numVertsIn - 1];
  643. float4 endVertex = pVtxIn[0];
  644. ds = dot3F4(planeNormalWS, firstVertex) + planeEqWS;
  645. for (ve = 0; ve < numVertsIn; ve++)
  646. {
  647. endVertex = pVtxIn[ve];
  648. de = dot3F4(planeNormalWS, endVertex) + planeEqWS;
  649. if (ds < 0)
  650. {
  651. if (de < 0)
  652. {
  653. // Start < 0, end < 0, so output endVertex
  654. ppVtxOut[numVertsOut++] = endVertex;
  655. }
  656. else
  657. {
  658. // Start < 0, end >= 0, so output intersection
  659. ppVtxOut[numVertsOut++] = lerp3(firstVertex, endVertex, (ds * 1.f / (ds - de)));
  660. }
  661. }
  662. else
  663. {
  664. if (de < 0)
  665. {
  666. // Start >= 0, end < 0 so output intersection and end
  667. ppVtxOut[numVertsOut++] = lerp3(firstVertex, endVertex, (ds * 1.f / (ds - de)));
  668. ppVtxOut[numVertsOut++] = endVertex;
  669. }
  670. }
  671. firstVertex = endVertex;
  672. ds = de;
  673. }
  674. return numVertsOut;
  675. }
  676. int clipFaceAgainstHull(const float4& separatingNormal, const b3ConvexPolyhedronData* hullA,
  677. const float4& posA, const b3Quaternion& ornA, float4* worldVertsB1, int numWorldVertsB1,
  678. float4* worldVertsB2, int capacityWorldVertsB2,
  679. const float minDist, float maxDist,
  680. const b3AlignedObjectArray<float4>& verticesA, const b3AlignedObjectArray<b3GpuFace>& facesA, const b3AlignedObjectArray<int>& indicesA,
  681. //const float4* verticesB, const b3GpuFace* facesB, const int* indicesB,
  682. float4* contactsOut,
  683. int contactCapacity)
  684. {
  685. int numContactsOut = 0;
  686. float4* pVtxIn = worldVertsB1;
  687. float4* pVtxOut = worldVertsB2;
  688. int numVertsIn = numWorldVertsB1;
  689. int numVertsOut = 0;
  690. int closestFaceA = -1;
  691. {
  692. float dmin = FLT_MAX;
  693. for (int face = 0; face < hullA->m_numFaces; face++)
  694. {
  695. const float4 Normal = b3MakeVector3(
  696. facesA[hullA->m_faceOffset + face].m_plane.x,
  697. facesA[hullA->m_faceOffset + face].m_plane.y,
  698. facesA[hullA->m_faceOffset + face].m_plane.z, 0.f);
  699. const float4 faceANormalWS = b3QuatRotate(ornA, Normal);
  700. float d = dot3F4(faceANormalWS, separatingNormal);
  701. if (d < dmin)
  702. {
  703. dmin = d;
  704. closestFaceA = face;
  705. }
  706. }
  707. }
  708. if (closestFaceA < 0)
  709. return numContactsOut;
  710. b3GpuFace polyA = facesA[hullA->m_faceOffset + closestFaceA];
  711. // clip polygon to back of planes of all faces of hull A that are adjacent to witness face
  712. // int numContacts = numWorldVertsB1;
  713. int numVerticesA = polyA.m_numIndices;
  714. for (int e0 = 0; e0 < numVerticesA; e0++)
  715. {
  716. const float4 a = verticesA[hullA->m_vertexOffset + indicesA[polyA.m_indexOffset + e0]];
  717. const float4 b = verticesA[hullA->m_vertexOffset + indicesA[polyA.m_indexOffset + ((e0 + 1) % numVerticesA)]];
  718. const float4 edge0 = a - b;
  719. const float4 WorldEdge0 = b3QuatRotate(ornA, edge0);
  720. float4 planeNormalA = make_float4(polyA.m_plane.x, polyA.m_plane.y, polyA.m_plane.z, 0.f);
  721. float4 worldPlaneAnormal1 = b3QuatRotate(ornA, planeNormalA);
  722. float4 planeNormalWS1 = -cross3(WorldEdge0, worldPlaneAnormal1);
  723. float4 worldA1 = transform(&a, &posA, &ornA);
  724. float planeEqWS1 = -dot3F4(worldA1, planeNormalWS1);
  725. float4 planeNormalWS = planeNormalWS1;
  726. float planeEqWS = planeEqWS1;
  727. //clip face
  728. //clipFace(*pVtxIn, *pVtxOut,planeNormalWS,planeEqWS);
  729. numVertsOut = clipFace(pVtxIn, numVertsIn, planeNormalWS, planeEqWS, pVtxOut);
  730. //btSwap(pVtxIn,pVtxOut);
  731. float4* tmp = pVtxOut;
  732. pVtxOut = pVtxIn;
  733. pVtxIn = tmp;
  734. numVertsIn = numVertsOut;
  735. numVertsOut = 0;
  736. }
  737. // only keep points that are behind the witness face
  738. {
  739. float4 localPlaneNormal = make_float4(polyA.m_plane.x, polyA.m_plane.y, polyA.m_plane.z, 0.f);
  740. float localPlaneEq = polyA.m_plane.w;
  741. float4 planeNormalWS = b3QuatRotate(ornA, localPlaneNormal);
  742. float planeEqWS = localPlaneEq - dot3F4(planeNormalWS, posA);
  743. for (int i = 0; i < numVertsIn; i++)
  744. {
  745. float depth = dot3F4(planeNormalWS, pVtxIn[i]) + planeEqWS;
  746. if (depth <= minDist)
  747. {
  748. depth = minDist;
  749. }
  750. if (numContactsOut < contactCapacity)
  751. {
  752. if (depth <= maxDist)
  753. {
  754. float4 pointInWorld = pVtxIn[i];
  755. //resultOut.addContactPoint(separatingNormal,point,depth);
  756. contactsOut[numContactsOut++] = b3MakeVector3(pointInWorld.x, pointInWorld.y, pointInWorld.z, depth);
  757. //printf("depth=%f\n",depth);
  758. }
  759. }
  760. else
  761. {
  762. b3Error("exceeding contact capacity (%d,%df)\n", numContactsOut, contactCapacity);
  763. }
  764. }
  765. }
  766. return numContactsOut;
  767. }
  768. static int clipHullAgainstHull(const float4& separatingNormal,
  769. const b3ConvexPolyhedronData& hullA, const b3ConvexPolyhedronData& hullB,
  770. const float4& posA, const b3Quaternion& ornA, const float4& posB, const b3Quaternion& ornB,
  771. float4* worldVertsB1, float4* worldVertsB2, int capacityWorldVerts,
  772. const float minDist, float maxDist,
  773. const b3AlignedObjectArray<float4>& verticesA, const b3AlignedObjectArray<b3GpuFace>& facesA, const b3AlignedObjectArray<int>& indicesA,
  774. const b3AlignedObjectArray<float4>& verticesB, const b3AlignedObjectArray<b3GpuFace>& facesB, const b3AlignedObjectArray<int>& indicesB,
  775. float4* contactsOut,
  776. int contactCapacity)
  777. {
  778. int numContactsOut = 0;
  779. int numWorldVertsB1 = 0;
  780. B3_PROFILE("clipHullAgainstHull");
  781. // float curMaxDist=maxDist;
  782. int closestFaceB = -1;
  783. float dmax = -FLT_MAX;
  784. {
  785. //B3_PROFILE("closestFaceB");
  786. if (hullB.m_numFaces != 1)
  787. {
  788. //printf("wtf\n");
  789. }
  790. static bool once = true;
  791. //printf("separatingNormal=%f,%f,%f\n",separatingNormal.x,separatingNormal.y,separatingNormal.z);
  792. for (int face = 0; face < hullB.m_numFaces; face++)
  793. {
  794. #ifdef BT_DEBUG_SAT_FACE
  795. if (once)
  796. printf("face %d\n", face);
  797. const b3GpuFace* faceB = &facesB[hullB.m_faceOffset + face];
  798. if (once)
  799. {
  800. for (int i = 0; i < faceB->m_numIndices; i++)
  801. {
  802. float4 vert = verticesB[hullB.m_vertexOffset + indicesB[faceB->m_indexOffset + i]];
  803. printf("vert[%d] = %f,%f,%f\n", i, vert.x, vert.y, vert.z);
  804. }
  805. }
  806. #endif //BT_DEBUG_SAT_FACE \
  807. //if (facesB[hullB.m_faceOffset+face].m_numIndices>2)
  808. {
  809. const float4 Normal = b3MakeVector3(facesB[hullB.m_faceOffset + face].m_plane.x,
  810. facesB[hullB.m_faceOffset + face].m_plane.y, facesB[hullB.m_faceOffset + face].m_plane.z, 0.f);
  811. const float4 WorldNormal = b3QuatRotate(ornB, Normal);
  812. #ifdef BT_DEBUG_SAT_FACE
  813. if (once)
  814. printf("faceNormal = %f,%f,%f\n", Normal.x, Normal.y, Normal.z);
  815. #endif
  816. float d = dot3F4(WorldNormal, separatingNormal);
  817. if (d > dmax)
  818. {
  819. dmax = d;
  820. closestFaceB = face;
  821. }
  822. }
  823. }
  824. once = false;
  825. }
  826. b3Assert(closestFaceB >= 0);
  827. {
  828. //B3_PROFILE("worldVertsB1");
  829. const b3GpuFace& polyB = facesB[hullB.m_faceOffset + closestFaceB];
  830. const int numVertices = polyB.m_numIndices;
  831. for (int e0 = 0; e0 < numVertices; e0++)
  832. {
  833. const float4& b = verticesB[hullB.m_vertexOffset + indicesB[polyB.m_indexOffset + e0]];
  834. worldVertsB1[numWorldVertsB1++] = transform(&b, &posB, &ornB);
  835. }
  836. }
  837. if (closestFaceB >= 0)
  838. {
  839. //B3_PROFILE("clipFaceAgainstHull");
  840. numContactsOut = clipFaceAgainstHull((float4&)separatingNormal, &hullA,
  841. posA, ornA,
  842. worldVertsB1, numWorldVertsB1, worldVertsB2, capacityWorldVerts, minDist, maxDist,
  843. verticesA, facesA, indicesA,
  844. contactsOut, contactCapacity);
  845. }
  846. return numContactsOut;
  847. }
  848. #define PARALLEL_SUM(v, n) \
  849. for (int j = 1; j < n; j++) v[0] += v[j];
  850. #define PARALLEL_DO(execution, n) \
  851. for (int ie = 0; ie < n; ie++) \
  852. { \
  853. execution; \
  854. }
  855. #define REDUCE_MAX(v, n) \
  856. { \
  857. int i = 0; \
  858. for (int offset = 0; offset < n; offset++) v[i] = (v[i].y > v[i + offset].y) ? v[i] : v[i + offset]; \
  859. }
  860. #define REDUCE_MIN(v, n) \
  861. { \
  862. int i = 0; \
  863. for (int offset = 0; offset < n; offset++) v[i] = (v[i].y < v[i + offset].y) ? v[i] : v[i + offset]; \
  864. }
  865. int extractManifold(const float4* p, int nPoints, const float4& nearNormal, b3Int4* contactIdx)
  866. {
  867. if (nPoints == 0)
  868. return 0;
  869. if (nPoints <= 4)
  870. return nPoints;
  871. if (nPoints > 64)
  872. nPoints = 64;
  873. float4 center = make_float4(0, 0, 0, 0);
  874. {
  875. for (int i = 0; i < nPoints; i++)
  876. center += p[i];
  877. center /= (float)nPoints;
  878. }
  879. // sample 4 directions
  880. float4 aVector = p[0] - center;
  881. float4 u = cross3(nearNormal, aVector);
  882. float4 v = cross3(nearNormal, u);
  883. u = normalize3(u);
  884. v = normalize3(v);
  885. //keep point with deepest penetration
  886. float minW = FLT_MAX;
  887. int minIndex = -1;
  888. float4 maxDots;
  889. maxDots.x = FLT_MIN;
  890. maxDots.y = FLT_MIN;
  891. maxDots.z = FLT_MIN;
  892. maxDots.w = FLT_MIN;
  893. // idx, distance
  894. for (int ie = 0; ie < nPoints; ie++)
  895. {
  896. if (p[ie].w < minW)
  897. {
  898. minW = p[ie].w;
  899. minIndex = ie;
  900. }
  901. float f;
  902. float4 r = p[ie] - center;
  903. f = dot3F4(u, r);
  904. if (f < maxDots.x)
  905. {
  906. maxDots.x = f;
  907. contactIdx[0].x = ie;
  908. }
  909. f = dot3F4(-u, r);
  910. if (f < maxDots.y)
  911. {
  912. maxDots.y = f;
  913. contactIdx[0].y = ie;
  914. }
  915. f = dot3F4(v, r);
  916. if (f < maxDots.z)
  917. {
  918. maxDots.z = f;
  919. contactIdx[0].z = ie;
  920. }
  921. f = dot3F4(-v, r);
  922. if (f < maxDots.w)
  923. {
  924. maxDots.w = f;
  925. contactIdx[0].w = ie;
  926. }
  927. }
  928. if (contactIdx[0].x != minIndex && contactIdx[0].y != minIndex && contactIdx[0].z != minIndex && contactIdx[0].w != minIndex)
  929. {
  930. //replace the first contact with minimum (todo: replace contact with least penetration)
  931. contactIdx[0].x = minIndex;
  932. }
  933. return 4;
  934. }
  935. int clipHullHullSingle(
  936. int bodyIndexA, int bodyIndexB,
  937. const float4& posA,
  938. const b3Quaternion& ornA,
  939. const float4& posB,
  940. const b3Quaternion& ornB,
  941. int collidableIndexA, int collidableIndexB,
  942. const b3AlignedObjectArray<b3RigidBodyData>* bodyBuf,
  943. b3AlignedObjectArray<b3Contact4>* globalContactOut,
  944. int& nContacts,
  945. const b3AlignedObjectArray<b3ConvexPolyhedronData>& hostConvexDataA,
  946. const b3AlignedObjectArray<b3ConvexPolyhedronData>& hostConvexDataB,
  947. const b3AlignedObjectArray<b3Vector3>& verticesA,
  948. const b3AlignedObjectArray<b3Vector3>& uniqueEdgesA,
  949. const b3AlignedObjectArray<b3GpuFace>& facesA,
  950. const b3AlignedObjectArray<int>& indicesA,
  951. const b3AlignedObjectArray<b3Vector3>& verticesB,
  952. const b3AlignedObjectArray<b3Vector3>& uniqueEdgesB,
  953. const b3AlignedObjectArray<b3GpuFace>& facesB,
  954. const b3AlignedObjectArray<int>& indicesB,
  955. const b3AlignedObjectArray<b3Collidable>& hostCollidablesA,
  956. const b3AlignedObjectArray<b3Collidable>& hostCollidablesB,
  957. const b3Vector3& sepNormalWorldSpace,
  958. int maxContactCapacity)
  959. {
  960. int contactIndex = -1;
  961. b3ConvexPolyhedronData hullA, hullB;
  962. b3Collidable colA = hostCollidablesA[collidableIndexA];
  963. hullA = hostConvexDataA[colA.m_shapeIndex];
  964. //printf("numvertsA = %d\n",hullA.m_numVertices);
  965. b3Collidable colB = hostCollidablesB[collidableIndexB];
  966. hullB = hostConvexDataB[colB.m_shapeIndex];
  967. //printf("numvertsB = %d\n",hullB.m_numVertices);
  968. float4 contactsOut[MAX_VERTS];
  969. int localContactCapacity = MAX_VERTS;
  970. #ifdef _WIN32
  971. b3Assert(_finite(bodyBuf->at(bodyIndexA).m_pos.x));
  972. b3Assert(_finite(bodyBuf->at(bodyIndexB).m_pos.x));
  973. #endif
  974. {
  975. float4 worldVertsB1[MAX_VERTS];
  976. float4 worldVertsB2[MAX_VERTS];
  977. int capacityWorldVerts = MAX_VERTS;
  978. float4 hostNormal = make_float4(sepNormalWorldSpace.x, sepNormalWorldSpace.y, sepNormalWorldSpace.z, 0.f);
  979. int shapeA = hostCollidablesA[collidableIndexA].m_shapeIndex;
  980. int shapeB = hostCollidablesB[collidableIndexB].m_shapeIndex;
  981. b3Scalar minDist = -1;
  982. b3Scalar maxDist = 0.;
  983. b3Transform trA, trB;
  984. {
  985. //B3_PROFILE("transform computation");
  986. //trA.setIdentity();
  987. trA.setOrigin(b3MakeVector3(posA.x, posA.y, posA.z));
  988. trA.setRotation(b3Quaternion(ornA.x, ornA.y, ornA.z, ornA.w));
  989. //trB.setIdentity();
  990. trB.setOrigin(b3MakeVector3(posB.x, posB.y, posB.z));
  991. trB.setRotation(b3Quaternion(ornB.x, ornB.y, ornB.z, ornB.w));
  992. }
  993. b3Quaternion trAorn = trA.getRotation();
  994. b3Quaternion trBorn = trB.getRotation();
  995. int numContactsOut = clipHullAgainstHull(hostNormal,
  996. hostConvexDataA.at(shapeA),
  997. hostConvexDataB.at(shapeB),
  998. (float4&)trA.getOrigin(), (b3Quaternion&)trAorn,
  999. (float4&)trB.getOrigin(), (b3Quaternion&)trBorn,
  1000. worldVertsB1, worldVertsB2, capacityWorldVerts,
  1001. minDist, maxDist,
  1002. verticesA, facesA, indicesA,
  1003. verticesB, facesB, indicesB,
  1004. contactsOut, localContactCapacity);
  1005. if (numContactsOut > 0)
  1006. {
  1007. B3_PROFILE("overlap");
  1008. float4 normalOnSurfaceB = (float4&)hostNormal;
  1009. b3Int4 contactIdx;
  1010. contactIdx.x = 0;
  1011. contactIdx.y = 1;
  1012. contactIdx.z = 2;
  1013. contactIdx.w = 3;
  1014. int numPoints = 0;
  1015. {
  1016. // B3_PROFILE("extractManifold");
  1017. numPoints = extractManifold(contactsOut, numContactsOut, normalOnSurfaceB, &contactIdx);
  1018. }
  1019. b3Assert(numPoints);
  1020. if (nContacts < maxContactCapacity)
  1021. {
  1022. contactIndex = nContacts;
  1023. globalContactOut->expand();
  1024. b3Contact4& contact = globalContactOut->at(nContacts);
  1025. contact.m_batchIdx = 0; //i;
  1026. contact.m_bodyAPtrAndSignBit = (bodyBuf->at(bodyIndexA).m_invMass == 0) ? -bodyIndexA : bodyIndexA;
  1027. contact.m_bodyBPtrAndSignBit = (bodyBuf->at(bodyIndexB).m_invMass == 0) ? -bodyIndexB : bodyIndexB;
  1028. contact.m_frictionCoeffCmp = 45874;
  1029. contact.m_restituitionCoeffCmp = 0;
  1030. // float distance = 0.f;
  1031. for (int p = 0; p < numPoints; p++)
  1032. {
  1033. contact.m_worldPosB[p] = contactsOut[contactIdx.s[p]]; //check if it is actually on B
  1034. contact.m_worldNormalOnB = normalOnSurfaceB;
  1035. }
  1036. //printf("bodyIndexA %d,bodyIndexB %d,normal=%f,%f,%f numPoints %d\n",bodyIndexA,bodyIndexB,normalOnSurfaceB.x,normalOnSurfaceB.y,normalOnSurfaceB.z,numPoints);
  1037. contact.m_worldNormalOnB.w = (b3Scalar)numPoints;
  1038. nContacts++;
  1039. }
  1040. else
  1041. {
  1042. b3Error("Error: exceeding contact capacity (%d/%d)\n", nContacts, maxContactCapacity);
  1043. }
  1044. }
  1045. }
  1046. return contactIndex;
  1047. }
  1048. void computeContactPlaneConvex(int pairIndex,
  1049. int bodyIndexA, int bodyIndexB,
  1050. int collidableIndexA, int collidableIndexB,
  1051. const b3RigidBodyData* rigidBodies,
  1052. const b3Collidable* collidables,
  1053. const b3ConvexPolyhedronData* convexShapes,
  1054. const b3Vector3* convexVertices,
  1055. const int* convexIndices,
  1056. const b3GpuFace* faces,
  1057. b3Contact4* globalContactsOut,
  1058. int& nGlobalContactsOut,
  1059. int maxContactCapacity)
  1060. {
  1061. int shapeIndex = collidables[collidableIndexB].m_shapeIndex;
  1062. const b3ConvexPolyhedronData* hullB = &convexShapes[shapeIndex];
  1063. b3Vector3 posB = rigidBodies[bodyIndexB].m_pos;
  1064. b3Quaternion ornB = rigidBodies[bodyIndexB].m_quat;
  1065. b3Vector3 posA = rigidBodies[bodyIndexA].m_pos;
  1066. b3Quaternion ornA = rigidBodies[bodyIndexA].m_quat;
  1067. // int numContactsOut = 0;
  1068. // int numWorldVertsB1= 0;
  1069. b3Vector3 planeEq = faces[collidables[collidableIndexA].m_shapeIndex].m_plane;
  1070. b3Vector3 planeNormal = b3MakeVector3(planeEq.x, planeEq.y, planeEq.z);
  1071. b3Vector3 planeNormalWorld = b3QuatRotate(ornA, planeNormal);
  1072. float planeConstant = planeEq.w;
  1073. b3Transform convexWorldTransform;
  1074. convexWorldTransform.setIdentity();
  1075. convexWorldTransform.setOrigin(posB);
  1076. convexWorldTransform.setRotation(ornB);
  1077. b3Transform planeTransform;
  1078. planeTransform.setIdentity();
  1079. planeTransform.setOrigin(posA);
  1080. planeTransform.setRotation(ornA);
  1081. b3Transform planeInConvex;
  1082. planeInConvex = convexWorldTransform.inverse() * planeTransform;
  1083. b3Transform convexInPlane;
  1084. convexInPlane = planeTransform.inverse() * convexWorldTransform;
  1085. b3Vector3 planeNormalInConvex = planeInConvex.getBasis() * -planeNormal;
  1086. float maxDot = -1e30;
  1087. int hitVertex = -1;
  1088. b3Vector3 hitVtx;
  1089. #define MAX_PLANE_CONVEX_POINTS 64
  1090. b3Vector3 contactPoints[MAX_PLANE_CONVEX_POINTS];
  1091. int numPoints = 0;
  1092. b3Int4 contactIdx;
  1093. contactIdx.s[0] = 0;
  1094. contactIdx.s[1] = 1;
  1095. contactIdx.s[2] = 2;
  1096. contactIdx.s[3] = 3;
  1097. for (int i = 0; i < hullB->m_numVertices; i++)
  1098. {
  1099. b3Vector3 vtx = convexVertices[hullB->m_vertexOffset + i];
  1100. float curDot = vtx.dot(planeNormalInConvex);
  1101. if (curDot > maxDot)
  1102. {
  1103. hitVertex = i;
  1104. maxDot = curDot;
  1105. hitVtx = vtx;
  1106. //make sure the deepest points is always included
  1107. if (numPoints == MAX_PLANE_CONVEX_POINTS)
  1108. numPoints--;
  1109. }
  1110. if (numPoints < MAX_PLANE_CONVEX_POINTS)
  1111. {
  1112. b3Vector3 vtxWorld = convexWorldTransform * vtx;
  1113. b3Vector3 vtxInPlane = planeTransform.inverse() * vtxWorld;
  1114. float dist = planeNormal.dot(vtxInPlane) - planeConstant;
  1115. if (dist < 0.f)
  1116. {
  1117. vtxWorld.w = dist;
  1118. contactPoints[numPoints] = vtxWorld;
  1119. numPoints++;
  1120. }
  1121. }
  1122. }
  1123. int numReducedPoints = 0;
  1124. numReducedPoints = numPoints;
  1125. if (numPoints > 4)
  1126. {
  1127. numReducedPoints = extractManifoldSequentialGlobal(contactPoints, numPoints, planeNormalInConvex, &contactIdx);
  1128. }
  1129. int dstIdx;
  1130. // dstIdx = nGlobalContactsOut++;//AppendInc( nGlobalContactsOut, dstIdx );
  1131. if (numReducedPoints > 0)
  1132. {
  1133. if (nGlobalContactsOut < maxContactCapacity)
  1134. {
  1135. dstIdx = nGlobalContactsOut;
  1136. nGlobalContactsOut++;
  1137. b3Contact4* c = &globalContactsOut[dstIdx];
  1138. c->m_worldNormalOnB = -planeNormalWorld;
  1139. c->setFrictionCoeff(0.7);
  1140. c->setRestituitionCoeff(0.f);
  1141. c->m_batchIdx = pairIndex;
  1142. c->m_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass == 0 ? -bodyIndexA : bodyIndexA;
  1143. c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass == 0 ? -bodyIndexB : bodyIndexB;
  1144. for (int i = 0; i < numReducedPoints; i++)
  1145. {
  1146. b3Vector3 pOnB1 = contactPoints[contactIdx.s[i]];
  1147. c->m_worldPosB[i] = pOnB1;
  1148. }
  1149. c->m_worldNormalOnB.w = (b3Scalar)numReducedPoints;
  1150. } //if (dstIdx < numPairs)
  1151. }
  1152. // printf("computeContactPlaneConvex\n");
  1153. }
  1154. B3_FORCE_INLINE b3Vector3 MyUnQuantize(const unsigned short* vecIn, const b3Vector3& quantization, const b3Vector3& bvhAabbMin)
  1155. {
  1156. b3Vector3 vecOut;
  1157. vecOut.setValue(
  1158. (b3Scalar)(vecIn[0]) / (quantization.x),
  1159. (b3Scalar)(vecIn[1]) / (quantization.y),
  1160. (b3Scalar)(vecIn[2]) / (quantization.z));
  1161. vecOut += bvhAabbMin;
  1162. return vecOut;
  1163. }
  1164. void traverseTreeTree()
  1165. {
  1166. }
  1167. #include "Bullet3Common/shared/b3Mat3x3.h"
  1168. int numAabbChecks = 0;
  1169. int maxNumAabbChecks = 0;
  1170. int maxDepth = 0;
  1171. // work-in-progress
  1172. __kernel void findCompoundPairsKernel(
  1173. int pairIndex,
  1174. int bodyIndexA,
  1175. int bodyIndexB,
  1176. int collidableIndexA,
  1177. int collidableIndexB,
  1178. __global const b3RigidBodyData* rigidBodies,
  1179. __global const b3Collidable* collidables,
  1180. __global const b3ConvexPolyhedronData* convexShapes,
  1181. __global const b3AlignedObjectArray<b3Float4>& vertices,
  1182. __global const b3AlignedObjectArray<b3Aabb>& aabbsWorldSpace,
  1183. __global const b3AlignedObjectArray<b3Aabb>& aabbsLocalSpace,
  1184. __global const b3GpuChildShape* gpuChildShapes,
  1185. __global b3Int4* gpuCompoundPairsOut,
  1186. __global int* numCompoundPairsOut,
  1187. int maxNumCompoundPairsCapacity,
  1188. b3AlignedObjectArray<b3QuantizedBvhNode>& treeNodesCPU,
  1189. b3AlignedObjectArray<b3BvhSubtreeInfo>& subTreesCPU,
  1190. b3AlignedObjectArray<b3BvhInfo>& bvhInfoCPU)
  1191. {
  1192. numAabbChecks = 0;
  1193. maxNumAabbChecks = 0;
  1194. // int i = pairIndex;
  1195. {
  1196. int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;
  1197. int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;
  1198. //once the broadphase avoids static-static pairs, we can remove this test
  1199. if ((rigidBodies[bodyIndexA].m_invMass == 0) && (rigidBodies[bodyIndexB].m_invMass == 0))
  1200. {
  1201. return;
  1202. }
  1203. if ((collidables[collidableIndexA].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS) && (collidables[collidableIndexB].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS))
  1204. {
  1205. int bvhA = collidables[collidableIndexA].m_compoundBvhIndex;
  1206. int bvhB = collidables[collidableIndexB].m_compoundBvhIndex;
  1207. int numSubTreesA = bvhInfoCPU[bvhA].m_numSubTrees;
  1208. int subTreesOffsetA = bvhInfoCPU[bvhA].m_subTreeOffset;
  1209. int subTreesOffsetB = bvhInfoCPU[bvhB].m_subTreeOffset;
  1210. int numSubTreesB = bvhInfoCPU[bvhB].m_numSubTrees;
  1211. float4 posA = rigidBodies[bodyIndexA].m_pos;
  1212. b3Quat ornA = rigidBodies[bodyIndexA].m_quat;
  1213. b3Transform transA;
  1214. transA.setIdentity();
  1215. transA.setOrigin(posA);
  1216. transA.setRotation(ornA);
  1217. b3Quat ornB = rigidBodies[bodyIndexB].m_quat;
  1218. float4 posB = rigidBodies[bodyIndexB].m_pos;
  1219. b3Transform transB;
  1220. transB.setIdentity();
  1221. transB.setOrigin(posB);
  1222. transB.setRotation(ornB);
  1223. for (int p = 0; p < numSubTreesA; p++)
  1224. {
  1225. b3BvhSubtreeInfo subtreeA = subTreesCPU[subTreesOffsetA + p];
  1226. //bvhInfoCPU[bvhA].m_quantization
  1227. b3Vector3 treeAminLocal = MyUnQuantize(subtreeA.m_quantizedAabbMin, bvhInfoCPU[bvhA].m_quantization, bvhInfoCPU[bvhA].m_aabbMin);
  1228. b3Vector3 treeAmaxLocal = MyUnQuantize(subtreeA.m_quantizedAabbMax, bvhInfoCPU[bvhA].m_quantization, bvhInfoCPU[bvhA].m_aabbMin);
  1229. b3Vector3 aabbAMinOut, aabbAMaxOut;
  1230. float margin = 0.f;
  1231. b3TransformAabb2(treeAminLocal, treeAmaxLocal, margin, transA.getOrigin(), transA.getRotation(), &aabbAMinOut, &aabbAMaxOut);
  1232. for (int q = 0; q < numSubTreesB; q++)
  1233. {
  1234. b3BvhSubtreeInfo subtreeB = subTreesCPU[subTreesOffsetB + q];
  1235. b3Vector3 treeBminLocal = MyUnQuantize(subtreeB.m_quantizedAabbMin, bvhInfoCPU[bvhB].m_quantization, bvhInfoCPU[bvhB].m_aabbMin);
  1236. b3Vector3 treeBmaxLocal = MyUnQuantize(subtreeB.m_quantizedAabbMax, bvhInfoCPU[bvhB].m_quantization, bvhInfoCPU[bvhB].m_aabbMin);
  1237. b3Vector3 aabbBMinOut, aabbBMaxOut;
  1238. float margin = 0.f;
  1239. b3TransformAabb2(treeBminLocal, treeBmaxLocal, margin, transB.getOrigin(), transB.getRotation(), &aabbBMinOut, &aabbBMaxOut);
  1240. numAabbChecks = 0;
  1241. bool aabbOverlap = b3TestAabbAgainstAabb(aabbAMinOut, aabbAMaxOut, aabbBMinOut, aabbBMaxOut);
  1242. if (aabbOverlap)
  1243. {
  1244. int startNodeIndexA = subtreeA.m_rootNodeIndex + bvhInfoCPU[bvhA].m_nodeOffset;
  1245. // int endNodeIndexA = startNodeIndexA+subtreeA.m_subtreeSize;
  1246. int startNodeIndexB = subtreeB.m_rootNodeIndex + bvhInfoCPU[bvhB].m_nodeOffset;
  1247. // int endNodeIndexB = startNodeIndexB+subtreeB.m_subtreeSize;
  1248. b3AlignedObjectArray<b3Int2> nodeStack;
  1249. b3Int2 node0;
  1250. node0.x = startNodeIndexA;
  1251. node0.y = startNodeIndexB;
  1252. int maxStackDepth = 1024;
  1253. nodeStack.resize(maxStackDepth);
  1254. int depth = 0;
  1255. nodeStack[depth++] = node0;
  1256. do
  1257. {
  1258. if (depth > maxDepth)
  1259. {
  1260. maxDepth = depth;
  1261. printf("maxDepth=%d\n", maxDepth);
  1262. }
  1263. b3Int2 node = nodeStack[--depth];
  1264. b3Vector3 aMinLocal = MyUnQuantize(treeNodesCPU[node.x].m_quantizedAabbMin, bvhInfoCPU[bvhA].m_quantization, bvhInfoCPU[bvhA].m_aabbMin);
  1265. b3Vector3 aMaxLocal = MyUnQuantize(treeNodesCPU[node.x].m_quantizedAabbMax, bvhInfoCPU[bvhA].m_quantization, bvhInfoCPU[bvhA].m_aabbMin);
  1266. b3Vector3 bMinLocal = MyUnQuantize(treeNodesCPU[node.y].m_quantizedAabbMin, bvhInfoCPU[bvhB].m_quantization, bvhInfoCPU[bvhB].m_aabbMin);
  1267. b3Vector3 bMaxLocal = MyUnQuantize(treeNodesCPU[node.y].m_quantizedAabbMax, bvhInfoCPU[bvhB].m_quantization, bvhInfoCPU[bvhB].m_aabbMin);
  1268. float margin = 0.f;
  1269. b3Vector3 aabbAMinOut, aabbAMaxOut;
  1270. b3TransformAabb2(aMinLocal, aMaxLocal, margin, transA.getOrigin(), transA.getRotation(), &aabbAMinOut, &aabbAMaxOut);
  1271. b3Vector3 aabbBMinOut, aabbBMaxOut;
  1272. b3TransformAabb2(bMinLocal, bMaxLocal, margin, transB.getOrigin(), transB.getRotation(), &aabbBMinOut, &aabbBMaxOut);
  1273. numAabbChecks++;
  1274. bool nodeOverlap = b3TestAabbAgainstAabb(aabbAMinOut, aabbAMaxOut, aabbBMinOut, aabbBMaxOut);
  1275. if (nodeOverlap)
  1276. {
  1277. bool isLeafA = treeNodesCPU[node.x].isLeafNode();
  1278. bool isLeafB = treeNodesCPU[node.y].isLeafNode();
  1279. bool isInternalA = !isLeafA;
  1280. bool isInternalB = !isLeafB;
  1281. //fail, even though it might hit two leaf nodes
  1282. if (depth + 4 > maxStackDepth && !(isLeafA && isLeafB))
  1283. {
  1284. b3Error("Error: traversal exceeded maxStackDepth\n");
  1285. continue;
  1286. }
  1287. if (isInternalA)
  1288. {
  1289. int nodeAleftChild = node.x + 1;
  1290. bool isNodeALeftChildLeaf = treeNodesCPU[node.x + 1].isLeafNode();
  1291. int nodeArightChild = isNodeALeftChildLeaf ? node.x + 2 : node.x + 1 + treeNodesCPU[node.x + 1].getEscapeIndex();
  1292. if (isInternalB)
  1293. {
  1294. int nodeBleftChild = node.y + 1;
  1295. bool isNodeBLeftChildLeaf = treeNodesCPU[node.y + 1].isLeafNode();
  1296. int nodeBrightChild = isNodeBLeftChildLeaf ? node.y + 2 : node.y + 1 + treeNodesCPU[node.y + 1].getEscapeIndex();
  1297. nodeStack[depth++] = b3MakeInt2(nodeAleftChild, nodeBleftChild);
  1298. nodeStack[depth++] = b3MakeInt2(nodeArightChild, nodeBleftChild);
  1299. nodeStack[depth++] = b3MakeInt2(nodeAleftChild, nodeBrightChild);
  1300. nodeStack[depth++] = b3MakeInt2(nodeArightChild, nodeBrightChild);
  1301. }
  1302. else
  1303. {
  1304. nodeStack[depth++] = b3MakeInt2(nodeAleftChild, node.y);
  1305. nodeStack[depth++] = b3MakeInt2(nodeArightChild, node.y);
  1306. }
  1307. }
  1308. else
  1309. {
  1310. if (isInternalB)
  1311. {
  1312. int nodeBleftChild = node.y + 1;
  1313. bool isNodeBLeftChildLeaf = treeNodesCPU[node.y + 1].isLeafNode();
  1314. int nodeBrightChild = isNodeBLeftChildLeaf ? node.y + 2 : node.y + 1 + treeNodesCPU[node.y + 1].getEscapeIndex();
  1315. nodeStack[depth++] = b3MakeInt2(node.x, nodeBleftChild);
  1316. nodeStack[depth++] = b3MakeInt2(node.x, nodeBrightChild);
  1317. }
  1318. else
  1319. {
  1320. int compoundPairIdx = b3AtomicInc(numCompoundPairsOut);
  1321. if (compoundPairIdx < maxNumCompoundPairsCapacity)
  1322. {
  1323. int childShapeIndexA = treeNodesCPU[node.x].getTriangleIndex();
  1324. int childShapeIndexB = treeNodesCPU[node.y].getTriangleIndex();
  1325. gpuCompoundPairsOut[compoundPairIdx] = b3MakeInt4(bodyIndexA, bodyIndexB, childShapeIndexA, childShapeIndexB);
  1326. }
  1327. }
  1328. }
  1329. }
  1330. } while (depth);
  1331. maxNumAabbChecks = b3Max(numAabbChecks, maxNumAabbChecks);
  1332. }
  1333. }
  1334. }
  1335. return;
  1336. }
  1337. if ((collidables[collidableIndexA].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS) || (collidables[collidableIndexB].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS))
  1338. {
  1339. if (collidables[collidableIndexA].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS)
  1340. {
  1341. int numChildrenA = collidables[collidableIndexA].m_numChildShapes;
  1342. for (int c = 0; c < numChildrenA; c++)
  1343. {
  1344. int childShapeIndexA = collidables[collidableIndexA].m_shapeIndex + c;
  1345. int childColIndexA = gpuChildShapes[childShapeIndexA].m_shapeIndex;
  1346. float4 posA = rigidBodies[bodyIndexA].m_pos;
  1347. b3Quat ornA = rigidBodies[bodyIndexA].m_quat;
  1348. float4 childPosA = gpuChildShapes[childShapeIndexA].m_childPosition;
  1349. b3Quat childOrnA = gpuChildShapes[childShapeIndexA].m_childOrientation;
  1350. float4 newPosA = b3QuatRotate(ornA, childPosA) + posA;
  1351. b3Quat newOrnA = b3QuatMul(ornA, childOrnA);
  1352. b3Aabb aabbA = aabbsLocalSpace[childColIndexA];
  1353. b3Transform transA;
  1354. transA.setIdentity();
  1355. transA.setOrigin(newPosA);
  1356. transA.setRotation(newOrnA);
  1357. b3Scalar margin = 0.0f;
  1358. b3Vector3 aabbAMinOut, aabbAMaxOut;
  1359. b3TransformAabb2((const b3Float4&)aabbA.m_min, (const b3Float4&)aabbA.m_max, margin, transA.getOrigin(), transA.getRotation(), &aabbAMinOut, &aabbAMaxOut);
  1360. if (collidables[collidableIndexB].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS)
  1361. {
  1362. int numChildrenB = collidables[collidableIndexB].m_numChildShapes;
  1363. for (int b = 0; b < numChildrenB; b++)
  1364. {
  1365. int childShapeIndexB = collidables[collidableIndexB].m_shapeIndex + b;
  1366. int childColIndexB = gpuChildShapes[childShapeIndexB].m_shapeIndex;
  1367. b3Quat ornB = rigidBodies[bodyIndexB].m_quat;
  1368. float4 posB = rigidBodies[bodyIndexB].m_pos;
  1369. float4 childPosB = gpuChildShapes[childShapeIndexB].m_childPosition;
  1370. b3Quat childOrnB = gpuChildShapes[childShapeIndexB].m_childOrientation;
  1371. float4 newPosB = transform(&childPosB, &posB, &ornB);
  1372. b3Quat newOrnB = b3QuatMul(ornB, childOrnB);
  1373. b3Aabb aabbB = aabbsLocalSpace[childColIndexB];
  1374. b3Transform transB;
  1375. transB.setIdentity();
  1376. transB.setOrigin(newPosB);
  1377. transB.setRotation(newOrnB);
  1378. b3Vector3 aabbBMinOut, aabbBMaxOut;
  1379. b3TransformAabb2((const b3Float4&)aabbB.m_min, (const b3Float4&)aabbB.m_max, margin, transB.getOrigin(), transB.getRotation(), &aabbBMinOut, &aabbBMaxOut);
  1380. numAabbChecks++;
  1381. bool aabbOverlap = b3TestAabbAgainstAabb(aabbAMinOut, aabbAMaxOut, aabbBMinOut, aabbBMaxOut);
  1382. if (aabbOverlap)
  1383. {
  1384. /*
  1385. int numFacesA = convexShapes[shapeIndexA].m_numFaces;
  1386. float dmin = FLT_MAX;
  1387. float4 posA = newPosA;
  1388. posA.w = 0.f;
  1389. float4 posB = newPosB;
  1390. posB.w = 0.f;
  1391. float4 c0local = convexShapes[shapeIndexA].m_localCenter;
  1392. b3Quat ornA = newOrnA;
  1393. float4 c0 = transform(&c0local, &posA, &ornA);
  1394. float4 c1local = convexShapes[shapeIndexB].m_localCenter;
  1395. b3Quat ornB =newOrnB;
  1396. float4 c1 = transform(&c1local,&posB,&ornB);
  1397. const float4 DeltaC2 = c0 - c1;
  1398. */
  1399. { //
  1400. int compoundPairIdx = b3AtomicInc(numCompoundPairsOut);
  1401. if (compoundPairIdx < maxNumCompoundPairsCapacity)
  1402. {
  1403. gpuCompoundPairsOut[compoundPairIdx] = b3MakeInt4(bodyIndexA, bodyIndexB, childShapeIndexA, childShapeIndexB);
  1404. }
  1405. } //
  1406. } //fi(1)
  1407. } //for (int b=0
  1408. } //if (collidables[collidableIndexB].
  1409. else //if (collidables[collidableIndexB].m_shapeType==SHAPE_COMPOUND_OF_CONVEX_HULLS)
  1410. {
  1411. if (1)
  1412. {
  1413. // int numFacesA = convexShapes[shapeIndexA].m_numFaces;
  1414. // float dmin = FLT_MAX;
  1415. float4 posA = newPosA;
  1416. posA.w = 0.f;
  1417. float4 posB = rigidBodies[bodyIndexB].m_pos;
  1418. posB.w = 0.f;
  1419. float4 c0local = convexShapes[shapeIndexA].m_localCenter;
  1420. b3Quat ornA = newOrnA;
  1421. float4 c0;
  1422. c0 = transform(&c0local, &posA, &ornA);
  1423. float4 c1local = convexShapes[shapeIndexB].m_localCenter;
  1424. b3Quat ornB = rigidBodies[bodyIndexB].m_quat;
  1425. float4 c1;
  1426. c1 = transform(&c1local, &posB, &ornB);
  1427. // const float4 DeltaC2 = c0 - c1;
  1428. {
  1429. int compoundPairIdx = b3AtomicInc(numCompoundPairsOut);
  1430. if (compoundPairIdx < maxNumCompoundPairsCapacity)
  1431. {
  1432. gpuCompoundPairsOut[compoundPairIdx] = b3MakeInt4(bodyIndexA, bodyIndexB, childShapeIndexA, -1);
  1433. } //if (compoundPairIdx<maxNumCompoundPairsCapacity)
  1434. } //
  1435. } //fi (1)
  1436. } //if (collidables[collidableIndexB].m_shapeType==SHAPE_COMPOUND_OF_CONVEX_HULLS)
  1437. } //for (int b=0;b<numChildrenB;b++)
  1438. return;
  1439. } //if (collidables[collidableIndexB].m_shapeType==SHAPE_COMPOUND_OF_CONVEX_HULLS)
  1440. if ((collidables[collidableIndexA].m_shapeType != SHAPE_CONCAVE_TRIMESH) && (collidables[collidableIndexB].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS))
  1441. {
  1442. int numChildrenB = collidables[collidableIndexB].m_numChildShapes;
  1443. for (int b = 0; b < numChildrenB; b++)
  1444. {
  1445. int childShapeIndexB = collidables[collidableIndexB].m_shapeIndex + b;
  1446. int childColIndexB = gpuChildShapes[childShapeIndexB].m_shapeIndex;
  1447. b3Quat ornB = rigidBodies[bodyIndexB].m_quat;
  1448. float4 posB = rigidBodies[bodyIndexB].m_pos;
  1449. float4 childPosB = gpuChildShapes[childShapeIndexB].m_childPosition;
  1450. b3Quat childOrnB = gpuChildShapes[childShapeIndexB].m_childOrientation;
  1451. float4 newPosB = b3QuatRotate(ornB, childPosB) + posB;
  1452. b3Quat newOrnB = b3QuatMul(ornB, childOrnB);
  1453. int shapeIndexB = collidables[childColIndexB].m_shapeIndex;
  1454. //////////////////////////////////////
  1455. if (1)
  1456. {
  1457. // int numFacesA = convexShapes[shapeIndexA].m_numFaces;
  1458. // float dmin = FLT_MAX;
  1459. float4 posA = rigidBodies[bodyIndexA].m_pos;
  1460. posA.w = 0.f;
  1461. float4 posB = newPosB;
  1462. posB.w = 0.f;
  1463. float4 c0local = convexShapes[shapeIndexA].m_localCenter;
  1464. b3Quat ornA = rigidBodies[bodyIndexA].m_quat;
  1465. float4 c0;
  1466. c0 = transform(&c0local, &posA, &ornA);
  1467. float4 c1local = convexShapes[shapeIndexB].m_localCenter;
  1468. b3Quat ornB = newOrnB;
  1469. float4 c1;
  1470. c1 = transform(&c1local, &posB, &ornB);
  1471. // const float4 DeltaC2 = c0 - c1;
  1472. { //
  1473. int compoundPairIdx = b3AtomicInc(numCompoundPairsOut);
  1474. if (compoundPairIdx < maxNumCompoundPairsCapacity)
  1475. {
  1476. gpuCompoundPairsOut[compoundPairIdx] = b3MakeInt4(bodyIndexA, bodyIndexB, -1, childShapeIndexB);
  1477. } //fi (compoundPairIdx<maxNumCompoundPairsCapacity)
  1478. } //
  1479. } //fi (1)
  1480. } //for (int b=0;b<numChildrenB;b++)
  1481. return;
  1482. } //if (collidables[collidableIndexB].m_shapeType==SHAPE_COMPOUND_OF_CONVEX_HULLS)
  1483. return;
  1484. } //fi ((collidables[collidableIndexA].m_shapeType==SHAPE_COMPOUND_OF_CONVEX_HULLS) ||(collidables[collidableIndexB].m_shapeType==SHAPE_COMPOUND_OF_CONVEX_HULLS))
  1485. } //i<numPairs
  1486. }
  1487. __kernel void processCompoundPairsKernel(__global const b3Int4* gpuCompoundPairs,
  1488. __global const b3RigidBodyData* rigidBodies,
  1489. __global const b3Collidable* collidables,
  1490. __global const b3ConvexPolyhedronData* convexShapes,
  1491. __global const b3AlignedObjectArray<b3Float4>& vertices,
  1492. __global const b3AlignedObjectArray<b3Float4>& uniqueEdges,
  1493. __global const b3AlignedObjectArray<b3GpuFace>& faces,
  1494. __global const b3AlignedObjectArray<int>& indices,
  1495. __global b3Aabb* aabbs,
  1496. __global const b3GpuChildShape* gpuChildShapes,
  1497. __global b3AlignedObjectArray<b3Float4>& gpuCompoundSepNormalsOut,
  1498. __global b3AlignedObjectArray<int>& gpuHasCompoundSepNormalsOut,
  1499. int numCompoundPairs,
  1500. int i)
  1501. {
  1502. // int i = get_global_id(0);
  1503. if (i < numCompoundPairs)
  1504. {
  1505. int bodyIndexA = gpuCompoundPairs[i].x;
  1506. int bodyIndexB = gpuCompoundPairs[i].y;
  1507. int childShapeIndexA = gpuCompoundPairs[i].z;
  1508. int childShapeIndexB = gpuCompoundPairs[i].w;
  1509. int collidableIndexA = -1;
  1510. int collidableIndexB = -1;
  1511. b3Quat ornA = rigidBodies[bodyIndexA].m_quat;
  1512. float4 posA = rigidBodies[bodyIndexA].m_pos;
  1513. b3Quat ornB = rigidBodies[bodyIndexB].m_quat;
  1514. float4 posB = rigidBodies[bodyIndexB].m_pos;
  1515. if (childShapeIndexA >= 0)
  1516. {
  1517. collidableIndexA = gpuChildShapes[childShapeIndexA].m_shapeIndex;
  1518. float4 childPosA = gpuChildShapes[childShapeIndexA].m_childPosition;
  1519. b3Quat childOrnA = gpuChildShapes[childShapeIndexA].m_childOrientation;
  1520. float4 newPosA = b3QuatRotate(ornA, childPosA) + posA;
  1521. b3Quat newOrnA = b3QuatMul(ornA, childOrnA);
  1522. posA = newPosA;
  1523. ornA = newOrnA;
  1524. }
  1525. else
  1526. {
  1527. collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;
  1528. }
  1529. if (childShapeIndexB >= 0)
  1530. {
  1531. collidableIndexB = gpuChildShapes[childShapeIndexB].m_shapeIndex;
  1532. float4 childPosB = gpuChildShapes[childShapeIndexB].m_childPosition;
  1533. b3Quat childOrnB = gpuChildShapes[childShapeIndexB].m_childOrientation;
  1534. float4 newPosB = b3QuatRotate(ornB, childPosB) + posB;
  1535. b3Quat newOrnB = b3QuatMul(ornB, childOrnB);
  1536. posB = newPosB;
  1537. ornB = newOrnB;
  1538. }
  1539. else
  1540. {
  1541. collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;
  1542. }
  1543. gpuHasCompoundSepNormalsOut[i] = 0;
  1544. int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;
  1545. int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;
  1546. int shapeTypeA = collidables[collidableIndexA].m_shapeType;
  1547. int shapeTypeB = collidables[collidableIndexB].m_shapeType;
  1548. if ((shapeTypeA != SHAPE_CONVEX_HULL) || (shapeTypeB != SHAPE_CONVEX_HULL))
  1549. {
  1550. return;
  1551. }
  1552. int hasSeparatingAxis = 5;
  1553. // int numFacesA = convexShapes[shapeIndexA].m_numFaces;
  1554. float dmin = FLT_MAX;
  1555. posA.w = 0.f;
  1556. posB.w = 0.f;
  1557. float4 c0local = convexShapes[shapeIndexA].m_localCenter;
  1558. float4 c0 = transform(&c0local, &posA, &ornA);
  1559. float4 c1local = convexShapes[shapeIndexB].m_localCenter;
  1560. float4 c1 = transform(&c1local, &posB, &ornB);
  1561. const float4 DeltaC2 = c0 - c1;
  1562. float4 sepNormal = make_float4(1, 0, 0, 0);
  1563. // bool sepA = findSeparatingAxis( convexShapes[shapeIndexA], convexShapes[shapeIndexB],posA,ornA,posB,ornB,DeltaC2,vertices,uniqueEdges,faces,indices,&sepNormal,&dmin);
  1564. bool sepA = findSeparatingAxis(convexShapes[shapeIndexA], convexShapes[shapeIndexB], posA, ornA, posB, ornB, vertices, uniqueEdges, faces, indices, vertices, uniqueEdges, faces, indices, sepNormal); //,&dmin);
  1565. hasSeparatingAxis = 4;
  1566. if (!sepA)
  1567. {
  1568. hasSeparatingAxis = 0;
  1569. }
  1570. else
  1571. {
  1572. bool sepB = findSeparatingAxis(convexShapes[shapeIndexB], convexShapes[shapeIndexA], posB, ornB, posA, ornA, vertices, uniqueEdges, faces, indices, vertices, uniqueEdges, faces, indices, sepNormal); //,&dmin);
  1573. if (!sepB)
  1574. {
  1575. hasSeparatingAxis = 0;
  1576. }
  1577. else //(!sepB)
  1578. {
  1579. bool sepEE = findSeparatingAxisEdgeEdge(&convexShapes[shapeIndexA], &convexShapes[shapeIndexB], posA, ornA, posB, ornB, DeltaC2, vertices, uniqueEdges, faces, indices, &sepNormal, &dmin);
  1580. if (sepEE)
  1581. {
  1582. gpuCompoundSepNormalsOut[i] = sepNormal; //fastNormalize4(sepNormal);
  1583. gpuHasCompoundSepNormalsOut[i] = 1;
  1584. } //sepEE
  1585. } //(!sepB)
  1586. } //(!sepA)
  1587. }
  1588. }
  1589. __kernel void clipCompoundsHullHullKernel(__global const b3Int4* gpuCompoundPairs,
  1590. __global const b3RigidBodyData* rigidBodies,
  1591. __global const b3Collidable* collidables,
  1592. __global const b3ConvexPolyhedronData* convexShapes,
  1593. __global const b3AlignedObjectArray<b3Float4>& vertices,
  1594. __global const b3AlignedObjectArray<b3Float4>& uniqueEdges,
  1595. __global const b3AlignedObjectArray<b3GpuFace>& faces,
  1596. __global const b3AlignedObjectArray<int>& indices,
  1597. __global const b3GpuChildShape* gpuChildShapes,
  1598. __global const b3AlignedObjectArray<b3Float4>& gpuCompoundSepNormalsOut,
  1599. __global const b3AlignedObjectArray<int>& gpuHasCompoundSepNormalsOut,
  1600. __global struct b3Contact4Data* globalContactsOut,
  1601. int* nGlobalContactsOut,
  1602. int numCompoundPairs, int maxContactCapacity, int i)
  1603. {
  1604. // int i = get_global_id(0);
  1605. int pairIndex = i;
  1606. float4 worldVertsB1[64];
  1607. float4 worldVertsB2[64];
  1608. int capacityWorldVerts = 64;
  1609. float4 localContactsOut[64];
  1610. int localContactCapacity = 64;
  1611. float minDist = -1e30f;
  1612. float maxDist = 0.0f;
  1613. if (i < numCompoundPairs)
  1614. {
  1615. if (gpuHasCompoundSepNormalsOut[i])
  1616. {
  1617. int bodyIndexA = gpuCompoundPairs[i].x;
  1618. int bodyIndexB = gpuCompoundPairs[i].y;
  1619. int childShapeIndexA = gpuCompoundPairs[i].z;
  1620. int childShapeIndexB = gpuCompoundPairs[i].w;
  1621. int collidableIndexA = -1;
  1622. int collidableIndexB = -1;
  1623. b3Quat ornA = rigidBodies[bodyIndexA].m_quat;
  1624. float4 posA = rigidBodies[bodyIndexA].m_pos;
  1625. b3Quat ornB = rigidBodies[bodyIndexB].m_quat;
  1626. float4 posB = rigidBodies[bodyIndexB].m_pos;
  1627. if (childShapeIndexA >= 0)
  1628. {
  1629. collidableIndexA = gpuChildShapes[childShapeIndexA].m_shapeIndex;
  1630. float4 childPosA = gpuChildShapes[childShapeIndexA].m_childPosition;
  1631. b3Quat childOrnA = gpuChildShapes[childShapeIndexA].m_childOrientation;
  1632. float4 newPosA = b3QuatRotate(ornA, childPosA) + posA;
  1633. b3Quat newOrnA = b3QuatMul(ornA, childOrnA);
  1634. posA = newPosA;
  1635. ornA = newOrnA;
  1636. }
  1637. else
  1638. {
  1639. collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;
  1640. }
  1641. if (childShapeIndexB >= 0)
  1642. {
  1643. collidableIndexB = gpuChildShapes[childShapeIndexB].m_shapeIndex;
  1644. float4 childPosB = gpuChildShapes[childShapeIndexB].m_childPosition;
  1645. b3Quat childOrnB = gpuChildShapes[childShapeIndexB].m_childOrientation;
  1646. float4 newPosB = b3QuatRotate(ornB, childPosB) + posB;
  1647. b3Quat newOrnB = b3QuatMul(ornB, childOrnB);
  1648. posB = newPosB;
  1649. ornB = newOrnB;
  1650. }
  1651. else
  1652. {
  1653. collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;
  1654. }
  1655. int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;
  1656. int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;
  1657. int numLocalContactsOut = clipHullAgainstHull(gpuCompoundSepNormalsOut[i],
  1658. convexShapes[shapeIndexA], convexShapes[shapeIndexB],
  1659. posA, ornA,
  1660. posB, ornB,
  1661. worldVertsB1, worldVertsB2, capacityWorldVerts,
  1662. minDist, maxDist,
  1663. vertices, faces, indices,
  1664. vertices, faces, indices,
  1665. localContactsOut, localContactCapacity);
  1666. if (numLocalContactsOut > 0)
  1667. {
  1668. float4 normal = -gpuCompoundSepNormalsOut[i];
  1669. int nPoints = numLocalContactsOut;
  1670. float4* pointsIn = localContactsOut;
  1671. b3Int4 contactIdx; // = {-1,-1,-1,-1};
  1672. contactIdx.s[0] = 0;
  1673. contactIdx.s[1] = 1;
  1674. contactIdx.s[2] = 2;
  1675. contactIdx.s[3] = 3;
  1676. int nReducedContacts = extractManifoldSequentialGlobal(pointsIn, nPoints, normal, &contactIdx);
  1677. int dstIdx;
  1678. dstIdx = b3AtomicInc(nGlobalContactsOut);
  1679. if ((dstIdx + nReducedContacts) < maxContactCapacity)
  1680. {
  1681. __global struct b3Contact4Data* c = globalContactsOut + dstIdx;
  1682. c->m_worldNormalOnB = -normal;
  1683. c->m_restituitionCoeffCmp = (0.f * 0xffff);
  1684. c->m_frictionCoeffCmp = (0.7f * 0xffff);
  1685. c->m_batchIdx = pairIndex;
  1686. int bodyA = gpuCompoundPairs[pairIndex].x;
  1687. int bodyB = gpuCompoundPairs[pairIndex].y;
  1688. c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass == 0 ? -bodyA : bodyA;
  1689. c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass == 0 ? -bodyB : bodyB;
  1690. c->m_childIndexA = childShapeIndexA;
  1691. c->m_childIndexB = childShapeIndexB;
  1692. for (int i = 0; i < nReducedContacts; i++)
  1693. {
  1694. c->m_worldPosB[i] = pointsIn[contactIdx.s[i]];
  1695. }
  1696. b3Contact4Data_setNumPoints(c, nReducedContacts);
  1697. }
  1698. } // if (numContactsOut>0)
  1699. } // if (gpuHasCompoundSepNormalsOut[i])
  1700. } // if (i<numCompoundPairs)
  1701. }
  1702. void computeContactCompoundCompound(int pairIndex,
  1703. int bodyIndexA, int bodyIndexB,
  1704. int collidableIndexA, int collidableIndexB,
  1705. const b3RigidBodyData* rigidBodies,
  1706. const b3Collidable* collidables,
  1707. const b3ConvexPolyhedronData* convexShapes,
  1708. const b3GpuChildShape* cpuChildShapes,
  1709. const b3AlignedObjectArray<b3Aabb>& hostAabbsWorldSpace,
  1710. const b3AlignedObjectArray<b3Aabb>& hostAabbsLocalSpace,
  1711. const b3AlignedObjectArray<b3Vector3>& convexVertices,
  1712. const b3AlignedObjectArray<b3Vector3>& hostUniqueEdges,
  1713. const b3AlignedObjectArray<int>& convexIndices,
  1714. const b3AlignedObjectArray<b3GpuFace>& faces,
  1715. b3Contact4* globalContactsOut,
  1716. int& nGlobalContactsOut,
  1717. int maxContactCapacity,
  1718. b3AlignedObjectArray<b3QuantizedBvhNode>& treeNodesCPU,
  1719. b3AlignedObjectArray<b3BvhSubtreeInfo>& subTreesCPU,
  1720. b3AlignedObjectArray<b3BvhInfo>& bvhInfoCPU)
  1721. {
  1722. int shapeTypeB = collidables[collidableIndexB].m_shapeType;
  1723. b3Assert(shapeTypeB == SHAPE_COMPOUND_OF_CONVEX_HULLS);
  1724. b3AlignedObjectArray<b3Int4> cpuCompoundPairsOut;
  1725. int numCompoundPairsOut = 0;
  1726. int maxNumCompoundPairsCapacity = 8192; //1024;
  1727. cpuCompoundPairsOut.resize(maxNumCompoundPairsCapacity);
  1728. // work-in-progress
  1729. findCompoundPairsKernel(
  1730. pairIndex,
  1731. bodyIndexA, bodyIndexB,
  1732. collidableIndexA, collidableIndexB,
  1733. rigidBodies,
  1734. collidables,
  1735. convexShapes,
  1736. convexVertices,
  1737. hostAabbsWorldSpace,
  1738. hostAabbsLocalSpace,
  1739. cpuChildShapes,
  1740. &cpuCompoundPairsOut[0],
  1741. &numCompoundPairsOut,
  1742. maxNumCompoundPairsCapacity,
  1743. treeNodesCPU,
  1744. subTreesCPU,
  1745. bvhInfoCPU);
  1746. printf("maxNumAabbChecks=%d\n", maxNumAabbChecks);
  1747. if (numCompoundPairsOut > maxNumCompoundPairsCapacity)
  1748. {
  1749. b3Error("numCompoundPairsOut exceeded maxNumCompoundPairsCapacity (%d)\n", maxNumCompoundPairsCapacity);
  1750. numCompoundPairsOut = maxNumCompoundPairsCapacity;
  1751. }
  1752. b3AlignedObjectArray<b3Float4> cpuCompoundSepNormalsOut;
  1753. b3AlignedObjectArray<int> cpuHasCompoundSepNormalsOut;
  1754. cpuCompoundSepNormalsOut.resize(numCompoundPairsOut);
  1755. cpuHasCompoundSepNormalsOut.resize(numCompoundPairsOut);
  1756. for (int i = 0; i < numCompoundPairsOut; i++)
  1757. {
  1758. processCompoundPairsKernel(&cpuCompoundPairsOut[0], rigidBodies, collidables, convexShapes, convexVertices, hostUniqueEdges, faces, convexIndices, 0, cpuChildShapes,
  1759. cpuCompoundSepNormalsOut, cpuHasCompoundSepNormalsOut, numCompoundPairsOut, i);
  1760. }
  1761. for (int i = 0; i < numCompoundPairsOut; i++)
  1762. {
  1763. clipCompoundsHullHullKernel(&cpuCompoundPairsOut[0], rigidBodies, collidables, convexShapes, convexVertices, hostUniqueEdges, faces, convexIndices, cpuChildShapes,
  1764. cpuCompoundSepNormalsOut, cpuHasCompoundSepNormalsOut, globalContactsOut, &nGlobalContactsOut, numCompoundPairsOut, maxContactCapacity, i);
  1765. }
  1766. /*
  1767. int childColIndexA = gpuChildShapes[childShapeIndexA].m_shapeIndex;
  1768. float4 posA = rigidBodies[bodyIndexA].m_pos;
  1769. b3Quat ornA = rigidBodies[bodyIndexA].m_quat;
  1770. float4 childPosA = gpuChildShapes[childShapeIndexA].m_childPosition;
  1771. b3Quat childOrnA = gpuChildShapes[childShapeIndexA].m_childOrientation;
  1772. float4 newPosA = b3QuatRotate(ornA,childPosA)+posA;
  1773. b3Quat newOrnA = b3QuatMul(ornA,childOrnA);
  1774. int shapeIndexA = collidables[childColIndexA].m_shapeIndex;
  1775. bool foundSepAxis = findSeparatingAxis(hullA,hullB,
  1776. posA,
  1777. ornA,
  1778. posB,
  1779. ornB,
  1780. convexVertices,uniqueEdges,faces,convexIndices,
  1781. convexVertices,uniqueEdges,faces,convexIndices,
  1782. sepNormalWorldSpace
  1783. );
  1784. */
  1785. /*
  1786. if (foundSepAxis)
  1787. {
  1788. contactIndex = clipHullHullSingle(
  1789. bodyIndexA, bodyIndexB,
  1790. posA,ornA,
  1791. posB,ornB,
  1792. collidableIndexA, collidableIndexB,
  1793. &rigidBodies,
  1794. &globalContactsOut,
  1795. nGlobalContactsOut,
  1796. convexShapes,
  1797. convexShapes,
  1798. convexVertices,
  1799. uniqueEdges,
  1800. faces,
  1801. convexIndices,
  1802. convexVertices,
  1803. uniqueEdges,
  1804. faces,
  1805. convexIndices,
  1806. collidables,
  1807. collidables,
  1808. sepNormalWorldSpace,
  1809. maxContactCapacity);
  1810. }
  1811. */
  1812. // return contactIndex;
  1813. /*
  1814. int numChildrenB = collidables[collidableIndexB].m_numChildShapes;
  1815. for (int c=0;c<numChildrenB;c++)
  1816. {
  1817. int childShapeIndexB = collidables[collidableIndexB].m_shapeIndex+c;
  1818. int childColIndexB = cpuChildShapes[childShapeIndexB].m_shapeIndex;
  1819. float4 rootPosB = rigidBodies[bodyIndexB].m_pos;
  1820. b3Quaternion rootOrnB = rigidBodies[bodyIndexB].m_quat;
  1821. b3Vector3 childPosB = cpuChildShapes[childShapeIndexB].m_childPosition;
  1822. b3Quaternion childOrnB = cpuChildShapes[childShapeIndexB].m_childOrientation;
  1823. float4 posB = b3QuatRotate(rootOrnB,childPosB)+rootPosB;
  1824. b3Quaternion ornB = b3QuatMul(rootOrnB,childOrnB);//b3QuatMul(ornB,childOrnB);
  1825. int shapeIndexB = collidables[childColIndexB].m_shapeIndex;
  1826. const b3ConvexPolyhedronData* hullB = &convexShapes[shapeIndexB];
  1827. }
  1828. */
  1829. }
  1830. void computeContactPlaneCompound(int pairIndex,
  1831. int bodyIndexA, int bodyIndexB,
  1832. int collidableIndexA, int collidableIndexB,
  1833. const b3RigidBodyData* rigidBodies,
  1834. const b3Collidable* collidables,
  1835. const b3ConvexPolyhedronData* convexShapes,
  1836. const b3GpuChildShape* cpuChildShapes,
  1837. const b3Vector3* convexVertices,
  1838. const int* convexIndices,
  1839. const b3GpuFace* faces,
  1840. b3Contact4* globalContactsOut,
  1841. int& nGlobalContactsOut,
  1842. int maxContactCapacity)
  1843. {
  1844. int shapeTypeB = collidables[collidableIndexB].m_shapeType;
  1845. b3Assert(shapeTypeB == SHAPE_COMPOUND_OF_CONVEX_HULLS);
  1846. int numChildrenB = collidables[collidableIndexB].m_numChildShapes;
  1847. for (int c = 0; c < numChildrenB; c++)
  1848. {
  1849. int childShapeIndexB = collidables[collidableIndexB].m_shapeIndex + c;
  1850. int childColIndexB = cpuChildShapes[childShapeIndexB].m_shapeIndex;
  1851. float4 rootPosB = rigidBodies[bodyIndexB].m_pos;
  1852. b3Quaternion rootOrnB = rigidBodies[bodyIndexB].m_quat;
  1853. b3Vector3 childPosB = cpuChildShapes[childShapeIndexB].m_childPosition;
  1854. b3Quaternion childOrnB = cpuChildShapes[childShapeIndexB].m_childOrientation;
  1855. float4 posB = b3QuatRotate(rootOrnB, childPosB) + rootPosB;
  1856. b3Quaternion ornB = rootOrnB * childOrnB; //b3QuatMul(ornB,childOrnB);
  1857. int shapeIndexB = collidables[childColIndexB].m_shapeIndex;
  1858. const b3ConvexPolyhedronData* hullB = &convexShapes[shapeIndexB];
  1859. b3Vector3 posA = rigidBodies[bodyIndexA].m_pos;
  1860. b3Quaternion ornA = rigidBodies[bodyIndexA].m_quat;
  1861. // int numContactsOut = 0;
  1862. // int numWorldVertsB1= 0;
  1863. b3Vector3 planeEq = faces[collidables[collidableIndexA].m_shapeIndex].m_plane;
  1864. b3Vector3 planeNormal = b3MakeVector3(planeEq.x, planeEq.y, planeEq.z);
  1865. b3Vector3 planeNormalWorld = b3QuatRotate(ornA, planeNormal);
  1866. float planeConstant = planeEq.w;
  1867. b3Transform convexWorldTransform;
  1868. convexWorldTransform.setIdentity();
  1869. convexWorldTransform.setOrigin(posB);
  1870. convexWorldTransform.setRotation(ornB);
  1871. b3Transform planeTransform;
  1872. planeTransform.setIdentity();
  1873. planeTransform.setOrigin(posA);
  1874. planeTransform.setRotation(ornA);
  1875. b3Transform planeInConvex;
  1876. planeInConvex = convexWorldTransform.inverse() * planeTransform;
  1877. b3Transform convexInPlane;
  1878. convexInPlane = planeTransform.inverse() * convexWorldTransform;
  1879. b3Vector3 planeNormalInConvex = planeInConvex.getBasis() * -planeNormal;
  1880. float maxDot = -1e30;
  1881. int hitVertex = -1;
  1882. b3Vector3 hitVtx;
  1883. #define MAX_PLANE_CONVEX_POINTS 64
  1884. b3Vector3 contactPoints[MAX_PLANE_CONVEX_POINTS];
  1885. int numPoints = 0;
  1886. b3Int4 contactIdx;
  1887. contactIdx.s[0] = 0;
  1888. contactIdx.s[1] = 1;
  1889. contactIdx.s[2] = 2;
  1890. contactIdx.s[3] = 3;
  1891. for (int i = 0; i < hullB->m_numVertices; i++)
  1892. {
  1893. b3Vector3 vtx = convexVertices[hullB->m_vertexOffset + i];
  1894. float curDot = vtx.dot(planeNormalInConvex);
  1895. if (curDot > maxDot)
  1896. {
  1897. hitVertex = i;
  1898. maxDot = curDot;
  1899. hitVtx = vtx;
  1900. //make sure the deepest points is always included
  1901. if (numPoints == MAX_PLANE_CONVEX_POINTS)
  1902. numPoints--;
  1903. }
  1904. if (numPoints < MAX_PLANE_CONVEX_POINTS)
  1905. {
  1906. b3Vector3 vtxWorld = convexWorldTransform * vtx;
  1907. b3Vector3 vtxInPlane = planeTransform.inverse() * vtxWorld;
  1908. float dist = planeNormal.dot(vtxInPlane) - planeConstant;
  1909. if (dist < 0.f)
  1910. {
  1911. vtxWorld.w = dist;
  1912. contactPoints[numPoints] = vtxWorld;
  1913. numPoints++;
  1914. }
  1915. }
  1916. }
  1917. int numReducedPoints = 0;
  1918. numReducedPoints = numPoints;
  1919. if (numPoints > 4)
  1920. {
  1921. numReducedPoints = extractManifoldSequentialGlobal(contactPoints, numPoints, planeNormalInConvex, &contactIdx);
  1922. }
  1923. int dstIdx;
  1924. // dstIdx = nGlobalContactsOut++;//AppendInc( nGlobalContactsOut, dstIdx );
  1925. if (numReducedPoints > 0)
  1926. {
  1927. if (nGlobalContactsOut < maxContactCapacity)
  1928. {
  1929. dstIdx = nGlobalContactsOut;
  1930. nGlobalContactsOut++;
  1931. b3Contact4* c = &globalContactsOut[dstIdx];
  1932. c->m_worldNormalOnB = -planeNormalWorld;
  1933. c->setFrictionCoeff(0.7);
  1934. c->setRestituitionCoeff(0.f);
  1935. c->m_batchIdx = pairIndex;
  1936. c->m_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass == 0 ? -bodyIndexA : bodyIndexA;
  1937. c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass == 0 ? -bodyIndexB : bodyIndexB;
  1938. for (int i = 0; i < numReducedPoints; i++)
  1939. {
  1940. b3Vector3 pOnB1 = contactPoints[contactIdx.s[i]];
  1941. c->m_worldPosB[i] = pOnB1;
  1942. }
  1943. c->m_worldNormalOnB.w = (b3Scalar)numReducedPoints;
  1944. } //if (dstIdx < numPairs)
  1945. }
  1946. }
  1947. }
  1948. void computeContactSphereConvex(int pairIndex,
  1949. int bodyIndexA, int bodyIndexB,
  1950. int collidableIndexA, int collidableIndexB,
  1951. const b3RigidBodyData* rigidBodies,
  1952. const b3Collidable* collidables,
  1953. const b3ConvexPolyhedronData* convexShapes,
  1954. const b3Vector3* convexVertices,
  1955. const int* convexIndices,
  1956. const b3GpuFace* faces,
  1957. b3Contact4* globalContactsOut,
  1958. int& nGlobalContactsOut,
  1959. int maxContactCapacity)
  1960. {
  1961. float radius = collidables[collidableIndexA].m_radius;
  1962. float4 spherePos1 = rigidBodies[bodyIndexA].m_pos;
  1963. b3Quaternion sphereOrn = rigidBodies[bodyIndexA].m_quat;
  1964. float4 pos = rigidBodies[bodyIndexB].m_pos;
  1965. b3Quaternion quat = rigidBodies[bodyIndexB].m_quat;
  1966. b3Transform tr;
  1967. tr.setIdentity();
  1968. tr.setOrigin(pos);
  1969. tr.setRotation(quat);
  1970. b3Transform trInv = tr.inverse();
  1971. float4 spherePos = trInv(spherePos1);
  1972. int collidableIndex = rigidBodies[bodyIndexB].m_collidableIdx;
  1973. int shapeIndex = collidables[collidableIndex].m_shapeIndex;
  1974. int numFaces = convexShapes[shapeIndex].m_numFaces;
  1975. float4 closestPnt = b3MakeVector3(0, 0, 0, 0);
  1976. // float4 hitNormalWorld = b3MakeVector3(0, 0, 0, 0);
  1977. float minDist = -1000000.f; // TODO: What is the largest/smallest float?
  1978. bool bCollide = true;
  1979. int region = -1;
  1980. float4 localHitNormal;
  1981. for (int f = 0; f < numFaces; f++)
  1982. {
  1983. b3GpuFace face = faces[convexShapes[shapeIndex].m_faceOffset + f];
  1984. float4 planeEqn;
  1985. float4 localPlaneNormal = b3MakeVector3(face.m_plane.x, face.m_plane.y, face.m_plane.z, 0.f);
  1986. float4 n1 = localPlaneNormal; //quatRotate(quat,localPlaneNormal);
  1987. planeEqn = n1;
  1988. planeEqn[3] = face.m_plane.w;
  1989. float4 pntReturn;
  1990. float dist = signedDistanceFromPointToPlane(spherePos, planeEqn, &pntReturn);
  1991. if (dist > radius)
  1992. {
  1993. bCollide = false;
  1994. break;
  1995. }
  1996. if (dist > 0)
  1997. {
  1998. //might hit an edge or vertex
  1999. b3Vector3 out;
  2000. bool isInPoly = IsPointInPolygon(spherePos,
  2001. &face,
  2002. &convexVertices[convexShapes[shapeIndex].m_vertexOffset],
  2003. convexIndices,
  2004. &out);
  2005. if (isInPoly)
  2006. {
  2007. if (dist > minDist)
  2008. {
  2009. minDist = dist;
  2010. closestPnt = pntReturn;
  2011. localHitNormal = planeEqn;
  2012. region = 1;
  2013. }
  2014. }
  2015. else
  2016. {
  2017. b3Vector3 tmp = spherePos - out;
  2018. b3Scalar l2 = tmp.length2();
  2019. if (l2 < radius * radius)
  2020. {
  2021. dist = b3Sqrt(l2);
  2022. if (dist > minDist)
  2023. {
  2024. minDist = dist;
  2025. closestPnt = out;
  2026. localHitNormal = tmp / dist;
  2027. region = 2;
  2028. }
  2029. }
  2030. else
  2031. {
  2032. bCollide = false;
  2033. break;
  2034. }
  2035. }
  2036. }
  2037. else
  2038. {
  2039. if (dist > minDist)
  2040. {
  2041. minDist = dist;
  2042. closestPnt = pntReturn;
  2043. localHitNormal = planeEqn;
  2044. region = 3;
  2045. }
  2046. }
  2047. }
  2048. static int numChecks = 0;
  2049. numChecks++;
  2050. if (bCollide && minDist > -10000)
  2051. {
  2052. float4 normalOnSurfaceB1 = tr.getBasis() * localHitNormal; //-hitNormalWorld;
  2053. float4 pOnB1 = tr(closestPnt);
  2054. //printf("dist ,%f,",minDist);
  2055. float actualDepth = minDist - radius;
  2056. if (actualDepth < 0)
  2057. {
  2058. //printf("actualDepth = ,%f,", actualDepth);
  2059. //printf("normalOnSurfaceB1 = ,%f,%f,%f,", normalOnSurfaceB1.x,normalOnSurfaceB1.y,normalOnSurfaceB1.z);
  2060. //printf("region=,%d,\n", region);
  2061. pOnB1[3] = actualDepth;
  2062. int dstIdx;
  2063. // dstIdx = nGlobalContactsOut++;//AppendInc( nGlobalContactsOut, dstIdx );
  2064. if (nGlobalContactsOut < maxContactCapacity)
  2065. {
  2066. dstIdx = nGlobalContactsOut;
  2067. nGlobalContactsOut++;
  2068. b3Contact4* c = &globalContactsOut[dstIdx];
  2069. c->m_worldNormalOnB = normalOnSurfaceB1;
  2070. c->setFrictionCoeff(0.7);
  2071. c->setRestituitionCoeff(0.f);
  2072. c->m_batchIdx = pairIndex;
  2073. c->m_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass == 0 ? -bodyIndexA : bodyIndexA;
  2074. c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass == 0 ? -bodyIndexB : bodyIndexB;
  2075. c->m_worldPosB[0] = pOnB1;
  2076. int numPoints = 1;
  2077. c->m_worldNormalOnB.w = (b3Scalar)numPoints;
  2078. } //if (dstIdx < numPairs)
  2079. }
  2080. } //if (hasCollision)
  2081. }
  2082. int computeContactConvexConvex2(
  2083. int pairIndex,
  2084. int bodyIndexA, int bodyIndexB,
  2085. int collidableIndexA, int collidableIndexB,
  2086. const b3AlignedObjectArray<b3RigidBodyData>& rigidBodies,
  2087. const b3AlignedObjectArray<b3Collidable>& collidables,
  2088. const b3AlignedObjectArray<b3ConvexPolyhedronData>& convexShapes,
  2089. const b3AlignedObjectArray<b3Vector3>& convexVertices,
  2090. const b3AlignedObjectArray<b3Vector3>& uniqueEdges,
  2091. const b3AlignedObjectArray<int>& convexIndices,
  2092. const b3AlignedObjectArray<b3GpuFace>& faces,
  2093. b3AlignedObjectArray<b3Contact4>& globalContactsOut,
  2094. int& nGlobalContactsOut,
  2095. int maxContactCapacity,
  2096. const b3AlignedObjectArray<b3Contact4>& oldContacts)
  2097. {
  2098. int contactIndex = -1;
  2099. b3Vector3 posA = rigidBodies[bodyIndexA].m_pos;
  2100. b3Quaternion ornA = rigidBodies[bodyIndexA].m_quat;
  2101. b3Vector3 posB = rigidBodies[bodyIndexB].m_pos;
  2102. b3Quaternion ornB = rigidBodies[bodyIndexB].m_quat;
  2103. b3ConvexPolyhedronData hullA, hullB;
  2104. b3Vector3 sepNormalWorldSpace;
  2105. b3Collidable colA = collidables[collidableIndexA];
  2106. hullA = convexShapes[colA.m_shapeIndex];
  2107. //printf("numvertsA = %d\n",hullA.m_numVertices);
  2108. b3Collidable colB = collidables[collidableIndexB];
  2109. hullB = convexShapes[colB.m_shapeIndex];
  2110. //printf("numvertsB = %d\n",hullB.m_numVertices);
  2111. // int contactCapacity = MAX_VERTS;
  2112. //int numContactsOut=0;
  2113. #ifdef _WIN32
  2114. b3Assert(_finite(rigidBodies[bodyIndexA].m_pos.x));
  2115. b3Assert(_finite(rigidBodies[bodyIndexB].m_pos.x));
  2116. #endif
  2117. bool foundSepAxis = findSeparatingAxis(hullA, hullB,
  2118. posA,
  2119. ornA,
  2120. posB,
  2121. ornB,
  2122. convexVertices, uniqueEdges, faces, convexIndices,
  2123. convexVertices, uniqueEdges, faces, convexIndices,
  2124. sepNormalWorldSpace);
  2125. if (foundSepAxis)
  2126. {
  2127. contactIndex = clipHullHullSingle(
  2128. bodyIndexA, bodyIndexB,
  2129. posA, ornA,
  2130. posB, ornB,
  2131. collidableIndexA, collidableIndexB,
  2132. &rigidBodies,
  2133. &globalContactsOut,
  2134. nGlobalContactsOut,
  2135. convexShapes,
  2136. convexShapes,
  2137. convexVertices,
  2138. uniqueEdges,
  2139. faces,
  2140. convexIndices,
  2141. convexVertices,
  2142. uniqueEdges,
  2143. faces,
  2144. convexIndices,
  2145. collidables,
  2146. collidables,
  2147. sepNormalWorldSpace,
  2148. maxContactCapacity);
  2149. }
  2150. return contactIndex;
  2151. }
  2152. void GpuSatCollision::computeConvexConvexContactsGPUSAT(b3OpenCLArray<b3Int4>* pairs, int nPairs,
  2153. const b3OpenCLArray<b3RigidBodyData>* bodyBuf,
  2154. b3OpenCLArray<b3Contact4>* contactOut, int& nContacts,
  2155. const b3OpenCLArray<b3Contact4>* oldContacts,
  2156. int maxContactCapacity,
  2157. int compoundPairCapacity,
  2158. const b3OpenCLArray<b3ConvexPolyhedronData>& convexData,
  2159. const b3OpenCLArray<b3Vector3>& gpuVertices,
  2160. const b3OpenCLArray<b3Vector3>& gpuUniqueEdges,
  2161. const b3OpenCLArray<b3GpuFace>& gpuFaces,
  2162. const b3OpenCLArray<int>& gpuIndices,
  2163. const b3OpenCLArray<b3Collidable>& gpuCollidables,
  2164. const b3OpenCLArray<b3GpuChildShape>& gpuChildShapes,
  2165. const b3OpenCLArray<b3Aabb>& clAabbsWorldSpace,
  2166. const b3OpenCLArray<b3Aabb>& clAabbsLocalSpace,
  2167. b3OpenCLArray<b3Vector3>& worldVertsB1GPU,
  2168. b3OpenCLArray<b3Int4>& clippingFacesOutGPU,
  2169. b3OpenCLArray<b3Vector3>& worldNormalsAGPU,
  2170. b3OpenCLArray<b3Vector3>& worldVertsA1GPU,
  2171. b3OpenCLArray<b3Vector3>& worldVertsB2GPU,
  2172. b3AlignedObjectArray<class b3OptimizedBvh*>& bvhDataUnused,
  2173. b3OpenCLArray<b3QuantizedBvhNode>* treeNodesGPU,
  2174. b3OpenCLArray<b3BvhSubtreeInfo>* subTreesGPU,
  2175. b3OpenCLArray<b3BvhInfo>* bvhInfo,
  2176. int numObjects,
  2177. int maxTriConvexPairCapacity,
  2178. b3OpenCLArray<b3Int4>& triangleConvexPairsOut,
  2179. int& numTriConvexPairsOut)
  2180. {
  2181. myframecount++;
  2182. if (!nPairs)
  2183. return;
  2184. #ifdef CHECK_ON_HOST
  2185. b3AlignedObjectArray<b3QuantizedBvhNode> treeNodesCPU;
  2186. treeNodesGPU->copyToHost(treeNodesCPU);
  2187. b3AlignedObjectArray<b3BvhSubtreeInfo> subTreesCPU;
  2188. subTreesGPU->copyToHost(subTreesCPU);
  2189. b3AlignedObjectArray<b3BvhInfo> bvhInfoCPU;
  2190. bvhInfo->copyToHost(bvhInfoCPU);
  2191. b3AlignedObjectArray<b3Aabb> hostAabbsWorldSpace;
  2192. clAabbsWorldSpace.copyToHost(hostAabbsWorldSpace);
  2193. b3AlignedObjectArray<b3Aabb> hostAabbsLocalSpace;
  2194. clAabbsLocalSpace.copyToHost(hostAabbsLocalSpace);
  2195. b3AlignedObjectArray<b3Int4> hostPairs;
  2196. pairs->copyToHost(hostPairs);
  2197. b3AlignedObjectArray<b3RigidBodyData> hostBodyBuf;
  2198. bodyBuf->copyToHost(hostBodyBuf);
  2199. b3AlignedObjectArray<b3ConvexPolyhedronData> hostConvexData;
  2200. convexData.copyToHost(hostConvexData);
  2201. b3AlignedObjectArray<b3Vector3> hostVertices;
  2202. gpuVertices.copyToHost(hostVertices);
  2203. b3AlignedObjectArray<b3Vector3> hostUniqueEdges;
  2204. gpuUniqueEdges.copyToHost(hostUniqueEdges);
  2205. b3AlignedObjectArray<b3GpuFace> hostFaces;
  2206. gpuFaces.copyToHost(hostFaces);
  2207. b3AlignedObjectArray<int> hostIndices;
  2208. gpuIndices.copyToHost(hostIndices);
  2209. b3AlignedObjectArray<b3Collidable> hostCollidables;
  2210. gpuCollidables.copyToHost(hostCollidables);
  2211. b3AlignedObjectArray<b3GpuChildShape> cpuChildShapes;
  2212. gpuChildShapes.copyToHost(cpuChildShapes);
  2213. b3AlignedObjectArray<b3Int4> hostTriangleConvexPairs;
  2214. b3AlignedObjectArray<b3Contact4> hostContacts;
  2215. if (nContacts)
  2216. {
  2217. contactOut->copyToHost(hostContacts);
  2218. }
  2219. b3AlignedObjectArray<b3Contact4> oldHostContacts;
  2220. if (oldContacts->size())
  2221. {
  2222. oldContacts->copyToHost(oldHostContacts);
  2223. }
  2224. hostContacts.resize(maxContactCapacity);
  2225. for (int i = 0; i < nPairs; i++)
  2226. {
  2227. int bodyIndexA = hostPairs[i].x;
  2228. int bodyIndexB = hostPairs[i].y;
  2229. int collidableIndexA = hostBodyBuf[bodyIndexA].m_collidableIdx;
  2230. int collidableIndexB = hostBodyBuf[bodyIndexB].m_collidableIdx;
  2231. if (hostCollidables[collidableIndexA].m_shapeType == SHAPE_SPHERE &&
  2232. hostCollidables[collidableIndexB].m_shapeType == SHAPE_CONVEX_HULL)
  2233. {
  2234. computeContactSphereConvex(i, bodyIndexA, bodyIndexB, collidableIndexA, collidableIndexB, &hostBodyBuf[0],
  2235. &hostCollidables[0], &hostConvexData[0], &hostVertices[0], &hostIndices[0], &hostFaces[0], &hostContacts[0], nContacts, maxContactCapacity);
  2236. }
  2237. if (hostCollidables[collidableIndexA].m_shapeType == SHAPE_CONVEX_HULL &&
  2238. hostCollidables[collidableIndexB].m_shapeType == SHAPE_SPHERE)
  2239. {
  2240. computeContactSphereConvex(i, bodyIndexB, bodyIndexA, collidableIndexB, collidableIndexA, &hostBodyBuf[0],
  2241. &hostCollidables[0], &hostConvexData[0], &hostVertices[0], &hostIndices[0], &hostFaces[0], &hostContacts[0], nContacts, maxContactCapacity);
  2242. //printf("convex-sphere\n");
  2243. }
  2244. if (hostCollidables[collidableIndexA].m_shapeType == SHAPE_CONVEX_HULL &&
  2245. hostCollidables[collidableIndexB].m_shapeType == SHAPE_PLANE)
  2246. {
  2247. computeContactPlaneConvex(i, bodyIndexB, bodyIndexA, collidableIndexB, collidableIndexA, &hostBodyBuf[0],
  2248. &hostCollidables[0], &hostConvexData[0], &hostVertices[0], &hostIndices[0], &hostFaces[0], &hostContacts[0], nContacts, maxContactCapacity);
  2249. // printf("convex-plane\n");
  2250. }
  2251. if (hostCollidables[collidableIndexA].m_shapeType == SHAPE_PLANE &&
  2252. hostCollidables[collidableIndexB].m_shapeType == SHAPE_CONVEX_HULL)
  2253. {
  2254. computeContactPlaneConvex(i, bodyIndexA, bodyIndexB, collidableIndexA, collidableIndexB, &hostBodyBuf[0],
  2255. &hostCollidables[0], &hostConvexData[0], &hostVertices[0], &hostIndices[0], &hostFaces[0], &hostContacts[0], nContacts, maxContactCapacity);
  2256. // printf("plane-convex\n");
  2257. }
  2258. if (hostCollidables[collidableIndexA].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS &&
  2259. hostCollidables[collidableIndexB].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS)
  2260. {
  2261. computeContactCompoundCompound(i, bodyIndexB, bodyIndexA, collidableIndexB, collidableIndexA, &hostBodyBuf[0],
  2262. &hostCollidables[0], &hostConvexData[0], &cpuChildShapes[0], hostAabbsWorldSpace, hostAabbsLocalSpace, hostVertices, hostUniqueEdges, hostIndices, hostFaces, &hostContacts[0],
  2263. nContacts, maxContactCapacity, treeNodesCPU, subTreesCPU, bvhInfoCPU);
  2264. // printf("convex-plane\n");
  2265. }
  2266. if (hostCollidables[collidableIndexA].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS &&
  2267. hostCollidables[collidableIndexB].m_shapeType == SHAPE_PLANE)
  2268. {
  2269. computeContactPlaneCompound(i, bodyIndexB, bodyIndexA, collidableIndexB, collidableIndexA, &hostBodyBuf[0],
  2270. &hostCollidables[0], &hostConvexData[0], &cpuChildShapes[0], &hostVertices[0], &hostIndices[0], &hostFaces[0], &hostContacts[0], nContacts, maxContactCapacity);
  2271. // printf("convex-plane\n");
  2272. }
  2273. if (hostCollidables[collidableIndexA].m_shapeType == SHAPE_PLANE &&
  2274. hostCollidables[collidableIndexB].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS)
  2275. {
  2276. computeContactPlaneCompound(i, bodyIndexA, bodyIndexB, collidableIndexA, collidableIndexB, &hostBodyBuf[0],
  2277. &hostCollidables[0], &hostConvexData[0], &cpuChildShapes[0], &hostVertices[0], &hostIndices[0], &hostFaces[0], &hostContacts[0], nContacts, maxContactCapacity);
  2278. // printf("plane-convex\n");
  2279. }
  2280. if (hostCollidables[collidableIndexA].m_shapeType == SHAPE_CONVEX_HULL &&
  2281. hostCollidables[collidableIndexB].m_shapeType == SHAPE_CONVEX_HULL)
  2282. {
  2283. //printf("hostPairs[i].z=%d\n",hostPairs[i].z);
  2284. int contactIndex = computeContactConvexConvex2(i, bodyIndexA, bodyIndexB, collidableIndexA, collidableIndexB, hostBodyBuf, hostCollidables, hostConvexData, hostVertices, hostUniqueEdges, hostIndices, hostFaces, hostContacts, nContacts, maxContactCapacity, oldHostContacts);
  2285. //int contactIndex = computeContactConvexConvex(hostPairs,i,bodyIndexA,bodyIndexB,collidableIndexA,collidableIndexB,hostBodyBuf,hostCollidables,hostConvexData,hostVertices,hostUniqueEdges,hostIndices,hostFaces,hostContacts,nContacts,maxContactCapacity,oldHostContacts);
  2286. if (contactIndex >= 0)
  2287. {
  2288. // printf("convex convex contactIndex = %d\n",contactIndex);
  2289. hostPairs[i].z = contactIndex;
  2290. }
  2291. // printf("plane-convex\n");
  2292. }
  2293. }
  2294. if (hostPairs.size())
  2295. {
  2296. pairs->copyFromHost(hostPairs);
  2297. }
  2298. hostContacts.resize(nContacts);
  2299. if (nContacts)
  2300. {
  2301. contactOut->copyFromHost(hostContacts);
  2302. }
  2303. else
  2304. {
  2305. contactOut->resize(0);
  2306. }
  2307. m_totalContactsOut.copyFromHostPointer(&nContacts, 1, 0, true);
  2308. //printf("(HOST) nContacts = %d\n",nContacts);
  2309. #else
  2310. {
  2311. if (nPairs)
  2312. {
  2313. m_totalContactsOut.copyFromHostPointer(&nContacts, 1, 0, true);
  2314. B3_PROFILE("primitiveContactsKernel");
  2315. b3BufferInfoCL bInfo[] = {
  2316. b3BufferInfoCL(pairs->getBufferCL(), true),
  2317. b3BufferInfoCL(bodyBuf->getBufferCL(), true),
  2318. b3BufferInfoCL(gpuCollidables.getBufferCL(), true),
  2319. b3BufferInfoCL(convexData.getBufferCL(), true),
  2320. b3BufferInfoCL(gpuVertices.getBufferCL(), true),
  2321. b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true),
  2322. b3BufferInfoCL(gpuFaces.getBufferCL(), true),
  2323. b3BufferInfoCL(gpuIndices.getBufferCL(), true),
  2324. b3BufferInfoCL(contactOut->getBufferCL()),
  2325. b3BufferInfoCL(m_totalContactsOut.getBufferCL())};
  2326. b3LauncherCL launcher(m_queue, m_primitiveContactsKernel, "m_primitiveContactsKernel");
  2327. launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
  2328. launcher.setConst(nPairs);
  2329. launcher.setConst(maxContactCapacity);
  2330. int num = nPairs;
  2331. launcher.launch1D(num);
  2332. clFinish(m_queue);
  2333. nContacts = m_totalContactsOut.at(0);
  2334. contactOut->resize(nContacts);
  2335. }
  2336. }
  2337. #endif //CHECK_ON_HOST
  2338. B3_PROFILE("computeConvexConvexContactsGPUSAT");
  2339. // printf("nContacts = %d\n",nContacts);
  2340. m_sepNormals.resize(nPairs);
  2341. m_hasSeparatingNormals.resize(nPairs);
  2342. int concaveCapacity = maxTriConvexPairCapacity;
  2343. m_concaveSepNormals.resize(concaveCapacity);
  2344. m_concaveHasSeparatingNormals.resize(concaveCapacity);
  2345. m_numConcavePairsOut.resize(0);
  2346. m_numConcavePairsOut.push_back(0);
  2347. m_gpuCompoundPairs.resize(compoundPairCapacity);
  2348. m_gpuCompoundSepNormals.resize(compoundPairCapacity);
  2349. m_gpuHasCompoundSepNormals.resize(compoundPairCapacity);
  2350. m_numCompoundPairsOut.resize(0);
  2351. m_numCompoundPairsOut.push_back(0);
  2352. int numCompoundPairs = 0;
  2353. int numConcavePairs = 0;
  2354. {
  2355. clFinish(m_queue);
  2356. if (findSeparatingAxisOnGpu)
  2357. {
  2358. m_dmins.resize(nPairs);
  2359. if (splitSearchSepAxisConvex)
  2360. {
  2361. if (useMprGpu)
  2362. {
  2363. nContacts = m_totalContactsOut.at(0);
  2364. {
  2365. B3_PROFILE("mprPenetrationKernel");
  2366. b3BufferInfoCL bInfo[] = {
  2367. b3BufferInfoCL(pairs->getBufferCL(), true),
  2368. b3BufferInfoCL(bodyBuf->getBufferCL(), true),
  2369. b3BufferInfoCL(gpuCollidables.getBufferCL(), true),
  2370. b3BufferInfoCL(convexData.getBufferCL(), true),
  2371. b3BufferInfoCL(gpuVertices.getBufferCL(), true),
  2372. b3BufferInfoCL(m_sepNormals.getBufferCL()),
  2373. b3BufferInfoCL(m_hasSeparatingNormals.getBufferCL()),
  2374. b3BufferInfoCL(contactOut->getBufferCL()),
  2375. b3BufferInfoCL(m_totalContactsOut.getBufferCL())};
  2376. b3LauncherCL launcher(m_queue, m_mprPenetrationKernel, "mprPenetrationKernel");
  2377. launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
  2378. launcher.setConst(maxContactCapacity);
  2379. launcher.setConst(nPairs);
  2380. int num = nPairs;
  2381. launcher.launch1D(num);
  2382. clFinish(m_queue);
  2383. /*
  2384. b3AlignedObjectArray<int>hostHasSepAxis;
  2385. m_hasSeparatingNormals.copyToHost(hostHasSepAxis);
  2386. b3AlignedObjectArray<b3Vector3>hostSepAxis;
  2387. m_sepNormals.copyToHost(hostSepAxis);
  2388. */
  2389. nContacts = m_totalContactsOut.at(0);
  2390. contactOut->resize(nContacts);
  2391. // printf("nContacts (after mprPenetrationKernel) = %d\n",nContacts);
  2392. if (nContacts > maxContactCapacity)
  2393. {
  2394. b3Error("Error: contacts exceeds capacity (%d/%d)\n", nContacts, maxContactCapacity);
  2395. nContacts = maxContactCapacity;
  2396. }
  2397. }
  2398. }
  2399. if (1)
  2400. {
  2401. if (1)
  2402. {
  2403. {
  2404. B3_PROFILE("findSeparatingAxisVertexFaceKernel");
  2405. b3BufferInfoCL bInfo[] = {
  2406. b3BufferInfoCL(pairs->getBufferCL(), true),
  2407. b3BufferInfoCL(bodyBuf->getBufferCL(), true),
  2408. b3BufferInfoCL(gpuCollidables.getBufferCL(), true),
  2409. b3BufferInfoCL(convexData.getBufferCL(), true),
  2410. b3BufferInfoCL(gpuVertices.getBufferCL(), true),
  2411. b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true),
  2412. b3BufferInfoCL(gpuFaces.getBufferCL(), true),
  2413. b3BufferInfoCL(gpuIndices.getBufferCL(), true),
  2414. b3BufferInfoCL(clAabbsWorldSpace.getBufferCL(), true),
  2415. b3BufferInfoCL(m_sepNormals.getBufferCL()),
  2416. b3BufferInfoCL(m_hasSeparatingNormals.getBufferCL()),
  2417. b3BufferInfoCL(m_dmins.getBufferCL())};
  2418. b3LauncherCL launcher(m_queue, m_findSeparatingAxisVertexFaceKernel, "findSeparatingAxisVertexFaceKernel");
  2419. launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
  2420. launcher.setConst(nPairs);
  2421. int num = nPairs;
  2422. launcher.launch1D(num);
  2423. clFinish(m_queue);
  2424. }
  2425. int numDirections = sizeof(unitSphere162) / sizeof(b3Vector3);
  2426. {
  2427. B3_PROFILE("findSeparatingAxisEdgeEdgeKernel");
  2428. b3BufferInfoCL bInfo[] = {
  2429. b3BufferInfoCL(pairs->getBufferCL(), true),
  2430. b3BufferInfoCL(bodyBuf->getBufferCL(), true),
  2431. b3BufferInfoCL(gpuCollidables.getBufferCL(), true),
  2432. b3BufferInfoCL(convexData.getBufferCL(), true),
  2433. b3BufferInfoCL(gpuVertices.getBufferCL(), true),
  2434. b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true),
  2435. b3BufferInfoCL(gpuFaces.getBufferCL(), true),
  2436. b3BufferInfoCL(gpuIndices.getBufferCL(), true),
  2437. b3BufferInfoCL(clAabbsWorldSpace.getBufferCL(), true),
  2438. b3BufferInfoCL(m_sepNormals.getBufferCL()),
  2439. b3BufferInfoCL(m_hasSeparatingNormals.getBufferCL()),
  2440. b3BufferInfoCL(m_dmins.getBufferCL()),
  2441. b3BufferInfoCL(m_unitSphereDirections.getBufferCL(), true)
  2442. };
  2443. b3LauncherCL launcher(m_queue, m_findSeparatingAxisEdgeEdgeKernel, "findSeparatingAxisEdgeEdgeKernel");
  2444. launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
  2445. launcher.setConst(numDirections);
  2446. launcher.setConst(nPairs);
  2447. int num = nPairs;
  2448. launcher.launch1D(num);
  2449. clFinish(m_queue);
  2450. }
  2451. }
  2452. if (useMprGpu)
  2453. {
  2454. B3_PROFILE("findSeparatingAxisUnitSphereKernel");
  2455. b3BufferInfoCL bInfo[] = {
  2456. b3BufferInfoCL(pairs->getBufferCL(), true),
  2457. b3BufferInfoCL(bodyBuf->getBufferCL(), true),
  2458. b3BufferInfoCL(gpuCollidables.getBufferCL(), true),
  2459. b3BufferInfoCL(convexData.getBufferCL(), true),
  2460. b3BufferInfoCL(gpuVertices.getBufferCL(), true),
  2461. b3BufferInfoCL(m_unitSphereDirections.getBufferCL(), true),
  2462. b3BufferInfoCL(m_sepNormals.getBufferCL()),
  2463. b3BufferInfoCL(m_hasSeparatingNormals.getBufferCL()),
  2464. b3BufferInfoCL(m_dmins.getBufferCL())};
  2465. b3LauncherCL launcher(m_queue, m_findSeparatingAxisUnitSphereKernel, "findSeparatingAxisUnitSphereKernel");
  2466. launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
  2467. int numDirections = sizeof(unitSphere162) / sizeof(b3Vector3);
  2468. launcher.setConst(numDirections);
  2469. launcher.setConst(nPairs);
  2470. int num = nPairs;
  2471. launcher.launch1D(num);
  2472. clFinish(m_queue);
  2473. }
  2474. }
  2475. }
  2476. else
  2477. {
  2478. B3_PROFILE("findSeparatingAxisKernel");
  2479. b3BufferInfoCL bInfo[] = {
  2480. b3BufferInfoCL(pairs->getBufferCL(), true),
  2481. b3BufferInfoCL(bodyBuf->getBufferCL(), true),
  2482. b3BufferInfoCL(gpuCollidables.getBufferCL(), true),
  2483. b3BufferInfoCL(convexData.getBufferCL(), true),
  2484. b3BufferInfoCL(gpuVertices.getBufferCL(), true),
  2485. b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true),
  2486. b3BufferInfoCL(gpuFaces.getBufferCL(), true),
  2487. b3BufferInfoCL(gpuIndices.getBufferCL(), true),
  2488. b3BufferInfoCL(clAabbsWorldSpace.getBufferCL(), true),
  2489. b3BufferInfoCL(m_sepNormals.getBufferCL()),
  2490. b3BufferInfoCL(m_hasSeparatingNormals.getBufferCL())};
  2491. b3LauncherCL launcher(m_queue, m_findSeparatingAxisKernel, "m_findSeparatingAxisKernel");
  2492. launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
  2493. launcher.setConst(nPairs);
  2494. int num = nPairs;
  2495. launcher.launch1D(num);
  2496. clFinish(m_queue);
  2497. }
  2498. }
  2499. else
  2500. {
  2501. B3_PROFILE("findSeparatingAxisKernel CPU");
  2502. b3AlignedObjectArray<b3Int4> hostPairs;
  2503. pairs->copyToHost(hostPairs);
  2504. b3AlignedObjectArray<b3RigidBodyData> hostBodyBuf;
  2505. bodyBuf->copyToHost(hostBodyBuf);
  2506. b3AlignedObjectArray<b3Collidable> hostCollidables;
  2507. gpuCollidables.copyToHost(hostCollidables);
  2508. b3AlignedObjectArray<b3GpuChildShape> cpuChildShapes;
  2509. gpuChildShapes.copyToHost(cpuChildShapes);
  2510. b3AlignedObjectArray<b3ConvexPolyhedronData> hostConvexShapeData;
  2511. convexData.copyToHost(hostConvexShapeData);
  2512. b3AlignedObjectArray<b3Vector3> hostVertices;
  2513. gpuVertices.copyToHost(hostVertices);
  2514. b3AlignedObjectArray<int> hostHasSepAxis;
  2515. hostHasSepAxis.resize(nPairs);
  2516. b3AlignedObjectArray<b3Vector3> hostSepAxis;
  2517. hostSepAxis.resize(nPairs);
  2518. b3AlignedObjectArray<b3Vector3> hostUniqueEdges;
  2519. gpuUniqueEdges.copyToHost(hostUniqueEdges);
  2520. b3AlignedObjectArray<b3GpuFace> hostFaces;
  2521. gpuFaces.copyToHost(hostFaces);
  2522. b3AlignedObjectArray<int> hostIndices;
  2523. gpuIndices.copyToHost(hostIndices);
  2524. b3AlignedObjectArray<b3Contact4> hostContacts;
  2525. if (nContacts)
  2526. {
  2527. contactOut->copyToHost(hostContacts);
  2528. }
  2529. hostContacts.resize(maxContactCapacity);
  2530. int nGlobalContactsOut = nContacts;
  2531. for (int i = 0; i < nPairs; i++)
  2532. {
  2533. int bodyIndexA = hostPairs[i].x;
  2534. int bodyIndexB = hostPairs[i].y;
  2535. int collidableIndexA = hostBodyBuf[bodyIndexA].m_collidableIdx;
  2536. int collidableIndexB = hostBodyBuf[bodyIndexB].m_collidableIdx;
  2537. int shapeIndexA = hostCollidables[collidableIndexA].m_shapeIndex;
  2538. int shapeIndexB = hostCollidables[collidableIndexB].m_shapeIndex;
  2539. hostHasSepAxis[i] = 0;
  2540. //once the broadphase avoids static-static pairs, we can remove this test
  2541. if ((hostBodyBuf[bodyIndexA].m_invMass == 0) && (hostBodyBuf[bodyIndexB].m_invMass == 0))
  2542. {
  2543. continue;
  2544. }
  2545. if ((hostCollidables[collidableIndexA].m_shapeType != SHAPE_CONVEX_HULL) || (hostCollidables[collidableIndexB].m_shapeType != SHAPE_CONVEX_HULL))
  2546. {
  2547. continue;
  2548. }
  2549. float dmin = FLT_MAX;
  2550. b3ConvexPolyhedronData* convexShapeA = &hostConvexShapeData[shapeIndexA];
  2551. b3ConvexPolyhedronData* convexShapeB = &hostConvexShapeData[shapeIndexB];
  2552. b3Vector3 posA = hostBodyBuf[bodyIndexA].m_pos;
  2553. b3Vector3 posB = hostBodyBuf[bodyIndexB].m_pos;
  2554. b3Quaternion ornA = hostBodyBuf[bodyIndexA].m_quat;
  2555. b3Quaternion ornB = hostBodyBuf[bodyIndexB].m_quat;
  2556. if (useGjk)
  2557. {
  2558. //first approximate the separating axis, to 'fail-proof' GJK+EPA or MPR
  2559. {
  2560. b3Vector3 c0local = hostConvexShapeData[shapeIndexA].m_localCenter;
  2561. b3Vector3 c0 = b3TransformPoint(c0local, posA, ornA);
  2562. b3Vector3 c1local = hostConvexShapeData[shapeIndexB].m_localCenter;
  2563. b3Vector3 c1 = b3TransformPoint(c1local, posB, ornB);
  2564. b3Vector3 DeltaC2 = c0 - c1;
  2565. b3Vector3 sepAxis;
  2566. bool hasSepAxisA = b3FindSeparatingAxis(convexShapeA, convexShapeB, posA, ornA, posB, ornB, DeltaC2,
  2567. &hostVertices.at(0), &hostUniqueEdges.at(0), &hostFaces.at(0), &hostIndices.at(0),
  2568. &hostVertices.at(0), &hostUniqueEdges.at(0), &hostFaces.at(0), &hostIndices.at(0),
  2569. &sepAxis, &dmin);
  2570. if (hasSepAxisA)
  2571. {
  2572. bool hasSepAxisB = b3FindSeparatingAxis(convexShapeB, convexShapeA, posB, ornB, posA, ornA, DeltaC2,
  2573. &hostVertices.at(0), &hostUniqueEdges.at(0), &hostFaces.at(0), &hostIndices.at(0),
  2574. &hostVertices.at(0), &hostUniqueEdges.at(0), &hostFaces.at(0), &hostIndices.at(0),
  2575. &sepAxis, &dmin);
  2576. if (hasSepAxisB)
  2577. {
  2578. bool hasEdgeEdge = b3FindSeparatingAxisEdgeEdge(convexShapeA, convexShapeB, posA, ornA, posB, ornB, DeltaC2,
  2579. &hostVertices.at(0), &hostUniqueEdges.at(0), &hostFaces.at(0), &hostIndices.at(0),
  2580. &hostVertices.at(0), &hostUniqueEdges.at(0), &hostFaces.at(0), &hostIndices.at(0),
  2581. &sepAxis, &dmin, false);
  2582. if (hasEdgeEdge)
  2583. {
  2584. hostHasSepAxis[i] = 1;
  2585. hostSepAxis[i] = sepAxis;
  2586. hostSepAxis[i].w = dmin;
  2587. }
  2588. }
  2589. }
  2590. }
  2591. if (hostHasSepAxis[i])
  2592. {
  2593. int pairIndex = i;
  2594. bool useMpr = true;
  2595. if (useMpr)
  2596. {
  2597. int res = 0;
  2598. float depth = 0.f;
  2599. b3Vector3 sepAxis2 = b3MakeVector3(1, 0, 0);
  2600. b3Vector3 resultPointOnBWorld = b3MakeVector3(0, 0, 0);
  2601. float depthOut;
  2602. b3Vector3 dirOut;
  2603. b3Vector3 posOut;
  2604. //res = b3MprPenetration(bodyIndexA,bodyIndexB,hostBodyBuf,hostConvexShapeData,hostCollidables,hostVertices,&mprConfig,&depthOut,&dirOut,&posOut);
  2605. res = b3MprPenetration(pairIndex, bodyIndexA, bodyIndexB, &hostBodyBuf[0], &hostConvexShapeData[0], &hostCollidables[0], &hostVertices[0], &hostSepAxis[0], &hostHasSepAxis[0], &depthOut, &dirOut, &posOut);
  2606. depth = depthOut;
  2607. sepAxis2 = b3MakeVector3(-dirOut.x, -dirOut.y, -dirOut.z);
  2608. resultPointOnBWorld = posOut;
  2609. //hostHasSepAxis[i] = 0;
  2610. if (res == 0)
  2611. {
  2612. //add point?
  2613. //printf("depth = %f\n",depth);
  2614. //printf("normal = %f,%f,%f\n",dir.v[0],dir.v[1],dir.v[2]);
  2615. //qprintf("pos = %f,%f,%f\n",pos.v[0],pos.v[1],pos.v[2]);
  2616. float dist = 0.f;
  2617. const b3ConvexPolyhedronData& hullA = hostConvexShapeData[hostCollidables[hostBodyBuf[bodyIndexA].m_collidableIdx].m_shapeIndex];
  2618. const b3ConvexPolyhedronData& hullB = hostConvexShapeData[hostCollidables[hostBodyBuf[bodyIndexB].m_collidableIdx].m_shapeIndex];
  2619. if (b3TestSepAxis(&hullA, &hullB, posA, ornA, posB, ornB, &sepAxis2, &hostVertices[0], &hostVertices[0], &dist))
  2620. {
  2621. if (depth > dist)
  2622. {
  2623. float diff = depth - dist;
  2624. static float maxdiff = 0.f;
  2625. if (maxdiff < diff)
  2626. {
  2627. maxdiff = diff;
  2628. printf("maxdiff = %20.10f\n", maxdiff);
  2629. }
  2630. }
  2631. }
  2632. if (depth > dmin)
  2633. {
  2634. b3Vector3 oldAxis = hostSepAxis[i];
  2635. depth = dmin;
  2636. sepAxis2 = oldAxis;
  2637. }
  2638. if (b3TestSepAxis(&hullA, &hullB, posA, ornA, posB, ornB, &sepAxis2, &hostVertices[0], &hostVertices[0], &dist))
  2639. {
  2640. if (depth > dist)
  2641. {
  2642. float diff = depth - dist;
  2643. //printf("?diff = %f\n",diff );
  2644. static float maxdiff = 0.f;
  2645. if (maxdiff < diff)
  2646. {
  2647. maxdiff = diff;
  2648. printf("maxdiff = %20.10f\n", maxdiff);
  2649. }
  2650. }
  2651. //this is used for SAT
  2652. //hostHasSepAxis[i] = 1;
  2653. //hostSepAxis[i] = sepAxis2;
  2654. //add contact point
  2655. //int contactIndex = nGlobalContactsOut;
  2656. b3Contact4& newContact = hostContacts.at(nGlobalContactsOut);
  2657. nGlobalContactsOut++;
  2658. newContact.m_batchIdx = 0; //i;
  2659. newContact.m_bodyAPtrAndSignBit = (hostBodyBuf.at(bodyIndexA).m_invMass == 0) ? -bodyIndexA : bodyIndexA;
  2660. newContact.m_bodyBPtrAndSignBit = (hostBodyBuf.at(bodyIndexB).m_invMass == 0) ? -bodyIndexB : bodyIndexB;
  2661. newContact.m_frictionCoeffCmp = 45874;
  2662. newContact.m_restituitionCoeffCmp = 0;
  2663. static float maxDepth = 0.f;
  2664. if (depth > maxDepth)
  2665. {
  2666. maxDepth = depth;
  2667. printf("MPR maxdepth = %f\n", maxDepth);
  2668. }
  2669. resultPointOnBWorld.w = -depth;
  2670. newContact.m_worldPosB[0] = resultPointOnBWorld;
  2671. //b3Vector3 resultPointOnAWorld = resultPointOnBWorld+depth*sepAxis2;
  2672. newContact.m_worldNormalOnB = sepAxis2;
  2673. newContact.m_worldNormalOnB.w = (b3Scalar)1;
  2674. }
  2675. else
  2676. {
  2677. printf("rejected\n");
  2678. }
  2679. }
  2680. }
  2681. else
  2682. {
  2683. //int contactIndex = computeContactConvexConvex2( i,bodyIndexA,bodyIndexB,collidableIndexA,collidableIndexB,hostBodyBuf, hostCollidables,hostConvexData,hostVertices,hostUniqueEdges,hostIndices,hostFaces,hostContacts,nContacts,maxContactCapacity,oldHostContacts);
  2684. b3AlignedObjectArray<b3Contact4> oldHostContacts;
  2685. int result;
  2686. result = computeContactConvexConvex2( //hostPairs,
  2687. pairIndex,
  2688. bodyIndexA, bodyIndexB,
  2689. collidableIndexA, collidableIndexB,
  2690. hostBodyBuf,
  2691. hostCollidables,
  2692. hostConvexShapeData,
  2693. hostVertices,
  2694. hostUniqueEdges,
  2695. hostIndices,
  2696. hostFaces,
  2697. hostContacts,
  2698. nGlobalContactsOut,
  2699. maxContactCapacity,
  2700. oldHostContacts
  2701. //hostHasSepAxis,
  2702. //hostSepAxis
  2703. );
  2704. } //mpr
  2705. } //hostHasSepAxis[i] = 1;
  2706. }
  2707. else
  2708. {
  2709. b3Vector3 c0local = hostConvexShapeData[shapeIndexA].m_localCenter;
  2710. b3Vector3 c0 = b3TransformPoint(c0local, posA, ornA);
  2711. b3Vector3 c1local = hostConvexShapeData[shapeIndexB].m_localCenter;
  2712. b3Vector3 c1 = b3TransformPoint(c1local, posB, ornB);
  2713. b3Vector3 DeltaC2 = c0 - c1;
  2714. b3Vector3 sepAxis;
  2715. bool hasSepAxisA = b3FindSeparatingAxis(convexShapeA, convexShapeB, posA, ornA, posB, ornB, DeltaC2,
  2716. &hostVertices.at(0), &hostUniqueEdges.at(0), &hostFaces.at(0), &hostIndices.at(0),
  2717. &hostVertices.at(0), &hostUniqueEdges.at(0), &hostFaces.at(0), &hostIndices.at(0),
  2718. &sepAxis, &dmin);
  2719. if (hasSepAxisA)
  2720. {
  2721. bool hasSepAxisB = b3FindSeparatingAxis(convexShapeB, convexShapeA, posB, ornB, posA, ornA, DeltaC2,
  2722. &hostVertices.at(0), &hostUniqueEdges.at(0), &hostFaces.at(0), &hostIndices.at(0),
  2723. &hostVertices.at(0), &hostUniqueEdges.at(0), &hostFaces.at(0), &hostIndices.at(0),
  2724. &sepAxis, &dmin);
  2725. if (hasSepAxisB)
  2726. {
  2727. bool hasEdgeEdge = b3FindSeparatingAxisEdgeEdge(convexShapeA, convexShapeB, posA, ornA, posB, ornB, DeltaC2,
  2728. &hostVertices.at(0), &hostUniqueEdges.at(0), &hostFaces.at(0), &hostIndices.at(0),
  2729. &hostVertices.at(0), &hostUniqueEdges.at(0), &hostFaces.at(0), &hostIndices.at(0),
  2730. &sepAxis, &dmin, true);
  2731. if (hasEdgeEdge)
  2732. {
  2733. hostHasSepAxis[i] = 1;
  2734. hostSepAxis[i] = sepAxis;
  2735. }
  2736. }
  2737. }
  2738. }
  2739. }
  2740. if (useGjkContacts) //nGlobalContactsOut>0)
  2741. {
  2742. //printf("nGlobalContactsOut=%d\n",nGlobalContactsOut);
  2743. nContacts = nGlobalContactsOut;
  2744. contactOut->copyFromHost(hostContacts);
  2745. m_totalContactsOut.copyFromHostPointer(&nContacts, 1, 0, true);
  2746. }
  2747. m_hasSeparatingNormals.copyFromHost(hostHasSepAxis);
  2748. m_sepNormals.copyFromHost(hostSepAxis);
  2749. /*
  2750. //double-check results from GPU (comment-out the 'else' so both paths are executed
  2751. b3AlignedObjectArray<int> checkHasSepAxis;
  2752. m_hasSeparatingNormals.copyToHost(checkHasSepAxis);
  2753. static int frameCount = 0;
  2754. frameCount++;
  2755. for (int i=0;i<nPairs;i++)
  2756. {
  2757. if (hostHasSepAxis[i] != checkHasSepAxis[i])
  2758. {
  2759. printf("at frameCount %d hostHasSepAxis[%d] = %d but checkHasSepAxis[i] = %d\n",
  2760. frameCount,i,hostHasSepAxis[i],checkHasSepAxis[i]);
  2761. }
  2762. }
  2763. //m_hasSeparatingNormals.copyFromHost(hostHasSepAxis);
  2764. // m_sepNormals.copyFromHost(hostSepAxis);
  2765. */
  2766. }
  2767. numCompoundPairs = m_numCompoundPairsOut.at(0);
  2768. bool useGpuFindCompoundPairs = true;
  2769. if (useGpuFindCompoundPairs)
  2770. {
  2771. B3_PROFILE("findCompoundPairsKernel");
  2772. b3BufferInfoCL bInfo[] =
  2773. {
  2774. b3BufferInfoCL(pairs->getBufferCL(), true),
  2775. b3BufferInfoCL(bodyBuf->getBufferCL(), true),
  2776. b3BufferInfoCL(gpuCollidables.getBufferCL(), true),
  2777. b3BufferInfoCL(convexData.getBufferCL(), true),
  2778. b3BufferInfoCL(gpuVertices.getBufferCL(), true),
  2779. b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true),
  2780. b3BufferInfoCL(gpuFaces.getBufferCL(), true),
  2781. b3BufferInfoCL(gpuIndices.getBufferCL(), true),
  2782. b3BufferInfoCL(clAabbsLocalSpace.getBufferCL(), true),
  2783. b3BufferInfoCL(gpuChildShapes.getBufferCL(), true),
  2784. b3BufferInfoCL(m_gpuCompoundPairs.getBufferCL()),
  2785. b3BufferInfoCL(m_numCompoundPairsOut.getBufferCL()),
  2786. b3BufferInfoCL(subTreesGPU->getBufferCL()),
  2787. b3BufferInfoCL(treeNodesGPU->getBufferCL()),
  2788. b3BufferInfoCL(bvhInfo->getBufferCL())};
  2789. b3LauncherCL launcher(m_queue, m_findCompoundPairsKernel, "m_findCompoundPairsKernel");
  2790. launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
  2791. launcher.setConst(nPairs);
  2792. launcher.setConst(compoundPairCapacity);
  2793. int num = nPairs;
  2794. launcher.launch1D(num);
  2795. clFinish(m_queue);
  2796. numCompoundPairs = m_numCompoundPairsOut.at(0);
  2797. //printf("numCompoundPairs =%d\n",numCompoundPairs );
  2798. if (numCompoundPairs)
  2799. {
  2800. //printf("numCompoundPairs=%d\n",numCompoundPairs);
  2801. }
  2802. }
  2803. else
  2804. {
  2805. b3AlignedObjectArray<b3QuantizedBvhNode> treeNodesCPU;
  2806. treeNodesGPU->copyToHost(treeNodesCPU);
  2807. b3AlignedObjectArray<b3BvhSubtreeInfo> subTreesCPU;
  2808. subTreesGPU->copyToHost(subTreesCPU);
  2809. b3AlignedObjectArray<b3BvhInfo> bvhInfoCPU;
  2810. bvhInfo->copyToHost(bvhInfoCPU);
  2811. b3AlignedObjectArray<b3Aabb> hostAabbsWorldSpace;
  2812. clAabbsWorldSpace.copyToHost(hostAabbsWorldSpace);
  2813. b3AlignedObjectArray<b3Aabb> hostAabbsLocalSpace;
  2814. clAabbsLocalSpace.copyToHost(hostAabbsLocalSpace);
  2815. b3AlignedObjectArray<b3Int4> hostPairs;
  2816. pairs->copyToHost(hostPairs);
  2817. b3AlignedObjectArray<b3RigidBodyData> hostBodyBuf;
  2818. bodyBuf->copyToHost(hostBodyBuf);
  2819. b3AlignedObjectArray<b3Int4> cpuCompoundPairsOut;
  2820. cpuCompoundPairsOut.resize(compoundPairCapacity);
  2821. b3AlignedObjectArray<b3Collidable> hostCollidables;
  2822. gpuCollidables.copyToHost(hostCollidables);
  2823. b3AlignedObjectArray<b3GpuChildShape> cpuChildShapes;
  2824. gpuChildShapes.copyToHost(cpuChildShapes);
  2825. b3AlignedObjectArray<b3ConvexPolyhedronData> hostConvexData;
  2826. convexData.copyToHost(hostConvexData);
  2827. b3AlignedObjectArray<b3Vector3> hostVertices;
  2828. gpuVertices.copyToHost(hostVertices);
  2829. for (int pairIndex = 0; pairIndex < nPairs; pairIndex++)
  2830. {
  2831. int bodyIndexA = hostPairs[pairIndex].x;
  2832. int bodyIndexB = hostPairs[pairIndex].y;
  2833. int collidableIndexA = hostBodyBuf[bodyIndexA].m_collidableIdx;
  2834. int collidableIndexB = hostBodyBuf[bodyIndexB].m_collidableIdx;
  2835. if (cpuChildShapes.size())
  2836. {
  2837. findCompoundPairsKernel(
  2838. pairIndex,
  2839. bodyIndexA,
  2840. bodyIndexB,
  2841. collidableIndexA,
  2842. collidableIndexB,
  2843. &hostBodyBuf[0],
  2844. &hostCollidables[0],
  2845. &hostConvexData[0],
  2846. hostVertices,
  2847. hostAabbsWorldSpace,
  2848. hostAabbsLocalSpace,
  2849. &cpuChildShapes[0],
  2850. &cpuCompoundPairsOut[0],
  2851. &numCompoundPairs,
  2852. compoundPairCapacity,
  2853. treeNodesCPU,
  2854. subTreesCPU,
  2855. bvhInfoCPU);
  2856. }
  2857. }
  2858. m_numCompoundPairsOut.copyFromHostPointer(&numCompoundPairs, 1, 0, true);
  2859. if (numCompoundPairs)
  2860. {
  2861. b3CompoundOverlappingPair* ptr = (b3CompoundOverlappingPair*)&cpuCompoundPairsOut[0];
  2862. m_gpuCompoundPairs.copyFromHostPointer(ptr, numCompoundPairs, 0, true);
  2863. }
  2864. //cpuCompoundPairsOut
  2865. }
  2866. if (numCompoundPairs)
  2867. {
  2868. printf("numCompoundPairs=%d\n", numCompoundPairs);
  2869. }
  2870. if (numCompoundPairs > compoundPairCapacity)
  2871. {
  2872. b3Error("Exceeded compound pair capacity (%d/%d)\n", numCompoundPairs, compoundPairCapacity);
  2873. numCompoundPairs = compoundPairCapacity;
  2874. }
  2875. m_gpuCompoundPairs.resize(numCompoundPairs);
  2876. m_gpuHasCompoundSepNormals.resize(numCompoundPairs);
  2877. m_gpuCompoundSepNormals.resize(numCompoundPairs);
  2878. if (numCompoundPairs)
  2879. {
  2880. B3_PROFILE("processCompoundPairsPrimitivesKernel");
  2881. b3BufferInfoCL bInfo[] =
  2882. {
  2883. b3BufferInfoCL(m_gpuCompoundPairs.getBufferCL(), true),
  2884. b3BufferInfoCL(bodyBuf->getBufferCL(), true),
  2885. b3BufferInfoCL(gpuCollidables.getBufferCL(), true),
  2886. b3BufferInfoCL(convexData.getBufferCL(), true),
  2887. b3BufferInfoCL(gpuVertices.getBufferCL(), true),
  2888. b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true),
  2889. b3BufferInfoCL(gpuFaces.getBufferCL(), true),
  2890. b3BufferInfoCL(gpuIndices.getBufferCL(), true),
  2891. b3BufferInfoCL(clAabbsWorldSpace.getBufferCL(), true),
  2892. b3BufferInfoCL(gpuChildShapes.getBufferCL(), true),
  2893. b3BufferInfoCL(contactOut->getBufferCL()),
  2894. b3BufferInfoCL(m_totalContactsOut.getBufferCL())};
  2895. b3LauncherCL launcher(m_queue, m_processCompoundPairsPrimitivesKernel, "m_processCompoundPairsPrimitivesKernel");
  2896. launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
  2897. launcher.setConst(numCompoundPairs);
  2898. launcher.setConst(maxContactCapacity);
  2899. int num = numCompoundPairs;
  2900. launcher.launch1D(num);
  2901. clFinish(m_queue);
  2902. nContacts = m_totalContactsOut.at(0);
  2903. //printf("nContacts (after processCompoundPairsPrimitivesKernel) = %d\n",nContacts);
  2904. if (nContacts > maxContactCapacity)
  2905. {
  2906. b3Error("Error: contacts exceeds capacity (%d/%d)\n", nContacts, maxContactCapacity);
  2907. nContacts = maxContactCapacity;
  2908. }
  2909. }
  2910. if (numCompoundPairs)
  2911. {
  2912. B3_PROFILE("processCompoundPairsKernel");
  2913. b3BufferInfoCL bInfo[] =
  2914. {
  2915. b3BufferInfoCL(m_gpuCompoundPairs.getBufferCL(), true),
  2916. b3BufferInfoCL(bodyBuf->getBufferCL(), true),
  2917. b3BufferInfoCL(gpuCollidables.getBufferCL(), true),
  2918. b3BufferInfoCL(convexData.getBufferCL(), true),
  2919. b3BufferInfoCL(gpuVertices.getBufferCL(), true),
  2920. b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true),
  2921. b3BufferInfoCL(gpuFaces.getBufferCL(), true),
  2922. b3BufferInfoCL(gpuIndices.getBufferCL(), true),
  2923. b3BufferInfoCL(clAabbsWorldSpace.getBufferCL(), true),
  2924. b3BufferInfoCL(gpuChildShapes.getBufferCL(), true),
  2925. b3BufferInfoCL(m_gpuCompoundSepNormals.getBufferCL()),
  2926. b3BufferInfoCL(m_gpuHasCompoundSepNormals.getBufferCL())};
  2927. b3LauncherCL launcher(m_queue, m_processCompoundPairsKernel, "m_processCompoundPairsKernel");
  2928. launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
  2929. launcher.setConst(numCompoundPairs);
  2930. int num = numCompoundPairs;
  2931. launcher.launch1D(num);
  2932. clFinish(m_queue);
  2933. }
  2934. //printf("numConcave = %d\n",numConcave);
  2935. // printf("hostNormals.size()=%d\n",hostNormals.size());
  2936. //int numPairs = pairCount.at(0);
  2937. }
  2938. int vertexFaceCapacity = 64;
  2939. {
  2940. //now perform the tree query on GPU
  2941. if (treeNodesGPU->size() && treeNodesGPU->size())
  2942. {
  2943. if (bvhTraversalKernelGPU)
  2944. {
  2945. B3_PROFILE("m_bvhTraversalKernel");
  2946. numConcavePairs = m_numConcavePairsOut.at(0);
  2947. b3LauncherCL launcher(m_queue, m_bvhTraversalKernel, "m_bvhTraversalKernel");
  2948. launcher.setBuffer(pairs->getBufferCL());
  2949. launcher.setBuffer(bodyBuf->getBufferCL());
  2950. launcher.setBuffer(gpuCollidables.getBufferCL());
  2951. launcher.setBuffer(clAabbsWorldSpace.getBufferCL());
  2952. launcher.setBuffer(triangleConvexPairsOut.getBufferCL());
  2953. launcher.setBuffer(m_numConcavePairsOut.getBufferCL());
  2954. launcher.setBuffer(subTreesGPU->getBufferCL());
  2955. launcher.setBuffer(treeNodesGPU->getBufferCL());
  2956. launcher.setBuffer(bvhInfo->getBufferCL());
  2957. launcher.setConst(nPairs);
  2958. launcher.setConst(maxTriConvexPairCapacity);
  2959. int num = nPairs;
  2960. launcher.launch1D(num);
  2961. clFinish(m_queue);
  2962. numConcavePairs = m_numConcavePairsOut.at(0);
  2963. }
  2964. else
  2965. {
  2966. b3AlignedObjectArray<b3Int4> hostPairs;
  2967. pairs->copyToHost(hostPairs);
  2968. b3AlignedObjectArray<b3RigidBodyData> hostBodyBuf;
  2969. bodyBuf->copyToHost(hostBodyBuf);
  2970. b3AlignedObjectArray<b3Collidable> hostCollidables;
  2971. gpuCollidables.copyToHost(hostCollidables);
  2972. b3AlignedObjectArray<b3Aabb> hostAabbsWorldSpace;
  2973. clAabbsWorldSpace.copyToHost(hostAabbsWorldSpace);
  2974. //int maxTriConvexPairCapacity,
  2975. b3AlignedObjectArray<b3Int4> triangleConvexPairsOutHost;
  2976. triangleConvexPairsOutHost.resize(maxTriConvexPairCapacity);
  2977. //int numTriConvexPairsOutHost=0;
  2978. numConcavePairs = 0;
  2979. //m_numConcavePairsOut
  2980. b3AlignedObjectArray<b3QuantizedBvhNode> treeNodesCPU;
  2981. treeNodesGPU->copyToHost(treeNodesCPU);
  2982. b3AlignedObjectArray<b3BvhSubtreeInfo> subTreesCPU;
  2983. subTreesGPU->copyToHost(subTreesCPU);
  2984. b3AlignedObjectArray<b3BvhInfo> bvhInfoCPU;
  2985. bvhInfo->copyToHost(bvhInfoCPU);
  2986. //compute it...
  2987. volatile int hostNumConcavePairsOut = 0;
  2988. //
  2989. for (int i = 0; i < nPairs; i++)
  2990. {
  2991. b3BvhTraversal(&hostPairs.at(0),
  2992. &hostBodyBuf.at(0),
  2993. &hostCollidables.at(0),
  2994. &hostAabbsWorldSpace.at(0),
  2995. &triangleConvexPairsOutHost.at(0),
  2996. &hostNumConcavePairsOut,
  2997. &subTreesCPU.at(0),
  2998. &treeNodesCPU.at(0),
  2999. &bvhInfoCPU.at(0),
  3000. nPairs,
  3001. maxTriConvexPairCapacity,
  3002. i);
  3003. }
  3004. numConcavePairs = hostNumConcavePairsOut;
  3005. if (hostNumConcavePairsOut)
  3006. {
  3007. triangleConvexPairsOutHost.resize(hostNumConcavePairsOut);
  3008. triangleConvexPairsOut.copyFromHost(triangleConvexPairsOutHost);
  3009. }
  3010. //
  3011. m_numConcavePairsOut.resize(0);
  3012. m_numConcavePairsOut.push_back(numConcavePairs);
  3013. }
  3014. //printf("numConcavePairs=%d (max = %d\n",numConcavePairs,maxTriConvexPairCapacity);
  3015. if (numConcavePairs > maxTriConvexPairCapacity)
  3016. {
  3017. static int exceeded_maxTriConvexPairCapacity_count = 0;
  3018. b3Error("Exceeded the maxTriConvexPairCapacity (found %d but max is %d, it happened %d times)\n",
  3019. numConcavePairs, maxTriConvexPairCapacity, exceeded_maxTriConvexPairCapacity_count++);
  3020. numConcavePairs = maxTriConvexPairCapacity;
  3021. }
  3022. triangleConvexPairsOut.resize(numConcavePairs);
  3023. if (numConcavePairs)
  3024. {
  3025. clippingFacesOutGPU.resize(numConcavePairs);
  3026. worldNormalsAGPU.resize(numConcavePairs);
  3027. worldVertsA1GPU.resize(vertexFaceCapacity * (numConcavePairs));
  3028. worldVertsB1GPU.resize(vertexFaceCapacity * (numConcavePairs));
  3029. if (findConcaveSeparatingAxisKernelGPU)
  3030. {
  3031. /*
  3032. m_concaveHasSeparatingNormals.copyFromHost(concaveHasSeparatingNormalsCPU);
  3033. clippingFacesOutGPU.copyFromHost(clippingFacesOutCPU);
  3034. worldVertsA1GPU.copyFromHost(worldVertsA1CPU);
  3035. worldNormalsAGPU.copyFromHost(worldNormalsACPU);
  3036. worldVertsB1GPU.copyFromHost(worldVertsB1CPU);
  3037. */
  3038. //now perform a SAT test for each triangle-convex element (stored in triangleConvexPairsOut)
  3039. if (splitSearchSepAxisConcave)
  3040. {
  3041. //printf("numConcavePairs = %d\n",numConcavePairs);
  3042. m_dmins.resize(numConcavePairs);
  3043. {
  3044. B3_PROFILE("findConcaveSeparatingAxisVertexFaceKernel");
  3045. b3BufferInfoCL bInfo[] = {
  3046. b3BufferInfoCL(triangleConvexPairsOut.getBufferCL()),
  3047. b3BufferInfoCL(bodyBuf->getBufferCL(), true),
  3048. b3BufferInfoCL(gpuCollidables.getBufferCL(), true),
  3049. b3BufferInfoCL(convexData.getBufferCL(), true),
  3050. b3BufferInfoCL(gpuVertices.getBufferCL(), true),
  3051. b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true),
  3052. b3BufferInfoCL(gpuFaces.getBufferCL(), true),
  3053. b3BufferInfoCL(gpuIndices.getBufferCL(), true),
  3054. b3BufferInfoCL(gpuChildShapes.getBufferCL(), true),
  3055. b3BufferInfoCL(clAabbsWorldSpace.getBufferCL(), true),
  3056. b3BufferInfoCL(m_concaveSepNormals.getBufferCL()),
  3057. b3BufferInfoCL(m_concaveHasSeparatingNormals.getBufferCL()),
  3058. b3BufferInfoCL(clippingFacesOutGPU.getBufferCL()),
  3059. b3BufferInfoCL(worldVertsA1GPU.getBufferCL()),
  3060. b3BufferInfoCL(worldNormalsAGPU.getBufferCL()),
  3061. b3BufferInfoCL(worldVertsB1GPU.getBufferCL()),
  3062. b3BufferInfoCL(m_dmins.getBufferCL())};
  3063. b3LauncherCL launcher(m_queue, m_findConcaveSeparatingAxisVertexFaceKernel, "m_findConcaveSeparatingAxisVertexFaceKernel");
  3064. launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
  3065. launcher.setConst(vertexFaceCapacity);
  3066. launcher.setConst(numConcavePairs);
  3067. int num = numConcavePairs;
  3068. launcher.launch1D(num);
  3069. clFinish(m_queue);
  3070. }
  3071. // numConcavePairs = 0;
  3072. if (1)
  3073. {
  3074. B3_PROFILE("findConcaveSeparatingAxisEdgeEdgeKernel");
  3075. b3BufferInfoCL bInfo[] = {
  3076. b3BufferInfoCL(triangleConvexPairsOut.getBufferCL()),
  3077. b3BufferInfoCL(bodyBuf->getBufferCL(), true),
  3078. b3BufferInfoCL(gpuCollidables.getBufferCL(), true),
  3079. b3BufferInfoCL(convexData.getBufferCL(), true),
  3080. b3BufferInfoCL(gpuVertices.getBufferCL(), true),
  3081. b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true),
  3082. b3BufferInfoCL(gpuFaces.getBufferCL(), true),
  3083. b3BufferInfoCL(gpuIndices.getBufferCL(), true),
  3084. b3BufferInfoCL(gpuChildShapes.getBufferCL(), true),
  3085. b3BufferInfoCL(clAabbsWorldSpace.getBufferCL(), true),
  3086. b3BufferInfoCL(m_concaveSepNormals.getBufferCL()),
  3087. b3BufferInfoCL(m_concaveHasSeparatingNormals.getBufferCL()),
  3088. b3BufferInfoCL(clippingFacesOutGPU.getBufferCL()),
  3089. b3BufferInfoCL(worldVertsA1GPU.getBufferCL()),
  3090. b3BufferInfoCL(worldNormalsAGPU.getBufferCL()),
  3091. b3BufferInfoCL(worldVertsB1GPU.getBufferCL()),
  3092. b3BufferInfoCL(m_dmins.getBufferCL())};
  3093. b3LauncherCL launcher(m_queue, m_findConcaveSeparatingAxisEdgeEdgeKernel, "m_findConcaveSeparatingAxisEdgeEdgeKernel");
  3094. launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
  3095. launcher.setConst(vertexFaceCapacity);
  3096. launcher.setConst(numConcavePairs);
  3097. int num = numConcavePairs;
  3098. launcher.launch1D(num);
  3099. clFinish(m_queue);
  3100. }
  3101. // numConcavePairs = 0;
  3102. }
  3103. else
  3104. {
  3105. B3_PROFILE("findConcaveSeparatingAxisKernel");
  3106. b3BufferInfoCL bInfo[] = {
  3107. b3BufferInfoCL(triangleConvexPairsOut.getBufferCL()),
  3108. b3BufferInfoCL(bodyBuf->getBufferCL(), true),
  3109. b3BufferInfoCL(gpuCollidables.getBufferCL(), true),
  3110. b3BufferInfoCL(convexData.getBufferCL(), true),
  3111. b3BufferInfoCL(gpuVertices.getBufferCL(), true),
  3112. b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true),
  3113. b3BufferInfoCL(gpuFaces.getBufferCL(), true),
  3114. b3BufferInfoCL(gpuIndices.getBufferCL(), true),
  3115. b3BufferInfoCL(gpuChildShapes.getBufferCL(), true),
  3116. b3BufferInfoCL(clAabbsWorldSpace.getBufferCL(), true),
  3117. b3BufferInfoCL(m_concaveSepNormals.getBufferCL()),
  3118. b3BufferInfoCL(m_concaveHasSeparatingNormals.getBufferCL()),
  3119. b3BufferInfoCL(clippingFacesOutGPU.getBufferCL()),
  3120. b3BufferInfoCL(worldVertsA1GPU.getBufferCL()),
  3121. b3BufferInfoCL(worldNormalsAGPU.getBufferCL()),
  3122. b3BufferInfoCL(worldVertsB1GPU.getBufferCL())};
  3123. b3LauncherCL launcher(m_queue, m_findConcaveSeparatingAxisKernel, "m_findConcaveSeparatingAxisKernel");
  3124. launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
  3125. launcher.setConst(vertexFaceCapacity);
  3126. launcher.setConst(numConcavePairs);
  3127. int num = numConcavePairs;
  3128. launcher.launch1D(num);
  3129. clFinish(m_queue);
  3130. }
  3131. }
  3132. else
  3133. {
  3134. b3AlignedObjectArray<b3Int4> clippingFacesOutCPU;
  3135. b3AlignedObjectArray<b3Vector3> worldVertsA1CPU;
  3136. b3AlignedObjectArray<b3Vector3> worldNormalsACPU;
  3137. b3AlignedObjectArray<b3Vector3> worldVertsB1CPU;
  3138. b3AlignedObjectArray<int> concaveHasSeparatingNormalsCPU;
  3139. b3AlignedObjectArray<b3Int4> triangleConvexPairsOutHost;
  3140. triangleConvexPairsOut.copyToHost(triangleConvexPairsOutHost);
  3141. //triangleConvexPairsOutHost.resize(maxTriConvexPairCapacity);
  3142. b3AlignedObjectArray<b3RigidBodyData> hostBodyBuf;
  3143. bodyBuf->copyToHost(hostBodyBuf);
  3144. b3AlignedObjectArray<b3Collidable> hostCollidables;
  3145. gpuCollidables.copyToHost(hostCollidables);
  3146. b3AlignedObjectArray<b3Aabb> hostAabbsWorldSpace;
  3147. clAabbsWorldSpace.copyToHost(hostAabbsWorldSpace);
  3148. b3AlignedObjectArray<b3ConvexPolyhedronData> hostConvexData;
  3149. convexData.copyToHost(hostConvexData);
  3150. b3AlignedObjectArray<b3Vector3> hostVertices;
  3151. gpuVertices.copyToHost(hostVertices);
  3152. b3AlignedObjectArray<b3Vector3> hostUniqueEdges;
  3153. gpuUniqueEdges.copyToHost(hostUniqueEdges);
  3154. b3AlignedObjectArray<b3GpuFace> hostFaces;
  3155. gpuFaces.copyToHost(hostFaces);
  3156. b3AlignedObjectArray<int> hostIndices;
  3157. gpuIndices.copyToHost(hostIndices);
  3158. b3AlignedObjectArray<b3GpuChildShape> cpuChildShapes;
  3159. gpuChildShapes.copyToHost(cpuChildShapes);
  3160. b3AlignedObjectArray<b3Vector3> concaveSepNormalsHost;
  3161. m_concaveSepNormals.copyToHost(concaveSepNormalsHost);
  3162. concaveHasSeparatingNormalsCPU.resize(concaveSepNormalsHost.size());
  3163. b3GpuChildShape* childShapePointerCPU = 0;
  3164. if (cpuChildShapes.size())
  3165. childShapePointerCPU = &cpuChildShapes.at(0);
  3166. clippingFacesOutCPU.resize(clippingFacesOutGPU.size());
  3167. worldVertsA1CPU.resize(worldVertsA1GPU.size());
  3168. worldNormalsACPU.resize(worldNormalsAGPU.size());
  3169. worldVertsB1CPU.resize(worldVertsB1GPU.size());
  3170. for (int i = 0; i < numConcavePairs; i++)
  3171. {
  3172. b3FindConcaveSeparatingAxisKernel(&triangleConvexPairsOutHost.at(0),
  3173. &hostBodyBuf.at(0),
  3174. &hostCollidables.at(0),
  3175. &hostConvexData.at(0), &hostVertices.at(0), &hostUniqueEdges.at(0),
  3176. &hostFaces.at(0), &hostIndices.at(0), childShapePointerCPU,
  3177. &hostAabbsWorldSpace.at(0),
  3178. &concaveSepNormalsHost.at(0),
  3179. &clippingFacesOutCPU.at(0),
  3180. &worldVertsA1CPU.at(0),
  3181. &worldNormalsACPU.at(0),
  3182. &worldVertsB1CPU.at(0),
  3183. &concaveHasSeparatingNormalsCPU.at(0),
  3184. vertexFaceCapacity,
  3185. numConcavePairs, i);
  3186. };
  3187. m_concaveSepNormals.copyFromHost(concaveSepNormalsHost);
  3188. m_concaveHasSeparatingNormals.copyFromHost(concaveHasSeparatingNormalsCPU);
  3189. clippingFacesOutGPU.copyFromHost(clippingFacesOutCPU);
  3190. worldVertsA1GPU.copyFromHost(worldVertsA1CPU);
  3191. worldNormalsAGPU.copyFromHost(worldNormalsACPU);
  3192. worldVertsB1GPU.copyFromHost(worldVertsB1CPU);
  3193. }
  3194. // b3AlignedObjectArray<b3Vector3> cpuCompoundSepNormals;
  3195. // m_concaveSepNormals.copyToHost(cpuCompoundSepNormals);
  3196. // b3AlignedObjectArray<b3Int4> cpuConcavePairs;
  3197. // triangleConvexPairsOut.copyToHost(cpuConcavePairs);
  3198. }
  3199. }
  3200. }
  3201. if (numConcavePairs)
  3202. {
  3203. if (numConcavePairs)
  3204. {
  3205. B3_PROFILE("findConcaveSphereContactsKernel");
  3206. nContacts = m_totalContactsOut.at(0);
  3207. // printf("nContacts1 = %d\n",nContacts);
  3208. b3BufferInfoCL bInfo[] = {
  3209. b3BufferInfoCL(triangleConvexPairsOut.getBufferCL()),
  3210. b3BufferInfoCL(bodyBuf->getBufferCL(), true),
  3211. b3BufferInfoCL(gpuCollidables.getBufferCL(), true),
  3212. b3BufferInfoCL(convexData.getBufferCL(), true),
  3213. b3BufferInfoCL(gpuVertices.getBufferCL(), true),
  3214. b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true),
  3215. b3BufferInfoCL(gpuFaces.getBufferCL(), true),
  3216. b3BufferInfoCL(gpuIndices.getBufferCL(), true),
  3217. b3BufferInfoCL(clAabbsWorldSpace.getBufferCL(), true),
  3218. b3BufferInfoCL(contactOut->getBufferCL()),
  3219. b3BufferInfoCL(m_totalContactsOut.getBufferCL())};
  3220. b3LauncherCL launcher(m_queue, m_findConcaveSphereContactsKernel, "m_findConcaveSphereContactsKernel");
  3221. launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
  3222. launcher.setConst(numConcavePairs);
  3223. launcher.setConst(maxContactCapacity);
  3224. int num = numConcavePairs;
  3225. launcher.launch1D(num);
  3226. clFinish(m_queue);
  3227. nContacts = m_totalContactsOut.at(0);
  3228. //printf("nContacts (after findConcaveSphereContactsKernel) = %d\n",nContacts);
  3229. //printf("nContacts2 = %d\n",nContacts);
  3230. if (nContacts >= maxContactCapacity)
  3231. {
  3232. b3Error("Error: contacts exceeds capacity (%d/%d)\n", nContacts, maxContactCapacity);
  3233. nContacts = maxContactCapacity;
  3234. }
  3235. }
  3236. }
  3237. #ifdef __APPLE__
  3238. bool contactClippingOnGpu = true;
  3239. #else
  3240. bool contactClippingOnGpu = true;
  3241. #endif
  3242. if (contactClippingOnGpu)
  3243. {
  3244. m_totalContactsOut.copyFromHostPointer(&nContacts, 1, 0, true);
  3245. // printf("nContacts3 = %d\n",nContacts);
  3246. //B3_PROFILE("clipHullHullKernel");
  3247. bool breakupConcaveConvexKernel = true;
  3248. #ifdef __APPLE__
  3249. //actually, some Apple OpenCL platform/device combinations work fine...
  3250. breakupConcaveConvexKernel = true;
  3251. #endif
  3252. //concave-convex contact clipping
  3253. if (numConcavePairs)
  3254. {
  3255. // printf("numConcavePairs = %d\n", numConcavePairs);
  3256. // nContacts = m_totalContactsOut.at(0);
  3257. // printf("nContacts before = %d\n", nContacts);
  3258. if (breakupConcaveConvexKernel)
  3259. {
  3260. worldVertsB2GPU.resize(vertexFaceCapacity * numConcavePairs);
  3261. //clipFacesAndFindContacts
  3262. if (clipConcaveFacesAndFindContactsCPU)
  3263. {
  3264. b3AlignedObjectArray<b3Int4> clippingFacesOutCPU;
  3265. b3AlignedObjectArray<b3Vector3> worldVertsA1CPU;
  3266. b3AlignedObjectArray<b3Vector3> worldNormalsACPU;
  3267. b3AlignedObjectArray<b3Vector3> worldVertsB1CPU;
  3268. clippingFacesOutGPU.copyToHost(clippingFacesOutCPU);
  3269. worldVertsA1GPU.copyToHost(worldVertsA1CPU);
  3270. worldNormalsAGPU.copyToHost(worldNormalsACPU);
  3271. worldVertsB1GPU.copyToHost(worldVertsB1CPU);
  3272. b3AlignedObjectArray<int> concaveHasSeparatingNormalsCPU;
  3273. m_concaveHasSeparatingNormals.copyToHost(concaveHasSeparatingNormalsCPU);
  3274. b3AlignedObjectArray<b3Vector3> concaveSepNormalsHost;
  3275. m_concaveSepNormals.copyToHost(concaveSepNormalsHost);
  3276. b3AlignedObjectArray<b3Vector3> worldVertsB2CPU;
  3277. worldVertsB2CPU.resize(worldVertsB2GPU.size());
  3278. for (int i = 0; i < numConcavePairs; i++)
  3279. {
  3280. clipFacesAndFindContactsKernel(&concaveSepNormalsHost.at(0),
  3281. &concaveHasSeparatingNormalsCPU.at(0),
  3282. &clippingFacesOutCPU.at(0),
  3283. &worldVertsA1CPU.at(0),
  3284. &worldNormalsACPU.at(0),
  3285. &worldVertsB1CPU.at(0),
  3286. &worldVertsB2CPU.at(0),
  3287. vertexFaceCapacity,
  3288. i);
  3289. }
  3290. clippingFacesOutGPU.copyFromHost(clippingFacesOutCPU);
  3291. worldVertsB2GPU.copyFromHost(worldVertsB2CPU);
  3292. }
  3293. else
  3294. {
  3295. if (1)
  3296. {
  3297. B3_PROFILE("clipFacesAndFindContacts");
  3298. //nContacts = m_totalContactsOut.at(0);
  3299. //int h = m_hasSeparatingNormals.at(0);
  3300. //int4 p = clippingFacesOutGPU.at(0);
  3301. b3BufferInfoCL bInfo[] = {
  3302. b3BufferInfoCL(m_concaveSepNormals.getBufferCL()),
  3303. b3BufferInfoCL(m_concaveHasSeparatingNormals.getBufferCL()),
  3304. b3BufferInfoCL(clippingFacesOutGPU.getBufferCL()),
  3305. b3BufferInfoCL(worldVertsA1GPU.getBufferCL()),
  3306. b3BufferInfoCL(worldNormalsAGPU.getBufferCL()),
  3307. b3BufferInfoCL(worldVertsB1GPU.getBufferCL()),
  3308. b3BufferInfoCL(worldVertsB2GPU.getBufferCL())};
  3309. b3LauncherCL launcher(m_queue, m_clipFacesAndFindContacts, "m_clipFacesAndFindContacts");
  3310. launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
  3311. launcher.setConst(vertexFaceCapacity);
  3312. launcher.setConst(numConcavePairs);
  3313. int debugMode = 0;
  3314. launcher.setConst(debugMode);
  3315. int num = numConcavePairs;
  3316. launcher.launch1D(num);
  3317. clFinish(m_queue);
  3318. //int bla = m_totalContactsOut.at(0);
  3319. }
  3320. }
  3321. //contactReduction
  3322. {
  3323. int newContactCapacity = nContacts + numConcavePairs;
  3324. contactOut->reserve(newContactCapacity);
  3325. if (reduceConcaveContactsOnGPU)
  3326. {
  3327. // printf("newReservation = %d\n",newReservation);
  3328. {
  3329. B3_PROFILE("newContactReductionKernel");
  3330. b3BufferInfoCL bInfo[] =
  3331. {
  3332. b3BufferInfoCL(triangleConvexPairsOut.getBufferCL(), true),
  3333. b3BufferInfoCL(bodyBuf->getBufferCL(), true),
  3334. b3BufferInfoCL(m_concaveSepNormals.getBufferCL()),
  3335. b3BufferInfoCL(m_concaveHasSeparatingNormals.getBufferCL()),
  3336. b3BufferInfoCL(contactOut->getBufferCL()),
  3337. b3BufferInfoCL(clippingFacesOutGPU.getBufferCL()),
  3338. b3BufferInfoCL(worldVertsB2GPU.getBufferCL()),
  3339. b3BufferInfoCL(m_totalContactsOut.getBufferCL())};
  3340. b3LauncherCL launcher(m_queue, m_newContactReductionKernel, "m_newContactReductionKernel");
  3341. launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
  3342. launcher.setConst(vertexFaceCapacity);
  3343. launcher.setConst(newContactCapacity);
  3344. launcher.setConst(numConcavePairs);
  3345. int num = numConcavePairs;
  3346. launcher.launch1D(num);
  3347. }
  3348. nContacts = m_totalContactsOut.at(0);
  3349. contactOut->resize(nContacts);
  3350. //printf("contactOut4 (after newContactReductionKernel) = %d\n",nContacts);
  3351. }
  3352. else
  3353. {
  3354. volatile int nGlobalContactsOut = nContacts;
  3355. b3AlignedObjectArray<b3Int4> triangleConvexPairsOutHost;
  3356. triangleConvexPairsOut.copyToHost(triangleConvexPairsOutHost);
  3357. b3AlignedObjectArray<b3RigidBodyData> hostBodyBuf;
  3358. bodyBuf->copyToHost(hostBodyBuf);
  3359. b3AlignedObjectArray<int> concaveHasSeparatingNormalsCPU;
  3360. m_concaveHasSeparatingNormals.copyToHost(concaveHasSeparatingNormalsCPU);
  3361. b3AlignedObjectArray<b3Vector3> concaveSepNormalsHost;
  3362. m_concaveSepNormals.copyToHost(concaveSepNormalsHost);
  3363. b3AlignedObjectArray<b3Contact4> hostContacts;
  3364. if (nContacts)
  3365. {
  3366. contactOut->copyToHost(hostContacts);
  3367. }
  3368. hostContacts.resize(newContactCapacity);
  3369. b3AlignedObjectArray<b3Int4> clippingFacesOutCPU;
  3370. b3AlignedObjectArray<b3Vector3> worldVertsB2CPU;
  3371. clippingFacesOutGPU.copyToHost(clippingFacesOutCPU);
  3372. worldVertsB2GPU.copyToHost(worldVertsB2CPU);
  3373. for (int i = 0; i < numConcavePairs; i++)
  3374. {
  3375. b3NewContactReductionKernel(&triangleConvexPairsOutHost.at(0),
  3376. &hostBodyBuf.at(0),
  3377. &concaveSepNormalsHost.at(0),
  3378. &concaveHasSeparatingNormalsCPU.at(0),
  3379. &hostContacts.at(0),
  3380. &clippingFacesOutCPU.at(0),
  3381. &worldVertsB2CPU.at(0),
  3382. &nGlobalContactsOut,
  3383. vertexFaceCapacity,
  3384. newContactCapacity,
  3385. numConcavePairs,
  3386. i);
  3387. }
  3388. nContacts = nGlobalContactsOut;
  3389. m_totalContactsOut.copyFromHostPointer(&nContacts, 1, 0, true);
  3390. // nContacts = m_totalContactsOut.at(0);
  3391. //contactOut->resize(nContacts);
  3392. hostContacts.resize(nContacts);
  3393. //printf("contactOut4 (after newContactReductionKernel) = %d\n",nContacts);
  3394. contactOut->copyFromHost(hostContacts);
  3395. }
  3396. }
  3397. //re-use?
  3398. }
  3399. else
  3400. {
  3401. B3_PROFILE("clipHullHullConcaveConvexKernel");
  3402. nContacts = m_totalContactsOut.at(0);
  3403. int newContactCapacity = contactOut->capacity();
  3404. //printf("contactOut5 = %d\n",nContacts);
  3405. b3BufferInfoCL bInfo[] = {
  3406. b3BufferInfoCL(triangleConvexPairsOut.getBufferCL(), true),
  3407. b3BufferInfoCL(bodyBuf->getBufferCL(), true),
  3408. b3BufferInfoCL(gpuCollidables.getBufferCL(), true),
  3409. b3BufferInfoCL(convexData.getBufferCL(), true),
  3410. b3BufferInfoCL(gpuVertices.getBufferCL(), true),
  3411. b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true),
  3412. b3BufferInfoCL(gpuFaces.getBufferCL(), true),
  3413. b3BufferInfoCL(gpuIndices.getBufferCL(), true),
  3414. b3BufferInfoCL(gpuChildShapes.getBufferCL(), true),
  3415. b3BufferInfoCL(m_concaveSepNormals.getBufferCL()),
  3416. b3BufferInfoCL(contactOut->getBufferCL()),
  3417. b3BufferInfoCL(m_totalContactsOut.getBufferCL())};
  3418. b3LauncherCL launcher(m_queue, m_clipHullHullConcaveConvexKernel, "m_clipHullHullConcaveConvexKernel");
  3419. launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
  3420. launcher.setConst(newContactCapacity);
  3421. launcher.setConst(numConcavePairs);
  3422. int num = numConcavePairs;
  3423. launcher.launch1D(num);
  3424. clFinish(m_queue);
  3425. nContacts = m_totalContactsOut.at(0);
  3426. contactOut->resize(nContacts);
  3427. //printf("contactOut6 = %d\n",nContacts);
  3428. b3AlignedObjectArray<b3Contact4> cpuContacts;
  3429. contactOut->copyToHost(cpuContacts);
  3430. }
  3431. // printf("nContacts after = %d\n", nContacts);
  3432. } //numConcavePairs
  3433. //convex-convex contact clipping
  3434. bool breakupKernel = false;
  3435. #ifdef __APPLE__
  3436. breakupKernel = true;
  3437. #endif
  3438. #ifdef CHECK_ON_HOST
  3439. bool computeConvexConvex = false;
  3440. #else
  3441. bool computeConvexConvex = true;
  3442. #endif //CHECK_ON_HOST
  3443. if (computeConvexConvex)
  3444. {
  3445. B3_PROFILE("clipHullHullKernel");
  3446. if (breakupKernel)
  3447. {
  3448. worldVertsB1GPU.resize(vertexFaceCapacity * nPairs);
  3449. clippingFacesOutGPU.resize(nPairs);
  3450. worldNormalsAGPU.resize(nPairs);
  3451. worldVertsA1GPU.resize(vertexFaceCapacity * nPairs);
  3452. worldVertsB2GPU.resize(vertexFaceCapacity * nPairs);
  3453. if (findConvexClippingFacesGPU)
  3454. {
  3455. B3_PROFILE("findClippingFacesKernel");
  3456. b3BufferInfoCL bInfo[] = {
  3457. b3BufferInfoCL(pairs->getBufferCL(), true),
  3458. b3BufferInfoCL(bodyBuf->getBufferCL(), true),
  3459. b3BufferInfoCL(gpuCollidables.getBufferCL(), true),
  3460. b3BufferInfoCL(convexData.getBufferCL(), true),
  3461. b3BufferInfoCL(gpuVertices.getBufferCL(), true),
  3462. b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true),
  3463. b3BufferInfoCL(gpuFaces.getBufferCL(), true),
  3464. b3BufferInfoCL(gpuIndices.getBufferCL(), true),
  3465. b3BufferInfoCL(m_sepNormals.getBufferCL()),
  3466. b3BufferInfoCL(m_hasSeparatingNormals.getBufferCL()),
  3467. b3BufferInfoCL(clippingFacesOutGPU.getBufferCL()),
  3468. b3BufferInfoCL(worldVertsA1GPU.getBufferCL()),
  3469. b3BufferInfoCL(worldNormalsAGPU.getBufferCL()),
  3470. b3BufferInfoCL(worldVertsB1GPU.getBufferCL())};
  3471. b3LauncherCL launcher(m_queue, m_findClippingFacesKernel, "m_findClippingFacesKernel");
  3472. launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
  3473. launcher.setConst(vertexFaceCapacity);
  3474. launcher.setConst(nPairs);
  3475. int num = nPairs;
  3476. launcher.launch1D(num);
  3477. clFinish(m_queue);
  3478. }
  3479. else
  3480. {
  3481. float minDist = -1e30f;
  3482. float maxDist = 0.02f;
  3483. b3AlignedObjectArray<b3ConvexPolyhedronData> hostConvexData;
  3484. convexData.copyToHost(hostConvexData);
  3485. b3AlignedObjectArray<b3Collidable> hostCollidables;
  3486. gpuCollidables.copyToHost(hostCollidables);
  3487. b3AlignedObjectArray<int> hostHasSepNormals;
  3488. m_hasSeparatingNormals.copyToHost(hostHasSepNormals);
  3489. b3AlignedObjectArray<b3Vector3> cpuSepNormals;
  3490. m_sepNormals.copyToHost(cpuSepNormals);
  3491. b3AlignedObjectArray<b3Int4> hostPairs;
  3492. pairs->copyToHost(hostPairs);
  3493. b3AlignedObjectArray<b3RigidBodyData> hostBodyBuf;
  3494. bodyBuf->copyToHost(hostBodyBuf);
  3495. //worldVertsB1GPU.resize(vertexFaceCapacity*nPairs);
  3496. b3AlignedObjectArray<b3Vector3> worldVertsB1CPU;
  3497. worldVertsB1GPU.copyToHost(worldVertsB1CPU);
  3498. b3AlignedObjectArray<b3Int4> clippingFacesOutCPU;
  3499. clippingFacesOutGPU.copyToHost(clippingFacesOutCPU);
  3500. b3AlignedObjectArray<b3Vector3> worldNormalsACPU;
  3501. worldNormalsACPU.resize(nPairs);
  3502. b3AlignedObjectArray<b3Vector3> worldVertsA1CPU;
  3503. worldVertsA1CPU.resize(worldVertsA1GPU.size());
  3504. b3AlignedObjectArray<b3Vector3> hostVertices;
  3505. gpuVertices.copyToHost(hostVertices);
  3506. b3AlignedObjectArray<b3GpuFace> hostFaces;
  3507. gpuFaces.copyToHost(hostFaces);
  3508. b3AlignedObjectArray<int> hostIndices;
  3509. gpuIndices.copyToHost(hostIndices);
  3510. for (int i = 0; i < nPairs; i++)
  3511. {
  3512. int bodyIndexA = hostPairs[i].x;
  3513. int bodyIndexB = hostPairs[i].y;
  3514. int collidableIndexA = hostBodyBuf[bodyIndexA].m_collidableIdx;
  3515. int collidableIndexB = hostBodyBuf[bodyIndexB].m_collidableIdx;
  3516. int shapeIndexA = hostCollidables[collidableIndexA].m_shapeIndex;
  3517. int shapeIndexB = hostCollidables[collidableIndexB].m_shapeIndex;
  3518. if (hostHasSepNormals[i])
  3519. {
  3520. b3FindClippingFaces(cpuSepNormals[i],
  3521. &hostConvexData[shapeIndexA],
  3522. &hostConvexData[shapeIndexB],
  3523. hostBodyBuf[bodyIndexA].m_pos, hostBodyBuf[bodyIndexA].m_quat,
  3524. hostBodyBuf[bodyIndexB].m_pos, hostBodyBuf[bodyIndexB].m_quat,
  3525. &worldVertsA1CPU.at(0), &worldNormalsACPU.at(0),
  3526. &worldVertsB1CPU.at(0),
  3527. vertexFaceCapacity, minDist, maxDist,
  3528. &hostVertices.at(0), &hostFaces.at(0),
  3529. &hostIndices.at(0),
  3530. &hostVertices.at(0), &hostFaces.at(0),
  3531. &hostIndices.at(0), &clippingFacesOutCPU.at(0), i);
  3532. }
  3533. }
  3534. clippingFacesOutGPU.copyFromHost(clippingFacesOutCPU);
  3535. worldVertsA1GPU.copyFromHost(worldVertsA1CPU);
  3536. worldNormalsAGPU.copyFromHost(worldNormalsACPU);
  3537. worldVertsB1GPU.copyFromHost(worldVertsB1CPU);
  3538. }
  3539. ///clip face B against face A, reduce contacts and append them to a global contact array
  3540. if (1)
  3541. {
  3542. if (clipConvexFacesAndFindContactsCPU)
  3543. {
  3544. //b3AlignedObjectArray<b3Int4> hostPairs;
  3545. //pairs->copyToHost(hostPairs);
  3546. b3AlignedObjectArray<b3Vector3> hostSepNormals;
  3547. m_sepNormals.copyToHost(hostSepNormals);
  3548. b3AlignedObjectArray<int> hostHasSepAxis;
  3549. m_hasSeparatingNormals.copyToHost(hostHasSepAxis);
  3550. b3AlignedObjectArray<b3Int4> hostClippingFaces;
  3551. clippingFacesOutGPU.copyToHost(hostClippingFaces);
  3552. b3AlignedObjectArray<b3Vector3> worldVertsB2CPU;
  3553. worldVertsB2CPU.resize(vertexFaceCapacity * nPairs);
  3554. b3AlignedObjectArray<b3Vector3> worldVertsA1CPU;
  3555. worldVertsA1GPU.copyToHost(worldVertsA1CPU);
  3556. b3AlignedObjectArray<b3Vector3> worldNormalsACPU;
  3557. worldNormalsAGPU.copyToHost(worldNormalsACPU);
  3558. b3AlignedObjectArray<b3Vector3> worldVertsB1CPU;
  3559. worldVertsB1GPU.copyToHost(worldVertsB1CPU);
  3560. /*
  3561. __global const b3Float4* separatingNormals,
  3562. __global const int* hasSeparatingAxis,
  3563. __global b3Int4* clippingFacesOut,
  3564. __global b3Float4* worldVertsA1,
  3565. __global b3Float4* worldNormalsA1,
  3566. __global b3Float4* worldVertsB1,
  3567. __global b3Float4* worldVertsB2,
  3568. int vertexFaceCapacity,
  3569. int pairIndex
  3570. */
  3571. for (int i = 0; i < nPairs; i++)
  3572. {
  3573. clipFacesAndFindContactsKernel(
  3574. &hostSepNormals.at(0),
  3575. &hostHasSepAxis.at(0),
  3576. &hostClippingFaces.at(0),
  3577. &worldVertsA1CPU.at(0),
  3578. &worldNormalsACPU.at(0),
  3579. &worldVertsB1CPU.at(0),
  3580. &worldVertsB2CPU.at(0),
  3581. vertexFaceCapacity,
  3582. i);
  3583. }
  3584. clippingFacesOutGPU.copyFromHost(hostClippingFaces);
  3585. worldVertsB2GPU.copyFromHost(worldVertsB2CPU);
  3586. }
  3587. else
  3588. {
  3589. B3_PROFILE("clipFacesAndFindContacts");
  3590. //nContacts = m_totalContactsOut.at(0);
  3591. //int h = m_hasSeparatingNormals.at(0);
  3592. //int4 p = clippingFacesOutGPU.at(0);
  3593. b3BufferInfoCL bInfo[] = {
  3594. b3BufferInfoCL(m_sepNormals.getBufferCL()),
  3595. b3BufferInfoCL(m_hasSeparatingNormals.getBufferCL()),
  3596. b3BufferInfoCL(clippingFacesOutGPU.getBufferCL()),
  3597. b3BufferInfoCL(worldVertsA1GPU.getBufferCL()),
  3598. b3BufferInfoCL(worldNormalsAGPU.getBufferCL()),
  3599. b3BufferInfoCL(worldVertsB1GPU.getBufferCL()),
  3600. b3BufferInfoCL(worldVertsB2GPU.getBufferCL())};
  3601. b3LauncherCL launcher(m_queue, m_clipFacesAndFindContacts, "m_clipFacesAndFindContacts");
  3602. launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
  3603. launcher.setConst(vertexFaceCapacity);
  3604. launcher.setConst(nPairs);
  3605. int debugMode = 0;
  3606. launcher.setConst(debugMode);
  3607. int num = nPairs;
  3608. launcher.launch1D(num);
  3609. clFinish(m_queue);
  3610. }
  3611. {
  3612. nContacts = m_totalContactsOut.at(0);
  3613. //printf("nContacts = %d\n",nContacts);
  3614. int newContactCapacity = nContacts + nPairs;
  3615. contactOut->reserve(newContactCapacity);
  3616. if (reduceConvexContactsOnGPU)
  3617. {
  3618. {
  3619. B3_PROFILE("newContactReductionKernel");
  3620. b3BufferInfoCL bInfo[] =
  3621. {
  3622. b3BufferInfoCL(pairs->getBufferCL(), true),
  3623. b3BufferInfoCL(bodyBuf->getBufferCL(), true),
  3624. b3BufferInfoCL(m_sepNormals.getBufferCL()),
  3625. b3BufferInfoCL(m_hasSeparatingNormals.getBufferCL()),
  3626. b3BufferInfoCL(contactOut->getBufferCL()),
  3627. b3BufferInfoCL(clippingFacesOutGPU.getBufferCL()),
  3628. b3BufferInfoCL(worldVertsB2GPU.getBufferCL()),
  3629. b3BufferInfoCL(m_totalContactsOut.getBufferCL())};
  3630. b3LauncherCL launcher(m_queue, m_newContactReductionKernel, "m_newContactReductionKernel");
  3631. launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
  3632. launcher.setConst(vertexFaceCapacity);
  3633. launcher.setConst(newContactCapacity);
  3634. launcher.setConst(nPairs);
  3635. int num = nPairs;
  3636. launcher.launch1D(num);
  3637. }
  3638. nContacts = m_totalContactsOut.at(0);
  3639. contactOut->resize(nContacts);
  3640. }
  3641. else
  3642. {
  3643. volatile int nGlobalContactsOut = nContacts;
  3644. b3AlignedObjectArray<b3Int4> hostPairs;
  3645. pairs->copyToHost(hostPairs);
  3646. b3AlignedObjectArray<b3RigidBodyData> hostBodyBuf;
  3647. bodyBuf->copyToHost(hostBodyBuf);
  3648. b3AlignedObjectArray<b3Vector3> hostSepNormals;
  3649. m_sepNormals.copyToHost(hostSepNormals);
  3650. b3AlignedObjectArray<int> hostHasSepAxis;
  3651. m_hasSeparatingNormals.copyToHost(hostHasSepAxis);
  3652. b3AlignedObjectArray<b3Contact4> hostContactsOut;
  3653. contactOut->copyToHost(hostContactsOut);
  3654. hostContactsOut.resize(newContactCapacity);
  3655. b3AlignedObjectArray<b3Int4> hostClippingFaces;
  3656. clippingFacesOutGPU.copyToHost(hostClippingFaces);
  3657. b3AlignedObjectArray<b3Vector3> worldVertsB2CPU;
  3658. worldVertsB2GPU.copyToHost(worldVertsB2CPU);
  3659. for (int i = 0; i < nPairs; i++)
  3660. {
  3661. b3NewContactReductionKernel(&hostPairs.at(0),
  3662. &hostBodyBuf.at(0),
  3663. &hostSepNormals.at(0),
  3664. &hostHasSepAxis.at(0),
  3665. &hostContactsOut.at(0),
  3666. &hostClippingFaces.at(0),
  3667. &worldVertsB2CPU.at(0),
  3668. &nGlobalContactsOut,
  3669. vertexFaceCapacity,
  3670. newContactCapacity,
  3671. nPairs,
  3672. i);
  3673. }
  3674. nContacts = nGlobalContactsOut;
  3675. m_totalContactsOut.copyFromHostPointer(&nContacts, 1, 0, true);
  3676. hostContactsOut.resize(nContacts);
  3677. //printf("contactOut4 (after newContactReductionKernel) = %d\n",nContacts);
  3678. contactOut->copyFromHost(hostContactsOut);
  3679. }
  3680. // b3Contact4 pt = contactOut->at(0);
  3681. // printf("nContacts = %d\n",nContacts);
  3682. }
  3683. }
  3684. }
  3685. else //breakupKernel
  3686. {
  3687. if (nPairs)
  3688. {
  3689. b3BufferInfoCL bInfo[] = {
  3690. b3BufferInfoCL(pairs->getBufferCL(), true),
  3691. b3BufferInfoCL(bodyBuf->getBufferCL(), true),
  3692. b3BufferInfoCL(gpuCollidables.getBufferCL(), true),
  3693. b3BufferInfoCL(convexData.getBufferCL(), true),
  3694. b3BufferInfoCL(gpuVertices.getBufferCL(), true),
  3695. b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true),
  3696. b3BufferInfoCL(gpuFaces.getBufferCL(), true),
  3697. b3BufferInfoCL(gpuIndices.getBufferCL(), true),
  3698. b3BufferInfoCL(m_sepNormals.getBufferCL()),
  3699. b3BufferInfoCL(m_hasSeparatingNormals.getBufferCL()),
  3700. b3BufferInfoCL(contactOut->getBufferCL()),
  3701. b3BufferInfoCL(m_totalContactsOut.getBufferCL())};
  3702. b3LauncherCL launcher(m_queue, m_clipHullHullKernel, "m_clipHullHullKernel");
  3703. launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
  3704. launcher.setConst(nPairs);
  3705. launcher.setConst(maxContactCapacity);
  3706. int num = nPairs;
  3707. launcher.launch1D(num);
  3708. clFinish(m_queue);
  3709. nContacts = m_totalContactsOut.at(0);
  3710. if (nContacts >= maxContactCapacity)
  3711. {
  3712. b3Error("Exceeded contact capacity (%d/%d)\n", nContacts, maxContactCapacity);
  3713. nContacts = maxContactCapacity;
  3714. }
  3715. contactOut->resize(nContacts);
  3716. }
  3717. }
  3718. int nCompoundsPairs = m_gpuCompoundPairs.size();
  3719. if (nCompoundsPairs)
  3720. {
  3721. b3BufferInfoCL bInfo[] = {
  3722. b3BufferInfoCL(m_gpuCompoundPairs.getBufferCL(), true),
  3723. b3BufferInfoCL(bodyBuf->getBufferCL(), true),
  3724. b3BufferInfoCL(gpuCollidables.getBufferCL(), true),
  3725. b3BufferInfoCL(convexData.getBufferCL(), true),
  3726. b3BufferInfoCL(gpuVertices.getBufferCL(), true),
  3727. b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true),
  3728. b3BufferInfoCL(gpuFaces.getBufferCL(), true),
  3729. b3BufferInfoCL(gpuIndices.getBufferCL(), true),
  3730. b3BufferInfoCL(gpuChildShapes.getBufferCL(), true),
  3731. b3BufferInfoCL(m_gpuCompoundSepNormals.getBufferCL(), true),
  3732. b3BufferInfoCL(m_gpuHasCompoundSepNormals.getBufferCL(), true),
  3733. b3BufferInfoCL(contactOut->getBufferCL()),
  3734. b3BufferInfoCL(m_totalContactsOut.getBufferCL())};
  3735. b3LauncherCL launcher(m_queue, m_clipCompoundsHullHullKernel, "m_clipCompoundsHullHullKernel");
  3736. launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
  3737. launcher.setConst(nCompoundsPairs);
  3738. launcher.setConst(maxContactCapacity);
  3739. int num = nCompoundsPairs;
  3740. launcher.launch1D(num);
  3741. clFinish(m_queue);
  3742. nContacts = m_totalContactsOut.at(0);
  3743. if (nContacts > maxContactCapacity)
  3744. {
  3745. b3Error("Error: contacts exceeds capacity (%d/%d)\n", nContacts, maxContactCapacity);
  3746. nContacts = maxContactCapacity;
  3747. }
  3748. contactOut->resize(nContacts);
  3749. } //if nCompoundsPairs
  3750. }
  3751. } //contactClippingOnGpu
  3752. //printf("nContacts end = %d\n",nContacts);
  3753. //printf("frameCount = %d\n",frameCount++);
  3754. }