ufbx.h 211 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897
  1. #ifndef UFBX_UFBX_H_INCLUDED
  2. #define UFBX_UFBX_H_INCLUDED
  3. // -- User configuration
  4. #if defined(UFBX_CONFIG_HEADER)
  5. #include UFBX_CONFIG_HEADER
  6. #endif
  7. // -- Headers
  8. #if !defined(UFBX_NO_LIBC_TYPES)
  9. #include <stdint.h>
  10. #include <stddef.h>
  11. #include <stdbool.h>
  12. #endif
  13. // -- Platform
  14. #ifndef UFBX_STDC
  15. #if defined(__STDC_VERSION__)
  16. #define UFBX_STDC __STDC_VERSION__
  17. #else
  18. #define UFBX_STDC 0
  19. #endif
  20. #endif
  21. #ifndef UFBX_CPP
  22. #if defined(__cplusplus)
  23. #define UFBX_CPP __cplusplus
  24. #else
  25. #define UFBX_CPP 0
  26. #endif
  27. #endif
  28. #ifndef UFBX_PLATFORM_MSC
  29. #if !defined(UFBX_STANDARD_C) && defined(_MSC_VER)
  30. #define UFBX_PLATFORM_MSC _MSC_VER
  31. #else
  32. #define UFBX_PLATFORM_MSC 0
  33. #endif
  34. #endif
  35. #ifndef UFBX_PLATFORM_GNUC
  36. #if !defined(UFBX_STANDARD_C) && defined(__GNUC__)
  37. #define UFBX_PLATFORM_GNUC __GNUC__
  38. #else
  39. #define UFBX_PLATFORM_GNUC 0
  40. #endif
  41. #endif
  42. #ifndef UFBX_CPP11
  43. // MSVC does not advertise C++11 by default so we need special detection
  44. #if UFBX_CPP >= 201103L || (UFBX_CPP > 0 && UFBX_PLATFORM_MSC >= 1900)
  45. #define UFBX_CPP11 1
  46. #else
  47. #define UFBX_CPP11 0
  48. #endif
  49. #endif
  50. #if defined(_MSC_VER)
  51. #pragma warning(push)
  52. #pragma warning(disable: 4061) // enumerator 'ENUM' in switch of enum 'enum' is not explicitly handled by a case label
  53. #pragma warning(disable: 4201) // nonstandard extension used: nameless struct/union
  54. #pragma warning(disable: 4505) // unreferenced local function has been removed
  55. #pragma warning(disable: 4820) // type': 'N' bytes padding added after data member 'member'
  56. #elif defined(__clang__)
  57. #pragma clang diagnostic push
  58. #pragma clang diagnostic ignored "-Wpedantic"
  59. #pragma clang diagnostic ignored "-Wpadded"
  60. #if defined(__cplusplus)
  61. #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
  62. #pragma clang diagnostic ignored "-Wold-style-cast"
  63. #endif
  64. #elif defined(__GNUC__)
  65. #pragma GCC diagnostic push
  66. #pragma GCC diagnostic ignored "-Wpedantic"
  67. #pragma GCC diagnostic ignored "-Wpadded"
  68. #if defined(__cplusplus)
  69. #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
  70. #pragma GCC diagnostic ignored "-Wold-style-cast"
  71. #else
  72. #if __GNUC__ >= 5
  73. #pragma GCC diagnostic ignored "-Wc90-c99-compat"
  74. #pragma GCC diagnostic ignored "-Wc99-c11-compat"
  75. #endif
  76. #endif
  77. #endif
  78. #if UFBX_PLATFORM_MSC
  79. #define ufbx_inline static __forceinline
  80. #elif UFBX_PLATFORM_GNUC
  81. #define ufbx_inline static inline __attribute__((always_inline, unused))
  82. #else
  83. #define ufbx_inline static
  84. #endif
  85. // Assertion function used in ufbx, defaults to C standard `assert()`.
  86. // You can define this to your custom preferred assert macro, but in that case
  87. // make sure that it is also used within `ufbx.c`.
  88. // Defining `UFBX_NO_ASSERT` to any value disables assertions.
  89. #ifndef ufbx_assert
  90. #if defined(UFBX_NO_ASSERT) || defined(UFBX_NO_LIBC)
  91. #define ufbx_assert(cond) (void)0
  92. #else
  93. #include <assert.h>
  94. #define ufbx_assert(cond) assert(cond)
  95. #endif
  96. #endif
  97. // Pointer may be `NULL`.
  98. #define ufbx_nullable
  99. // Changing this value from default or calling this function can lead into
  100. // breaking API guarantees.
  101. #define ufbx_unsafe
  102. // Linkage of the main ufbx API functions.
  103. // Defaults to nothing, or `static` if `UFBX_STATIC` is defined.
  104. // If you want to isolate ufbx to a single translation unit you can do the following:
  105. // #define UFBX_STATIC
  106. // #include "ufbx.h"
  107. // #include "ufbx.c"
  108. #ifndef ufbx_abi
  109. #if defined(UFBX_STATIC)
  110. #define ufbx_abi static
  111. #else
  112. #define ufbx_abi
  113. #endif
  114. #endif
  115. // Linkage of the main ufbx data fields in the header.
  116. // Defaults to `extern`, or `static` if `UFBX_STATIC` is defined.
  117. #ifndef ufbx_abi_data
  118. #if defined(UFBX_STATIC)
  119. #define ufbx_abi_data static
  120. #else
  121. #define ufbx_abi_data extern
  122. #endif
  123. #endif
  124. // Linkage of the main ufbx data fields in the source.
  125. // Defaults to nothing, or `static` if `UFBX_STATIC` is defined.
  126. #ifndef ufbx_abi_data_definition
  127. #if defined(UFBX_STATIC)
  128. #define ufbx_abi_data_def static
  129. #else
  130. #define ufbx_abi_data_def
  131. #endif
  132. #endif
  133. // -- Configuration
  134. #ifndef UFBX_REAL_TYPE
  135. #if defined(UFBX_REAL_IS_FLOAT)
  136. #define UFBX_REAL_TYPE float
  137. #else
  138. #define UFBX_REAL_TYPE double
  139. #endif
  140. #endif
  141. // Limits for embedded arrays within structures.
  142. #define UFBX_ERROR_STACK_MAX_DEPTH 8
  143. #define UFBX_PANIC_MESSAGE_LENGTH 128
  144. #define UFBX_ERROR_INFO_LENGTH 256
  145. // Number of thread groups to use if threading is enabled.
  146. // A thread group processes a number of tasks and is then waited and potentially
  147. // re-used later. In essence, this controls the granularity of threading.
  148. #define UFBX_THREAD_GROUP_COUNT 4
  149. // -- Language
  150. // bindgen-disable
  151. #if UFBX_CPP11
  152. template <typename T, typename U>
  153. struct ufbxi_type_is { };
  154. template <typename T>
  155. struct ufbxi_type_is<T, T> { using type = int; };
  156. template <typename T>
  157. struct ufbx_converter { };
  158. #define UFBX_CONVERSION_IMPL(p_name) \
  159. template <typename T, typename S=typename ufbxi_type_is<T, decltype(ufbx_converter<T>::from(*(const p_name*)nullptr))>::type> \
  160. operator T() const { return ufbx_converter<T>::from(*this); }
  161. #define UFBX_CONVERSION_TO_IMPL(p_name) \
  162. template <typename T, typename S=typename ufbxi_type_is<p_name, decltype(ufbx_converter<T>::to(*(const T*)nullptr))>::type> \
  163. p_name(const T &t) { *this = ufbx_converter<T>::to(t); }
  164. #define UFBX_CONVERSION_LIST_IMPL(p_name) \
  165. template <typename T, typename S=typename ufbxi_type_is<T, decltype(ufbx_converter<T>::from_list((p_name*)nullptr, (size_t)0))>::type> \
  166. operator T() const { return ufbx_converter<T>::from_list(data, count); }
  167. #else
  168. #define UFBX_CONVERSION_IMPL(p_name)
  169. #define UFBX_CONVERSION_TO_IMPL(p_name)
  170. #define UFBX_CONVERSION_LIST_IMPL(p_name)
  171. #endif
  172. #if defined(__cplusplus)
  173. #define UFBX_LIST_TYPE(p_name, p_type) struct p_name { p_type *data; size_t count; \
  174. p_type &operator[](size_t index) const { ufbx_assert(index < count); return data[index]; } \
  175. p_type *begin() const { return data; } \
  176. p_type *end() const { return data + count; } \
  177. UFBX_CONVERSION_LIST_IMPL(p_type) \
  178. }
  179. #else
  180. #define UFBX_LIST_TYPE(p_name, p_type) typedef struct p_name { p_type *data; size_t count; } p_name
  181. #endif
  182. // This cannot be enabled automatically if supported as the source file may be
  183. // compiled with a different compiler using different settings than the header
  184. // consumers, in practice it should work but it causes issues such as #70.
  185. #if (UFBX_STDC >= 202311L || UFBX_CPP11) && defined(UFBX_USE_EXPLICIT_ENUM)
  186. #define UFBX_ENUM_REPR : int
  187. #define UFBX_ENUM_FORCE_WIDTH(p_prefix)
  188. #define UFBX_FLAG_REPR : int
  189. #define UFBX_FLAG_FORCE_WIDTH(p_prefix)
  190. #define UFBX_HAS_FORCE_32BIT 0
  191. #else
  192. #define UFBX_ENUM_REPR
  193. #define UFBX_ENUM_FORCE_WIDTH(p_prefix) p_prefix##_FORCE_32BIT = 0x7fffffff
  194. #define UFBX_FLAG_REPR
  195. #define UFBX_FLAG_FORCE_WIDTH(p_prefix) p_prefix##_FORCE_32BIT = 0x7fffffff
  196. #define UFBX_HAS_FORCE_32BIT 1
  197. #endif
  198. #define UFBX_ENUM_TYPE(p_name, p_prefix, p_last) \
  199. enum { p_prefix##_COUNT = p_last + 1 }
  200. #if UFBX_CPP
  201. #define UFBX_VERTEX_ATTRIB_IMPL(p_type) \
  202. p_type &operator[](size_t index) const { ufbx_assert(index < indices.count); return values.data[indices.data[index]]; }
  203. #else
  204. #define UFBX_VERTEX_ATTRIB_IMPL(p_type)
  205. #endif
  206. #if UFBX_CPP11
  207. #define UFBX_CALLBACK_IMPL(p_name, p_fn, p_return, p_params, p_args) \
  208. template <typename F> static p_return _cpp_adapter p_params { F &f = *static_cast<F*>(user); return f p_args; } \
  209. p_name() = default; \
  210. p_name(p_fn *f) : fn(f), user(nullptr) { } \
  211. template <typename F> p_name(F *f) : fn(&_cpp_adapter<F>), user(static_cast<void*>(f)) { }
  212. #else
  213. #define UFBX_CALLBACK_IMPL(p_name, p_fn, p_return, p_params, p_args)
  214. #endif
  215. // bindgen-enable
  216. // -- Version
  217. // Packing/unpacking for `UFBX_HEADER_VERSION` and `ufbx_source_version`.
  218. #define ufbx_pack_version(major, minor, patch) ((uint32_t)(major)*1000000u + (uint32_t)(minor)*1000u + (uint32_t)(patch))
  219. #define ufbx_version_major(version) ((uint32_t)(version)/1000000u%1000u)
  220. #define ufbx_version_minor(version) ((uint32_t)(version)/1000u%1000u)
  221. #define ufbx_version_patch(version) ((uint32_t)(version)%1000u)
  222. // Version of the ufbx header.
  223. // `UFBX_VERSION` is simply an alias of `UFBX_HEADER_VERSION`.
  224. // `ufbx_source_version` contains the version of the corresponding source file.
  225. // HINT: The version can be compared numerically to the result of `ufbx_pack_version()`,
  226. // for example `#if UFBX_VERSION >= ufbx_pack_version(0, 12, 0)`.
  227. #define UFBX_HEADER_VERSION ufbx_pack_version(0, 15, 0)
  228. #define UFBX_VERSION UFBX_HEADER_VERSION
  229. // -- Basic types
  230. // Main floating point type used everywhere in ufbx, defaults to `double`.
  231. // If you define `UFBX_REAL_IS_FLOAT` to any value, `ufbx_real` will be defined
  232. // as `float` instead.
  233. // You can also manually define `UFBX_REAL_TYPE` to any floating point type.
  234. typedef UFBX_REAL_TYPE ufbx_real;
  235. // Null-terminated UTF-8 encoded string within an FBX file
  236. typedef struct ufbx_string {
  237. const char *data;
  238. size_t length;
  239. UFBX_CONVERSION_IMPL(ufbx_string)
  240. } ufbx_string;
  241. // Opaque byte buffer blob
  242. typedef struct ufbx_blob {
  243. const void *data;
  244. size_t size;
  245. UFBX_CONVERSION_IMPL(ufbx_blob)
  246. } ufbx_blob;
  247. // 2D vector
  248. typedef struct ufbx_vec2 {
  249. union {
  250. struct { ufbx_real x, y; };
  251. ufbx_real v[2];
  252. };
  253. UFBX_CONVERSION_IMPL(ufbx_vec2)
  254. } ufbx_vec2;
  255. // 3D vector
  256. typedef struct ufbx_vec3 {
  257. union {
  258. struct { ufbx_real x, y, z; };
  259. ufbx_real v[3];
  260. };
  261. UFBX_CONVERSION_IMPL(ufbx_vec3)
  262. } ufbx_vec3;
  263. // 4D vector
  264. typedef struct ufbx_vec4 {
  265. union {
  266. struct { ufbx_real x, y, z, w; };
  267. ufbx_real v[4];
  268. };
  269. UFBX_CONVERSION_IMPL(ufbx_vec4)
  270. } ufbx_vec4;
  271. // Quaternion
  272. typedef struct ufbx_quat {
  273. union {
  274. struct { ufbx_real x, y, z, w; };
  275. ufbx_real v[4];
  276. };
  277. UFBX_CONVERSION_IMPL(ufbx_quat)
  278. } ufbx_quat;
  279. // Order in which Euler-angle rotation axes are applied for a transform
  280. // NOTE: The order in the name refers to the order of axes *applied*,
  281. // not the multiplication order: eg. `UFBX_ROTATION_ORDER_XYZ` is `Z*Y*X`
  282. // [TODO: Figure out what the spheric rotation order is...]
  283. typedef enum ufbx_rotation_order UFBX_ENUM_REPR {
  284. UFBX_ROTATION_ORDER_XYZ,
  285. UFBX_ROTATION_ORDER_XZY,
  286. UFBX_ROTATION_ORDER_YZX,
  287. UFBX_ROTATION_ORDER_YXZ,
  288. UFBX_ROTATION_ORDER_ZXY,
  289. UFBX_ROTATION_ORDER_ZYX,
  290. UFBX_ROTATION_ORDER_SPHERIC,
  291. UFBX_ENUM_FORCE_WIDTH(UFBX_ROTATION_ORDER)
  292. } ufbx_rotation_order;
  293. UFBX_ENUM_TYPE(ufbx_rotation_order, UFBX_ROTATION_ORDER, UFBX_ROTATION_ORDER_SPHERIC);
  294. // Explicit translation+rotation+scale transformation.
  295. // NOTE: Rotation is a quaternion, not Euler angles!
  296. typedef struct ufbx_transform {
  297. ufbx_vec3 translation;
  298. ufbx_quat rotation;
  299. ufbx_vec3 scale;
  300. UFBX_CONVERSION_IMPL(ufbx_transform)
  301. } ufbx_transform;
  302. // 4x3 matrix encoding an affine transformation.
  303. // `cols[0..2]` are the X/Y/Z basis vectors, `cols[3]` is the translation
  304. typedef struct ufbx_matrix {
  305. union {
  306. struct {
  307. ufbx_real m00, m10, m20;
  308. ufbx_real m01, m11, m21;
  309. ufbx_real m02, m12, m22;
  310. ufbx_real m03, m13, m23;
  311. };
  312. ufbx_vec3 cols[4];
  313. ufbx_real v[12];
  314. };
  315. UFBX_CONVERSION_IMPL(ufbx_matrix)
  316. } ufbx_matrix;
  317. typedef struct ufbx_void_list {
  318. void *data;
  319. size_t count;
  320. } ufbx_void_list;
  321. UFBX_LIST_TYPE(ufbx_bool_list, bool);
  322. UFBX_LIST_TYPE(ufbx_uint32_list, uint32_t);
  323. UFBX_LIST_TYPE(ufbx_real_list, ufbx_real);
  324. UFBX_LIST_TYPE(ufbx_vec2_list, ufbx_vec2);
  325. UFBX_LIST_TYPE(ufbx_vec3_list, ufbx_vec3);
  326. UFBX_LIST_TYPE(ufbx_vec4_list, ufbx_vec4);
  327. UFBX_LIST_TYPE(ufbx_string_list, ufbx_string);
  328. // Sentinel value used to represent a missing index.
  329. #define UFBX_NO_INDEX ((uint32_t)~0u)
  330. // -- Document object model
  331. typedef enum ufbx_dom_value_type UFBX_ENUM_REPR {
  332. UFBX_DOM_VALUE_NUMBER,
  333. UFBX_DOM_VALUE_STRING,
  334. UFBX_DOM_VALUE_ARRAY_I8,
  335. UFBX_DOM_VALUE_ARRAY_I32,
  336. UFBX_DOM_VALUE_ARRAY_I64,
  337. UFBX_DOM_VALUE_ARRAY_F32,
  338. UFBX_DOM_VALUE_ARRAY_F64,
  339. UFBX_DOM_VALUE_ARRAY_RAW_STRING,
  340. UFBX_DOM_VALUE_ARRAY_IGNORED,
  341. UFBX_ENUM_FORCE_WIDTH(UFBX_DOM_VALUE_TYPE)
  342. } ufbx_dom_value_type;
  343. UFBX_ENUM_TYPE(ufbx_dom_value_type, UFBX_DOM_VALUE_TYPE, UFBX_DOM_VALUE_ARRAY_IGNORED);
  344. typedef struct ufbx_dom_node ufbx_dom_node;
  345. typedef struct ufbx_dom_value {
  346. ufbx_dom_value_type type;
  347. ufbx_string value_str;
  348. ufbx_blob value_blob;
  349. int64_t value_int;
  350. double value_float;
  351. } ufbx_dom_value;
  352. UFBX_LIST_TYPE(ufbx_dom_node_list, ufbx_dom_node*);
  353. UFBX_LIST_TYPE(ufbx_dom_value_list, ufbx_dom_value);
  354. struct ufbx_dom_node {
  355. ufbx_string name;
  356. ufbx_dom_node_list children;
  357. ufbx_dom_value_list values;
  358. };
  359. // -- Properties
  360. // FBX elements have properties which are arbitrary key/value pairs that can
  361. // have inherited default values or be animated. In most cases you don't need
  362. // to access these unless you need a feature not implemented directly in ufbx.
  363. // NOTE: Prefer using `ufbx_find_prop[_len](...)` to search for a property by
  364. // name as it can find it from the defaults if necessary.
  365. typedef struct ufbx_prop ufbx_prop;
  366. typedef struct ufbx_props ufbx_props;
  367. // Data type contained within the property. All the data fields are always
  368. // populated regardless of type, so there's no need to switch by type usually
  369. // eg. `prop->value_real` and `prop->value_int` have the same value (well, close)
  370. // if `prop->type == UFBX_PROP_INTEGER`. String values are not converted from/to.
  371. typedef enum ufbx_prop_type UFBX_ENUM_REPR {
  372. UFBX_PROP_UNKNOWN,
  373. UFBX_PROP_BOOLEAN,
  374. UFBX_PROP_INTEGER,
  375. UFBX_PROP_NUMBER,
  376. UFBX_PROP_VECTOR,
  377. UFBX_PROP_COLOR,
  378. UFBX_PROP_COLOR_WITH_ALPHA,
  379. UFBX_PROP_STRING,
  380. UFBX_PROP_DATE_TIME,
  381. UFBX_PROP_TRANSLATION,
  382. UFBX_PROP_ROTATION,
  383. UFBX_PROP_SCALING,
  384. UFBX_PROP_DISTANCE,
  385. UFBX_PROP_COMPOUND,
  386. UFBX_PROP_BLOB,
  387. UFBX_PROP_REFERENCE,
  388. UFBX_ENUM_FORCE_WIDTH(UFBX_PROP_TYPE)
  389. } ufbx_prop_type;
  390. UFBX_ENUM_TYPE(ufbx_prop_type, UFBX_PROP_TYPE, UFBX_PROP_REFERENCE);
  391. // Property flags: Advanced information about properties, not usually needed.
  392. typedef enum ufbx_prop_flags UFBX_FLAG_REPR {
  393. // Supports animation.
  394. // NOTE: ufbx ignores this and allows animations on non-animatable properties.
  395. UFBX_PROP_FLAG_ANIMATABLE = 0x1,
  396. // User defined (custom) property.
  397. UFBX_PROP_FLAG_USER_DEFINED = 0x2,
  398. // Hidden in UI.
  399. UFBX_PROP_FLAG_HIDDEN = 0x4,
  400. // Disallow modification from UI for components.
  401. UFBX_PROP_FLAG_LOCK_X = 0x10,
  402. UFBX_PROP_FLAG_LOCK_Y = 0x20,
  403. UFBX_PROP_FLAG_LOCK_Z = 0x40,
  404. UFBX_PROP_FLAG_LOCK_W = 0x80,
  405. // Disable animation from components.
  406. UFBX_PROP_FLAG_MUTE_X = 0x100,
  407. UFBX_PROP_FLAG_MUTE_Y = 0x200,
  408. UFBX_PROP_FLAG_MUTE_Z = 0x400,
  409. UFBX_PROP_FLAG_MUTE_W = 0x800,
  410. // Property created by ufbx when an element has a connected `ufbx_anim_prop`
  411. // but doesn't contain the `ufbx_prop` it's referring to.
  412. // NOTE: The property may have been found in the templated defaults.
  413. UFBX_PROP_FLAG_SYNTHETIC = 0x1000,
  414. // The property has at least one `ufbx_anim_prop` in some layer.
  415. UFBX_PROP_FLAG_ANIMATED = 0x2000,
  416. // Used by `ufbx_evaluate_prop()` to indicate the the property was not found.
  417. UFBX_PROP_FLAG_NOT_FOUND = 0x4000,
  418. // The property is connected to another one.
  419. // This use case is relatively rare so `ufbx_prop` does not track connections
  420. // directly. You can find connections from `ufbx_element.connections_dst` where
  421. // `ufbx_connection.dst_prop` is this property and `ufbx_connection.src_prop` is defined.
  422. UFBX_PROP_FLAG_CONNECTED = 0x8000,
  423. // The value of this property is undefined (represented as zero).
  424. UFBX_PROP_FLAG_NO_VALUE = 0x10000,
  425. // This property has been overridden by the user.
  426. // See `ufbx_anim.prop_overrides` for more information.
  427. UFBX_PROP_FLAG_OVERRIDDEN = 0x20000,
  428. // Value type.
  429. // `REAL/VEC2/VEC3/VEC4` are mutually exclusive but may coexist with eg. `STRING`
  430. // in some rare cases where the string defines the unit for the vector.
  431. UFBX_PROP_FLAG_VALUE_REAL = 0x100000,
  432. UFBX_PROP_FLAG_VALUE_VEC2 = 0x200000,
  433. UFBX_PROP_FLAG_VALUE_VEC3 = 0x400000,
  434. UFBX_PROP_FLAG_VALUE_VEC4 = 0x800000,
  435. UFBX_PROP_FLAG_VALUE_INT = 0x1000000,
  436. UFBX_PROP_FLAG_VALUE_STR = 0x2000000,
  437. UFBX_PROP_FLAG_VALUE_BLOB = 0x4000000,
  438. UFBX_FLAG_FORCE_WIDTH(UFBX_PROP_FLAGS)
  439. } ufbx_prop_flags;
  440. // Single property with name/type/value.
  441. struct ufbx_prop {
  442. ufbx_string name;
  443. uint32_t _internal_key;
  444. ufbx_prop_type type;
  445. ufbx_prop_flags flags;
  446. ufbx_string value_str;
  447. ufbx_blob value_blob;
  448. int64_t value_int;
  449. union {
  450. ufbx_real value_real_arr[4];
  451. ufbx_real value_real;
  452. ufbx_vec2 value_vec2;
  453. ufbx_vec3 value_vec3;
  454. ufbx_vec4 value_vec4;
  455. };
  456. };
  457. UFBX_LIST_TYPE(ufbx_prop_list, ufbx_prop);
  458. // List of alphabetically sorted properties with potential defaults.
  459. // For animated objects in as scene from `ufbx_evaluate_scene()` this list
  460. // only has the animated properties, the originals are stored under `defaults`.
  461. struct ufbx_props {
  462. ufbx_prop_list props;
  463. size_t num_animated;
  464. ufbx_nullable ufbx_props *defaults;
  465. };
  466. typedef struct ufbx_scene ufbx_scene;
  467. // -- Elements
  468. // Element is the lowest level representation of the FBX file in ufbx.
  469. // An element contains type, id, name, and properties (see `ufbx_props` above)
  470. // Elements may be connected to each other arbitrarily via `ufbx_connection`
  471. typedef struct ufbx_element ufbx_element;
  472. // Unknown
  473. typedef struct ufbx_unknown ufbx_unknown;
  474. // Nodes
  475. typedef struct ufbx_node ufbx_node;
  476. // Node attributes (common)
  477. typedef struct ufbx_mesh ufbx_mesh;
  478. typedef struct ufbx_light ufbx_light;
  479. typedef struct ufbx_camera ufbx_camera;
  480. typedef struct ufbx_bone ufbx_bone;
  481. typedef struct ufbx_empty ufbx_empty;
  482. // Node attributes (curves/surfaces)
  483. typedef struct ufbx_line_curve ufbx_line_curve;
  484. typedef struct ufbx_nurbs_curve ufbx_nurbs_curve;
  485. typedef struct ufbx_nurbs_surface ufbx_nurbs_surface;
  486. typedef struct ufbx_nurbs_trim_surface ufbx_nurbs_trim_surface;
  487. typedef struct ufbx_nurbs_trim_boundary ufbx_nurbs_trim_boundary;
  488. // Node attributes (advanced)
  489. typedef struct ufbx_procedural_geometry ufbx_procedural_geometry;
  490. typedef struct ufbx_stereo_camera ufbx_stereo_camera;
  491. typedef struct ufbx_camera_switcher ufbx_camera_switcher;
  492. typedef struct ufbx_marker ufbx_marker;
  493. typedef struct ufbx_lod_group ufbx_lod_group;
  494. // Deformers
  495. typedef struct ufbx_skin_deformer ufbx_skin_deformer;
  496. typedef struct ufbx_skin_cluster ufbx_skin_cluster;
  497. typedef struct ufbx_blend_deformer ufbx_blend_deformer;
  498. typedef struct ufbx_blend_channel ufbx_blend_channel;
  499. typedef struct ufbx_blend_shape ufbx_blend_shape;
  500. typedef struct ufbx_cache_deformer ufbx_cache_deformer;
  501. typedef struct ufbx_cache_file ufbx_cache_file;
  502. // Materials
  503. typedef struct ufbx_material ufbx_material;
  504. typedef struct ufbx_texture ufbx_texture;
  505. typedef struct ufbx_video ufbx_video;
  506. typedef struct ufbx_shader ufbx_shader;
  507. typedef struct ufbx_shader_binding ufbx_shader_binding;
  508. // Animation
  509. typedef struct ufbx_anim_stack ufbx_anim_stack;
  510. typedef struct ufbx_anim_layer ufbx_anim_layer;
  511. typedef struct ufbx_anim_value ufbx_anim_value;
  512. typedef struct ufbx_anim_curve ufbx_anim_curve;
  513. // Collections
  514. typedef struct ufbx_display_layer ufbx_display_layer;
  515. typedef struct ufbx_selection_set ufbx_selection_set;
  516. typedef struct ufbx_selection_node ufbx_selection_node;
  517. // Constraints
  518. typedef struct ufbx_character ufbx_character;
  519. typedef struct ufbx_constraint ufbx_constraint;
  520. // Audio
  521. typedef struct ufbx_audio_layer ufbx_audio_layer;
  522. typedef struct ufbx_audio_clip ufbx_audio_clip;
  523. // Miscellaneous
  524. typedef struct ufbx_pose ufbx_pose;
  525. typedef struct ufbx_metadata_object ufbx_metadata_object;
  526. UFBX_LIST_TYPE(ufbx_element_list, ufbx_element*);
  527. UFBX_LIST_TYPE(ufbx_unknown_list, ufbx_unknown*);
  528. UFBX_LIST_TYPE(ufbx_node_list, ufbx_node*);
  529. UFBX_LIST_TYPE(ufbx_mesh_list, ufbx_mesh*);
  530. UFBX_LIST_TYPE(ufbx_light_list, ufbx_light*);
  531. UFBX_LIST_TYPE(ufbx_camera_list, ufbx_camera*);
  532. UFBX_LIST_TYPE(ufbx_bone_list, ufbx_bone*);
  533. UFBX_LIST_TYPE(ufbx_empty_list, ufbx_empty*);
  534. UFBX_LIST_TYPE(ufbx_line_curve_list, ufbx_line_curve*);
  535. UFBX_LIST_TYPE(ufbx_nurbs_curve_list, ufbx_nurbs_curve*);
  536. UFBX_LIST_TYPE(ufbx_nurbs_surface_list, ufbx_nurbs_surface*);
  537. UFBX_LIST_TYPE(ufbx_nurbs_trim_surface_list, ufbx_nurbs_trim_surface*);
  538. UFBX_LIST_TYPE(ufbx_nurbs_trim_boundary_list, ufbx_nurbs_trim_boundary*);
  539. UFBX_LIST_TYPE(ufbx_procedural_geometry_list, ufbx_procedural_geometry*);
  540. UFBX_LIST_TYPE(ufbx_stereo_camera_list, ufbx_stereo_camera*);
  541. UFBX_LIST_TYPE(ufbx_camera_switcher_list, ufbx_camera_switcher*);
  542. UFBX_LIST_TYPE(ufbx_marker_list, ufbx_marker*);
  543. UFBX_LIST_TYPE(ufbx_lod_group_list, ufbx_lod_group*);
  544. UFBX_LIST_TYPE(ufbx_skin_deformer_list, ufbx_skin_deformer*);
  545. UFBX_LIST_TYPE(ufbx_skin_cluster_list, ufbx_skin_cluster*);
  546. UFBX_LIST_TYPE(ufbx_blend_deformer_list, ufbx_blend_deformer*);
  547. UFBX_LIST_TYPE(ufbx_blend_channel_list, ufbx_blend_channel*);
  548. UFBX_LIST_TYPE(ufbx_blend_shape_list, ufbx_blend_shape*);
  549. UFBX_LIST_TYPE(ufbx_cache_deformer_list, ufbx_cache_deformer*);
  550. UFBX_LIST_TYPE(ufbx_cache_file_list, ufbx_cache_file*);
  551. UFBX_LIST_TYPE(ufbx_material_list, ufbx_material*);
  552. UFBX_LIST_TYPE(ufbx_texture_list, ufbx_texture*);
  553. UFBX_LIST_TYPE(ufbx_video_list, ufbx_video*);
  554. UFBX_LIST_TYPE(ufbx_shader_list, ufbx_shader*);
  555. UFBX_LIST_TYPE(ufbx_shader_binding_list, ufbx_shader_binding*);
  556. UFBX_LIST_TYPE(ufbx_anim_stack_list, ufbx_anim_stack*);
  557. UFBX_LIST_TYPE(ufbx_anim_layer_list, ufbx_anim_layer*);
  558. UFBX_LIST_TYPE(ufbx_anim_value_list, ufbx_anim_value*);
  559. UFBX_LIST_TYPE(ufbx_anim_curve_list, ufbx_anim_curve*);
  560. UFBX_LIST_TYPE(ufbx_display_layer_list, ufbx_display_layer*);
  561. UFBX_LIST_TYPE(ufbx_selection_set_list, ufbx_selection_set*);
  562. UFBX_LIST_TYPE(ufbx_selection_node_list, ufbx_selection_node*);
  563. UFBX_LIST_TYPE(ufbx_character_list, ufbx_character*);
  564. UFBX_LIST_TYPE(ufbx_constraint_list, ufbx_constraint*);
  565. UFBX_LIST_TYPE(ufbx_audio_layer_list, ufbx_audio_layer*);
  566. UFBX_LIST_TYPE(ufbx_audio_clip_list, ufbx_audio_clip*);
  567. UFBX_LIST_TYPE(ufbx_pose_list, ufbx_pose*);
  568. UFBX_LIST_TYPE(ufbx_metadata_object_list, ufbx_metadata_object*);
  569. typedef enum ufbx_element_type UFBX_ENUM_REPR {
  570. UFBX_ELEMENT_UNKNOWN, // < `ufbx_unknown`
  571. UFBX_ELEMENT_NODE, // < `ufbx_node`
  572. UFBX_ELEMENT_MESH, // < `ufbx_mesh`
  573. UFBX_ELEMENT_LIGHT, // < `ufbx_light`
  574. UFBX_ELEMENT_CAMERA, // < `ufbx_camera`
  575. UFBX_ELEMENT_BONE, // < `ufbx_bone`
  576. UFBX_ELEMENT_EMPTY, // < `ufbx_empty`
  577. UFBX_ELEMENT_LINE_CURVE, // < `ufbx_line_curve`
  578. UFBX_ELEMENT_NURBS_CURVE, // < `ufbx_nurbs_curve`
  579. UFBX_ELEMENT_NURBS_SURFACE, // < `ufbx_nurbs_surface`
  580. UFBX_ELEMENT_NURBS_TRIM_SURFACE, // < `ufbx_nurbs_trim_surface`
  581. UFBX_ELEMENT_NURBS_TRIM_BOUNDARY, // < `ufbx_nurbs_trim_boundary`
  582. UFBX_ELEMENT_PROCEDURAL_GEOMETRY, // < `ufbx_procedural_geometry`
  583. UFBX_ELEMENT_STEREO_CAMERA, // < `ufbx_stereo_camera`
  584. UFBX_ELEMENT_CAMERA_SWITCHER, // < `ufbx_camera_switcher`
  585. UFBX_ELEMENT_MARKER, // < `ufbx_marker`
  586. UFBX_ELEMENT_LOD_GROUP, // < `ufbx_lod_group`
  587. UFBX_ELEMENT_SKIN_DEFORMER, // < `ufbx_skin_deformer`
  588. UFBX_ELEMENT_SKIN_CLUSTER, // < `ufbx_skin_cluster`
  589. UFBX_ELEMENT_BLEND_DEFORMER, // < `ufbx_blend_deformer`
  590. UFBX_ELEMENT_BLEND_CHANNEL, // < `ufbx_blend_channel`
  591. UFBX_ELEMENT_BLEND_SHAPE, // < `ufbx_blend_shape`
  592. UFBX_ELEMENT_CACHE_DEFORMER, // < `ufbx_cache_deformer`
  593. UFBX_ELEMENT_CACHE_FILE, // < `ufbx_cache_file`
  594. UFBX_ELEMENT_MATERIAL, // < `ufbx_material`
  595. UFBX_ELEMENT_TEXTURE, // < `ufbx_texture`
  596. UFBX_ELEMENT_VIDEO, // < `ufbx_video`
  597. UFBX_ELEMENT_SHADER, // < `ufbx_shader`
  598. UFBX_ELEMENT_SHADER_BINDING, // < `ufbx_shader_binding`
  599. UFBX_ELEMENT_ANIM_STACK, // < `ufbx_anim_stack`
  600. UFBX_ELEMENT_ANIM_LAYER, // < `ufbx_anim_layer`
  601. UFBX_ELEMENT_ANIM_VALUE, // < `ufbx_anim_value`
  602. UFBX_ELEMENT_ANIM_CURVE, // < `ufbx_anim_curve`
  603. UFBX_ELEMENT_DISPLAY_LAYER, // < `ufbx_display_layer`
  604. UFBX_ELEMENT_SELECTION_SET, // < `ufbx_selection_set`
  605. UFBX_ELEMENT_SELECTION_NODE, // < `ufbx_selection_node`
  606. UFBX_ELEMENT_CHARACTER, // < `ufbx_character`
  607. UFBX_ELEMENT_CONSTRAINT, // < `ufbx_constraint`
  608. UFBX_ELEMENT_AUDIO_LAYER, // < `ufbx_audio_layer`
  609. UFBX_ELEMENT_AUDIO_CLIP, // < `ufbx_audio_clip`
  610. UFBX_ELEMENT_POSE, // < `ufbx_pose`
  611. UFBX_ELEMENT_METADATA_OBJECT, // < `ufbx_metadata_object`
  612. UFBX_ELEMENT_TYPE_FIRST_ATTRIB = UFBX_ELEMENT_MESH,
  613. UFBX_ELEMENT_TYPE_LAST_ATTRIB = UFBX_ELEMENT_LOD_GROUP,
  614. UFBX_ENUM_FORCE_WIDTH(UFBX_ELEMENT_TYPE)
  615. } ufbx_element_type;
  616. UFBX_ENUM_TYPE(ufbx_element_type, UFBX_ELEMENT_TYPE, UFBX_ELEMENT_METADATA_OBJECT);
  617. // Connection between two elements.
  618. // Source and destination are somewhat arbitrary but the destination is
  619. // often the "container" like a parent node or mesh containing a deformer.
  620. typedef struct ufbx_connection {
  621. ufbx_element *src;
  622. ufbx_element *dst;
  623. ufbx_string src_prop;
  624. ufbx_string dst_prop;
  625. } ufbx_connection;
  626. UFBX_LIST_TYPE(ufbx_connection_list, ufbx_connection);
  627. // Element "base-class" common to each element.
  628. // Some fields (like `connections_src`) are advanced and not visible
  629. // in the specialized element structs.
  630. // NOTE: The `element_id` value is consistent when loading the
  631. // _same_ file, but re-exporting the file will invalidate them.
  632. struct ufbx_element {
  633. ufbx_string name;
  634. ufbx_props props;
  635. uint32_t element_id;
  636. uint32_t typed_id;
  637. ufbx_node_list instances;
  638. ufbx_element_type type;
  639. ufbx_connection_list connections_src;
  640. ufbx_connection_list connections_dst;
  641. ufbx_nullable ufbx_dom_node *dom_node;
  642. ufbx_scene *scene;
  643. };
  644. // -- Unknown
  645. struct ufbx_unknown {
  646. // Shared "base-class" header, see `ufbx_element`.
  647. union { ufbx_element element; struct {
  648. ufbx_string name;
  649. ufbx_props props;
  650. uint32_t element_id;
  651. uint32_t typed_id;
  652. }; };
  653. // FBX format specific type information.
  654. // In ASCII FBX format:
  655. // super_type: ID, "type::name", "sub_type" { ... }
  656. ufbx_string type;
  657. ufbx_string super_type;
  658. ufbx_string sub_type;
  659. };
  660. // -- Nodes
  661. // Inherit type specifies how hierarchial node transforms are combined.
  662. // This only affects the final scaling, as rotation and translation are always
  663. // inherited correctly.
  664. // NOTE: These don't map to `"InheritType"` property as there may be new ones for
  665. // compatibility with various exporters.
  666. typedef enum ufbx_inherit_mode UFBX_ENUM_REPR {
  667. // Normal matrix composition of hierarchy: `R*S*r*s`.
  668. // child.node_to_world = parent.node_to_world * child.node_to_parent;
  669. UFBX_INHERIT_MODE_NORMAL,
  670. // Ignore parent scale when computing the transform: `R*r*s`.
  671. // ufbx_transform t = node.local_transform;
  672. // t.translation *= parent.inherit_scale;
  673. // t.scale *= node.inherit_scale_node.inherit_scale;
  674. // child.node_to_world = parent.unscaled_node_to_world * t;
  675. // Also known as "Segment scale compensate" in some software.
  676. UFBX_INHERIT_MODE_IGNORE_PARENT_SCALE,
  677. // Apply parent scale component-wise: `R*r*S*s`.
  678. // ufbx_transform t = node.local_transform;
  679. // t.translation *= parent.inherit_scale;
  680. // t.scale *= node.inherit_scale_node.inherit_scale;
  681. // child.node_to_world = parent.unscaled_node_to_world * t;
  682. UFBX_INHERIT_MODE_COMPONENTWISE_SCALE,
  683. UFBX_ENUM_FORCE_WIDTH(UFBX_INHERIT_MODE)
  684. } ufbx_inherit_mode;
  685. UFBX_ENUM_TYPE(ufbx_inherit_mode, UFBX_INHERIT_MODE, UFBX_INHERIT_MODE_COMPONENTWISE_SCALE);
  686. // Axis used to mirror transformations for handedness conversion.
  687. typedef enum ufbx_mirror_axis UFBX_ENUM_REPR {
  688. UFBX_MIRROR_AXIS_NONE,
  689. UFBX_MIRROR_AXIS_X,
  690. UFBX_MIRROR_AXIS_Y,
  691. UFBX_MIRROR_AXIS_Z,
  692. UFBX_ENUM_FORCE_WIDTH(UFBX_MIRROR_AXIS)
  693. } ufbx_mirror_axis;
  694. UFBX_ENUM_TYPE(ufbx_mirror_axis, UFBX_MIRROR_AXIS, UFBX_MIRROR_AXIS_Z);
  695. // Nodes form the scene transformation hierarchy and can contain attached
  696. // elements such as meshes or lights. In normal cases a single `ufbx_node`
  697. // contains only a single attached element, so using `type/mesh/...` is safe.
  698. struct ufbx_node {
  699. union { ufbx_element element; struct {
  700. ufbx_string name;
  701. ufbx_props props;
  702. uint32_t element_id;
  703. uint32_t typed_id;
  704. }; };
  705. // Node hierarchy
  706. // Parent node containing this one if not root.
  707. //
  708. // Always non-`NULL` for non-root nodes unless
  709. // `ufbx_load_opts.allow_nodes_out_of_root` is enabled.
  710. ufbx_nullable ufbx_node *parent;
  711. // List of child nodes parented to this node.
  712. ufbx_node_list children;
  713. // Common attached element type and typed pointers. Set to `NULL` if not in
  714. // use, so checking `attrib_type` is not required.
  715. //
  716. // HINT: If you need less common attributes access `ufbx_node.attrib`, you
  717. // can use utility functions like `ufbx_as_nurbs_curve(attrib)` to convert
  718. // and check the attribute in one step.
  719. ufbx_nullable ufbx_mesh *mesh;
  720. ufbx_nullable ufbx_light *light;
  721. ufbx_nullable ufbx_camera *camera;
  722. ufbx_nullable ufbx_bone *bone;
  723. // Less common attributes use these fields.
  724. //
  725. // Defined even if it is one of the above, eg. `ufbx_mesh`. In case there
  726. // is multiple attributes this will be the first one.
  727. ufbx_nullable ufbx_element *attrib;
  728. // Geometry transform helper if one exists.
  729. // See `UFBX_GEOMETRY_TRANSFORM_HANDLING_HELPER_NODES`.
  730. ufbx_nullable ufbx_node *geometry_transform_helper;
  731. // Scale helper if one exists.
  732. // See `UFBX_INHERIT_MODE_HANDLING_HELPER_NODES`.
  733. ufbx_nullable ufbx_node *scale_helper;
  734. // `attrib->type` if `attrib` is defined, otherwise `UFBX_ELEMENT_UNKNOWN`.
  735. ufbx_element_type attrib_type;
  736. // List of _all_ attached attribute elements.
  737. //
  738. // In most cases there is only zero or one attributes per node, but if you
  739. // have a very exotic FBX file nodes may have multiple attributes.
  740. ufbx_element_list all_attribs;
  741. // Local transform in parent, geometry transform is a non-inherited
  742. // transform applied only to attachments like meshes
  743. ufbx_inherit_mode inherit_mode;
  744. ufbx_inherit_mode original_inherit_mode;
  745. ufbx_transform local_transform;
  746. ufbx_transform geometry_transform;
  747. // Combined scale when using `UFBX_INHERIT_MODE_COMPONENTWISE_SCALE`.
  748. // Contains `local_transform.scale` otherwise.
  749. ufbx_vec3 inherit_scale;
  750. // Node where scale is inherited from for `UFBX_INHERIT_MODE_COMPONENTWISE_SCALE`
  751. // and even for `UFBX_INHERIT_MODE_IGNORE_PARENT_SCALE`.
  752. // For componentwise-scale nodes, this will point to `parent`, for scale ignoring
  753. // nodes this will point to the parent of the nearest componentwise-scaled node
  754. // in the parent chain.
  755. ufbx_nullable ufbx_node *inherit_scale_node;
  756. // Raw Euler angles in degrees for those who want them
  757. // Specifies the axis order `euler_rotation` is applied in.
  758. ufbx_rotation_order rotation_order;
  759. // Rotation around the local X/Y/Z axes in `rotation_order`.
  760. // The angles are specified in degrees.
  761. ufbx_vec3 euler_rotation;
  762. // Matrices derived from the transformations, for transforming geometry
  763. // prefer using `geometry_to_world` as that supports geometric transforms.
  764. // Transform from this node to `parent` space.
  765. // Equivalent to `ufbx_transform_to_matrix(&local_transform)`.
  766. ufbx_matrix node_to_parent;
  767. // Transform from this node to the world space, ie. multiplying all the
  768. // `node_to_parent` matrices of the parent chain together.
  769. ufbx_matrix node_to_world;
  770. // Transform from the attribute to this node. Does not affect the transforms
  771. // of `children`!
  772. // Equivalent to `ufbx_transform_to_matrix(&geometry_transform)`.
  773. ufbx_matrix geometry_to_node;
  774. // Transform from attribute space to world space.
  775. // Equivalent to `ufbx_matrix_mul(&node_to_world, &geometry_to_node)`.
  776. ufbx_matrix geometry_to_world;
  777. // Transform from this node to world space, ignoring self scaling.
  778. ufbx_matrix unscaled_node_to_world;
  779. // ufbx-specific adjustment for switching between coodrinate/unit systems.
  780. // HINT: In most cases you don't need to deal with these as these are baked
  781. // into all the transforms above and into `ufbx_evaluate_transform()`.
  782. ufbx_vec3 adjust_pre_translation; // < Translation applied between parent and self
  783. ufbx_quat adjust_pre_rotation; // < Rotation applied between parent and self
  784. ufbx_real adjust_pre_scale; // < Scaling applied between parent and self
  785. ufbx_quat adjust_post_rotation; // < Rotation applied in local space at the end
  786. ufbx_real adjust_post_scale; // < Scaling applied in local space at the end
  787. ufbx_real adjust_translation_scale; // < Scaling applied to translation only
  788. ufbx_mirror_axis adjust_mirror_axis; // < Mirror translation and rotation on this axis
  789. // Materials used by `mesh` or other `attrib`.
  790. // There may be multiple copies of a single `ufbx_mesh` with different materials
  791. // in the `ufbx_node` instances.
  792. ufbx_material_list materials;
  793. // Bind pose
  794. ufbx_nullable ufbx_pose *bind_pose;
  795. // Visibility state.
  796. bool visible;
  797. // True if this node is the implicit root node of the scene.
  798. bool is_root;
  799. // True if the node has a non-identity `geometry_transform`.
  800. bool has_geometry_transform;
  801. // If `true` the transform is adjusted by ufbx, not enabled by default.
  802. // See `adjust_pre_rotation`, `adjust_pre_scale`, `adjust_post_rotation`,
  803. // and `adjust_post_scale`.
  804. bool has_adjust_transform;
  805. // Scale is adjusted by root scale.
  806. bool has_root_adjust_transform;
  807. // True if this node is a synthetic geometry transform helper.
  808. // See `UFBX_GEOMETRY_TRANSFORM_HANDLING_HELPER_NODES`.
  809. bool is_geometry_transform_helper;
  810. // True if the node is a synthetic scale compensation helper.
  811. // See `UFBX_INHERIT_MODE_HANDLING_HELPER_NODES`.
  812. bool is_scale_helper;
  813. // Parent node to children that can compensate for parent scale.
  814. bool is_scale_compensate_parent;
  815. // How deep is this node in the parent hierarchy. Root node is at depth `0`
  816. // and the immediate children of root at `1`.
  817. uint32_t node_depth;
  818. };
  819. // Vertex attribute: All attributes are stored in a consistent indexed format
  820. // regardless of how it's actually stored in the file.
  821. //
  822. // `values` is a contiguous array of attribute values.
  823. // `indices` maps each mesh index into a value in the `values` array.
  824. //
  825. // If `unique_per_vertex` is set then the attribute is guaranteed to have a
  826. // single defined value per vertex accessible via:
  827. // attrib.values.data[attrib.indices.data[mesh->vertex_first_index[vertex_ix]]
  828. typedef struct ufbx_vertex_attrib {
  829. // Is this attribute defined by the mesh.
  830. bool exists;
  831. // List of values the attribute uses.
  832. ufbx_void_list values;
  833. // Indices into `values[]`, indexed up to `ufbx_mesh.num_indices`.
  834. ufbx_uint32_list indices;
  835. // Number of `ufbx_real` entries per value.
  836. size_t value_reals;
  837. // `true` if this attribute is defined per vertex, instead of per index.
  838. bool unique_per_vertex;
  839. // Optional 4th 'W' component for the attribute.
  840. // May be defined for the following:
  841. // ufbx_mesh.vertex_normal
  842. // ufbx_mesh.vertex_tangent / ufbx_uv_set.vertex_tangent
  843. // ufbx_mesh.vertex_bitangent / ufbx_uv_set.vertex_bitangent
  844. // NOTE: This is not loaded by default, set `ufbx_load_opts.retain_vertex_attrib_w`.
  845. ufbx_real_list values_w;
  846. } ufbx_vertex_attrib;
  847. // 1D vertex attribute, see `ufbx_vertex_attrib` for information
  848. typedef struct ufbx_vertex_real {
  849. bool exists;
  850. ufbx_real_list values;
  851. ufbx_uint32_list indices;
  852. size_t value_reals;
  853. bool unique_per_vertex;
  854. ufbx_real_list values_w;
  855. UFBX_VERTEX_ATTRIB_IMPL(ufbx_real)
  856. } ufbx_vertex_real;
  857. // 2D vertex attribute, see `ufbx_vertex_attrib` for information
  858. typedef struct ufbx_vertex_vec2 {
  859. bool exists;
  860. ufbx_vec2_list values;
  861. ufbx_uint32_list indices;
  862. size_t value_reals;
  863. bool unique_per_vertex;
  864. ufbx_real_list values_w;
  865. UFBX_VERTEX_ATTRIB_IMPL(ufbx_vec2)
  866. } ufbx_vertex_vec2;
  867. // 3D vertex attribute, see `ufbx_vertex_attrib` for information
  868. typedef struct ufbx_vertex_vec3 {
  869. bool exists;
  870. ufbx_vec3_list values;
  871. ufbx_uint32_list indices;
  872. size_t value_reals;
  873. bool unique_per_vertex;
  874. ufbx_real_list values_w;
  875. UFBX_VERTEX_ATTRIB_IMPL(ufbx_vec3)
  876. } ufbx_vertex_vec3;
  877. // 4D vertex attribute, see `ufbx_vertex_attrib` for information
  878. typedef struct ufbx_vertex_vec4 {
  879. bool exists;
  880. ufbx_vec4_list values;
  881. ufbx_uint32_list indices;
  882. size_t value_reals;
  883. bool unique_per_vertex;
  884. ufbx_real_list values_w;
  885. UFBX_VERTEX_ATTRIB_IMPL(ufbx_vec4)
  886. } ufbx_vertex_vec4;
  887. // Vertex UV set/layer
  888. typedef struct ufbx_uv_set {
  889. ufbx_string name;
  890. uint32_t index;
  891. // Vertex attributes, see `ufbx_mesh` attributes for more information
  892. ufbx_vertex_vec2 vertex_uv; // < UV / texture coordinates
  893. ufbx_vertex_vec3 vertex_tangent; // < (optional) Tangent vector in UV.x direction
  894. ufbx_vertex_vec3 vertex_bitangent; // < (optional) Tangent vector in UV.y direction
  895. } ufbx_uv_set;
  896. // Vertex color set/layer
  897. typedef struct ufbx_color_set {
  898. ufbx_string name;
  899. uint32_t index;
  900. // Vertex attributes, see `ufbx_mesh` attributes for more information
  901. ufbx_vertex_vec4 vertex_color; // < Per-vertex RGBA color
  902. } ufbx_color_set;
  903. UFBX_LIST_TYPE(ufbx_uv_set_list, ufbx_uv_set);
  904. UFBX_LIST_TYPE(ufbx_color_set_list, ufbx_color_set);
  905. // Edge between two _indices_ in a mesh
  906. typedef struct ufbx_edge {
  907. union {
  908. struct { uint32_t a, b; };
  909. uint32_t indices[2];
  910. };
  911. } ufbx_edge;
  912. UFBX_LIST_TYPE(ufbx_edge_list, ufbx_edge);
  913. // Polygonal face with arbitrary number vertices, a single face contains a
  914. // contiguous range of mesh indices, eg. `{5,3}` would have indices 5, 6, 7
  915. //
  916. // NOTE: `num_indices` maybe less than 3 in which case the face is invalid!
  917. // [TODO #23: should probably remove the bad faces at load time]
  918. typedef struct ufbx_face {
  919. uint32_t index_begin;
  920. uint32_t num_indices;
  921. } ufbx_face;
  922. UFBX_LIST_TYPE(ufbx_face_list, ufbx_face);
  923. // Subset of mesh faces used by a single material or group.
  924. typedef struct ufbx_mesh_part {
  925. // Index of the mesh part.
  926. uint32_t index;
  927. // Sub-set of the geometry
  928. size_t num_faces; // < Number of faces (polygons)
  929. size_t num_triangles; // < Number of triangles if triangulated
  930. size_t num_empty_faces; // < Number of faces with zero vertices
  931. size_t num_point_faces; // < Number of faces with a single vertex
  932. size_t num_line_faces; // < Number of faces with two vertices
  933. // Indices to `ufbx_mesh.faces[]`.
  934. // Always contains `num_faces` elements.
  935. ufbx_uint32_list face_indices;
  936. } ufbx_mesh_part;
  937. UFBX_LIST_TYPE(ufbx_mesh_part_list, ufbx_mesh_part);
  938. typedef struct ufbx_face_group {
  939. int32_t id; // < Numerical ID for this group.
  940. ufbx_string name; // < Name for the face group.
  941. } ufbx_face_group;
  942. UFBX_LIST_TYPE(ufbx_face_group_list, ufbx_face_group);
  943. typedef struct ufbx_subdivision_weight_range {
  944. uint32_t weight_begin;
  945. uint32_t num_weights;
  946. } ufbx_subdivision_weight_range;
  947. UFBX_LIST_TYPE(ufbx_subdivision_weight_range_list, ufbx_subdivision_weight_range);
  948. typedef struct ufbx_subdivision_weight {
  949. ufbx_real weight;
  950. uint32_t index;
  951. } ufbx_subdivision_weight;
  952. UFBX_LIST_TYPE(ufbx_subdivision_weight_list, ufbx_subdivision_weight);
  953. typedef struct ufbx_subdivision_result {
  954. size_t result_memory_used;
  955. size_t temp_memory_used;
  956. size_t result_allocs;
  957. size_t temp_allocs;
  958. // Weights of vertices in the source model.
  959. // Defined if `ufbx_subdivide_opts.evaluate_source_vertices` is set.
  960. ufbx_subdivision_weight_range_list source_vertex_ranges;
  961. ufbx_subdivision_weight_list source_vertex_weights;
  962. // Weights of skin clusters in the source model.
  963. // Defined if `ufbx_subdivide_opts.evaluate_skin_weights` is set.
  964. ufbx_subdivision_weight_range_list skin_cluster_ranges;
  965. ufbx_subdivision_weight_list skin_cluster_weights;
  966. } ufbx_subdivision_result;
  967. typedef enum ufbx_subdivision_display_mode UFBX_ENUM_REPR {
  968. UFBX_SUBDIVISION_DISPLAY_DISABLED,
  969. UFBX_SUBDIVISION_DISPLAY_HULL,
  970. UFBX_SUBDIVISION_DISPLAY_HULL_AND_SMOOTH,
  971. UFBX_SUBDIVISION_DISPLAY_SMOOTH,
  972. UFBX_ENUM_FORCE_WIDTH(UFBX_SUBDIVISION_DISPLAY_MODE)
  973. } ufbx_subdivision_display_mode;
  974. UFBX_ENUM_TYPE(ufbx_subdivision_display_mode, UFBX_SUBDIVISION_DISPLAY_MODE, UFBX_SUBDIVISION_DISPLAY_SMOOTH);
  975. typedef enum ufbx_subdivision_boundary UFBX_ENUM_REPR {
  976. UFBX_SUBDIVISION_BOUNDARY_DEFAULT,
  977. UFBX_SUBDIVISION_BOUNDARY_LEGACY,
  978. // OpenSubdiv: `VTX_BOUNDARY_EDGE_AND_CORNER` / `FVAR_LINEAR_CORNERS_ONLY`
  979. UFBX_SUBDIVISION_BOUNDARY_SHARP_CORNERS,
  980. // OpenSubdiv: `VTX_BOUNDARY_EDGE_ONLY` / `FVAR_LINEAR_NONE`
  981. UFBX_SUBDIVISION_BOUNDARY_SHARP_NONE,
  982. // OpenSubdiv: `FVAR_LINEAR_BOUNDARIES`
  983. UFBX_SUBDIVISION_BOUNDARY_SHARP_BOUNDARY,
  984. // OpenSubdiv: `FVAR_LINEAR_ALL`
  985. UFBX_SUBDIVISION_BOUNDARY_SHARP_INTERIOR,
  986. UFBX_ENUM_FORCE_WIDTH(UFBX_SUBDIVISION_BOUNDARY)
  987. } ufbx_subdivision_boundary;
  988. UFBX_ENUM_TYPE(ufbx_subdivision_boundary, UFBX_SUBDIVISION_BOUNDARY, UFBX_SUBDIVISION_BOUNDARY_SHARP_INTERIOR);
  989. // Polygonal mesh geometry.
  990. //
  991. // Example mesh with two triangles (x, z) and a quad (y).
  992. // The faces have a constant UV coordinate x/y/z.
  993. // The vertices have _per vertex_ normals that point up/down.
  994. //
  995. // ^ ^ ^
  996. // A---B-----C
  997. // |x / /|
  998. // | / y / |
  999. // |/ / z|
  1000. // D-----E---F
  1001. // v v v
  1002. //
  1003. // Attributes may have multiple values within a single vertex, for example a
  1004. // UV seam vertex has two UV coordinates. Thus polygons are defined using
  1005. // an index that counts each corner of each face polygon. If an attribute is
  1006. // defined (even per-vertex) it will always have a valid `indices` array.
  1007. //
  1008. // {0,3} {3,4} {7,3} faces ({ index_begin, num_indices })
  1009. // 0 1 2 3 4 5 6 7 8 9 index
  1010. //
  1011. // 0 1 3 1 2 4 3 2 4 5 vertex_indices[index]
  1012. // A B D B C E D C E F vertices[vertex_indices[index]]
  1013. //
  1014. // 0 0 1 0 0 1 1 0 1 1 vertex_normal.indices[index]
  1015. // ^ ^ v ^ ^ v v ^ v v vertex_normal.data[vertex_normal.indices[index]]
  1016. //
  1017. // 0 0 0 1 1 1 1 2 2 2 vertex_uv.indices[index]
  1018. // x x x y y y y z z z vertex_uv.data[vertex_uv.indices[index]]
  1019. //
  1020. // Vertex position can also be accessed uniformly through an accessor:
  1021. // 0 1 3 1 2 4 3 2 4 5 vertex_position.indices[index]
  1022. // A B D B C E D C E F vertex_position.data[vertex_position.indices[index]]
  1023. //
  1024. // Some geometry data is specified per logical vertex. Vertex positions are
  1025. // the only attribute that is guaranteed to be defined _uniquely_ per vertex.
  1026. // Vertex attributes _may_ be defined per vertex if `unique_per_vertex == true`.
  1027. // You can access the per-vertex values by first finding the first index that
  1028. // refers to the given vertex.
  1029. //
  1030. // 0 1 2 3 4 5 vertex
  1031. // A B C D E F vertices[vertex]
  1032. //
  1033. // 0 1 4 2 5 9 vertex_first_index[vertex]
  1034. // 0 0 0 1 1 1 vertex_normal.indices[vertex_first_index[vertex]]
  1035. // ^ ^ ^ v v v vertex_normal.data[vertex_normal.indices[vertex_first_index[vertex]]]
  1036. //
  1037. struct ufbx_mesh {
  1038. union { ufbx_element element; struct {
  1039. ufbx_string name;
  1040. ufbx_props props;
  1041. uint32_t element_id;
  1042. uint32_t typed_id;
  1043. ufbx_node_list instances;
  1044. }; };
  1045. // Number of "logical" vertices that would be treated as a single point,
  1046. // one vertex may be split to multiple indices for split attributes, eg. UVs
  1047. size_t num_vertices; // < Number of logical "vertex" points
  1048. size_t num_indices; // < Number of combiend vertex/attribute tuples
  1049. size_t num_faces; // < Number of faces (polygons) in the mesh
  1050. size_t num_triangles; // < Number of triangles if triangulated
  1051. // Number of edges in the mesh.
  1052. // NOTE: May be zero in valid meshes if the file doesn't contain edge adjacency data!
  1053. size_t num_edges;
  1054. size_t max_face_triangles; // < Maximum number of triangles in a face in this mesh
  1055. size_t num_empty_faces; // < Number of faces with zero vertices
  1056. size_t num_point_faces; // < Number of faces with a single vertex
  1057. size_t num_line_faces; // < Number of faces with two vertices
  1058. // Faces and optional per-face extra data
  1059. ufbx_face_list faces; // < Face index range
  1060. ufbx_bool_list face_smoothing; // < Should the face have soft normals
  1061. ufbx_uint32_list face_material; // < Indices to `ufbx_mesh.materials[]` and `ufbx_node.materials[]`
  1062. ufbx_uint32_list face_group; // < Face polygon group index, indices to `ufbx_mesh.face_groups[]`
  1063. ufbx_bool_list face_hole; // < Should the face be hidden as a "hole"
  1064. // Edges and optional per-edge extra data
  1065. ufbx_edge_list edges; // < Edge index range
  1066. ufbx_bool_list edge_smoothing; // < Should the edge have soft normals
  1067. ufbx_real_list edge_crease; // < Crease value for subdivision surfaces
  1068. ufbx_bool_list edge_visibility; // < Should the edge be visible
  1069. // Logical vertices and positions, alternatively you can use
  1070. // `vertex_position` for consistent interface with other attributes.
  1071. ufbx_uint32_list vertex_indices;
  1072. ufbx_vec3_list vertices;
  1073. // First index referring to a given vertex, `UFBX_NO_INDEX` if the vertex is unused.
  1074. ufbx_uint32_list vertex_first_index;
  1075. // Vertex attributes, see the comment over the struct.
  1076. //
  1077. // NOTE: Not all meshes have all attributes, in that case `indices/data == NULL`!
  1078. //
  1079. // NOTE: UV/tangent/bitangent and color are the from first sets,
  1080. // use `uv_sets/color_sets` to access the other layers.
  1081. ufbx_vertex_vec3 vertex_position; // < Vertex positions
  1082. ufbx_vertex_vec3 vertex_normal; // < (optional) Normal vectors, always defined if `ufbx_load_opts.generate_missing_normals`
  1083. ufbx_vertex_vec2 vertex_uv; // < (optional) UV / texture coordinates
  1084. ufbx_vertex_vec3 vertex_tangent; // < (optional) Tangent vector in UV.x direction
  1085. ufbx_vertex_vec3 vertex_bitangent; // < (optional) Tangent vector in UV.y direction
  1086. ufbx_vertex_vec4 vertex_color; // < (optional) Per-vertex RGBA color
  1087. ufbx_vertex_real vertex_crease; // < (optional) Crease value for subdivision surfaces
  1088. // Multiple named UV/color sets
  1089. // NOTE: The first set contains the same data as `vertex_uv/color`!
  1090. ufbx_uv_set_list uv_sets;
  1091. ufbx_color_set_list color_sets;
  1092. // Materials used by the mesh.
  1093. // NOTE: These can be wrong if you want to support per-instance materials!
  1094. // Use `ufbx_node.materials[]` to get the per-instance materials at the same indices.
  1095. ufbx_material_list materials;
  1096. // Face groups for this mesh.
  1097. ufbx_face_group_list face_groups;
  1098. // Segments that use a given material.
  1099. // Defined even if the mesh doesn't have any materials.
  1100. ufbx_mesh_part_list material_parts;
  1101. // Segments for each face group.
  1102. ufbx_mesh_part_list face_group_parts;
  1103. // Order of `material_parts` by first face that refers to it.
  1104. // Useful for compatibility with FBX SDK and various importers using it,
  1105. // as they use this material order by default.
  1106. ufbx_uint32_list material_part_usage_order;
  1107. // Skinned vertex positions, for efficiency the skinned positions are the
  1108. // same as the static ones for non-skinned meshes and `skinned_is_local`
  1109. // is set to true meaning you need to transform them manually using
  1110. // `ufbx_transform_position(&node->geometry_to_world, skinned_pos)`!
  1111. bool skinned_is_local;
  1112. ufbx_vertex_vec3 skinned_position;
  1113. ufbx_vertex_vec3 skinned_normal;
  1114. // Deformers
  1115. ufbx_skin_deformer_list skin_deformers;
  1116. ufbx_blend_deformer_list blend_deformers;
  1117. ufbx_cache_deformer_list cache_deformers;
  1118. ufbx_element_list all_deformers;
  1119. // Subdivision
  1120. uint32_t subdivision_preview_levels;
  1121. uint32_t subdivision_render_levels;
  1122. ufbx_subdivision_display_mode subdivision_display_mode;
  1123. ufbx_subdivision_boundary subdivision_boundary;
  1124. ufbx_subdivision_boundary subdivision_uv_boundary;
  1125. // The winding of the faces has been reversed.
  1126. bool reversed_winding;
  1127. // Normals have been generated instead of evalauted.
  1128. // Either from missing normals (via `ufbx_load_opts.generate_missing_normals`), skinning,
  1129. // tessellation, or subdivision.
  1130. bool generated_normals;
  1131. // Subdivision (result)
  1132. bool subdivision_evaluated;
  1133. ufbx_nullable ufbx_subdivision_result *subdivision_result;
  1134. // Tessellation (result)
  1135. bool from_tessellated_nurbs;
  1136. };
  1137. // The kind of light source
  1138. typedef enum ufbx_light_type UFBX_ENUM_REPR {
  1139. // Single point at local origin, at `node->world_transform.position`
  1140. UFBX_LIGHT_POINT,
  1141. // Infinite directional light pointing locally towards `light->local_direction`
  1142. // For global: `ufbx_transform_direction(&node->node_to_world, light->local_direction)`
  1143. UFBX_LIGHT_DIRECTIONAL,
  1144. // Cone shaped light towards `light->local_direction`, between `light->inner/outer_angle`.
  1145. // For global: `ufbx_transform_direction(&node->node_to_world, light->local_direction)`
  1146. UFBX_LIGHT_SPOT,
  1147. // Area light, shape specified by `light->area_shape`
  1148. // TODO: Units?
  1149. UFBX_LIGHT_AREA,
  1150. // Volumetric light source
  1151. // TODO: How does this work
  1152. UFBX_LIGHT_VOLUME,
  1153. UFBX_ENUM_FORCE_WIDTH(UFBX_LIGHT_TYPE)
  1154. } ufbx_light_type;
  1155. UFBX_ENUM_TYPE(ufbx_light_type, UFBX_LIGHT_TYPE, UFBX_LIGHT_VOLUME);
  1156. // How fast does the light intensity decay at a distance
  1157. typedef enum ufbx_light_decay UFBX_ENUM_REPR {
  1158. UFBX_LIGHT_DECAY_NONE, // < 1 (no decay)
  1159. UFBX_LIGHT_DECAY_LINEAR, // < 1 / d
  1160. UFBX_LIGHT_DECAY_QUADRATIC, // < 1 / d^2 (physically accurate)
  1161. UFBX_LIGHT_DECAY_CUBIC, // < 1 / d^3
  1162. UFBX_ENUM_FORCE_WIDTH(UFBX_LIGHT_DECAY)
  1163. } ufbx_light_decay;
  1164. UFBX_ENUM_TYPE(ufbx_light_decay, UFBX_LIGHT_DECAY, UFBX_LIGHT_DECAY_CUBIC);
  1165. typedef enum ufbx_light_area_shape UFBX_ENUM_REPR {
  1166. UFBX_LIGHT_AREA_SHAPE_RECTANGLE,
  1167. UFBX_LIGHT_AREA_SHAPE_SPHERE,
  1168. UFBX_ENUM_FORCE_WIDTH(UFBX_LIGHT_AREA_SHAPE)
  1169. } ufbx_light_area_shape;
  1170. UFBX_ENUM_TYPE(ufbx_light_area_shape, UFBX_LIGHT_AREA_SHAPE, UFBX_LIGHT_AREA_SHAPE_SPHERE);
  1171. // Light source attached to a `ufbx_node`
  1172. struct ufbx_light {
  1173. union { ufbx_element element; struct {
  1174. ufbx_string name;
  1175. ufbx_props props;
  1176. uint32_t element_id;
  1177. uint32_t typed_id;
  1178. ufbx_node_list instances;
  1179. }; };
  1180. // Color and intensity of the light, usually you want to use `color * intensity`
  1181. // NOTE: `intensity` is 0.01x of the property `"Intensity"` as that matches
  1182. // matches values in DCC programs before exporting.
  1183. ufbx_vec3 color;
  1184. ufbx_real intensity;
  1185. // Direction the light is aimed at in node's local space, usually -Y
  1186. ufbx_vec3 local_direction;
  1187. // Type of the light and shape parameters
  1188. ufbx_light_type type;
  1189. ufbx_light_decay decay;
  1190. ufbx_light_area_shape area_shape;
  1191. ufbx_real inner_angle;
  1192. ufbx_real outer_angle;
  1193. bool cast_light;
  1194. bool cast_shadows;
  1195. };
  1196. typedef enum ufbx_projection_mode UFBX_ENUM_REPR {
  1197. // Perspective projection.
  1198. UFBX_PROJECTION_MODE_PERSPECTIVE,
  1199. // Orthographic projection.
  1200. UFBX_PROJECTION_MODE_ORTHOGRAPHIC,
  1201. UFBX_ENUM_FORCE_WIDTH(UFBX_PROJECTION_MODE)
  1202. } ufbx_projection_mode;
  1203. UFBX_ENUM_TYPE(ufbx_projection_mode, UFBX_PROJECTION_MODE, UFBX_PROJECTION_MODE_ORTHOGRAPHIC);
  1204. // Method of specifying the rendering resolution from properties
  1205. // NOTE: Handled internally by ufbx, ignore unless you interpret `ufbx_props` directly!
  1206. typedef enum ufbx_aspect_mode UFBX_ENUM_REPR {
  1207. // No defined resolution
  1208. UFBX_ASPECT_MODE_WINDOW_SIZE,
  1209. // `"AspectWidth"` and `"AspectHeight"` are relative to each other
  1210. UFBX_ASPECT_MODE_FIXED_RATIO,
  1211. // `"AspectWidth"` and `"AspectHeight"` are both pixels
  1212. UFBX_ASPECT_MODE_FIXED_RESOLUTION,
  1213. // `"AspectWidth"` is pixels, `"AspectHeight"` is relative to width
  1214. UFBX_ASPECT_MODE_FIXED_WIDTH,
  1215. // < `"AspectHeight"` is pixels, `"AspectWidth"` is relative to height
  1216. UFBX_ASPECT_MODE_FIXED_HEIGHT,
  1217. UFBX_ENUM_FORCE_WIDTH(UFBX_ASPECT_MODE)
  1218. } ufbx_aspect_mode;
  1219. UFBX_ENUM_TYPE(ufbx_aspect_mode, UFBX_ASPECT_MODE, UFBX_ASPECT_MODE_FIXED_HEIGHT);
  1220. // Method of specifying the field of view from properties
  1221. // NOTE: Handled internally by ufbx, ignore unless you interpret `ufbx_props` directly!
  1222. typedef enum ufbx_aperture_mode UFBX_ENUM_REPR {
  1223. // Use separate `"FieldOfViewX"` and `"FieldOfViewY"` as horizontal/vertical FOV angles
  1224. UFBX_APERTURE_MODE_HORIZONTAL_AND_VERTICAL,
  1225. // Use `"FieldOfView"` as horizontal FOV angle, derive vertical angle via aspect ratio
  1226. UFBX_APERTURE_MODE_HORIZONTAL,
  1227. // Use `"FieldOfView"` as vertical FOV angle, derive horizontal angle via aspect ratio
  1228. UFBX_APERTURE_MODE_VERTICAL,
  1229. // Compute the field of view from the render gate size and focal length
  1230. UFBX_APERTURE_MODE_FOCAL_LENGTH,
  1231. UFBX_ENUM_FORCE_WIDTH(UFBX_APERTURE_MODE)
  1232. } ufbx_aperture_mode;
  1233. UFBX_ENUM_TYPE(ufbx_aperture_mode, UFBX_APERTURE_MODE, UFBX_APERTURE_MODE_FOCAL_LENGTH);
  1234. // Method of specifying the render gate size from properties
  1235. // NOTE: Handled internally by ufbx, ignore unless you interpret `ufbx_props` directly!
  1236. typedef enum ufbx_gate_fit UFBX_ENUM_REPR {
  1237. // Use the film/aperture size directly as the render gate
  1238. UFBX_GATE_FIT_NONE,
  1239. // Fit the render gate to the height of the film, derive width from aspect ratio
  1240. UFBX_GATE_FIT_VERTICAL,
  1241. // Fit the render gate to the width of the film, derive height from aspect ratio
  1242. UFBX_GATE_FIT_HORIZONTAL,
  1243. // Fit the render gate so that it is fully contained within the film gate
  1244. UFBX_GATE_FIT_FILL,
  1245. // Fit the render gate so that it fully contains the film gate
  1246. UFBX_GATE_FIT_OVERSCAN,
  1247. // Stretch the render gate to match the film gate
  1248. // TODO: Does this differ from `UFBX_GATE_FIT_NONE`?
  1249. UFBX_GATE_FIT_STRETCH,
  1250. UFBX_ENUM_FORCE_WIDTH(UFBX_GATE_FIT)
  1251. } ufbx_gate_fit;
  1252. UFBX_ENUM_TYPE(ufbx_gate_fit, UFBX_GATE_FIT, UFBX_GATE_FIT_STRETCH);
  1253. // Camera film/aperture size defaults
  1254. // NOTE: Handled internally by ufbx, ignore unless you interpret `ufbx_props` directly!
  1255. typedef enum ufbx_aperture_format UFBX_ENUM_REPR {
  1256. UFBX_APERTURE_FORMAT_CUSTOM, // < Use `"FilmWidth"` and `"FilmHeight"`
  1257. UFBX_APERTURE_FORMAT_16MM_THEATRICAL, // < 0.404 x 0.295 inches
  1258. UFBX_APERTURE_FORMAT_SUPER_16MM, // < 0.493 x 0.292 inches
  1259. UFBX_APERTURE_FORMAT_35MM_ACADEMY, // < 0.864 x 0.630 inches
  1260. UFBX_APERTURE_FORMAT_35MM_TV_PROJECTION, // < 0.816 x 0.612 inches
  1261. UFBX_APERTURE_FORMAT_35MM_FULL_APERTURE, // < 0.980 x 0.735 inches
  1262. UFBX_APERTURE_FORMAT_35MM_185_PROJECTION, // < 0.825 x 0.446 inches
  1263. UFBX_APERTURE_FORMAT_35MM_ANAMORPHIC, // < 0.864 x 0.732 inches (squeeze ratio: 2)
  1264. UFBX_APERTURE_FORMAT_70MM_PROJECTION, // < 2.066 x 0.906 inches
  1265. UFBX_APERTURE_FORMAT_VISTAVISION, // < 1.485 x 0.991 inches
  1266. UFBX_APERTURE_FORMAT_DYNAVISION, // < 2.080 x 1.480 inches
  1267. UFBX_APERTURE_FORMAT_IMAX, // < 2.772 x 2.072 inches
  1268. UFBX_ENUM_FORCE_WIDTH(UFBX_APERTURE_FORMAT)
  1269. } ufbx_aperture_format;
  1270. UFBX_ENUM_TYPE(ufbx_aperture_format, UFBX_APERTURE_FORMAT, UFBX_APERTURE_FORMAT_IMAX);
  1271. typedef enum ufbx_coordinate_axis UFBX_ENUM_REPR {
  1272. UFBX_COORDINATE_AXIS_POSITIVE_X,
  1273. UFBX_COORDINATE_AXIS_NEGATIVE_X,
  1274. UFBX_COORDINATE_AXIS_POSITIVE_Y,
  1275. UFBX_COORDINATE_AXIS_NEGATIVE_Y,
  1276. UFBX_COORDINATE_AXIS_POSITIVE_Z,
  1277. UFBX_COORDINATE_AXIS_NEGATIVE_Z,
  1278. UFBX_COORDINATE_AXIS_UNKNOWN,
  1279. UFBX_ENUM_FORCE_WIDTH(UFBX_COORDINATE_AXIS)
  1280. } ufbx_coordinate_axis;
  1281. UFBX_ENUM_TYPE(ufbx_coordinate_axis, UFBX_COORDINATE_AXIS, UFBX_COORDINATE_AXIS_UNKNOWN);
  1282. // Coordinate axes the scene is represented in.
  1283. // NOTE: `front` is the _opposite_ from forward!
  1284. typedef struct ufbx_coordinate_axes {
  1285. ufbx_coordinate_axis right;
  1286. ufbx_coordinate_axis up;
  1287. ufbx_coordinate_axis front;
  1288. } ufbx_coordinate_axes;
  1289. // Camera attached to a `ufbx_node`
  1290. struct ufbx_camera {
  1291. union { ufbx_element element; struct {
  1292. ufbx_string name;
  1293. ufbx_props props;
  1294. uint32_t element_id;
  1295. uint32_t typed_id;
  1296. ufbx_node_list instances;
  1297. }; };
  1298. // Projection mode (perspective/orthographic).
  1299. ufbx_projection_mode projection_mode;
  1300. // If set to `true`, `resolution` reprensents actual pixel values, otherwise
  1301. // it's only useful for its aspect ratio.
  1302. bool resolution_is_pixels;
  1303. // Render resolution, either in pixels or arbitrary units, depending on above
  1304. ufbx_vec2 resolution;
  1305. // Horizontal/vertical field of view in degrees
  1306. // Valid if `projection_mode == UFBX_PROJECTION_MODE_PERSPECTIVE`.
  1307. ufbx_vec2 field_of_view_deg;
  1308. // Component-wise `tan(field_of_view_deg)`, also represents the size of the
  1309. // proection frustum slice at distance of 1.
  1310. // Valid if `projection_mode == UFBX_PROJECTION_MODE_PERSPECTIVE`.
  1311. ufbx_vec2 field_of_view_tan;
  1312. // Orthographic camera extents.
  1313. // Valid if `projection_mode == UFBX_PROJECTION_MODE_ORTHOGRAPHIC`.
  1314. ufbx_real orthographic_extent;
  1315. // Orthographic camera size.
  1316. // Valid if `projection_mode == UFBX_PROJECTION_MODE_ORTHOGRAPHIC`.
  1317. ufbx_vec2 orthographic_size;
  1318. // Size of the projection plane at distance 1.
  1319. // Equal to `field_of_view_tan` if perspective, `orthographic_size` if orthographic.
  1320. ufbx_vec2 projection_plane;
  1321. // Aspect ratio of the camera.
  1322. ufbx_real aspect_ratio;
  1323. // Near plane of the frustum in units from the camera.
  1324. ufbx_real near_plane;
  1325. // Far plane of the frustum in units from the camera.
  1326. ufbx_real far_plane;
  1327. // Coordinate system that the projection uses.
  1328. // FBX saves cameras with +X forward and +Y up, but you can override this using
  1329. // `ufbx_load_opts.target_camera_axes` and it will be reflected here.
  1330. ufbx_coordinate_axes projection_axes;
  1331. // Advanced properties used to compute the above
  1332. ufbx_aspect_mode aspect_mode;
  1333. ufbx_aperture_mode aperture_mode;
  1334. ufbx_gate_fit gate_fit;
  1335. ufbx_aperture_format aperture_format;
  1336. ufbx_real focal_length_mm; // < Focal length in millimeters
  1337. ufbx_vec2 film_size_inch; // < Film size in inches
  1338. ufbx_vec2 aperture_size_inch; // < Aperture/film gate size in inches
  1339. ufbx_real squeeze_ratio; // < Anamoprhic stretch ratio
  1340. };
  1341. // Bone attached to a `ufbx_node`, provides the logical length of the bone
  1342. // but most interesting information is directly in `ufbx_node`.
  1343. struct ufbx_bone {
  1344. union { ufbx_element element; struct {
  1345. ufbx_string name;
  1346. ufbx_props props;
  1347. uint32_t element_id;
  1348. uint32_t typed_id;
  1349. ufbx_node_list instances;
  1350. }; };
  1351. // Visual radius of the bone
  1352. ufbx_real radius;
  1353. // Length of the bone relative to the distance between two nodes
  1354. ufbx_real relative_length;
  1355. // Is the bone a root bone
  1356. bool is_root;
  1357. };
  1358. // Empty/NULL/locator connected to a node, actual details in `ufbx_node`
  1359. struct ufbx_empty {
  1360. union { ufbx_element element; struct {
  1361. ufbx_string name;
  1362. ufbx_props props;
  1363. uint32_t element_id;
  1364. uint32_t typed_id;
  1365. ufbx_node_list instances;
  1366. }; };
  1367. };
  1368. // -- Node attributes (curves/surfaces)
  1369. // Segment of a `ufbx_line_curve`, indices refer to `ufbx_line_curve.point_indices[]`
  1370. typedef struct ufbx_line_segment {
  1371. uint32_t index_begin;
  1372. uint32_t num_indices;
  1373. } ufbx_line_segment;
  1374. UFBX_LIST_TYPE(ufbx_line_segment_list, ufbx_line_segment);
  1375. struct ufbx_line_curve {
  1376. union { ufbx_element element; struct {
  1377. ufbx_string name;
  1378. ufbx_props props;
  1379. uint32_t element_id;
  1380. uint32_t typed_id;
  1381. ufbx_node_list instances;
  1382. }; };
  1383. ufbx_vec3 color;
  1384. ufbx_vec3_list control_points; // < List of possible values the line passes through
  1385. ufbx_uint32_list point_indices; // < Indices to `control_points[]` the line goes through
  1386. ufbx_line_segment_list segments;
  1387. // Tessellation (result)
  1388. bool from_tessellated_nurbs;
  1389. };
  1390. typedef enum ufbx_nurbs_topology UFBX_ENUM_REPR {
  1391. // The endpoints are not connected.
  1392. UFBX_NURBS_TOPOLOGY_OPEN,
  1393. // Repeats first `ufbx_nurbs_basis.order - 1` control points after the end.
  1394. UFBX_NURBS_TOPOLOGY_PERIODIC,
  1395. // Repeats the first control point after the end.
  1396. UFBX_NURBS_TOPOLOGY_CLOSED,
  1397. UFBX_ENUM_FORCE_WIDTH(UFBX_NURBS_TOPOLOGY)
  1398. } ufbx_nurbs_topology;
  1399. UFBX_ENUM_TYPE(ufbx_nurbs_topology, UFBX_NURBS_TOPOLOGY, UFBX_NURBS_TOPOLOGY_CLOSED);
  1400. // NURBS basis functions for an axis
  1401. typedef struct ufbx_nurbs_basis {
  1402. // Number of control points influencing a point on the curve/surface.
  1403. // Equal to the degree plus one.
  1404. uint32_t order;
  1405. // Topology (periodicity) of the dimension.
  1406. ufbx_nurbs_topology topology;
  1407. // Subdivision of the parameter range to control points.
  1408. ufbx_real_list knot_vector;
  1409. // Range for the parameter value.
  1410. ufbx_real t_min;
  1411. ufbx_real t_max;
  1412. // Parameter values of control points.
  1413. ufbx_real_list spans;
  1414. // `true` if this axis is two-dimensional.
  1415. bool is_2d;
  1416. // Number of control points that need to be copied to the end.
  1417. // This is just for convenience as it could be derived from `topology` and
  1418. // `order`. If for example `num_wrap_control_points == 3` you should repeat
  1419. // the first 3 control points after the end.
  1420. // HINT: You don't need to worry about this if you use ufbx functions
  1421. // like `ufbx_evaluate_nurbs_curve()` as they handle this internally.
  1422. size_t num_wrap_control_points;
  1423. // `true` if the parametrization is well defined.
  1424. bool valid;
  1425. } ufbx_nurbs_basis;
  1426. struct ufbx_nurbs_curve {
  1427. union { ufbx_element element; struct {
  1428. ufbx_string name;
  1429. ufbx_props props;
  1430. uint32_t element_id;
  1431. uint32_t typed_id;
  1432. ufbx_node_list instances;
  1433. }; };
  1434. // Basis in the U axis
  1435. ufbx_nurbs_basis basis;
  1436. // Linear array of control points
  1437. // NOTE: The control points are _not_ homogeneous, meaning you have to multiply
  1438. // them by `w` before evaluating the surface.
  1439. ufbx_vec4_list control_points;
  1440. };
  1441. struct ufbx_nurbs_surface {
  1442. union { ufbx_element element; struct {
  1443. ufbx_string name;
  1444. ufbx_props props;
  1445. uint32_t element_id;
  1446. uint32_t typed_id;
  1447. ufbx_node_list instances;
  1448. }; };
  1449. // Basis in the U/V axes
  1450. ufbx_nurbs_basis basis_u;
  1451. ufbx_nurbs_basis basis_v;
  1452. // Number of control points for the U/V axes
  1453. size_t num_control_points_u;
  1454. size_t num_control_points_v;
  1455. // 2D array of control points.
  1456. // Memory layout: `V * num_control_points_u + U`
  1457. // NOTE: The control points are _not_ homogeneous, meaning you have to multiply
  1458. // them by `w` before evaluating the surface.
  1459. ufbx_vec4_list control_points;
  1460. // How many segments tessellate each span in `ufbx_nurbs_basis.spans`.
  1461. uint32_t span_subdivision_u;
  1462. uint32_t span_subdivision_v;
  1463. // If `true` the resulting normals should be flipped when evaluated.
  1464. bool flip_normals;
  1465. // Material for the whole surface.
  1466. // NOTE: May be `NULL`!
  1467. ufbx_nullable ufbx_material *material;
  1468. };
  1469. struct ufbx_nurbs_trim_surface {
  1470. union { ufbx_element element; struct {
  1471. ufbx_string name;
  1472. ufbx_props props;
  1473. uint32_t element_id;
  1474. uint32_t typed_id;
  1475. ufbx_node_list instances;
  1476. }; };
  1477. };
  1478. struct ufbx_nurbs_trim_boundary {
  1479. union { ufbx_element element; struct {
  1480. ufbx_string name;
  1481. ufbx_props props;
  1482. uint32_t element_id;
  1483. uint32_t typed_id;
  1484. ufbx_node_list instances;
  1485. }; };
  1486. };
  1487. // -- Node attributes (advanced)
  1488. struct ufbx_procedural_geometry {
  1489. union { ufbx_element element; struct {
  1490. ufbx_string name;
  1491. ufbx_props props;
  1492. uint32_t element_id;
  1493. uint32_t typed_id;
  1494. ufbx_node_list instances;
  1495. }; };
  1496. };
  1497. struct ufbx_stereo_camera {
  1498. union { ufbx_element element; struct {
  1499. ufbx_string name;
  1500. ufbx_props props;
  1501. uint32_t element_id;
  1502. uint32_t typed_id;
  1503. ufbx_node_list instances;
  1504. }; };
  1505. ufbx_nullable ufbx_camera *left;
  1506. ufbx_nullable ufbx_camera *right;
  1507. };
  1508. struct ufbx_camera_switcher {
  1509. union { ufbx_element element; struct {
  1510. ufbx_string name;
  1511. ufbx_props props;
  1512. uint32_t element_id;
  1513. uint32_t typed_id;
  1514. ufbx_node_list instances;
  1515. }; };
  1516. };
  1517. typedef enum ufbx_marker_type UFBX_ENUM_REPR {
  1518. UFBX_MARKER_UNKNOWN, // < Unknown marker type
  1519. UFBX_MARKER_FK_EFFECTOR, // < FK (Forward Kinematics) effector
  1520. UFBX_MARKER_IK_EFFECTOR, // < IK (Inverse Kinematics) effector
  1521. UFBX_ENUM_FORCE_WIDTH(UFBX_MARKER_TYPE)
  1522. } ufbx_marker_type;
  1523. UFBX_ENUM_TYPE(ufbx_marker_type, UFBX_MARKER_TYPE, UFBX_MARKER_IK_EFFECTOR);
  1524. // Tracking marker for effectors
  1525. struct ufbx_marker {
  1526. union { ufbx_element element; struct {
  1527. ufbx_string name;
  1528. ufbx_props props;
  1529. uint32_t element_id;
  1530. uint32_t typed_id;
  1531. ufbx_node_list instances;
  1532. }; };
  1533. // Type of the marker
  1534. ufbx_marker_type type;
  1535. };
  1536. // LOD level display mode.
  1537. typedef enum ufbx_lod_display UFBX_ENUM_REPR {
  1538. UFBX_LOD_DISPLAY_USE_LOD, // < Display the LOD level if the distance is appropriate.
  1539. UFBX_LOD_DISPLAY_SHOW, // < Always display the LOD level.
  1540. UFBX_LOD_DISPLAY_HIDE, // < Never display the LOD level.
  1541. UFBX_ENUM_FORCE_WIDTH(UFBX_LOD_DISPLAY)
  1542. } ufbx_lod_display;
  1543. UFBX_ENUM_TYPE(ufbx_lod_display, UFBX_LOD_DISPLAY, UFBX_LOD_DISPLAY_HIDE);
  1544. // Single LOD level within an LOD group.
  1545. // Specifies properties of the Nth child of the _node_ containing the LOD group.
  1546. typedef struct ufbx_lod_level {
  1547. // Minimum distance to show this LOD level.
  1548. // NOTE: In world units by default, or in screen percentage if
  1549. // `ufbx_lod_group.relative_distances` is set.
  1550. ufbx_real distance;
  1551. // LOD display mode.
  1552. // NOTE: Mostly for editing, you should probably ignore this
  1553. // unless making a modeling program.
  1554. ufbx_lod_display display;
  1555. } ufbx_lod_level;
  1556. UFBX_LIST_TYPE(ufbx_lod_level_list, ufbx_lod_level);
  1557. // Group of LOD (Level of Detail) levels for an object.
  1558. // The actual LOD models are defined in the parent `ufbx_node.children`.
  1559. struct ufbx_lod_group {
  1560. union { ufbx_element element; struct {
  1561. ufbx_string name;
  1562. ufbx_props props;
  1563. uint32_t element_id;
  1564. uint32_t typed_id;
  1565. ufbx_node_list instances;
  1566. }; };
  1567. // If set to `true`, `ufbx_lod_level.distance` represents a screen size percentage.
  1568. bool relative_distances;
  1569. // LOD levels matching in order to `ufbx_node.children`.
  1570. ufbx_lod_level_list lod_levels;
  1571. // If set to `true` don't account for parent transform when computing the distance.
  1572. bool ignore_parent_transform;
  1573. // If `use_distance_limit` is enabled hide the group if the distance is not between
  1574. // `distance_limit_min` and `distance_limit_max`.
  1575. bool use_distance_limit;
  1576. ufbx_real distance_limit_min;
  1577. ufbx_real distance_limit_max;
  1578. };
  1579. // -- Deformers
  1580. // Method to evaluate the skinning on a per-vertex level
  1581. typedef enum ufbx_skinning_method UFBX_ENUM_REPR {
  1582. // Linear blend skinning: Blend transformation matrices by vertex weights
  1583. UFBX_SKINNING_METHOD_LINEAR,
  1584. // One vertex should have only one bone attached
  1585. UFBX_SKINNING_METHOD_RIGID,
  1586. // Convert the transformations to dual quaternions and blend in that space
  1587. UFBX_SKINNING_METHOD_DUAL_QUATERNION,
  1588. // Blend between `UFBX_SKINNING_METHOD_LINEAR` and `UFBX_SKINNING_METHOD_BLENDED_DQ_LINEAR`
  1589. // The blend weight can be found either per-vertex in `ufbx_skin_vertex.dq_weight`
  1590. // or in `ufbx_skin_deformer.dq_vertices/dq_weights` (indexed by vertex).
  1591. UFBX_SKINNING_METHOD_BLENDED_DQ_LINEAR,
  1592. UFBX_ENUM_FORCE_WIDTH(UFBX_SKINNING_METHOD)
  1593. } ufbx_skinning_method;
  1594. UFBX_ENUM_TYPE(ufbx_skinning_method, UFBX_SKINNING_METHOD, UFBX_SKINNING_METHOD_BLENDED_DQ_LINEAR);
  1595. // Skin weight information for a single mesh vertex
  1596. typedef struct ufbx_skin_vertex {
  1597. // Each vertex is influenced by weights from `ufbx_skin_deformer.weights[]`
  1598. // The weights are sorted by decreasing weight so you can take the first N
  1599. // weights to get a cheaper approximation of the vertex.
  1600. // NOTE: The weights are not guaranteed to be normalized!
  1601. uint32_t weight_begin; // < Index to start from in the `weights[]` array
  1602. uint32_t num_weights; // < Number of weights influencing the vertex
  1603. // Blend weight between Linear Blend Skinning (0.0) and Dual Quaternion (1.0).
  1604. // Should be used if `skinning_method == UFBX_SKINNING_METHOD_BLENDED_DQ_LINEAR`
  1605. ufbx_real dq_weight;
  1606. } ufbx_skin_vertex;
  1607. UFBX_LIST_TYPE(ufbx_skin_vertex_list, ufbx_skin_vertex);
  1608. // Single per-vertex per-cluster weight, see `ufbx_skin_vertex`
  1609. typedef struct ufbx_skin_weight {
  1610. uint32_t cluster_index; // < Index into `ufbx_skin_deformer.clusters[]`
  1611. ufbx_real weight; // < Amount this bone influence the vertex
  1612. } ufbx_skin_weight;
  1613. UFBX_LIST_TYPE(ufbx_skin_weight_list, ufbx_skin_weight);
  1614. // Skin deformer specifies a binding between a logical set of bones (a skeleton)
  1615. // and a mesh. Each bone is represented by a `ufbx_skin_cluster` that contains
  1616. // the binding matrix and a `ufbx_node *bone` that has the current transformation.
  1617. struct ufbx_skin_deformer {
  1618. union { ufbx_element element; struct {
  1619. ufbx_string name;
  1620. ufbx_props props;
  1621. uint32_t element_id;
  1622. uint32_t typed_id;
  1623. }; };
  1624. ufbx_skinning_method skinning_method;
  1625. // Clusters (bones) in the skin
  1626. ufbx_skin_cluster_list clusters;
  1627. // Per-vertex weight information
  1628. ufbx_skin_vertex_list vertices;
  1629. ufbx_skin_weight_list weights;
  1630. // Largest amount of weights a single vertex can have
  1631. size_t max_weights_per_vertex;
  1632. // Blend weights between Linear Blend Skinning (0.0) and Dual Quaternion (1.0).
  1633. // HINT: You probably want to use `vertices` and `ufbx_skin_vertex.dq_weight` instead!
  1634. // NOTE: These may be out-of-bounds for a given mesh, `vertices` is always safe.
  1635. size_t num_dq_weights;
  1636. ufbx_uint32_list dq_vertices;
  1637. ufbx_real_list dq_weights;
  1638. };
  1639. // Cluster of vertices bound to a single bone.
  1640. struct ufbx_skin_cluster {
  1641. union { ufbx_element element; struct {
  1642. ufbx_string name;
  1643. ufbx_props props;
  1644. uint32_t element_id;
  1645. uint32_t typed_id;
  1646. }; };
  1647. // The bone node the cluster is attached to
  1648. // NOTE: Always valid if found from `ufbx_skin_deformer.clusters[]` unless
  1649. // `ufbx_load_opts.connect_broken_elements` is `true`.
  1650. ufbx_nullable ufbx_node *bone_node;
  1651. // Binding matrix from local mesh vertices to the bone
  1652. ufbx_matrix geometry_to_bone;
  1653. // Binding matrix from local mesh _node_ to the bone.
  1654. // NOTE: Prefer `geometry_to_bone` in most use cases!
  1655. ufbx_matrix mesh_node_to_bone;
  1656. // Matrix that specifies the rest/bind pose transform of the node,
  1657. // not generally needed for skinning, use `geometry_to_bone` instead.
  1658. ufbx_matrix bind_to_world;
  1659. // Precomputed matrix/transform that accounts for the current bone transform
  1660. // ie. `ufbx_matrix_mul(&cluster->bone->node_to_world, &cluster->geometry_to_bone)`
  1661. ufbx_matrix geometry_to_world;
  1662. ufbx_transform geometry_to_world_transform;
  1663. // Raw weights indexed by each _vertex_ of a mesh (not index!)
  1664. // HINT: It may be simpler to use `ufbx_skin_deformer.vertices[]/weights[]` instead!
  1665. // NOTE: These may be out-of-bounds for a given mesh, `ufbx_skin_deformer.vertices` is always safe.
  1666. size_t num_weights; // < Number of vertices in the cluster
  1667. ufbx_uint32_list vertices; // < Vertex indices in `ufbx_mesh.vertices[]`
  1668. ufbx_real_list weights; // < Per-vertex weight values
  1669. };
  1670. // Blend shape deformer can contain multiple channels (think of sliders between morphs)
  1671. // that may optionally have in-between keyframes.
  1672. struct ufbx_blend_deformer {
  1673. union { ufbx_element element; struct {
  1674. ufbx_string name;
  1675. ufbx_props props;
  1676. uint32_t element_id;
  1677. uint32_t typed_id;
  1678. }; };
  1679. // Independent morph targets of the deformer.
  1680. ufbx_blend_channel_list channels;
  1681. };
  1682. // Blend shape associated with a target weight in a series of morphs
  1683. typedef struct ufbx_blend_keyframe {
  1684. // The target blend shape offsets.
  1685. ufbx_blend_shape *shape;
  1686. // Weight value at which to apply the keyframe at full strength
  1687. ufbx_real target_weight;
  1688. // The weight the shape should be currently applied with
  1689. ufbx_real effective_weight;
  1690. } ufbx_blend_keyframe;
  1691. UFBX_LIST_TYPE(ufbx_blend_keyframe_list, ufbx_blend_keyframe);
  1692. // Blend channel consists of multiple morph-key targets that are interpolated.
  1693. // In simple cases there will be only one keyframe that is the target shape.
  1694. struct ufbx_blend_channel {
  1695. union { ufbx_element element; struct {
  1696. ufbx_string name;
  1697. ufbx_props props;
  1698. uint32_t element_id;
  1699. uint32_t typed_id;
  1700. }; };
  1701. // Current weight of the channel
  1702. ufbx_real weight;
  1703. // Key morph targets to blend between depending on `weight`
  1704. // In usual cases there's only one target per channel
  1705. ufbx_blend_keyframe_list keyframes;
  1706. // Final blend shape ignoring any intermediate blend shapes.
  1707. ufbx_nullable ufbx_blend_shape *target_shape;
  1708. };
  1709. // Blend shape target containing the actual vertex offsets
  1710. struct ufbx_blend_shape {
  1711. union { ufbx_element element; struct {
  1712. ufbx_string name;
  1713. ufbx_props props;
  1714. uint32_t element_id;
  1715. uint32_t typed_id;
  1716. }; };
  1717. // Vertex offsets to apply over the base mesh
  1718. // NOTE: The `offset_vertices` may be out-of-bounds for a given mesh!
  1719. size_t num_offsets; // < Number of vertex offsets in the following arrays
  1720. ufbx_uint32_list offset_vertices; // < Indices to `ufbx_mesh.vertices[]`
  1721. ufbx_vec3_list position_offsets; // < Always specified per-vertex offsets
  1722. ufbx_vec3_list normal_offsets; // < Empty if not specified
  1723. };
  1724. typedef enum ufbx_cache_file_format UFBX_ENUM_REPR {
  1725. UFBX_CACHE_FILE_FORMAT_UNKNOWN, // < Unknown cache file format
  1726. UFBX_CACHE_FILE_FORMAT_PC2, // < .pc2 Point cache file
  1727. UFBX_CACHE_FILE_FORMAT_MC, // < .mc/.mcx Maya cache file
  1728. UFBX_ENUM_FORCE_WIDTH(UFBX_CACHE_FILE_FORMAT)
  1729. } ufbx_cache_file_format;
  1730. UFBX_ENUM_TYPE(ufbx_cache_file_format, UFBX_CACHE_FILE_FORMAT, UFBX_CACHE_FILE_FORMAT_MC);
  1731. typedef enum ufbx_cache_data_format UFBX_ENUM_REPR {
  1732. UFBX_CACHE_DATA_FORMAT_UNKNOWN, // < Unknown data format
  1733. UFBX_CACHE_DATA_FORMAT_REAL_FLOAT, // < `float data[]`
  1734. UFBX_CACHE_DATA_FORMAT_VEC3_FLOAT, // < `struct { float x, y, z; } data[]`
  1735. UFBX_CACHE_DATA_FORMAT_REAL_DOUBLE, // < `double data[]`
  1736. UFBX_CACHE_DATA_FORMAT_VEC3_DOUBLE, // < `struct { double x, y, z; } data[]`
  1737. UFBX_ENUM_FORCE_WIDTH(UFBX_CACHE_DATA_FORMAT)
  1738. } ufbx_cache_data_format;
  1739. UFBX_ENUM_TYPE(ufbx_cache_data_format, UFBX_CACHE_DATA_FORMAT, UFBX_CACHE_DATA_FORMAT_VEC3_DOUBLE);
  1740. typedef enum ufbx_cache_data_encoding UFBX_ENUM_REPR {
  1741. UFBX_CACHE_DATA_ENCODING_UNKNOWN, // < Unknown data encoding
  1742. UFBX_CACHE_DATA_ENCODING_LITTLE_ENDIAN, // < Contiguous little-endian array
  1743. UFBX_CACHE_DATA_ENCODING_BIG_ENDIAN, // < Contiguous big-endian array
  1744. UFBX_ENUM_FORCE_WIDTH(UFBX_CACHE_DATA_ENCODING)
  1745. } ufbx_cache_data_encoding;
  1746. UFBX_ENUM_TYPE(ufbx_cache_data_encoding, UFBX_CACHE_DATA_ENCODING, UFBX_CACHE_DATA_ENCODING_BIG_ENDIAN);
  1747. // Known interpretations of geometry cache data.
  1748. typedef enum ufbx_cache_interpretation UFBX_ENUM_REPR {
  1749. // Unknown interpretation, see `ufbx_cache_channel.interpretation_name` for more information.
  1750. UFBX_CACHE_INTERPRETATION_UNKNOWN,
  1751. // Generic "points" interpretation, FBX SDK default. Usually fine to interpret
  1752. // as vertex positions if no other cache channels are specified.
  1753. UFBX_CACHE_INTERPRETATION_POINTS,
  1754. // Vertex positions.
  1755. UFBX_CACHE_INTERPRETATION_VERTEX_POSITION,
  1756. // Vertex normals.
  1757. UFBX_CACHE_INTERPRETATION_VERTEX_NORMAL,
  1758. UFBX_ENUM_FORCE_WIDTH(UFBX_CACHE_INTERPRETATION)
  1759. } ufbx_cache_interpretation;
  1760. UFBX_ENUM_TYPE(ufbx_cache_interpretation, UFBX_CACHE_INTERPRETATION, UFBX_CACHE_INTERPRETATION_VERTEX_NORMAL);
  1761. typedef struct ufbx_cache_frame {
  1762. // Name of the channel this frame belongs to.
  1763. ufbx_string channel;
  1764. // Time of this frame in seconds.
  1765. double time;
  1766. // Name of the file containing the data.
  1767. // The specified file may contain multiple frames, use `data_offset` etc. to
  1768. // read at the right position.
  1769. ufbx_string filename;
  1770. // Format of the wrapper file.
  1771. ufbx_cache_file_format file_format;
  1772. // Axis to mirror the read data by.
  1773. ufbx_mirror_axis mirror_axis;
  1774. // Factor to scale the geometry by.
  1775. ufbx_real scale_factor;
  1776. ufbx_cache_data_format data_format; // < Format of the data in the file
  1777. ufbx_cache_data_encoding data_encoding; // < Binary encoding of the data
  1778. uint64_t data_offset; // < Byte offset into the file
  1779. uint32_t data_count; // < Number of data elements
  1780. uint32_t data_element_bytes; // < Size of a single data element in bytes
  1781. uint64_t data_total_bytes; // < Size of the whole data blob in bytes
  1782. } ufbx_cache_frame;
  1783. UFBX_LIST_TYPE(ufbx_cache_frame_list, ufbx_cache_frame);
  1784. typedef struct ufbx_cache_channel {
  1785. // Name of the geometry cache channel.
  1786. ufbx_string name;
  1787. // What does the data in this channel represent.
  1788. ufbx_cache_interpretation interpretation;
  1789. // Source name for `interpretation`, especially useful if `interpretation` is
  1790. // `UFBX_CACHE_INTERPRETATION_UNKNOWN`.
  1791. ufbx_string interpretation_name;
  1792. // List of frames belonging to this channel.
  1793. // Sorted by time (`ufbx_cache_frame.time`).
  1794. ufbx_cache_frame_list frames;
  1795. // Axis to mirror the frames by.
  1796. ufbx_mirror_axis mirror_axis;
  1797. // Factor to scale the geometry by.
  1798. ufbx_real scale_factor;
  1799. } ufbx_cache_channel;
  1800. UFBX_LIST_TYPE(ufbx_cache_channel_list, ufbx_cache_channel);
  1801. typedef struct ufbx_geometry_cache {
  1802. ufbx_string root_filename;
  1803. ufbx_cache_channel_list channels;
  1804. ufbx_cache_frame_list frames;
  1805. ufbx_string_list extra_info;
  1806. } ufbx_geometry_cache;
  1807. struct ufbx_cache_deformer {
  1808. union { ufbx_element element; struct {
  1809. ufbx_string name;
  1810. ufbx_props props;
  1811. uint32_t element_id;
  1812. uint32_t typed_id;
  1813. }; };
  1814. ufbx_string channel;
  1815. ufbx_nullable ufbx_cache_file *file;
  1816. // Only valid if `ufbx_load_opts.load_external_files` is set!
  1817. ufbx_nullable ufbx_geometry_cache *external_cache;
  1818. ufbx_nullable ufbx_cache_channel *external_channel;
  1819. };
  1820. struct ufbx_cache_file {
  1821. union { ufbx_element element; struct {
  1822. ufbx_string name;
  1823. ufbx_props props;
  1824. uint32_t element_id;
  1825. uint32_t typed_id;
  1826. }; };
  1827. // Filename relative to the currently loaded file.
  1828. // HINT: If using functions other than `ufbx_load_file()`, you can provide
  1829. // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this.
  1830. ufbx_string filename;
  1831. // Absolute filename specified in the file.
  1832. ufbx_string absolute_filename;
  1833. // Relative filename specified in the file.
  1834. // NOTE: May be absolute if the file is saved in a different drive.
  1835. ufbx_string relative_filename;
  1836. // Filename relative to the loaded file, non-UTF-8 encoded.
  1837. // HINT: If using functions other than `ufbx_load_file()`, you can provide
  1838. // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this.
  1839. ufbx_blob raw_filename;
  1840. // Absolute filename specified in the file, non-UTF-8 encoded.
  1841. ufbx_blob raw_absolute_filename;
  1842. // Relative filename specified in the file, non-UTF-8 encoded.
  1843. // NOTE: May be absolute if the file is saved in a different drive.
  1844. ufbx_blob raw_relative_filename;
  1845. ufbx_cache_file_format format;
  1846. // Only valid if `ufbx_load_opts.load_external_files` is set!
  1847. ufbx_nullable ufbx_geometry_cache *external_cache;
  1848. };
  1849. // -- Materials
  1850. // Material property, either specified with a constant value or a mapped texture
  1851. typedef struct ufbx_material_map {
  1852. // Constant value or factor for the map.
  1853. // May be specified simultaneously with a texture, in this case most shading models
  1854. // use multiplicative tinting of the texture values.
  1855. union {
  1856. ufbx_real value_real;
  1857. ufbx_vec2 value_vec2;
  1858. ufbx_vec3 value_vec3;
  1859. ufbx_vec4 value_vec4;
  1860. };
  1861. int64_t value_int;
  1862. // Texture if connected, otherwise `NULL`.
  1863. // May be valid but "disabled" (application specific) if `texture_enabled == false`.
  1864. ufbx_nullable ufbx_texture *texture;
  1865. // `true` if the file has specified any of the values above.
  1866. // NOTE: The value may be set to a non-zero default even if `has_value == false`,
  1867. // for example missing factors are set to `1.0` if a color is defined.
  1868. bool has_value;
  1869. // Controls whether shading should use `texture`.
  1870. // NOTE: Some shading models allow this to be `true` even if `texture == NULL`.
  1871. bool texture_enabled;
  1872. // Set to `true` if this feature should be disabled (specific to shader type).
  1873. bool feature_disabled;
  1874. // Number of components in the value from 1 to 4 if defined, 0 if not.
  1875. uint8_t value_components;
  1876. } ufbx_material_map;
  1877. // Material feature
  1878. typedef struct ufbx_material_feature_info {
  1879. // Whether the material model uses this feature or not.
  1880. // NOTE: The feature can be enabled but still not used if eg. the corresponding factor is at zero!
  1881. bool enabled;
  1882. // Explicitly enabled/disabled by the material.
  1883. bool is_explicit;
  1884. } ufbx_material_feature_info;
  1885. // Texture attached to an FBX property
  1886. typedef struct ufbx_material_texture {
  1887. ufbx_string material_prop; // < Name of the property in `ufbx_material.props`
  1888. ufbx_string shader_prop; // < Shader-specific property mapping name
  1889. // Texture attached to the property.
  1890. ufbx_texture *texture;
  1891. } ufbx_material_texture;
  1892. UFBX_LIST_TYPE(ufbx_material_texture_list, ufbx_material_texture);
  1893. // Shading model type
  1894. typedef enum ufbx_shader_type UFBX_ENUM_REPR {
  1895. // Unknown shading model
  1896. UFBX_SHADER_UNKNOWN,
  1897. // FBX builtin diffuse material
  1898. UFBX_SHADER_FBX_LAMBERT,
  1899. // FBX builtin diffuse+specular material
  1900. UFBX_SHADER_FBX_PHONG,
  1901. // Open Shading Language standard surface
  1902. // https://github.com/Autodesk/standard-surface
  1903. UFBX_SHADER_OSL_STANDARD_SURFACE,
  1904. // Arnold standard surface
  1905. // https://docs.arnoldrenderer.com/display/A5AFMUG/Standard+Surface
  1906. UFBX_SHADER_ARNOLD_STANDARD_SURFACE,
  1907. // 3ds Max Physical Material
  1908. // https://knowledge.autodesk.com/support/3ds-max/learn-explore/caas/CloudHelp/cloudhelp/2022/ENU/3DSMax-Lighting-Shading/files/GUID-C1328905-7783-4917-AB86-FC3CC19E8972-htm.html
  1909. UFBX_SHADER_3DS_MAX_PHYSICAL_MATERIAL,
  1910. // 3ds Max PBR (Metal/Rough) material
  1911. // https://knowledge.autodesk.com/support/3ds-max/learn-explore/caas/CloudHelp/cloudhelp/2021/ENU/3DSMax-Lighting-Shading/files/GUID-A16234A5-6500-4662-8B20-A5EC9FE1B255-htm.html
  1912. UFBX_SHADER_3DS_MAX_PBR_METAL_ROUGH,
  1913. // 3ds Max PBR (Spec/Gloss) material
  1914. // https://knowledge.autodesk.com/support/3ds-max/learn-explore/caas/CloudHelp/cloudhelp/2021/ENU/3DSMax-Lighting-Shading/files/GUID-18087194-B2A6-43EF-9B80-8FD1736FAE52-htm.html
  1915. UFBX_SHADER_3DS_MAX_PBR_SPEC_GLOSS,
  1916. // 3ds glTF Material
  1917. // https://help.autodesk.com/view/3DSMAX/2023/ENU/?guid=GUID-7ABFB805-1D9F-417E-9C22-704BFDF160FA
  1918. UFBX_SHADER_GLTF_MATERIAL,
  1919. // Stingray ShaderFX shader graph.
  1920. // Contains a serialized `"ShaderGraph"` in `ufbx_props`.
  1921. UFBX_SHADER_SHADERFX_GRAPH,
  1922. // Variation of the FBX phong shader that can recover PBR properties like
  1923. // `metalness` or `roughness` from the FBX non-physical values.
  1924. // NOTE: Enable `ufbx_load_opts.use_blender_pbr_material`.
  1925. UFBX_SHADER_BLENDER_PHONG,
  1926. // Wavefront .mtl format shader (used by .obj files)
  1927. UFBX_SHADER_WAVEFRONT_MTL,
  1928. UFBX_ENUM_FORCE_WIDTH(UFBX_SHADER_TYPE)
  1929. } ufbx_shader_type;
  1930. UFBX_ENUM_TYPE(ufbx_shader_type, UFBX_SHADER_TYPE, UFBX_SHADER_WAVEFRONT_MTL);
  1931. // FBX builtin material properties, matches maps in `ufbx_material_fbx_maps`
  1932. typedef enum ufbx_material_fbx_map UFBX_ENUM_REPR {
  1933. UFBX_MATERIAL_FBX_DIFFUSE_FACTOR,
  1934. UFBX_MATERIAL_FBX_DIFFUSE_COLOR,
  1935. UFBX_MATERIAL_FBX_SPECULAR_FACTOR,
  1936. UFBX_MATERIAL_FBX_SPECULAR_COLOR,
  1937. UFBX_MATERIAL_FBX_SPECULAR_EXPONENT,
  1938. UFBX_MATERIAL_FBX_REFLECTION_FACTOR,
  1939. UFBX_MATERIAL_FBX_REFLECTION_COLOR,
  1940. UFBX_MATERIAL_FBX_TRANSPARENCY_FACTOR,
  1941. UFBX_MATERIAL_FBX_TRANSPARENCY_COLOR,
  1942. UFBX_MATERIAL_FBX_EMISSION_FACTOR,
  1943. UFBX_MATERIAL_FBX_EMISSION_COLOR,
  1944. UFBX_MATERIAL_FBX_AMBIENT_FACTOR,
  1945. UFBX_MATERIAL_FBX_AMBIENT_COLOR,
  1946. UFBX_MATERIAL_FBX_NORMAL_MAP,
  1947. UFBX_MATERIAL_FBX_BUMP,
  1948. UFBX_MATERIAL_FBX_BUMP_FACTOR,
  1949. UFBX_MATERIAL_FBX_DISPLACEMENT_FACTOR,
  1950. UFBX_MATERIAL_FBX_DISPLACEMENT,
  1951. UFBX_MATERIAL_FBX_VECTOR_DISPLACEMENT_FACTOR,
  1952. UFBX_MATERIAL_FBX_VECTOR_DISPLACEMENT,
  1953. UFBX_ENUM_FORCE_WIDTH(UFBX_MATERIAL_FBX_MAP)
  1954. } ufbx_material_fbx_map;
  1955. UFBX_ENUM_TYPE(ufbx_material_fbx_map, UFBX_MATERIAL_FBX_MAP, UFBX_MATERIAL_FBX_VECTOR_DISPLACEMENT);
  1956. // Known PBR material properties, matches maps in `ufbx_material_pbr_maps`
  1957. typedef enum ufbx_material_pbr_map UFBX_ENUM_REPR {
  1958. UFBX_MATERIAL_PBR_BASE_FACTOR,
  1959. UFBX_MATERIAL_PBR_BASE_COLOR,
  1960. UFBX_MATERIAL_PBR_ROUGHNESS,
  1961. UFBX_MATERIAL_PBR_METALNESS,
  1962. UFBX_MATERIAL_PBR_DIFFUSE_ROUGHNESS,
  1963. UFBX_MATERIAL_PBR_SPECULAR_FACTOR,
  1964. UFBX_MATERIAL_PBR_SPECULAR_COLOR,
  1965. UFBX_MATERIAL_PBR_SPECULAR_IOR,
  1966. UFBX_MATERIAL_PBR_SPECULAR_ANISOTROPY,
  1967. UFBX_MATERIAL_PBR_SPECULAR_ROTATION,
  1968. UFBX_MATERIAL_PBR_TRANSMISSION_FACTOR,
  1969. UFBX_MATERIAL_PBR_TRANSMISSION_COLOR,
  1970. UFBX_MATERIAL_PBR_TRANSMISSION_DEPTH,
  1971. UFBX_MATERIAL_PBR_TRANSMISSION_SCATTER,
  1972. UFBX_MATERIAL_PBR_TRANSMISSION_SCATTER_ANISOTROPY,
  1973. UFBX_MATERIAL_PBR_TRANSMISSION_DISPERSION,
  1974. UFBX_MATERIAL_PBR_TRANSMISSION_ROUGHNESS,
  1975. UFBX_MATERIAL_PBR_TRANSMISSION_EXTRA_ROUGHNESS,
  1976. UFBX_MATERIAL_PBR_TRANSMISSION_PRIORITY,
  1977. UFBX_MATERIAL_PBR_TRANSMISSION_ENABLE_IN_AOV,
  1978. UFBX_MATERIAL_PBR_SUBSURFACE_FACTOR,
  1979. UFBX_MATERIAL_PBR_SUBSURFACE_COLOR,
  1980. UFBX_MATERIAL_PBR_SUBSURFACE_RADIUS,
  1981. UFBX_MATERIAL_PBR_SUBSURFACE_SCALE,
  1982. UFBX_MATERIAL_PBR_SUBSURFACE_ANISOTROPY,
  1983. UFBX_MATERIAL_PBR_SUBSURFACE_TINT_COLOR,
  1984. UFBX_MATERIAL_PBR_SUBSURFACE_TYPE,
  1985. UFBX_MATERIAL_PBR_SHEEN_FACTOR,
  1986. UFBX_MATERIAL_PBR_SHEEN_COLOR,
  1987. UFBX_MATERIAL_PBR_SHEEN_ROUGHNESS,
  1988. UFBX_MATERIAL_PBR_COAT_FACTOR,
  1989. UFBX_MATERIAL_PBR_COAT_COLOR,
  1990. UFBX_MATERIAL_PBR_COAT_ROUGHNESS,
  1991. UFBX_MATERIAL_PBR_COAT_IOR,
  1992. UFBX_MATERIAL_PBR_COAT_ANISOTROPY,
  1993. UFBX_MATERIAL_PBR_COAT_ROTATION,
  1994. UFBX_MATERIAL_PBR_COAT_NORMAL,
  1995. UFBX_MATERIAL_PBR_COAT_AFFECT_BASE_COLOR,
  1996. UFBX_MATERIAL_PBR_COAT_AFFECT_BASE_ROUGHNESS,
  1997. UFBX_MATERIAL_PBR_THIN_FILM_THICKNESS,
  1998. UFBX_MATERIAL_PBR_THIN_FILM_IOR,
  1999. UFBX_MATERIAL_PBR_EMISSION_FACTOR,
  2000. UFBX_MATERIAL_PBR_EMISSION_COLOR,
  2001. UFBX_MATERIAL_PBR_OPACITY,
  2002. UFBX_MATERIAL_PBR_INDIRECT_DIFFUSE,
  2003. UFBX_MATERIAL_PBR_INDIRECT_SPECULAR,
  2004. UFBX_MATERIAL_PBR_NORMAL_MAP,
  2005. UFBX_MATERIAL_PBR_TANGENT_MAP,
  2006. UFBX_MATERIAL_PBR_DISPLACEMENT_MAP,
  2007. UFBX_MATERIAL_PBR_MATTE_FACTOR,
  2008. UFBX_MATERIAL_PBR_MATTE_COLOR,
  2009. UFBX_MATERIAL_PBR_AMBIENT_OCCLUSION,
  2010. UFBX_MATERIAL_PBR_GLOSSINESS,
  2011. UFBX_MATERIAL_PBR_COAT_GLOSSINESS,
  2012. UFBX_MATERIAL_PBR_TRANSMISSION_GLOSSINESS,
  2013. UFBX_ENUM_FORCE_WIDTH(UFBX_MATERIAL_PBR_MAP)
  2014. } ufbx_material_pbr_map;
  2015. UFBX_ENUM_TYPE(ufbx_material_pbr_map, UFBX_MATERIAL_PBR_MAP, UFBX_MATERIAL_PBR_TRANSMISSION_GLOSSINESS);
  2016. // Known material features
  2017. typedef enum ufbx_material_feature UFBX_ENUM_REPR {
  2018. UFBX_MATERIAL_FEATURE_PBR,
  2019. UFBX_MATERIAL_FEATURE_METALNESS,
  2020. UFBX_MATERIAL_FEATURE_DIFFUSE,
  2021. UFBX_MATERIAL_FEATURE_SPECULAR,
  2022. UFBX_MATERIAL_FEATURE_EMISSION,
  2023. UFBX_MATERIAL_FEATURE_TRANSMISSION,
  2024. UFBX_MATERIAL_FEATURE_COAT,
  2025. UFBX_MATERIAL_FEATURE_SHEEN,
  2026. UFBX_MATERIAL_FEATURE_OPACITY,
  2027. UFBX_MATERIAL_FEATURE_AMBIENT_OCCLUSION,
  2028. UFBX_MATERIAL_FEATURE_MATTE,
  2029. UFBX_MATERIAL_FEATURE_UNLIT,
  2030. UFBX_MATERIAL_FEATURE_IOR,
  2031. UFBX_MATERIAL_FEATURE_DIFFUSE_ROUGHNESS,
  2032. UFBX_MATERIAL_FEATURE_TRANSMISSION_ROUGHNESS,
  2033. UFBX_MATERIAL_FEATURE_THIN_WALLED,
  2034. UFBX_MATERIAL_FEATURE_CAUSTICS,
  2035. UFBX_MATERIAL_FEATURE_EXIT_TO_BACKGROUND,
  2036. UFBX_MATERIAL_FEATURE_INTERNAL_REFLECTIONS,
  2037. UFBX_MATERIAL_FEATURE_DOUBLE_SIDED,
  2038. UFBX_MATERIAL_FEATURE_ROUGHNESS_AS_GLOSSINESS,
  2039. UFBX_MATERIAL_FEATURE_COAT_ROUGHNESS_AS_GLOSSINESS,
  2040. UFBX_MATERIAL_FEATURE_TRANSMISSION_ROUGHNESS_AS_GLOSSINESS,
  2041. UFBX_ENUM_FORCE_WIDTH(UFBX_MATERIAL_FEATURE)
  2042. } ufbx_material_feature;
  2043. UFBX_ENUM_TYPE(ufbx_material_feature, UFBX_MATERIAL_FEATURE, UFBX_MATERIAL_FEATURE_TRANSMISSION_ROUGHNESS_AS_GLOSSINESS);
  2044. typedef struct ufbx_material_fbx_maps {
  2045. union {
  2046. ufbx_material_map maps[UFBX_MATERIAL_FBX_MAP_COUNT];
  2047. struct {
  2048. ufbx_material_map diffuse_factor;
  2049. ufbx_material_map diffuse_color;
  2050. ufbx_material_map specular_factor;
  2051. ufbx_material_map specular_color;
  2052. ufbx_material_map specular_exponent;
  2053. ufbx_material_map reflection_factor;
  2054. ufbx_material_map reflection_color;
  2055. ufbx_material_map transparency_factor;
  2056. ufbx_material_map transparency_color;
  2057. ufbx_material_map emission_factor;
  2058. ufbx_material_map emission_color;
  2059. ufbx_material_map ambient_factor;
  2060. ufbx_material_map ambient_color;
  2061. ufbx_material_map normal_map;
  2062. ufbx_material_map bump;
  2063. ufbx_material_map bump_factor;
  2064. ufbx_material_map displacement_factor;
  2065. ufbx_material_map displacement;
  2066. ufbx_material_map vector_displacement_factor;
  2067. ufbx_material_map vector_displacement;
  2068. };
  2069. };
  2070. } ufbx_material_fbx_maps;
  2071. typedef struct ufbx_material_pbr_maps {
  2072. union {
  2073. ufbx_material_map maps[UFBX_MATERIAL_PBR_MAP_COUNT];
  2074. struct {
  2075. ufbx_material_map base_factor;
  2076. ufbx_material_map base_color;
  2077. ufbx_material_map roughness;
  2078. ufbx_material_map metalness;
  2079. ufbx_material_map diffuse_roughness;
  2080. ufbx_material_map specular_factor;
  2081. ufbx_material_map specular_color;
  2082. ufbx_material_map specular_ior;
  2083. ufbx_material_map specular_anisotropy;
  2084. ufbx_material_map specular_rotation;
  2085. ufbx_material_map transmission_factor;
  2086. ufbx_material_map transmission_color;
  2087. ufbx_material_map transmission_depth;
  2088. ufbx_material_map transmission_scatter;
  2089. ufbx_material_map transmission_scatter_anisotropy;
  2090. ufbx_material_map transmission_dispersion;
  2091. ufbx_material_map transmission_roughness;
  2092. ufbx_material_map transmission_extra_roughness;
  2093. ufbx_material_map transmission_priority;
  2094. ufbx_material_map transmission_enable_in_aov;
  2095. ufbx_material_map subsurface_factor;
  2096. ufbx_material_map subsurface_color;
  2097. ufbx_material_map subsurface_radius;
  2098. ufbx_material_map subsurface_scale;
  2099. ufbx_material_map subsurface_anisotropy;
  2100. ufbx_material_map subsurface_tint_color;
  2101. ufbx_material_map subsurface_type;
  2102. ufbx_material_map sheen_factor;
  2103. ufbx_material_map sheen_color;
  2104. ufbx_material_map sheen_roughness;
  2105. ufbx_material_map coat_factor;
  2106. ufbx_material_map coat_color;
  2107. ufbx_material_map coat_roughness;
  2108. ufbx_material_map coat_ior;
  2109. ufbx_material_map coat_anisotropy;
  2110. ufbx_material_map coat_rotation;
  2111. ufbx_material_map coat_normal;
  2112. ufbx_material_map coat_affect_base_color;
  2113. ufbx_material_map coat_affect_base_roughness;
  2114. ufbx_material_map thin_film_thickness;
  2115. ufbx_material_map thin_film_ior;
  2116. ufbx_material_map emission_factor;
  2117. ufbx_material_map emission_color;
  2118. ufbx_material_map opacity;
  2119. ufbx_material_map indirect_diffuse;
  2120. ufbx_material_map indirect_specular;
  2121. ufbx_material_map normal_map;
  2122. ufbx_material_map tangent_map;
  2123. ufbx_material_map displacement_map;
  2124. ufbx_material_map matte_factor;
  2125. ufbx_material_map matte_color;
  2126. ufbx_material_map ambient_occlusion;
  2127. ufbx_material_map glossiness;
  2128. ufbx_material_map coat_glossiness;
  2129. ufbx_material_map transmission_glossiness;
  2130. };
  2131. };
  2132. } ufbx_material_pbr_maps;
  2133. typedef struct ufbx_material_features {
  2134. union {
  2135. ufbx_material_feature_info features[UFBX_MATERIAL_FEATURE_COUNT];
  2136. struct {
  2137. ufbx_material_feature_info pbr;
  2138. ufbx_material_feature_info metalness;
  2139. ufbx_material_feature_info diffuse;
  2140. ufbx_material_feature_info specular;
  2141. ufbx_material_feature_info emission;
  2142. ufbx_material_feature_info transmission;
  2143. ufbx_material_feature_info coat;
  2144. ufbx_material_feature_info sheen;
  2145. ufbx_material_feature_info opacity;
  2146. ufbx_material_feature_info ambient_occlusion;
  2147. ufbx_material_feature_info matte;
  2148. ufbx_material_feature_info unlit;
  2149. ufbx_material_feature_info ior;
  2150. ufbx_material_feature_info diffuse_roughness;
  2151. ufbx_material_feature_info transmission_roughness;
  2152. ufbx_material_feature_info thin_walled;
  2153. ufbx_material_feature_info caustics;
  2154. ufbx_material_feature_info exit_to_background;
  2155. ufbx_material_feature_info internal_reflections;
  2156. ufbx_material_feature_info double_sided;
  2157. ufbx_material_feature_info roughness_as_glossiness;
  2158. ufbx_material_feature_info coat_roughness_as_glossiness;
  2159. ufbx_material_feature_info transmission_roughness_as_glossiness;
  2160. };
  2161. };
  2162. } ufbx_material_features;
  2163. // Surface material properties such as color, roughness, etc. Each property may
  2164. // be optionally bound to an `ufbx_texture`.
  2165. struct ufbx_material {
  2166. union { ufbx_element element; struct {
  2167. ufbx_string name;
  2168. ufbx_props props;
  2169. uint32_t element_id;
  2170. uint32_t typed_id;
  2171. }; };
  2172. // FBX builtin properties
  2173. // NOTE: These may be empty if the material is using a custom shader
  2174. ufbx_material_fbx_maps fbx;
  2175. // PBR material properties, defined for all shading models but may be
  2176. // somewhat approximate if `shader == NULL`.
  2177. ufbx_material_pbr_maps pbr;
  2178. // Material features, primarily applies to `pbr`.
  2179. ufbx_material_features features;
  2180. // Shading information
  2181. ufbx_shader_type shader_type; // < Always defined
  2182. ufbx_nullable ufbx_shader *shader; // < Optional extended shader information
  2183. ufbx_string shading_model_name; // < Often one of `{ "lambert", "phong", "unknown" }`
  2184. // Prefix before shader property names with trailing `|`.
  2185. // For example `"3dsMax|Parameters|"` where properties would have names like
  2186. // `"3dsMax|Parameters|base_color"`. You can ignore this if you use the built-in
  2187. // `ufbx_material_fbx_maps fbx` and `ufbx_material_pbr_maps pbr` structures.
  2188. ufbx_string shader_prop_prefix;
  2189. // All textures attached to the material, if you want specific maps if might be
  2190. // more convenient to use eg. `fbx.diffuse_color.texture` or `pbr.base_color.texture`
  2191. ufbx_material_texture_list textures; // < Sorted by `material_prop`
  2192. };
  2193. typedef enum ufbx_texture_type UFBX_ENUM_REPR {
  2194. // Texture associated with an image file/sequence. `texture->filename` and
  2195. // and `texture->relative_filename` contain the texture's path. If the file
  2196. // has embedded content `texture->content` may hold `texture->content_size`
  2197. // bytes of raw image data.
  2198. UFBX_TEXTURE_FILE,
  2199. // The texture consists of multiple texture layers blended together.
  2200. UFBX_TEXTURE_LAYERED,
  2201. // Reserved as these _should_ exist in FBX files.
  2202. UFBX_TEXTURE_PROCEDURAL,
  2203. // Node in a shader graph.
  2204. // Use `ufbx_texture.shader` for more information.
  2205. UFBX_TEXTURE_SHADER,
  2206. UFBX_ENUM_FORCE_WIDTH(UFBX_TEXTURE_TYPE)
  2207. } ufbx_texture_type;
  2208. UFBX_ENUM_TYPE(ufbx_texture_type, UFBX_TEXTURE_TYPE, UFBX_TEXTURE_SHADER);
  2209. // Blend modes to combine layered textures with, compatible with common blend
  2210. // mode definitions in many art programs. Simpler blend modes have equations
  2211. // specified below where `src` is the layer to composite over `dst`.
  2212. // See eg. https://www.w3.org/TR/2013/WD-compositing-1-20131010/#blendingseparable
  2213. typedef enum ufbx_blend_mode UFBX_ENUM_REPR {
  2214. UFBX_BLEND_TRANSLUCENT, // < `src` effects result alpha
  2215. UFBX_BLEND_ADDITIVE, // < `src + dst`
  2216. UFBX_BLEND_MULTIPLY, // < `src * dst`
  2217. UFBX_BLEND_MULTIPLY_2X, // < `2 * src * dst`
  2218. UFBX_BLEND_OVER, // < `src * src_alpha + dst * (1-src_alpha)`
  2219. UFBX_BLEND_REPLACE, // < `src` Replace the contents
  2220. UFBX_BLEND_DISSOLVE, // < `random() + src_alpha >= 1.0 ? src : dst`
  2221. UFBX_BLEND_DARKEN, // < `min(src, dst)`
  2222. UFBX_BLEND_COLOR_BURN, // < `src > 0 ? 1 - min(1, (1-dst) / src) : 0`
  2223. UFBX_BLEND_LINEAR_BURN, // < `src + dst - 1`
  2224. UFBX_BLEND_DARKER_COLOR, // < `value(src) < value(dst) ? src : dst`
  2225. UFBX_BLEND_LIGHTEN, // < `max(src, dst)`
  2226. UFBX_BLEND_SCREEN, // < `1 - (1-src)*(1-dst)`
  2227. UFBX_BLEND_COLOR_DODGE, // < `src < 1 ? dst / (1 - src)` : (dst>0?1:0)`
  2228. UFBX_BLEND_LINEAR_DODGE, // < `src + dst`
  2229. UFBX_BLEND_LIGHTER_COLOR, // < `value(src) > value(dst) ? src : dst`
  2230. UFBX_BLEND_SOFT_LIGHT, // < https://www.w3.org/TR/2013/WD-compositing-1-20131010/#blendingsoftlight
  2231. UFBX_BLEND_HARD_LIGHT, // < https://www.w3.org/TR/2013/WD-compositing-1-20131010/#blendinghardlight
  2232. UFBX_BLEND_VIVID_LIGHT, // < Combination of `COLOR_DODGE` and `COLOR_BURN`
  2233. UFBX_BLEND_LINEAR_LIGHT, // < Combination of `LINEAR_DODGE` and `LINEAR_BURN`
  2234. UFBX_BLEND_PIN_LIGHT, // < Combination of `DARKEN` and `LIGHTEN`
  2235. UFBX_BLEND_HARD_MIX, // < Produces primary colors depending on similarity
  2236. UFBX_BLEND_DIFFERENCE, // < `abs(src - dst)`
  2237. UFBX_BLEND_EXCLUSION, // < `dst + src - 2 * src * dst`
  2238. UFBX_BLEND_SUBTRACT, // < `dst - src`
  2239. UFBX_BLEND_DIVIDE, // < `dst / src`
  2240. UFBX_BLEND_HUE, // < Replace hue
  2241. UFBX_BLEND_SATURATION, // < Replace saturation
  2242. UFBX_BLEND_COLOR, // < Replace hue and saturatio
  2243. UFBX_BLEND_LUMINOSITY, // < Replace value
  2244. UFBX_BLEND_OVERLAY, // < Same as `HARD_LIGHT` but with `src` and `dst` swapped
  2245. UFBX_ENUM_FORCE_WIDTH(UFBX_BLEND_MODE)
  2246. } ufbx_blend_mode;
  2247. UFBX_ENUM_TYPE(ufbx_blend_mode, UFBX_BLEND_MODE, UFBX_BLEND_OVERLAY);
  2248. // Blend modes to combine layered textures with, compatible with common blend
  2249. typedef enum ufbx_wrap_mode UFBX_ENUM_REPR {
  2250. UFBX_WRAP_REPEAT, // < Repeat the texture past the [0,1] range
  2251. UFBX_WRAP_CLAMP, // < Clamp the normalized texture coordinates to [0,1]
  2252. UFBX_ENUM_FORCE_WIDTH(UFBX_WRAP_MODE)
  2253. } ufbx_wrap_mode;
  2254. UFBX_ENUM_TYPE(ufbx_wrap_mode, UFBX_WRAP_MODE, UFBX_WRAP_CLAMP);
  2255. // Single layer in a layered texture
  2256. typedef struct ufbx_texture_layer {
  2257. ufbx_texture *texture; // < The inner texture to evaluate, never `NULL`
  2258. ufbx_blend_mode blend_mode; // < Equation to combine the layer to the background
  2259. ufbx_real alpha; // < Blend weight of this layer
  2260. } ufbx_texture_layer;
  2261. UFBX_LIST_TYPE(ufbx_texture_layer_list, ufbx_texture_layer);
  2262. typedef enum ufbx_shader_texture_type UFBX_ENUM_REPR {
  2263. UFBX_SHADER_TEXTURE_UNKNOWN,
  2264. // Select an output of a multi-output shader.
  2265. // HINT: If this type is used the `ufbx_shader_texture.main_texture` and
  2266. // `ufbx_shader_texture.main_texture_output_index` fields are set.
  2267. UFBX_SHADER_TEXTURE_SELECT_OUTPUT,
  2268. // Open Shading Language (OSL) shader.
  2269. // https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
  2270. UFBX_SHADER_TEXTURE_OSL,
  2271. UFBX_ENUM_FORCE_WIDTH(UFBX_SHADER_TEXTURE_TYPE)
  2272. } ufbx_shader_texture_type;
  2273. UFBX_ENUM_TYPE(ufbx_shader_texture_type, UFBX_SHADER_TEXTURE_TYPE, UFBX_SHADER_TEXTURE_OSL);
  2274. // Input to a shader texture, see `ufbx_shader_texture`.
  2275. typedef struct ufbx_shader_texture_input {
  2276. // Name of the input.
  2277. ufbx_string name;
  2278. // Constant value of the input.
  2279. union {
  2280. ufbx_real value_real;
  2281. ufbx_vec2 value_vec2;
  2282. ufbx_vec3 value_vec3;
  2283. ufbx_vec4 value_vec4;
  2284. };
  2285. int64_t value_int;
  2286. ufbx_string value_str;
  2287. ufbx_blob value_blob;
  2288. // Texture connected to this input.
  2289. ufbx_nullable ufbx_texture *texture;
  2290. // Index of the output to use if `texture` is a multi-output shader node.
  2291. int64_t texture_output_index;
  2292. // Controls whether shading should use `texture`.
  2293. // NOTE: Some shading models allow this to be `true` even if `texture == NULL`.
  2294. bool texture_enabled;
  2295. // Property representing this input.
  2296. ufbx_prop *prop;
  2297. // Property representing `texture`.
  2298. ufbx_nullable ufbx_prop *texture_prop;
  2299. // Property representing `texture_enabled`.
  2300. ufbx_nullable ufbx_prop *texture_enabled_prop;
  2301. } ufbx_shader_texture_input;
  2302. UFBX_LIST_TYPE(ufbx_shader_texture_input_list, ufbx_shader_texture_input);
  2303. // Texture that emulates a shader graph node.
  2304. // 3ds Max exports some materials as node graphs serialized to textures.
  2305. // ufbx can parse a small subset of these, as normal maps are often hidden behind
  2306. // some kind of bump node.
  2307. // NOTE: These encode a lot of details of 3ds Max internals, not recommended for direct use.
  2308. // HINT: `ufbx_texture.file_textures[]` contains a list of "real" textures that are connected
  2309. // to the `ufbx_texture` that is pretending to be a shader node.
  2310. typedef struct ufbx_shader_texture {
  2311. // Type of this shader node.
  2312. ufbx_shader_texture_type type;
  2313. // Name of the shader to use.
  2314. ufbx_string shader_name;
  2315. // 64-bit opaque identifier for the shader type.
  2316. uint64_t shader_type_id;
  2317. // Input values/textures (possibly further shader textures) to the shader.
  2318. // Sorted by `ufbx_shader_texture_input.name`.
  2319. ufbx_shader_texture_input_list inputs;
  2320. // Shader source code if found.
  2321. ufbx_string shader_source;
  2322. ufbx_blob raw_shader_source;
  2323. // Representative texture for this shader.
  2324. // Only specified if `main_texture.outputs[main_texture_output_index]` is semantically
  2325. // equivalent to this texture.
  2326. ufbx_texture *main_texture;
  2327. // Output index of `main_texture` if it is a multi-output shader.
  2328. int64_t main_texture_output_index;
  2329. // Prefix for properties related to this shader in `ufbx_texture`.
  2330. // NOTE: Contains the trailing '|' if not empty.
  2331. ufbx_string prop_prefix;
  2332. } ufbx_shader_texture;
  2333. // Unique texture within the file.
  2334. typedef struct ufbx_texture_file {
  2335. // Index in `ufbx_scene.texture_files[]`.
  2336. uint32_t index;
  2337. // Paths to the resource.
  2338. // Filename relative to the currently loaded file.
  2339. // HINT: If using functions other than `ufbx_load_file()`, you can provide
  2340. // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this.
  2341. ufbx_string filename;
  2342. // Absolute filename specified in the file.
  2343. ufbx_string absolute_filename;
  2344. // Relative filename specified in the file.
  2345. // NOTE: May be absolute if the file is saved in a different drive.
  2346. ufbx_string relative_filename;
  2347. // Filename relative to the loaded file, non-UTF-8 encoded.
  2348. // HINT: If using functions other than `ufbx_load_file()`, you can provide
  2349. // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this.
  2350. ufbx_blob raw_filename;
  2351. // Absolute filename specified in the file, non-UTF-8 encoded.
  2352. ufbx_blob raw_absolute_filename;
  2353. // Relative filename specified in the file, non-UTF-8 encoded.
  2354. // NOTE: May be absolute if the file is saved in a different drive.
  2355. ufbx_blob raw_relative_filename;
  2356. // Optional embedded content blob, eg. raw .png format data
  2357. ufbx_blob content;
  2358. } ufbx_texture_file;
  2359. UFBX_LIST_TYPE(ufbx_texture_file_list, ufbx_texture_file);
  2360. // Texture that controls material appearance
  2361. struct ufbx_texture {
  2362. union { ufbx_element element; struct {
  2363. ufbx_string name;
  2364. ufbx_props props;
  2365. uint32_t element_id;
  2366. uint32_t typed_id;
  2367. }; };
  2368. // Texture type (file / layered / procedural / shader)
  2369. ufbx_texture_type type;
  2370. // FILE: Paths to the resource
  2371. // Filename relative to the currently loaded file.
  2372. // HINT: If using functions other than `ufbx_load_file()`, you can provide
  2373. // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this.
  2374. ufbx_string filename;
  2375. // Absolute filename specified in the file.
  2376. ufbx_string absolute_filename;
  2377. // Relative filename specified in the file.
  2378. // NOTE: May be absolute if the file is saved in a different drive.
  2379. ufbx_string relative_filename;
  2380. // Filename relative to the loaded file, non-UTF-8 encoded.
  2381. // HINT: If using functions other than `ufbx_load_file()`, you can provide
  2382. // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this.
  2383. ufbx_blob raw_filename;
  2384. // Absolute filename specified in the file, non-UTF-8 encoded.
  2385. ufbx_blob raw_absolute_filename;
  2386. // Relative filename specified in the file, non-UTF-8 encoded.
  2387. // NOTE: May be absolute if the file is saved in a different drive.
  2388. ufbx_blob raw_relative_filename;
  2389. // FILE: Optional embedded content blob, eg. raw .png format data
  2390. ufbx_blob content;
  2391. // FILE: Optional video texture
  2392. ufbx_nullable ufbx_video *video;
  2393. // FILE: Index into `ufbx_scene.texture_files[]` or `UFBX_NO_INDEX`.
  2394. uint32_t file_index;
  2395. // FILE: True if `file_index` has a valid value.
  2396. bool has_file;
  2397. // LAYERED: Inner texture layers, ordered from _bottom_ to _top_
  2398. ufbx_texture_layer_list layers;
  2399. // SHADER: Shader information
  2400. // NOTE: May be specified even if `type == UFBX_TEXTURE_FILE` if `ufbx_load_opts.disable_quirks`
  2401. // is _not_ specified. Some known shaders that represent files are interpreted as `UFBX_TEXTURE_FILE`.
  2402. ufbx_nullable ufbx_shader_texture *shader;
  2403. // List of file textures representing this texture.
  2404. // Defined even if `type == UFBX_TEXTURE_FILE` in which case the array contains only itself.
  2405. ufbx_texture_list file_textures;
  2406. // Name of the UV set to use
  2407. ufbx_string uv_set;
  2408. // Wrapping mode
  2409. ufbx_wrap_mode wrap_u;
  2410. ufbx_wrap_mode wrap_v;
  2411. // UV transform
  2412. bool has_uv_transform; // < Has a non-identity `transform` and derived matrices.
  2413. ufbx_transform uv_transform; // < Texture transformation in UV space
  2414. ufbx_matrix texture_to_uv; // < Matrix representation of `transform`
  2415. ufbx_matrix uv_to_texture; // < UV coordinate to normalized texture coordinate matrix
  2416. };
  2417. // TODO: Video textures
  2418. struct ufbx_video {
  2419. union { ufbx_element element; struct {
  2420. ufbx_string name;
  2421. ufbx_props props;
  2422. uint32_t element_id;
  2423. uint32_t typed_id;
  2424. }; };
  2425. // Paths to the resource
  2426. // Filename relative to the currently loaded file.
  2427. // HINT: If using functions other than `ufbx_load_file()`, you can provide
  2428. // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this.
  2429. ufbx_string filename;
  2430. // Absolute filename specified in the file.
  2431. ufbx_string absolute_filename;
  2432. // Relative filename specified in the file.
  2433. // NOTE: May be absolute if the file is saved in a different drive.
  2434. ufbx_string relative_filename;
  2435. // Filename relative to the loaded file, non-UTF-8 encoded.
  2436. // HINT: If using functions other than `ufbx_load_file()`, you can provide
  2437. // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this.
  2438. ufbx_blob raw_filename;
  2439. // Absolute filename specified in the file, non-UTF-8 encoded.
  2440. ufbx_blob raw_absolute_filename;
  2441. // Relative filename specified in the file, non-UTF-8 encoded.
  2442. // NOTE: May be absolute if the file is saved in a different drive.
  2443. ufbx_blob raw_relative_filename;
  2444. // Optional embedded content blob
  2445. ufbx_blob content;
  2446. };
  2447. // Shader specifies a shading model and contains `ufbx_shader_binding` elements
  2448. // that define how to interpret FBX properties in the shader.
  2449. struct ufbx_shader {
  2450. union { ufbx_element element; struct {
  2451. ufbx_string name;
  2452. ufbx_props props;
  2453. uint32_t element_id;
  2454. uint32_t typed_id;
  2455. }; };
  2456. // Known shading model
  2457. ufbx_shader_type type;
  2458. // TODO: Expose actual properties here
  2459. // Bindings from FBX properties to the shader
  2460. // HINT: `ufbx_find_shader_prop()` translates shader properties to FBX properties
  2461. ufbx_shader_binding_list bindings;
  2462. };
  2463. // Binding from a material property to shader implementation
  2464. typedef struct ufbx_shader_prop_binding {
  2465. ufbx_string shader_prop; // < Property name used by the shader implementation
  2466. ufbx_string material_prop; // < Property name inside `ufbx_material.props`
  2467. } ufbx_shader_prop_binding;
  2468. UFBX_LIST_TYPE(ufbx_shader_prop_binding_list, ufbx_shader_prop_binding);
  2469. // Shader binding table
  2470. struct ufbx_shader_binding {
  2471. union { ufbx_element element; struct {
  2472. ufbx_string name;
  2473. ufbx_props props;
  2474. uint32_t element_id;
  2475. uint32_t typed_id;
  2476. }; };
  2477. ufbx_shader_prop_binding_list prop_bindings; // < Sorted by `shader_prop`
  2478. };
  2479. // -- Animation
  2480. typedef struct ufbx_prop_override {
  2481. uint32_t element_id;
  2482. uint32_t _internal_key;
  2483. ufbx_string prop_name;
  2484. ufbx_vec4 value;
  2485. ufbx_string value_str;
  2486. int64_t value_int;
  2487. } ufbx_prop_override;
  2488. UFBX_LIST_TYPE(ufbx_prop_override_list, ufbx_prop_override);
  2489. typedef struct ufbx_transform_override {
  2490. uint32_t node_id;
  2491. ufbx_transform transform;
  2492. } ufbx_transform_override;
  2493. UFBX_LIST_TYPE(ufbx_transform_override_list, ufbx_transform_override);
  2494. // Animation descriptor used for evaluating animation.
  2495. // Usually obtained from `ufbx_scene` via either global animation `ufbx_scene.anim`,
  2496. // per-stack animation `ufbx_anim_stack.anim` or per-layer animation `ufbx_anim_layer.anim`.
  2497. //
  2498. // For advanced usage you can use `ufbx_create_anim()` to create animation descriptors
  2499. // with custom layers, property overrides, special flags, etc.
  2500. typedef struct ufbx_anim {
  2501. // Time begin/end for the animation, both may be zero if absent.
  2502. double time_begin;
  2503. double time_end;
  2504. // List of layers in the animation.
  2505. ufbx_anim_layer_list layers;
  2506. // Optional overrides for weights for each layer in `layers[]`.
  2507. ufbx_real_list override_layer_weights;
  2508. // Sorted by `element_id, prop_name`
  2509. ufbx_prop_override_list prop_overrides;
  2510. // Sorted by `node_id`
  2511. ufbx_transform_override_list transform_overrides;
  2512. // Evaluate connected properties as if they would not be connected.
  2513. bool ignore_connections;
  2514. // Custom `ufbx_anim` created by `ufbx_create_anim()`.
  2515. bool custom;
  2516. } ufbx_anim;
  2517. struct ufbx_anim_stack {
  2518. union { ufbx_element element; struct {
  2519. ufbx_string name;
  2520. ufbx_props props;
  2521. uint32_t element_id;
  2522. uint32_t typed_id;
  2523. }; };
  2524. double time_begin;
  2525. double time_end;
  2526. ufbx_anim_layer_list layers;
  2527. ufbx_anim *anim;
  2528. };
  2529. typedef struct ufbx_anim_prop {
  2530. ufbx_element *element;
  2531. uint32_t _internal_key;
  2532. ufbx_string prop_name;
  2533. ufbx_anim_value *anim_value;
  2534. } ufbx_anim_prop;
  2535. UFBX_LIST_TYPE(ufbx_anim_prop_list, ufbx_anim_prop);
  2536. struct ufbx_anim_layer {
  2537. union { ufbx_element element; struct {
  2538. ufbx_string name;
  2539. ufbx_props props;
  2540. uint32_t element_id;
  2541. uint32_t typed_id;
  2542. }; };
  2543. ufbx_real weight;
  2544. bool weight_is_animated;
  2545. bool blended;
  2546. bool additive;
  2547. bool compose_rotation;
  2548. bool compose_scale;
  2549. ufbx_anim_value_list anim_values;
  2550. ufbx_anim_prop_list anim_props; // < Sorted by `element,prop_name`
  2551. ufbx_anim *anim;
  2552. uint32_t _min_element_id;
  2553. uint32_t _max_element_id;
  2554. uint32_t _element_id_bitmask[4];
  2555. };
  2556. struct ufbx_anim_value {
  2557. union { ufbx_element element; struct {
  2558. ufbx_string name;
  2559. ufbx_props props;
  2560. uint32_t element_id;
  2561. uint32_t typed_id;
  2562. }; };
  2563. ufbx_vec3 default_value;
  2564. ufbx_nullable ufbx_anim_curve *curves[3];
  2565. };
  2566. // Animation curve segment interpolation mode between two keyframes
  2567. typedef enum ufbx_interpolation UFBX_ENUM_REPR {
  2568. UFBX_INTERPOLATION_CONSTANT_PREV, // < Hold previous key value
  2569. UFBX_INTERPOLATION_CONSTANT_NEXT, // < Hold next key value
  2570. UFBX_INTERPOLATION_LINEAR, // < Linear interpolation between two keys
  2571. UFBX_INTERPOLATION_CUBIC, // < Cubic interpolation, see `ufbx_tangent`
  2572. UFBX_ENUM_FORCE_WIDTH(UFBX_INTERPOLATION)
  2573. } ufbx_interpolation;
  2574. UFBX_ENUM_TYPE(ufbx_interpolation, UFBX_INTERPOLATION, UFBX_INTERPOLATION_CUBIC);
  2575. // Tangent vector at a keyframe, may be split into left/right
  2576. typedef struct ufbx_tangent {
  2577. float dx; // < Derivative in the time axis
  2578. float dy; // < Derivative in the (curve specific) value axis
  2579. } ufbx_tangent;
  2580. // Single real `value` at a specified `time`, interpolation between two keyframes
  2581. // is determined by the `interpolation` field of the _previous_ key.
  2582. // If `interpolation == UFBX_INTERPOLATION_CUBIC` the span is evaluated as a
  2583. // cubic bezier curve through the following points:
  2584. //
  2585. // (prev->time, prev->value)
  2586. // (prev->time + prev->right.dx, prev->value + prev->right.dy)
  2587. // (next->time - next->left.dx, next->value - next->left.dy)
  2588. // (next->time, next->value)
  2589. //
  2590. // HINT: You can use `ufbx_evaluate_curve(ufbx_anim_curve *curve, double time)`
  2591. // rather than trying to manually handle all the interpolation modes.
  2592. typedef struct ufbx_keyframe {
  2593. double time;
  2594. ufbx_real value;
  2595. ufbx_interpolation interpolation;
  2596. ufbx_tangent left;
  2597. ufbx_tangent right;
  2598. } ufbx_keyframe;
  2599. UFBX_LIST_TYPE(ufbx_keyframe_list, ufbx_keyframe);
  2600. struct ufbx_anim_curve {
  2601. union { ufbx_element element; struct {
  2602. ufbx_string name;
  2603. ufbx_props props;
  2604. uint32_t element_id;
  2605. uint32_t typed_id;
  2606. }; };
  2607. ufbx_keyframe_list keyframes;
  2608. ufbx_real min_value;
  2609. ufbx_real max_value;
  2610. };
  2611. // -- Collections
  2612. // Collection of nodes to hide/freeze
  2613. struct ufbx_display_layer {
  2614. union { ufbx_element element; struct {
  2615. ufbx_string name;
  2616. ufbx_props props;
  2617. uint32_t element_id;
  2618. uint32_t typed_id;
  2619. }; };
  2620. // Nodes included in the layer (exclusively at most one layer per node)
  2621. ufbx_node_list nodes;
  2622. // Layer state
  2623. bool visible; // < Contained nodes are visible
  2624. bool frozen; // < Contained nodes cannot be edited
  2625. ufbx_vec3 ui_color; // < Visual color for UI
  2626. };
  2627. // Named set of nodes/geometry features to select.
  2628. struct ufbx_selection_set {
  2629. union { ufbx_element element; struct {
  2630. ufbx_string name;
  2631. ufbx_props props;
  2632. uint32_t element_id;
  2633. uint32_t typed_id;
  2634. }; };
  2635. // Included nodes and geometry features
  2636. ufbx_selection_node_list nodes;
  2637. };
  2638. // Selection state of a node, potentially contains vertex/edge/face selection as well.
  2639. struct ufbx_selection_node {
  2640. union { ufbx_element element; struct {
  2641. ufbx_string name;
  2642. ufbx_props props;
  2643. uint32_t element_id;
  2644. uint32_t typed_id;
  2645. }; };
  2646. // Selection targets, possibly `NULL`
  2647. ufbx_nullable ufbx_node *target_node;
  2648. ufbx_nullable ufbx_mesh *target_mesh;
  2649. bool include_node; // < Is `target_node` included in the selection
  2650. // Indices to selected components.
  2651. // Guaranteed to be valid as per `ufbx_load_opts.index_error_handling`
  2652. // if `target_mesh` is not `NULL`.
  2653. ufbx_uint32_list vertices; // < Indices to `ufbx_mesh.vertices`
  2654. ufbx_uint32_list edges; // < Indices to `ufbx_mesh.edges`
  2655. ufbx_uint32_list faces; // < Indices to `ufbx_mesh.faces`
  2656. };
  2657. // -- Constraints
  2658. struct ufbx_character {
  2659. union { ufbx_element element; struct {
  2660. ufbx_string name;
  2661. ufbx_props props;
  2662. uint32_t element_id;
  2663. uint32_t typed_id;
  2664. }; };
  2665. };
  2666. // Type of property constrain eg. position or look-at
  2667. typedef enum ufbx_constraint_type UFBX_ENUM_REPR {
  2668. UFBX_CONSTRAINT_UNKNOWN,
  2669. UFBX_CONSTRAINT_AIM,
  2670. UFBX_CONSTRAINT_PARENT,
  2671. UFBX_CONSTRAINT_POSITION,
  2672. UFBX_CONSTRAINT_ROTATION,
  2673. UFBX_CONSTRAINT_SCALE,
  2674. // Inverse kinematic chain to a single effector `ufbx_constraint.ik_effector`
  2675. // `targets` optionally contains a list of pole targets!
  2676. UFBX_CONSTRAINT_SINGLE_CHAIN_IK,
  2677. UFBX_ENUM_FORCE_WIDTH(UFBX_CONSTRAINT_TYPE)
  2678. } ufbx_constraint_type;
  2679. UFBX_ENUM_TYPE(ufbx_constraint_type, UFBX_CONSTRAINT_TYPE, UFBX_CONSTRAINT_SINGLE_CHAIN_IK);
  2680. // Target to follow with a constraint
  2681. typedef struct ufbx_constraint_target {
  2682. ufbx_node *node; // < Target node reference
  2683. ufbx_real weight; // < Relative weight to other targets (does not always sum to 1)
  2684. ufbx_transform transform; // < Offset from the actual target
  2685. } ufbx_constraint_target;
  2686. UFBX_LIST_TYPE(ufbx_constraint_target_list, ufbx_constraint_target);
  2687. // Method to determine the up vector in aim constraints
  2688. typedef enum ufbx_constraint_aim_up_type UFBX_ENUM_REPR {
  2689. UFBX_CONSTRAINT_AIM_UP_SCENE, // < Align the up vector to the scene global up vector
  2690. UFBX_CONSTRAINT_AIM_UP_TO_NODE, // < Aim the up vector at `ufbx_constraint.aim_up_node`
  2691. UFBX_CONSTRAINT_AIM_UP_ALIGN_NODE, // < Copy the up vector from `ufbx_constraint.aim_up_node`
  2692. UFBX_CONSTRAINT_AIM_UP_VECTOR, // < Use `ufbx_constraint.aim_up_vector` as the up vector
  2693. UFBX_CONSTRAINT_AIM_UP_NONE, // < Don't align the up vector to anything
  2694. UFBX_ENUM_FORCE_WIDTH(UFBX_CONSTRAINT_AIM_UP_TYPE)
  2695. } ufbx_constraint_aim_up_type;
  2696. UFBX_ENUM_TYPE(ufbx_constraint_aim_up_type, UFBX_CONSTRAINT_AIM_UP_TYPE, UFBX_CONSTRAINT_AIM_UP_NONE);
  2697. // Method to determine the up vector in aim constraints
  2698. typedef enum ufbx_constraint_ik_pole_type UFBX_ENUM_REPR {
  2699. UFBX_CONSTRAINT_IK_POLE_VECTOR, // < Use towards calculated from `ufbx_constraint.targets`
  2700. UFBX_CONSTRAINT_IK_POLE_NODE, // < Use `ufbx_constraint.ik_pole_vector` directly
  2701. UFBX_ENUM_FORCE_WIDTH(UFBX_CONSTRAINT_IK_POLE_TYPE)
  2702. } ufbx_constraint_ik_pole_type;
  2703. UFBX_ENUM_TYPE(ufbx_constraint_ik_pole_type, UFBX_CONSTRAINT_IK_POLE_TYPE, UFBX_CONSTRAINT_IK_POLE_NODE);
  2704. struct ufbx_constraint {
  2705. union { ufbx_element element; struct {
  2706. ufbx_string name;
  2707. ufbx_props props;
  2708. uint32_t element_id;
  2709. uint32_t typed_id;
  2710. }; };
  2711. // Type of constraint to use
  2712. ufbx_constraint_type type;
  2713. ufbx_string type_name;
  2714. // Node to be constrained
  2715. ufbx_nullable ufbx_node *node;
  2716. // List of weighted targets for the constraint (pole vectors for IK)
  2717. ufbx_constraint_target_list targets;
  2718. // State of the constraint
  2719. ufbx_real weight;
  2720. bool active;
  2721. // Translation/rotation/scale axes the constraint is applied to
  2722. bool constrain_translation[3];
  2723. bool constrain_rotation[3];
  2724. bool constrain_scale[3];
  2725. // Offset from the constrained position
  2726. ufbx_transform transform_offset;
  2727. // AIM: Target and up vectors
  2728. ufbx_vec3 aim_vector;
  2729. ufbx_constraint_aim_up_type aim_up_type;
  2730. ufbx_nullable ufbx_node *aim_up_node;
  2731. ufbx_vec3 aim_up_vector;
  2732. // SINGLE_CHAIN_IK: Target for the IK, `targets` contains pole vectors!
  2733. ufbx_nullable ufbx_node *ik_effector;
  2734. ufbx_nullable ufbx_node *ik_end_node;
  2735. ufbx_vec3 ik_pole_vector;
  2736. };
  2737. // -- Audio
  2738. struct ufbx_audio_layer {
  2739. union { ufbx_element element; struct {
  2740. ufbx_string name;
  2741. ufbx_props props;
  2742. uint32_t element_id;
  2743. uint32_t typed_id;
  2744. }; };
  2745. // Clips contained in this layer.
  2746. ufbx_audio_clip_list clips;
  2747. };
  2748. struct ufbx_audio_clip {
  2749. union { ufbx_element element; struct {
  2750. ufbx_string name;
  2751. ufbx_props props;
  2752. uint32_t element_id;
  2753. uint32_t typed_id;
  2754. }; };
  2755. // Filename relative to the currently loaded file.
  2756. // HINT: If using functions other than `ufbx_load_file()`, you can provide
  2757. // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this.
  2758. ufbx_string filename;
  2759. // Absolute filename specified in the file.
  2760. ufbx_string absolute_filename;
  2761. // Relative filename specified in the file.
  2762. // NOTE: May be absolute if the file is saved in a different drive.
  2763. ufbx_string relative_filename;
  2764. // Filename relative to the loaded file, non-UTF-8 encoded.
  2765. // HINT: If using functions other than `ufbx_load_file()`, you can provide
  2766. // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this.
  2767. ufbx_blob raw_filename;
  2768. // Absolute filename specified in the file, non-UTF-8 encoded.
  2769. ufbx_blob raw_absolute_filename;
  2770. // Relative filename specified in the file, non-UTF-8 encoded.
  2771. // NOTE: May be absolute if the file is saved in a different drive.
  2772. ufbx_blob raw_relative_filename;
  2773. // Optional embedded content blob, eg. raw .png format data
  2774. ufbx_blob content;
  2775. };
  2776. // -- Miscellaneous
  2777. typedef struct ufbx_bone_pose {
  2778. // Node to apply the pose to.
  2779. ufbx_node *bone_node;
  2780. // Matrix from node local space to world space.
  2781. ufbx_matrix bone_to_world;
  2782. // Matrix from node local space to parent space.
  2783. // NOTE: FBX only stores world transformations so this is approximated from
  2784. // the parent world transform.
  2785. ufbx_matrix bone_to_parent;
  2786. } ufbx_bone_pose;
  2787. UFBX_LIST_TYPE(ufbx_bone_pose_list, ufbx_bone_pose);
  2788. struct ufbx_pose {
  2789. union { ufbx_element element; struct {
  2790. ufbx_string name;
  2791. ufbx_props props;
  2792. uint32_t element_id;
  2793. uint32_t typed_id;
  2794. }; };
  2795. // Set if this pose is marked as a bind pose.
  2796. bool is_bind_pose;
  2797. // List of bone poses.
  2798. // Sorted by `ufbx_node.typed_id`.
  2799. ufbx_bone_pose_list bone_poses;
  2800. };
  2801. struct ufbx_metadata_object {
  2802. union { ufbx_element element; struct {
  2803. ufbx_string name;
  2804. ufbx_props props;
  2805. uint32_t element_id;
  2806. uint32_t typed_id;
  2807. }; };
  2808. };
  2809. // -- Named elements
  2810. typedef struct ufbx_name_element {
  2811. ufbx_string name;
  2812. ufbx_element_type type;
  2813. uint32_t _internal_key;
  2814. ufbx_element *element;
  2815. } ufbx_name_element;
  2816. UFBX_LIST_TYPE(ufbx_name_element_list, ufbx_name_element);
  2817. // -- Scene
  2818. // Scene is the root object loaded by ufbx that everything is accessed from.
  2819. typedef enum ufbx_exporter UFBX_ENUM_REPR {
  2820. UFBX_EXPORTER_UNKNOWN,
  2821. UFBX_EXPORTER_FBX_SDK,
  2822. UFBX_EXPORTER_BLENDER_BINARY,
  2823. UFBX_EXPORTER_BLENDER_ASCII,
  2824. UFBX_EXPORTER_MOTION_BUILDER,
  2825. UFBX_ENUM_FORCE_WIDTH(UFBX_EXPORTER)
  2826. } ufbx_exporter;
  2827. UFBX_ENUM_TYPE(ufbx_exporter, UFBX_EXPORTER, UFBX_EXPORTER_MOTION_BUILDER);
  2828. typedef struct ufbx_application {
  2829. ufbx_string vendor;
  2830. ufbx_string name;
  2831. ufbx_string version;
  2832. } ufbx_application;
  2833. typedef enum ufbx_file_format UFBX_ENUM_REPR {
  2834. UFBX_FILE_FORMAT_UNKNOWN, // < Unknown file format
  2835. UFBX_FILE_FORMAT_FBX, // < .fbx Kaydara/Autodesk FBX file
  2836. UFBX_FILE_FORMAT_OBJ, // < .obj Wavefront OBJ file
  2837. UFBX_FILE_FORMAT_MTL, // < .mtl Wavefront MTL (Material template library) file
  2838. UFBX_ENUM_FORCE_WIDTH(UFBX_FILE_FORMAT)
  2839. } ufbx_file_format;
  2840. UFBX_ENUM_TYPE(ufbx_file_format, UFBX_FILE_FORMAT, UFBX_FILE_FORMAT_MTL);
  2841. typedef enum ufbx_warning_type UFBX_ENUM_REPR {
  2842. // Missing external file file (for example .mtl for Wavefront .obj file or a
  2843. // geometry cache)
  2844. UFBX_WARNING_MISSING_EXTERNAL_FILE,
  2845. // Loaded a Wavefront .mtl file derived from the filename instead of a proper
  2846. // `mtllib` statement.
  2847. UFBX_WARNING_IMPLICIT_MTL,
  2848. // Truncated array has been auto-expanded.
  2849. UFBX_WARNING_TRUNCATED_ARRAY,
  2850. // Geometry data has been defined but has no data.
  2851. UFBX_WARNING_MISSING_GEOMETRY_DATA,
  2852. // Duplicated connection between two elements that shouldn't have.
  2853. UFBX_WARNING_DUPLICATE_CONNECTION,
  2854. // Vertex 'W' attribute length differs from main attribute.
  2855. UFBX_WARNING_BAD_VERTEX_W_ATTRIBUTE,
  2856. // Missing polygon mapping type.
  2857. UFBX_WARNING_MISSING_POLYGON_MAPPING,
  2858. // Out-of-bounds index has been clamped to be in-bounds.
  2859. // HINT: You can use `ufbx_index_error_handling` to adjust behavior.
  2860. UFBX_WARNING_INDEX_CLAMPED,
  2861. // Non-UTF8 encoded strings.
  2862. // HINT: You can use `ufbx_unicode_error_handling` to adjust behavior.
  2863. UFBX_WARNING_BAD_UNICODE,
  2864. // Non-node element connected to root.
  2865. UFBX_WARNING_BAD_ELEMENT_CONNECTED_TO_ROOT,
  2866. // Duplicated object ID in the file, connections will be wrong.
  2867. UFBX_WARNING_DUPLICATE_OBJECT_ID,
  2868. // Empty face has been removed.
  2869. // Use `ufbx_load_opts.allow_empty_faces` if you want to allow them.
  2870. UFBX_WARNING_EMPTY_FACE_REMOVED,
  2871. // Unknown .obj file directive.
  2872. UFBX_WARNING_UNKNOWN_OBJ_DIRECTIVE,
  2873. // Warnings after this one are deduplicated.
  2874. // See `ufbx_warning.count` for how many times they happened.
  2875. UFBX_WARNING_TYPE_FIRST_DEDUPLICATED = UFBX_WARNING_INDEX_CLAMPED,
  2876. UFBX_ENUM_FORCE_WIDTH(UFBX_WARNING_TYPE)
  2877. } ufbx_warning_type;
  2878. UFBX_ENUM_TYPE(ufbx_warning_type, UFBX_WARNING_TYPE, UFBX_WARNING_UNKNOWN_OBJ_DIRECTIVE);
  2879. // Warning about a non-fatal issue in the file.
  2880. // Often contains information about issues that ufbx has corrected about the
  2881. // file but it might indicate something is not working properly.
  2882. typedef struct ufbx_warning {
  2883. // Type of the warning.
  2884. ufbx_warning_type type;
  2885. // Description of the warning.
  2886. ufbx_string description;
  2887. // The element related to this warning or `UFBX_NO_INDEX` if not related to a specific element.
  2888. uint32_t element_id;
  2889. // Number of times this warning was encountered.
  2890. size_t count;
  2891. } ufbx_warning;
  2892. UFBX_LIST_TYPE(ufbx_warning_list, ufbx_warning);
  2893. typedef enum ufbx_thumbnail_format UFBX_ENUM_REPR {
  2894. UFBX_THUMBNAIL_FORMAT_UNKNOWN, // < Unknown format
  2895. UFBX_THUMBNAIL_FORMAT_RGB_24, // < 8-bit RGB pixels, in memory R,G,B
  2896. UFBX_THUMBNAIL_FORMAT_RGBA_32, // < 8-bit RGBA pixels, in memory R,G,B,A
  2897. UFBX_ENUM_FORCE_WIDTH(UFBX_THUMBNAIL_FORMAT)
  2898. } ufbx_thumbnail_format;
  2899. UFBX_ENUM_TYPE(ufbx_thumbnail_format, UFBX_THUMBNAIL_FORMAT, UFBX_THUMBNAIL_FORMAT_RGBA_32);
  2900. // Specify how unit / coordinate system conversion should be performed.
  2901. // Affects how `ufbx_load_opts.target_axes` and `ufbx_load_opts.target_unit_meters` work,
  2902. // has no effect if neither is specified.
  2903. typedef enum ufbx_space_conversion UFBX_ENUM_REPR {
  2904. // Store the space conversion transform in the root node.
  2905. // Sets `ufbx_node.local_transform` of the root node.
  2906. UFBX_SPACE_CONVERSION_TRANSFORM_ROOT,
  2907. // Perform the conversion by using "adjust" transforms.
  2908. // Compensates for the transforms using `ufbx_node.adjust_pre_rotation` and
  2909. // `ufbx_node.adjust_pre_scale`. You don't need to account for these unless
  2910. // you are manually building transforms from `ufbx_props`.
  2911. UFBX_SPACE_CONVERSION_ADJUST_TRANSFORMS,
  2912. // Perform the conversion by scaling geometry in addition to adjusting transforms.
  2913. // Compensates transforms like `UFBX_SPACE_CONVERSION_ADJUST_TRANSFORMS` but
  2914. // applies scaling to geometry as well.
  2915. UFBX_SPACE_CONVERSION_MODIFY_GEOMETRY,
  2916. UFBX_ENUM_FORCE_WIDTH(UFBX_SPACE_CONVERSION)
  2917. } ufbx_space_conversion;
  2918. UFBX_ENUM_TYPE(ufbx_space_conversion, UFBX_SPACE_CONVERSION, UFBX_SPACE_CONVERSION_MODIFY_GEOMETRY);
  2919. // Embedded thumbnail in the file, valid if the dimensions are non-zero.
  2920. typedef struct ufbx_thumbnail {
  2921. ufbx_props props;
  2922. // Extents of the thumbnail
  2923. uint32_t width;
  2924. uint32_t height;
  2925. // Format of `ufbx_thumbnail.data`.
  2926. ufbx_thumbnail_format format;
  2927. // Thumbnail pixel data, layout as contiguous rows from bottom to top.
  2928. // See `ufbx_thumbnail.format` for the pixel format.
  2929. ufbx_blob data;
  2930. } ufbx_thumbnail;
  2931. // Miscellaneous data related to the loaded file
  2932. typedef struct ufbx_metadata {
  2933. // List of non-fatal warnings about the file.
  2934. // If you need to only check whether a specific warning was triggered you
  2935. // can use `ufbx_metadata.has_warning[]`.
  2936. ufbx_warning_list warnings;
  2937. // FBX ASCII file format.
  2938. bool ascii;
  2939. // FBX version in integer format, eg. 7400 for 7.4.
  2940. uint32_t version;
  2941. // File format of the source file.
  2942. ufbx_file_format file_format;
  2943. // Index arrays may contain `UFBX_NO_INDEX` instead of a valid index
  2944. // to indicate gaps.
  2945. bool may_contain_no_index;
  2946. // May contain meshes with no defined vertex position.
  2947. // NOTE: `ufbx_mesh.vertex_position.exists` may be `false`!
  2948. bool may_contain_missing_vertex_position;
  2949. // Arrays may contain items with `NULL` element references.
  2950. // See `ufbx_load_opts.connect_broken_elements`.
  2951. bool may_contain_broken_elements;
  2952. // Some API guarantees do not apply (depending on unsafe options used).
  2953. // Loaded with `ufbx_load_opts.allow_unsafe` enabled.
  2954. bool is_unsafe;
  2955. // Flag for each possible warning type.
  2956. // See `ufbx_metadata.warnings[]` for detailed warning information.
  2957. bool has_warning[UFBX_WARNING_TYPE_COUNT];
  2958. ufbx_string creator;
  2959. bool big_endian;
  2960. ufbx_string filename;
  2961. ufbx_string relative_root;
  2962. ufbx_blob raw_filename;
  2963. ufbx_blob raw_relative_root;
  2964. ufbx_exporter exporter;
  2965. uint32_t exporter_version;
  2966. ufbx_props scene_props;
  2967. ufbx_application original_application;
  2968. ufbx_application latest_application;
  2969. ufbx_thumbnail thumbnail;
  2970. bool geometry_ignored;
  2971. bool animation_ignored;
  2972. bool embedded_ignored;
  2973. size_t max_face_triangles;
  2974. size_t result_memory_used;
  2975. size_t temp_memory_used;
  2976. size_t result_allocs;
  2977. size_t temp_allocs;
  2978. size_t element_buffer_size;
  2979. size_t num_shader_textures;
  2980. ufbx_real bone_prop_size_unit;
  2981. bool bone_prop_limb_length_relative;
  2982. ufbx_real ortho_size_unit;
  2983. int64_t ktime_second; // < One second in internal KTime units
  2984. ufbx_string original_file_path;
  2985. ufbx_blob raw_original_file_path;
  2986. // Space conversion method used on the scene.
  2987. ufbx_space_conversion space_conversion;
  2988. // Transform that has been applied to root for axis/unit conversion.
  2989. ufbx_quat root_rotation;
  2990. ufbx_real root_scale;
  2991. // Axis that the scene has been mirrored by.
  2992. // All geometry has been mirrored in this axis.
  2993. ufbx_mirror_axis mirror_axis;
  2994. // Amount geometry has been scaled.
  2995. // See `UFBX_SPACE_CONVERSION_MODIFY_GEOMETRY`.
  2996. ufbx_real geometry_scale;
  2997. } ufbx_metadata;
  2998. typedef enum ufbx_time_mode UFBX_ENUM_REPR {
  2999. UFBX_TIME_MODE_DEFAULT,
  3000. UFBX_TIME_MODE_120_FPS,
  3001. UFBX_TIME_MODE_100_FPS,
  3002. UFBX_TIME_MODE_60_FPS,
  3003. UFBX_TIME_MODE_50_FPS,
  3004. UFBX_TIME_MODE_48_FPS,
  3005. UFBX_TIME_MODE_30_FPS,
  3006. UFBX_TIME_MODE_30_FPS_DROP,
  3007. UFBX_TIME_MODE_NTSC_DROP_FRAME,
  3008. UFBX_TIME_MODE_NTSC_FULL_FRAME,
  3009. UFBX_TIME_MODE_PAL,
  3010. UFBX_TIME_MODE_24_FPS,
  3011. UFBX_TIME_MODE_1000_FPS,
  3012. UFBX_TIME_MODE_FILM_FULL_FRAME,
  3013. UFBX_TIME_MODE_CUSTOM,
  3014. UFBX_TIME_MODE_96_FPS,
  3015. UFBX_TIME_MODE_72_FPS,
  3016. UFBX_TIME_MODE_59_94_FPS,
  3017. UFBX_ENUM_FORCE_WIDTH(UFBX_TIME_MODE)
  3018. } ufbx_time_mode;
  3019. UFBX_ENUM_TYPE(ufbx_time_mode, UFBX_TIME_MODE, UFBX_TIME_MODE_59_94_FPS);
  3020. typedef enum ufbx_time_protocol UFBX_ENUM_REPR {
  3021. UFBX_TIME_PROTOCOL_SMPTE,
  3022. UFBX_TIME_PROTOCOL_FRAME_COUNT,
  3023. UFBX_TIME_PROTOCOL_DEFAULT,
  3024. UFBX_ENUM_FORCE_WIDTH(UFBX_TIME_PROTOCOL)
  3025. } ufbx_time_protocol;
  3026. UFBX_ENUM_TYPE(ufbx_time_protocol, UFBX_TIME_PROTOCOL, UFBX_TIME_PROTOCOL_DEFAULT);
  3027. typedef enum ufbx_snap_mode UFBX_ENUM_REPR {
  3028. UFBX_SNAP_MODE_NONE,
  3029. UFBX_SNAP_MODE_SNAP,
  3030. UFBX_SNAP_MODE_PLAY,
  3031. UFBX_SNAP_MODE_SNAP_AND_PLAY,
  3032. UFBX_ENUM_FORCE_WIDTH(UFBX_SNAP_MODE)
  3033. } ufbx_snap_mode;
  3034. UFBX_ENUM_TYPE(ufbx_snap_mode, UFBX_SNAP_MODE, UFBX_SNAP_MODE_SNAP_AND_PLAY);
  3035. // Global settings: Axes and time/unit scales
  3036. typedef struct ufbx_scene_settings {
  3037. ufbx_props props;
  3038. // Mapping of X/Y/Z axes to world-space directions.
  3039. // HINT: Use `ufbx_load_opts.target_axes` to normalize this.
  3040. // NOTE: This contains the _original_ axes even if you supply `ufbx_load_opts.target_axes`.
  3041. ufbx_coordinate_axes axes;
  3042. // How many meters does a single world-space unit represent.
  3043. // FBX files usually default to centimeters, reported as `0.01` here.
  3044. // HINT: Use `ufbx_load_opts.target_unit_meters` to normalize this.
  3045. ufbx_real unit_meters;
  3046. // Frames per second the animation is defined at.
  3047. double frames_per_second;
  3048. ufbx_vec3 ambient_color;
  3049. ufbx_string default_camera;
  3050. // Animation user interface settings.
  3051. // HINT: Use `ufbx_scene_settings.frames_per_second` instead of interpreting these yourself.
  3052. ufbx_time_mode time_mode;
  3053. ufbx_time_protocol time_protocol;
  3054. ufbx_snap_mode snap_mode;
  3055. // Original settings (?)
  3056. ufbx_coordinate_axis original_axis_up;
  3057. ufbx_real original_unit_meters;
  3058. } ufbx_scene_settings;
  3059. struct ufbx_scene {
  3060. ufbx_metadata metadata;
  3061. // Global settings
  3062. ufbx_scene_settings settings;
  3063. // Node instances in the scene
  3064. ufbx_node *root_node;
  3065. // Default animation descriptor
  3066. ufbx_anim *anim;
  3067. union {
  3068. struct {
  3069. ufbx_unknown_list unknowns;
  3070. // Nodes
  3071. ufbx_node_list nodes;
  3072. // Node attributes (common)
  3073. ufbx_mesh_list meshes;
  3074. ufbx_light_list lights;
  3075. ufbx_camera_list cameras;
  3076. ufbx_bone_list bones;
  3077. ufbx_empty_list empties;
  3078. // Node attributes (curves/surfaces)
  3079. ufbx_line_curve_list line_curves;
  3080. ufbx_nurbs_curve_list nurbs_curves;
  3081. ufbx_nurbs_surface_list nurbs_surfaces;
  3082. ufbx_nurbs_trim_surface_list nurbs_trim_surfaces;
  3083. ufbx_nurbs_trim_boundary_list nurbs_trim_boundaries;
  3084. // Node attributes (advanced)
  3085. ufbx_procedural_geometry_list procedural_geometries;
  3086. ufbx_stereo_camera_list stereo_cameras;
  3087. ufbx_camera_switcher_list camera_switchers;
  3088. ufbx_marker_list markers;
  3089. ufbx_lod_group_list lod_groups;
  3090. // Deformers
  3091. ufbx_skin_deformer_list skin_deformers;
  3092. ufbx_skin_cluster_list skin_clusters;
  3093. ufbx_blend_deformer_list blend_deformers;
  3094. ufbx_blend_channel_list blend_channels;
  3095. ufbx_blend_shape_list blend_shapes;
  3096. ufbx_cache_deformer_list cache_deformers;
  3097. ufbx_cache_file_list cache_files;
  3098. // Materials
  3099. ufbx_material_list materials;
  3100. ufbx_texture_list textures;
  3101. ufbx_video_list videos;
  3102. ufbx_shader_list shaders;
  3103. ufbx_shader_binding_list shader_bindings;
  3104. // Animation
  3105. ufbx_anim_stack_list anim_stacks;
  3106. ufbx_anim_layer_list anim_layers;
  3107. ufbx_anim_value_list anim_values;
  3108. ufbx_anim_curve_list anim_curves;
  3109. // Collections
  3110. ufbx_display_layer_list display_layers;
  3111. ufbx_selection_set_list selection_sets;
  3112. ufbx_selection_node_list selection_nodes;
  3113. // Constraints
  3114. ufbx_character_list characters;
  3115. ufbx_constraint_list constraints;
  3116. // Audio
  3117. ufbx_audio_layer_list audio_layers;
  3118. ufbx_audio_clip_list audio_clips;
  3119. // Miscellaneous
  3120. ufbx_pose_list poses;
  3121. ufbx_metadata_object_list metadata_objects;
  3122. };
  3123. ufbx_element_list elements_by_type[UFBX_ELEMENT_TYPE_COUNT];
  3124. };
  3125. // Unique texture files referenced by the scene.
  3126. ufbx_texture_file_list texture_files;
  3127. // All elements and connections in the whole file
  3128. ufbx_element_list elements; // < Sorted by `id`
  3129. ufbx_connection_list connections_src; // < Sorted by `src,src_prop`
  3130. ufbx_connection_list connections_dst; // < Sorted by `dst,dst_prop`
  3131. // Elements sorted by name, type
  3132. ufbx_name_element_list elements_by_name;
  3133. // Enabled if `ufbx_load_opts.retain_dom == true`.
  3134. ufbx_nullable ufbx_dom_node *dom_root;
  3135. };
  3136. // -- Curves
  3137. typedef struct ufbx_curve_point {
  3138. bool valid;
  3139. ufbx_vec3 position;
  3140. ufbx_vec3 derivative;
  3141. } ufbx_curve_point;
  3142. typedef struct ufbx_surface_point {
  3143. bool valid;
  3144. ufbx_vec3 position;
  3145. ufbx_vec3 derivative_u;
  3146. ufbx_vec3 derivative_v;
  3147. } ufbx_surface_point;
  3148. // -- Mesh topology
  3149. typedef enum ufbx_topo_flags UFBX_FLAG_REPR {
  3150. UFBX_TOPO_NON_MANIFOLD = 0x1, // < Edge with three or more faces
  3151. UFBX_FLAG_FORCE_WIDTH(UFBX_TOPO_FLAGS)
  3152. } ufbx_topo_flags;
  3153. typedef struct ufbx_topo_edge {
  3154. uint32_t index; // < Starting index of the edge, always defined
  3155. uint32_t next; // < Ending index of the edge / next per-face `ufbx_topo_edge`, always defined
  3156. uint32_t prev; // < Previous per-face `ufbx_topo_edge`, always defined
  3157. uint32_t twin; // < `ufbx_topo_edge` on the opposite side, `UFBX_NO_INDEX` if not found
  3158. uint32_t face; // < Index into `mesh->faces[]`, always defined
  3159. uint32_t edge; // < Index into `mesh->edges[]`, `UFBX_NO_INDEX` if not found
  3160. ufbx_topo_flags flags;
  3161. } ufbx_topo_edge;
  3162. // Vertex data array for `ufbx_generate_indices()`.
  3163. // NOTE: `ufbx_generate_indices()` compares the vertices using `memcmp()`, so
  3164. // any padding should be cleared to zero.
  3165. typedef struct ufbx_vertex_stream {
  3166. void *data; // < Data pointer of shape `char[vertex_count][vertex_size]`.
  3167. size_t vertex_count; // < Number of vertices in this stream, for sanity checking.
  3168. size_t vertex_size; // < Size of a vertex in bytes.
  3169. } ufbx_vertex_stream;
  3170. // -- Memory callbacks
  3171. // You can optionally provide an allocator to ufbx, the default is to use the
  3172. // CRT malloc/realloc/free
  3173. // Allocate `size` bytes, must be at least 8 byte aligned
  3174. typedef void *ufbx_alloc_fn(void *user, size_t size);
  3175. // Reallocate `old_ptr` from `old_size` to `new_size`
  3176. // NOTE: If omit `alloc_fn` and `free_fn` they will be translated to:
  3177. // `alloc(size)` -> `realloc_fn(user, NULL, 0, size)`
  3178. // `free_fn(ptr, size)` -> `realloc_fn(user, ptr, size, 0)`
  3179. typedef void *ufbx_realloc_fn(void *user, void *old_ptr, size_t old_size, size_t new_size);
  3180. // Free pointer `ptr` (of `size` bytes) returned by `alloc_fn` or `realloc_fn`
  3181. typedef void ufbx_free_fn(void *user, void *ptr, size_t size);
  3182. // Free the allocator itself
  3183. typedef void ufbx_free_allocator_fn(void *user);
  3184. // Allocator callbacks and user context
  3185. // NOTE: The allocator will be stored to the loaded scene and will be called
  3186. // again from `ufbx_free_scene()` so make sure `user` outlives that!
  3187. // You can use `free_allocator_fn()` to free the allocator yourself.
  3188. typedef struct ufbx_allocator {
  3189. // Callback functions, see `typedef`s above for information
  3190. ufbx_alloc_fn *alloc_fn;
  3191. ufbx_realloc_fn *realloc_fn;
  3192. ufbx_free_fn *free_fn;
  3193. ufbx_free_allocator_fn *free_allocator_fn;
  3194. void *user;
  3195. } ufbx_allocator;
  3196. typedef struct ufbx_allocator_opts {
  3197. // Allocator callbacks
  3198. ufbx_allocator allocator;
  3199. // Maximum number of bytes to allocate before failing
  3200. size_t memory_limit;
  3201. // Maximum number of allocations to attempt before failing
  3202. size_t allocation_limit;
  3203. // Threshold to swap from batched allocations to individual ones
  3204. // Defaults to 1MB if set to zero
  3205. // NOTE: If set to `1` ufbx will allocate everything in the smallest
  3206. // possible chunks which may be useful for debugging (eg. ASAN)
  3207. size_t huge_threshold;
  3208. // Maximum size of a single allocation containing sub-allocations.
  3209. // Defaults to 16MB if set to zero
  3210. // The maximum amount of wasted memory depends on `max_chunk_size` and
  3211. // `huge_threshold`: each chunk can waste up to `huge_threshold` bytes
  3212. // internally and the last chunk might be incomplete. So for example
  3213. // with the defaults we can waste around 1MB/16MB = 6.25% overall plus
  3214. // up to 32MB due to the two incomplete blocks. The actual amounts differ
  3215. // slightly as the chunks start out at 4kB and double in size each time,
  3216. // meaning that the maximum fixed overhead (up to 32MB with defaults) is
  3217. // at most ~30% of the total allocation size.
  3218. size_t max_chunk_size;
  3219. } ufbx_allocator_opts;
  3220. // -- IO callbacks
  3221. // Try to read up to `size` bytes to `data`, return the amount of read bytes.
  3222. // Return `SIZE_MAX` to indicate an IO error.
  3223. typedef size_t ufbx_read_fn(void *user, void *data, size_t size);
  3224. // Skip `size` bytes in the file.
  3225. typedef bool ufbx_skip_fn(void *user, size_t size);
  3226. // Get the size of the file.
  3227. // Return `0` if unknown, `UINT64_MAX` if error.
  3228. typedef uint64_t ufbx_size_fn(void *user);
  3229. // Close the file
  3230. typedef void ufbx_close_fn(void *user);
  3231. typedef struct ufbx_stream {
  3232. ufbx_read_fn *read_fn; // < Required
  3233. ufbx_skip_fn *skip_fn; // < Optional: Will use `read_fn()` if missing
  3234. ufbx_size_fn *size_fn; // < Optional
  3235. ufbx_close_fn *close_fn; // < Optional
  3236. // Context passed to other functions
  3237. void *user;
  3238. } ufbx_stream;
  3239. typedef enum ufbx_open_file_type UFBX_ENUM_REPR {
  3240. UFBX_OPEN_FILE_MAIN_MODEL, // < Main model file
  3241. UFBX_OPEN_FILE_GEOMETRY_CACHE, // < Unknown geometry cache file
  3242. UFBX_OPEN_FILE_OBJ_MTL, // < .mtl material library file
  3243. UFBX_ENUM_FORCE_WIDTH(UFBX_OPEN_FILE_TYPE)
  3244. } ufbx_open_file_type;
  3245. UFBX_ENUM_TYPE(ufbx_open_file_type, UFBX_OPEN_FILE_TYPE, UFBX_OPEN_FILE_OBJ_MTL);
  3246. typedef uintptr_t ufbx_open_file_context;
  3247. typedef struct ufbx_open_file_info {
  3248. // Context that can be passed to the following functions to use a shared allocator:
  3249. // ufbx_open_file_ctx()
  3250. // ufbx_open_memory_ctx()
  3251. ufbx_open_file_context context;
  3252. // Kind of file to load.
  3253. ufbx_open_file_type type;
  3254. // Original filename in the file, not resolved or UTF-8 encoded.
  3255. // NOTE: Not necessarily NULL-terminated!
  3256. ufbx_blob original_filename;
  3257. } ufbx_open_file_info;
  3258. // Callback for opening an external file from the filesystem
  3259. typedef bool ufbx_open_file_fn(void *user, ufbx_stream *stream, const char *path, size_t path_len, const ufbx_open_file_info *info);
  3260. typedef struct ufbx_open_file_cb {
  3261. ufbx_open_file_fn *fn;
  3262. void *user;
  3263. UFBX_CALLBACK_IMPL(ufbx_open_file_cb, ufbx_open_file_fn, bool,
  3264. (void *user, ufbx_stream *stream, const char *path, size_t path_len, const ufbx_open_file_info *info),
  3265. (stream, path, path_len, info))
  3266. } ufbx_open_file_cb;
  3267. // Options for `ufbx_open_file()`.
  3268. typedef struct ufbx_open_file_opts {
  3269. uint32_t _begin_zero;
  3270. // Allocator to allocate the memory with.
  3271. ufbx_allocator_opts allocator;
  3272. // The filename is guaranteed to be NULL-terminated.
  3273. ufbx_unsafe bool filename_null_terminated;
  3274. uint32_t _end_zero;
  3275. } ufbx_open_file_opts;
  3276. // Memory stream options
  3277. typedef void ufbx_close_memory_fn(void *user, void *data, size_t data_size);
  3278. typedef struct ufbx_close_memory_cb {
  3279. ufbx_close_memory_fn *fn;
  3280. void *user;
  3281. UFBX_CALLBACK_IMPL(ufbx_close_memory_cb, ufbx_close_memory_fn, void,
  3282. (void *user, void *data, size_t data_size),
  3283. (data, data_size))
  3284. } ufbx_close_memory_cb;
  3285. // Options for `ufbx_open_memory()`.
  3286. typedef struct ufbx_open_memory_opts {
  3287. uint32_t _begin_zero;
  3288. // Allocator to allocate the memory with.
  3289. // NOTE: Used even if no copy is made to allocate a small metadata block.
  3290. ufbx_allocator_opts allocator;
  3291. // Do not copy the memory.
  3292. // You can use `close_cb` to free the memory when the stream is closed.
  3293. // NOTE: This means the provided data pointer is referenced after creating
  3294. // the memory stream, make sure the data stays valid until the stream is closed!
  3295. ufbx_unsafe bool no_copy;
  3296. // Callback to free the memory blob.
  3297. ufbx_close_memory_cb close_cb;
  3298. uint32_t _end_zero;
  3299. } ufbx_open_memory_opts;
  3300. // Detailed error stack frame
  3301. typedef struct ufbx_error_frame {
  3302. uint32_t source_line;
  3303. ufbx_string function;
  3304. ufbx_string description;
  3305. } ufbx_error_frame;
  3306. // Error causes (and `UFBX_ERROR_NONE` for no error).
  3307. typedef enum ufbx_error_type UFBX_ENUM_REPR {
  3308. // No error, operation has been performed successfully.
  3309. UFBX_ERROR_NONE,
  3310. // Unspecified error, most likely caused by an invalid FBX file or a file
  3311. // that contains something ufbx can't handle.
  3312. UFBX_ERROR_UNKNOWN,
  3313. // File not found.
  3314. UFBX_ERROR_FILE_NOT_FOUND,
  3315. // Empty file.
  3316. UFBX_ERROR_EMPTY_FILE,
  3317. // External file not found.
  3318. // See `ufbx_load_opts.load_external_files` for more information.
  3319. UFBX_ERROR_EXTERNAL_FILE_NOT_FOUND,
  3320. // Out of memory (allocator returned `NULL`).
  3321. UFBX_ERROR_OUT_OF_MEMORY,
  3322. // `ufbx_allocator_opts.memory_limit` exhausted.
  3323. UFBX_ERROR_MEMORY_LIMIT,
  3324. // `ufbx_allocator_opts.allocation_limit` exhausted.
  3325. UFBX_ERROR_ALLOCATION_LIMIT,
  3326. // File ended abruptly.
  3327. UFBX_ERROR_TRUNCATED_FILE,
  3328. // IO read error.
  3329. // eg. returning `SIZE_MAX` from `ufbx_stream.read_fn` or stdio `ferror()` condition.
  3330. UFBX_ERROR_IO,
  3331. // User cancelled the loading via `ufbx_load_opts.progress_cb` returning `UFBX_PROGRESS_CANCEL`.
  3332. UFBX_ERROR_CANCELLED,
  3333. // Could not detect file format from file data or filename.
  3334. // HINT: You can supply it manually using `ufbx_load_opts.file_format` or use `ufbx_load_opts.filename`
  3335. // when using `ufbx_load_memory()` to let ufbx guess the format from the extension.
  3336. UFBX_ERROR_UNRECOGNIZED_FILE_FORMAT,
  3337. // Options struct (eg. `ufbx_load_opts`) is not cleared to zero.
  3338. // Make sure you initialize the structure to zero via eg.
  3339. // ufbx_load_opts opts = { 0 }; // C
  3340. // ufbx_load_opts opts = { }; // C++
  3341. UFBX_ERROR_UNINITIALIZED_OPTIONS,
  3342. // The vertex streams in `ufbx_generate_indices()` are empty.
  3343. UFBX_ERROR_ZERO_VERTEX_SIZE,
  3344. // Vertex stream passed to `ufbx_generate_indices()`.
  3345. UFBX_ERROR_TRUNCATED_VERTEX_STREAM,
  3346. // Invalid UTF-8 encountered in a file when loading with `UFBX_UNICODE_ERROR_HANDLING_ABORT_LOADING`.
  3347. UFBX_ERROR_INVALID_UTF8,
  3348. // Feature needed for the operation has been compiled out.
  3349. UFBX_ERROR_FEATURE_DISABLED,
  3350. // Attempting to tessellate an invalid NURBS object.
  3351. // See `ufbx_nurbs_basis.valid`.
  3352. UFBX_ERROR_BAD_NURBS,
  3353. // Out of bounds index in the file when loading with `UFBX_INDEX_ERROR_HANDLING_ABORT_LOADING`.
  3354. UFBX_ERROR_BAD_INDEX,
  3355. // Node is deeper than `ufbx_load_opts.node_depth_limit` in the hierarchy.
  3356. UFBX_ERROR_NODE_DEPTH_LIMIT,
  3357. // Error parsing ASCII array in a thread.
  3358. // Threaded ASCII parsing is slightly more strict than non-threaded, for cursed files,
  3359. // set `ufbx_load_opts.force_single_thread_ascii_parsing` to `true`.
  3360. UFBX_ERROR_THREADED_ASCII_PARSE,
  3361. // Unsafe options specified without enabling `ufbx_load_opts.allow_unsafe`.
  3362. UFBX_ERROR_UNSAFE_OPTIONS,
  3363. // Duplicated override property in `ufbx_create_anim()`
  3364. UFBX_ERROR_DUPLICATE_OVERRIDE,
  3365. UFBX_ENUM_FORCE_WIDTH(UFBX_ERROR_TYPE)
  3366. } ufbx_error_type;
  3367. UFBX_ENUM_TYPE(ufbx_error_type, UFBX_ERROR_TYPE, UFBX_ERROR_DUPLICATE_OVERRIDE);
  3368. // Error description with detailed stack trace
  3369. // HINT: You can use `ufbx_format_error()` for formatting the error
  3370. typedef struct ufbx_error {
  3371. ufbx_error_type type;
  3372. ufbx_string description;
  3373. uint32_t stack_size;
  3374. ufbx_error_frame stack[UFBX_ERROR_STACK_MAX_DEPTH];
  3375. size_t info_length;
  3376. char info[UFBX_ERROR_INFO_LENGTH];
  3377. } ufbx_error;
  3378. // -- Progress callbacks
  3379. typedef struct ufbx_progress {
  3380. uint64_t bytes_read;
  3381. uint64_t bytes_total;
  3382. } ufbx_progress;
  3383. typedef enum ufbx_progress_result UFBX_ENUM_REPR {
  3384. UFBX_PROGRESS_CONTINUE = 0x100,
  3385. UFBX_PROGRESS_CANCEL = 0x200,
  3386. UFBX_ENUM_FORCE_WIDTH(UFBX_PROGRESS_RESULT)
  3387. } ufbx_progress_result;
  3388. // Called periodically with the current progress
  3389. // Return `false` to cancel further processing
  3390. typedef ufbx_progress_result ufbx_progress_fn(void *user, const ufbx_progress *progress);
  3391. typedef struct ufbx_progress_cb {
  3392. ufbx_progress_fn *fn;
  3393. void *user;
  3394. UFBX_CALLBACK_IMPL(ufbx_progress_cb, ufbx_progress_fn, ufbx_progress_result,
  3395. (void *user, const ufbx_progress *progress),
  3396. (progress))
  3397. } ufbx_progress_cb;
  3398. // -- Inflate
  3399. typedef struct ufbx_inflate_input ufbx_inflate_input;
  3400. typedef struct ufbx_inflate_retain ufbx_inflate_retain;
  3401. // Source data/stream to decompress with `ufbx_inflate()`
  3402. struct ufbx_inflate_input {
  3403. // Total size of the data in bytes
  3404. size_t total_size;
  3405. // (optional) Initial or complete data chunk
  3406. const void *data;
  3407. size_t data_size;
  3408. // (optional) Temporary buffer, defaults to 256b stack buffer
  3409. void *buffer;
  3410. size_t buffer_size;
  3411. // (optional) Streaming read function, concatenated after `data`
  3412. ufbx_read_fn *read_fn;
  3413. void *read_user;
  3414. // (optional) Progress reporting
  3415. ufbx_progress_cb progress_cb;
  3416. uint64_t progress_interval_hint; // < Bytes between progress report calls
  3417. // (optional) Change the progress scope
  3418. uint64_t progress_size_before;
  3419. uint64_t progress_size_after;
  3420. // (optional) No the DEFLATE header
  3421. bool no_header;
  3422. // (optional) No the Adler32 checksum
  3423. bool no_checksum;
  3424. // (optional) Force internal fast lookup bit amount
  3425. size_t internal_fast_bits;
  3426. };
  3427. // Persistent data between `ufbx_inflate()` calls
  3428. // NOTE: You must set `initialized` to `false`, but `data` may be uninitialized
  3429. struct ufbx_inflate_retain {
  3430. bool initialized;
  3431. uint64_t data[1024];
  3432. };
  3433. typedef enum ufbx_index_error_handling UFBX_ENUM_REPR {
  3434. // Clamp to a valid value.
  3435. UFBX_INDEX_ERROR_HANDLING_CLAMP,
  3436. // Set bad indices to `UFBX_NO_INDEX`.
  3437. // This is the recommended way if you need to deal with files with gaps in information.
  3438. // HINT: If you use this `ufbx_get_vertex_TYPE()` functions will return zero
  3439. // on invalid indices instead of failing.
  3440. UFBX_INDEX_ERROR_HANDLING_NO_INDEX,
  3441. // Fail loading entierely when encountering a bad index.
  3442. UFBX_INDEX_ERROR_HANDLING_ABORT_LOADING,
  3443. // Pass bad indices through as-is.
  3444. // Requires `ufbx_load_opts.allow_unsafe`.
  3445. // UNSAFE: Breaks any API guarantees regarding indexes being in bounds and makes
  3446. // `ufbx_get_vertex_TYPE()` memory-unsafe to use.
  3447. UFBX_INDEX_ERROR_HANDLING_UNSAFE_IGNORE,
  3448. UFBX_ENUM_FORCE_WIDTH(UFBX_INDEX_ERROR_HANDLING)
  3449. } ufbx_index_error_handling;
  3450. UFBX_ENUM_TYPE(ufbx_index_error_handling, UFBX_INDEX_ERROR_HANDLING, UFBX_INDEX_ERROR_HANDLING_UNSAFE_IGNORE);
  3451. typedef enum ufbx_unicode_error_handling UFBX_ENUM_REPR {
  3452. // Replace errors with U+FFFD "Replacement Character"
  3453. UFBX_UNICODE_ERROR_HANDLING_REPLACEMENT_CHARACTER,
  3454. // Replace errors with '_' U+5F "Low Line"
  3455. UFBX_UNICODE_ERROR_HANDLING_UNDERSCORE,
  3456. // Replace errors with '?' U+3F "Question Mark"
  3457. UFBX_UNICODE_ERROR_HANDLING_QUESTION_MARK,
  3458. // Remove errors from the output
  3459. UFBX_UNICODE_ERROR_HANDLING_REMOVE,
  3460. // Fail loading on encountering an Unicode error
  3461. UFBX_UNICODE_ERROR_HANDLING_ABORT_LOADING,
  3462. // Ignore and pass-through non-UTF-8 string data.
  3463. // Requires `ufbx_load_opts.allow_unsafe`.
  3464. // UNSAFE: Breaks API guarantee that `ufbx_string` is UTF-8 encoded.
  3465. UFBX_UNICODE_ERROR_HANDLING_UNSAFE_IGNORE,
  3466. UFBX_ENUM_FORCE_WIDTH(UFBX_UNICODE_ERROR_HANDLING)
  3467. } ufbx_unicode_error_handling;
  3468. UFBX_ENUM_TYPE(ufbx_unicode_error_handling, UFBX_UNICODE_ERROR_HANDLING, UFBX_UNICODE_ERROR_HANDLING_UNSAFE_IGNORE);
  3469. // How to handle FBX node geometry transforms.
  3470. // FBX nodes can have "geometry transforms" that affect only the attached meshes,
  3471. // but not the children. This is not allowed in many scene representations so
  3472. // ufbx provides some ways to simplify them.
  3473. // Geometry transforms can also be used to transform any other attributes such
  3474. // as lights or cameras.
  3475. typedef enum ufbx_geometry_transform_handling UFBX_ENUM_REPR {
  3476. // Preserve the geometry transforms as-is.
  3477. // To be correct for all files you have to use `ufbx_node.geometry_transform`,
  3478. // `ufbx_node.geometry_to_node`, or `ufbx_node.geometry_to_world` to compensate
  3479. // for any potential geometry transforms.
  3480. UFBX_GEOMETRY_TRANSFORM_HANDLING_PRESERVE,
  3481. // Add helper nodes between the nodes and geometry where needed.
  3482. // The created nodes have `ufbx_node.is_geometry_transform_helper` set and are
  3483. // named `ufbx_load_opts.geometry_transform_helper_name`.
  3484. UFBX_GEOMETRY_TRANSFORM_HANDLING_HELPER_NODES,
  3485. // Modify the geometry of meshes attached to nodes with geometry transforms.
  3486. // Will add helper nodes like `UFBX_GEOMETRY_TRANSFORM_HANDLING_HELPER_NODES` if
  3487. // necessary, for example if there are multiple instances of the same mesh with
  3488. // geometry transforms.
  3489. UFBX_GEOMETRY_TRANSFORM_HANDLING_MODIFY_GEOMETRY,
  3490. // Modify the geometry of meshes attached to nodes with geometry transforms.
  3491. // NOTE: This will not work correctly for instanced geometry.
  3492. UFBX_GEOMETRY_TRANSFORM_HANDLING_MODIFY_GEOMETRY_NO_FALLBACK,
  3493. UFBX_ENUM_FORCE_WIDTH(UFBX_GEOMETRY_TRANSFORM_HANDLING)
  3494. } ufbx_geometry_transform_handling;
  3495. UFBX_ENUM_TYPE(ufbx_geometry_transform_handling, UFBX_GEOMETRY_TRANSFORM_HANDLING, UFBX_GEOMETRY_TRANSFORM_HANDLING_MODIFY_GEOMETRY_NO_FALLBACK);
  3496. // How to handle FBX transform inherit modes.
  3497. typedef enum ufbx_inherit_mode_handling UFBX_ENUM_REPR {
  3498. // Preserve inherit mode in `ufbx_node.inherit_mode`.
  3499. // NOTE: To correctly handle all scenes you would need to handle the
  3500. // non-standard inherit modes.
  3501. UFBX_INHERIT_MODE_HANDLING_PRESERVE,
  3502. // Create scale helper nodes parented to nodes that need special inheritance.
  3503. // Scale helper nodes will have `ufbx_node.is_scale_helper` and parents of
  3504. // scale helpers will have `ufbx_node.scale_helper` pointing to it.
  3505. UFBX_INHERIT_MODE_HANDLING_HELPER_NODES,
  3506. // Attempt to compensate for bone scale by inversely scaling children.
  3507. // NOTE: This only works for uniform non-animated scaling, if scale is
  3508. // non-uniform or animated, ufbx will add scale helpers in the same way
  3509. // as `UFBX_INHERIT_MODE_HANDLING_HELPER_NODES`.
  3510. UFBX_INHERIT_MODE_HANDLING_COMPENSATE,
  3511. // Attempt to compensate for bone scale by inversely scaling children.
  3512. // Will never create helper nodes.
  3513. UFBX_INHERIT_MODE_HANDLING_COMPENSATE_NO_FALLBACK,
  3514. // Ignore non-standard inheritance modes.
  3515. // Forces all nodes to have `UFBX_INHERIT_MODE_NORMAL` regardless of the
  3516. // inherit mode specified in the file. This can be useful for emulating
  3517. // results from importers/programs that don't support inherit modes.
  3518. UFBX_INHERIT_MODE_HANDLING_IGNORE,
  3519. UFBX_ENUM_FORCE_WIDTH(UFBX_INHERIT_MODE_HANDLING)
  3520. } ufbx_inherit_mode_handling;
  3521. UFBX_ENUM_TYPE(ufbx_inherit_mode_handling, UFBX_INHERIT_MODE_HANDLING, UFBX_INHERIT_MODE_HANDLING_IGNORE);
  3522. // How to handle FBX transform pivots.
  3523. typedef enum ufbx_pivot_handling UFBX_ENUM_REPR {
  3524. // Take pivots into account when computing the transform.
  3525. UFBX_PIVOT_HANDLING_RETAIN,
  3526. // Translate objects to be located at their pivot.
  3527. // NOTE: Only applied if rotation and scaling pivots are equal.
  3528. // NOTE: Results in geometric translation. Use `ufbx_geometry_transform_handling`
  3529. // to interpret these in a standard scene graph.
  3530. UFBX_PIVOT_HANDLING_ADJUST_TO_PIVOT,
  3531. UFBX_ENUM_FORCE_WIDTH(UFBX_PIVOT_HANDLING)
  3532. } ufbx_pivot_handling;
  3533. UFBX_ENUM_TYPE(ufbx_pivot_handling, UFBX_PIVOT_HANDLING, UFBX_PIVOT_HANDLING_ADJUST_TO_PIVOT);
  3534. typedef enum ufbx_baked_key_flags UFBX_FLAG_REPR {
  3535. // This keyframe represents a constant step from the left side
  3536. UFBX_BAKED_KEY_STEP_LEFT = 0x1,
  3537. // This keyframe represents a constant step from the right side
  3538. UFBX_BAKED_KEY_STEP_RIGHT = 0x2,
  3539. // This keyframe is the main part of a step
  3540. // Bordering either `UFBX_BAKED_KEY_STEP_LEFT` or `UFBX_BAKED_KEY_STEP_RIGHT`.
  3541. UFBX_BAKED_KEY_STEP_KEY = 0x4,
  3542. // This keyframe is a real keyframe in the source animation
  3543. UFBX_BAKED_KEY_KEYFRAME = 0x8,
  3544. // This keyframe has been reduced by maximum sample rate.
  3545. // See `ufbx_bake_opts.maximum_sample_rate`.
  3546. UFBX_BAKED_KEY_REDUCED = 0x10,
  3547. UFBX_FLAG_FORCE_WIDTH(UFBX_BAKED_KEY)
  3548. } ufbx_baked_key_flags;
  3549. typedef struct ufbx_baked_vec3 {
  3550. double time; // < Time of the keyframe, in seconds
  3551. ufbx_vec3 value; // < Value at `time`, can be linearly interpolated
  3552. ufbx_baked_key_flags flags; // < Additional information about the keyframe
  3553. } ufbx_baked_vec3;
  3554. UFBX_LIST_TYPE(ufbx_baked_vec3_list, ufbx_baked_vec3);
  3555. typedef struct ufbx_baked_quat {
  3556. double time; // < Time of the keyframe, in seconds
  3557. ufbx_quat value; // < Value at `time`, can be (spherically) linearly interpolated
  3558. ufbx_baked_key_flags flags; // < Additional information about the keyframe
  3559. } ufbx_baked_quat;
  3560. UFBX_LIST_TYPE(ufbx_baked_quat_list, ufbx_baked_quat);
  3561. // Baked transform animation for a single node.
  3562. typedef struct ufbx_baked_node {
  3563. // Typed ID of the node, maps to `ufbx_scene.nodes[]`.
  3564. uint32_t typed_id;
  3565. // Element ID of the element, maps to `ufbx_scene.elements[]`.
  3566. uint32_t element_id;
  3567. // The translation channel has constant values for the whole animation.
  3568. bool constant_translation;
  3569. // The rotation channel has constant values for the whole animation.
  3570. bool constant_rotation;
  3571. // The scale channel has constant values for the whole animation.
  3572. bool constant_scale;
  3573. // Translation keys for the animation, maps to `ufbx_node.local_transform.translation`.
  3574. ufbx_baked_vec3_list translation_keys;
  3575. // Rotation keyframes, maps to `ufbx_node.local_transform.rotation`.
  3576. ufbx_baked_quat_list rotation_keys;
  3577. // Scale keyframes, maps to `ufbx_node.local_transform.scale`.
  3578. ufbx_baked_vec3_list scale_keys;
  3579. } ufbx_baked_node;
  3580. UFBX_LIST_TYPE(ufbx_baked_node_list, ufbx_baked_node);
  3581. // Baked property animation.
  3582. typedef struct ufbx_baked_prop {
  3583. // Name of the property, eg. `"Visibility"`.
  3584. ufbx_string name;
  3585. // The value of the property is constant for the whole animation.
  3586. bool constant_value;
  3587. // Property value keys.
  3588. ufbx_baked_vec3_list keys;
  3589. } ufbx_baked_prop;
  3590. UFBX_LIST_TYPE(ufbx_baked_prop_list, ufbx_baked_prop);
  3591. // Baked property animation for a single element.
  3592. typedef struct ufbx_baked_element {
  3593. // Element ID of the element, maps to `ufbx_scene.elements[]`.
  3594. uint32_t element_id;
  3595. // List of properties the animation modifies.
  3596. ufbx_baked_prop_list props;
  3597. } ufbx_baked_element;
  3598. UFBX_LIST_TYPE(ufbx_baked_element_list, ufbx_baked_element);
  3599. typedef struct ufbx_baked_anim_metadata {
  3600. // Memory statistics
  3601. size_t result_memory_used;
  3602. size_t temp_memory_used;
  3603. size_t result_allocs;
  3604. size_t temp_allocs;
  3605. } ufbx_baked_anim_metadata;
  3606. // Animation baked into linearly interpolated keyframes.
  3607. // See `ufbx_bake_anim()`.
  3608. typedef struct ufbx_baked_anim {
  3609. // Nodes that are modified by the animation.
  3610. // Some nodes may be missing if the specified animation does not transform them.
  3611. // Conversely, some non-obviously animated nodes may be included as exporters
  3612. // often may add dummy keyframes for objects.
  3613. ufbx_baked_node_list nodes;
  3614. // Element properties modified by the animation.
  3615. ufbx_baked_element_list elements;
  3616. // Playback time range for the animation.
  3617. double playback_time_begin;
  3618. double playback_time_end;
  3619. double playback_duration;
  3620. // Keyframe time range.
  3621. double key_time_min;
  3622. double key_time_max;
  3623. // Additional bake information.
  3624. ufbx_baked_anim_metadata metadata;
  3625. } ufbx_baked_anim;
  3626. // -- Thread API
  3627. //
  3628. // NOTE: This API is still experimental and may change.
  3629. // Documentation is currently missing on purpose.
  3630. typedef uintptr_t ufbx_thread_pool_context;
  3631. typedef struct ufbx_thread_pool_info {
  3632. uint32_t max_concurrent_tasks;
  3633. } ufbx_thread_pool_info;
  3634. typedef bool ufbx_thread_pool_init_fn(void *user, ufbx_thread_pool_context ctx, const ufbx_thread_pool_info *info);
  3635. typedef bool ufbx_thread_pool_run_fn(void *user, ufbx_thread_pool_context ctx, uint32_t group, uint32_t start_index, uint32_t count);
  3636. typedef bool ufbx_thread_pool_wait_fn(void *user, ufbx_thread_pool_context ctx, uint32_t group, uint32_t max_index);
  3637. typedef void ufbx_thread_pool_free_fn(void *user, ufbx_thread_pool_context ctx);
  3638. typedef struct ufbx_thread_pool {
  3639. ufbx_thread_pool_init_fn *init_fn;
  3640. ufbx_thread_pool_run_fn *run_fn;
  3641. ufbx_thread_pool_wait_fn *wait_fn;
  3642. ufbx_thread_pool_free_fn *free_fn;
  3643. void *user;
  3644. } ufbx_thread_pool;
  3645. typedef struct ufbx_thread_opts {
  3646. ufbx_thread_pool pool;
  3647. size_t num_tasks;
  3648. size_t memory_limit;
  3649. } ufbx_thread_opts;
  3650. // -- Main API
  3651. // Options for `ufbx_load_file/memory/stream/stdio()`
  3652. // NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++)
  3653. typedef struct ufbx_load_opts {
  3654. uint32_t _begin_zero;
  3655. ufbx_allocator_opts temp_allocator; // < Allocator used during loading
  3656. ufbx_allocator_opts result_allocator; // < Allocator used for the final scene
  3657. ufbx_thread_opts thread_opts; // < Threading options
  3658. // Preferences
  3659. bool ignore_geometry; // < Do not load geometry datsa (vertices, indices, etc)
  3660. bool ignore_animation; // < Do not load animation curves
  3661. bool ignore_embedded; // < Do not load embedded content
  3662. bool ignore_all_content; // < Do not load any content (geometry, animation, embedded)
  3663. bool evaluate_skinning; // < Evaluate skinning (see ufbx_mesh.skinned_vertices)
  3664. bool evaluate_caches; // < Evaluate vertex caches (see ufbx_mesh.skinned_vertices)
  3665. // Try to open external files referenced by the main file automatically.
  3666. // Applies to geometry caches and .mtl files for OBJ.
  3667. // NOTE: This may be risky for untrusted data as the input files may contain
  3668. // references to arbitrary paths in the filesystem.
  3669. // NOTE: This only applies to files *implicitly* referenced by the scene, if
  3670. // you request additional files via eg. `ufbx_load_opts.obj_mtl_path` they
  3671. // are still loaded.
  3672. // NOTE: Will fail loading if any external files are not found by default, use
  3673. // `ufbx_load_opts.ignore_missing_external_files` to suppress this, in this case
  3674. // you can find the errors at `ufbx_metadata.warnings[]` as `UFBX_WARNING_MISSING_EXTERNAL_FILE`.
  3675. bool load_external_files;
  3676. // Don't fail loading if external files are not found.
  3677. bool ignore_missing_external_files;
  3678. // Don't compute `ufbx_skin_deformer` `vertices` and `weights` arrays saving
  3679. // a bit of memory and time if not needed
  3680. bool skip_skin_vertices;
  3681. // Skip computing `ufbx_mesh.material_parts[]` and `ufbx_mesh.face_group_parts[]`.
  3682. bool skip_mesh_parts;
  3683. // Clean-up skin weights by removing negative, zero and NAN weights.
  3684. bool clean_skin_weights;
  3685. // Read Blender materials as PBR values.
  3686. // Blender converts PBR materials to legacy FBX Phong materials in a deterministic way.
  3687. // If this setting is enabled, such materials will be read as `UFBX_SHADER_BLENDER_PHONG`,
  3688. // which means ufbx will be able to parse roughness and metallic textures.
  3689. bool use_blender_pbr_material;
  3690. // Don't adjust reading the FBX file depending on the detected exporter
  3691. bool disable_quirks;
  3692. // Don't allow partially broken FBX files to load
  3693. bool strict;
  3694. // Force ASCII parsing to use a single thread.
  3695. // The multi-threaded ASCII parsing is slightly more lenient as it ignores
  3696. // the self-reported size of ASCII arrays, that threaded parsing depends on.
  3697. bool force_single_thread_ascii_parsing;
  3698. // UNSAFE: If enabled allows using unsafe options that may fundamentally
  3699. // break the API guarantees.
  3700. ufbx_unsafe bool allow_unsafe;
  3701. // Specify how to handle broken indices.
  3702. ufbx_index_error_handling index_error_handling;
  3703. // Connect related elements even if they are broken. If `false` (default)
  3704. // `ufbx_skin_cluster` with a missing `bone` field are _not_ included in
  3705. // the `ufbx_skin_deformer.clusters[]` array for example.
  3706. bool connect_broken_elements;
  3707. // Allow nodes that are not connected in any way to the root. Conversely if
  3708. // disabled, all lone nodes will be parented under `ufbx_scene.root_node`.
  3709. bool allow_nodes_out_of_root;
  3710. // Allow meshes with no vertex position attribute.
  3711. // NOTE: If this is set `ufbx_mesh.vertex_position.exists` may be `false`.
  3712. bool allow_missing_vertex_position;
  3713. // Allow faces with zero indices.
  3714. bool allow_empty_faces;
  3715. // Generate vertex normals for a meshes that are missing normals.
  3716. // You can see if the normals have been generated from `ufbx_mesh.generated_normals`.
  3717. bool generate_missing_normals;
  3718. // Ignore `open_file_cb` when loading the main file.
  3719. bool open_main_file_with_default;
  3720. // Path separator character, defaults to '\' on Windows and '/' otherwise.
  3721. char path_separator;
  3722. // Maximum depth of the node hirerachy.
  3723. // Will fail with `UFBX_ERROR_NODE_DEPTH_LIMIT` if a node is deeper than this limit.
  3724. // NOTE: The default of 0 allows arbitrarily deep hierarchies. Be careful if using
  3725. // recursive algorithms without setting this limit.
  3726. uint32_t node_depth_limit;
  3727. // Estimated file size for progress reporting
  3728. uint64_t file_size_estimate;
  3729. // Buffer size in bytes to use for reading from files or IO callbacks
  3730. size_t read_buffer_size;
  3731. // Filename to use as a base for relative file paths if not specified using
  3732. // `ufbx_load_file()`. Use `length = SIZE_MAX` for NULL-terminated strings.
  3733. // `raw_filename` will be derived from this if empty.
  3734. ufbx_string filename;
  3735. // Raw non-UTF8 filename. Does not support NULL termination.
  3736. // `filename` will be derived from this if empty.
  3737. ufbx_blob raw_filename;
  3738. // Progress reporting
  3739. ufbx_progress_cb progress_cb;
  3740. uint64_t progress_interval_hint; // < Bytes between progress report calls
  3741. // External file callbacks (defaults to stdio.h)
  3742. ufbx_open_file_cb open_file_cb;
  3743. // How to handle geometry transforms in the nodes.
  3744. // See `ufbx_geometry_transform_handling` for an explanation.
  3745. ufbx_geometry_transform_handling geometry_transform_handling;
  3746. // How to handle unconventional transform inherit modes.
  3747. // See `ufbx_inherit_mode_handling` for an explanation.
  3748. ufbx_inherit_mode_handling inherit_mode_handling;
  3749. // How to handle pivots.
  3750. // See `ufbx_pivot_handling` for an explanation.
  3751. ufbx_pivot_handling pivot_handling;
  3752. // How to perform space conversion by `target_axes` and `target_unit_meters`.
  3753. // See `ufbx_space_conversion` for an explanation.
  3754. ufbx_space_conversion space_conversion;
  3755. // Axis used to mirror for conversion between left-handed and right-handed coordinates.
  3756. ufbx_mirror_axis handedness_conversion_axis;
  3757. // Do not change winding of faces when converting handedness.
  3758. bool handedness_conversion_retain_winding;
  3759. // Reverse winding of all faces.
  3760. // If `handedness_conversion_retain_winding` is not specified, mirrored meshes
  3761. // will retain their original winding.
  3762. bool reverse_winding;
  3763. // Apply an implicit root transformation to match axes.
  3764. // Used if `ufbx_coordinate_axes_valid(target_axes)`.
  3765. ufbx_coordinate_axes target_axes;
  3766. // Scale the scene so that one world-space unit is `target_unit_meters` meters.
  3767. // By default units are not scaled.
  3768. ufbx_real target_unit_meters;
  3769. // Target space for camera.
  3770. // By default FBX cameras point towards the positive X axis.
  3771. // Used if `ufbx_coordinate_axes_valid(target_camera_axes)`.
  3772. ufbx_coordinate_axes target_camera_axes;
  3773. // Target space for directed lights.
  3774. // By default FBX lights point towards the negative Y axis.
  3775. // Used if `ufbx_coordinate_axes_valid(target_light_axes)`.
  3776. ufbx_coordinate_axes target_light_axes;
  3777. // Name for dummy geometry transform helper nodes.
  3778. // See `UFBX_GEOMETRY_TRANSFORM_HANDLING_HELPER_NODES`.
  3779. ufbx_string geometry_transform_helper_name;
  3780. // Name for dummy scale helper nodes.
  3781. // See `UFBX_INHERIT_MODE_HANDLING_HELPER_NODES`.
  3782. ufbx_string scale_helper_name;
  3783. // Normalize vertex normals.
  3784. bool normalize_normals;
  3785. // Normalize tangents and bitangents.
  3786. bool normalize_tangents;
  3787. // Override for the root transform
  3788. bool use_root_transform;
  3789. ufbx_transform root_transform;
  3790. // Animation keyframe clamp threhsold, only applies to specific interpolation modes.
  3791. double key_clamp_threshold;
  3792. // Specify how to handle Unicode errors in strings.
  3793. ufbx_unicode_error_handling unicode_error_handling;
  3794. // Retain the 'W' component of mesh normal/tangent/bitangent.
  3795. // See `ufbx_vertex_attrib.values_w`.
  3796. bool retain_vertex_attrib_w;
  3797. // Retain the raw document structure using `ufbx_dom_node`.
  3798. bool retain_dom;
  3799. // Force a specific file format instead of detecting it.
  3800. ufbx_file_format file_format;
  3801. // How far to read into the file to determine the file format.
  3802. // Default: 16kB
  3803. size_t file_format_lookahead;
  3804. // Do not attempt to detect file format from file content.
  3805. bool no_format_from_content;
  3806. // Do not attempt to detect file format from filename extension.
  3807. // ufbx primarily detects file format from the file header,
  3808. // this is just used as a fallback.
  3809. bool no_format_from_extension;
  3810. // (.obj) Try to find .mtl file with matching filename as the .obj file.
  3811. // Used if the file specified `mtllib` line is not found, eg. for a file called
  3812. // `model.obj` that contains the line `usemtl materials.mtl`, ufbx would first
  3813. // try to open `materials.mtl` and if that fails it tries to open `model.mtl`.
  3814. bool obj_search_mtl_by_filename;
  3815. // (.obj) Don't split geometry into meshes by object.
  3816. bool obj_merge_objects;
  3817. // (.obj) Don't split geometry into meshes by groups.
  3818. bool obj_merge_groups;
  3819. // (.obj) Force splitting groups even on object boundaries.
  3820. bool obj_split_groups;
  3821. // (.obj) Path to the .mtl file.
  3822. // Use `length = SIZE_MAX` for NULL-terminated strings.
  3823. // NOTE: This is used _instead_ of the one in the file even if not found
  3824. // and sidesteps `load_external_files` as it's _explicitly_ requested.
  3825. ufbx_string obj_mtl_path;
  3826. // (.obj) Data for the .mtl file.
  3827. ufbx_blob obj_mtl_data;
  3828. // The world unit in meters that .obj files are assumed to be in.
  3829. // .obj files do not define the working units. By default the unit scale
  3830. // is read as zero, and no unit conversion is performed.
  3831. ufbx_real obj_unit_meters;
  3832. // Coordinate space .obj files are assumed to be in.
  3833. // .obj files do not define the coordinate space they use. By default no
  3834. // coordinate space is assumed and no conversion is performed.
  3835. ufbx_coordinate_axes obj_axes;
  3836. uint32_t _end_zero;
  3837. } ufbx_load_opts;
  3838. // Options for `ufbx_evaluate_scene()`
  3839. // NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++)
  3840. typedef struct ufbx_evaluate_opts {
  3841. uint32_t _begin_zero;
  3842. ufbx_allocator_opts temp_allocator; // < Allocator used during evaluation
  3843. ufbx_allocator_opts result_allocator; // < Allocator used for the final scene
  3844. bool evaluate_skinning; // < Evaluate skinning (see ufbx_mesh.skinned_vertices)
  3845. bool evaluate_caches; // < Evaluate vertex caches (see ufbx_mesh.skinned_vertices)
  3846. // WARNING: Potentially unsafe! Try to open external files such as geometry caches
  3847. bool load_external_files;
  3848. // External file callbacks (defaults to stdio.h)
  3849. ufbx_open_file_cb open_file_cb;
  3850. uint32_t _end_zero;
  3851. } ufbx_evaluate_opts;
  3852. UFBX_LIST_TYPE(ufbx_const_uint32_list, const uint32_t);
  3853. UFBX_LIST_TYPE(ufbx_const_real_list, const ufbx_real);
  3854. typedef struct ufbx_prop_override_desc {
  3855. // Element (`ufbx_element.element_id`) to override the property from
  3856. uint32_t element_id;
  3857. // Property name to override.
  3858. ufbx_string prop_name;
  3859. // Override value, use `value.x` for scalars. `value_int` is initialized
  3860. // from `value.x` if zero so keep `value` zeroed even if you don't need it!
  3861. ufbx_vec4 value;
  3862. ufbx_string value_str;
  3863. int64_t value_int;
  3864. } ufbx_prop_override_desc;
  3865. UFBX_LIST_TYPE(ufbx_const_prop_override_desc_list, const ufbx_prop_override_desc);
  3866. UFBX_LIST_TYPE(ufbx_const_transform_override_list, const ufbx_transform_override);
  3867. typedef struct ufbx_anim_opts {
  3868. uint32_t _begin_zero;
  3869. // Animation layers indices.
  3870. // Corresponding to `ufbx_scene.anim_layers[]`, aka `ufbx_anim_layer.typed_id`.
  3871. ufbx_const_uint32_list layer_ids;
  3872. // Override layer weights, parallel to `ufbx_anim_opts.layer_ids[]`.
  3873. ufbx_const_real_list override_layer_weights;
  3874. // Property overrides.
  3875. // These allow you to override FBX properties, such as 'UFBX_Lcl_Rotation`.
  3876. ufbx_const_prop_override_desc_list prop_overrides;
  3877. // Transform overrides.
  3878. // These allow you to override individual nodes' `ufbx_node.local_transform`.
  3879. ufbx_const_transform_override_list transform_overrides;
  3880. // Ignore connected properties
  3881. bool ignore_connections;
  3882. ufbx_allocator_opts result_allocator; // < Allocator used to create the `ufbx_anim`
  3883. uint32_t _end_zero;
  3884. } ufbx_anim_opts;
  3885. // Specifies how to handle stepped tangents.
  3886. typedef enum ufbx_bake_step_handling UFBX_ENUM_REPR {
  3887. // One millisecond default step duration, with potential extra slack for converting to `float`.
  3888. UFBX_BAKE_STEP_HANDLING_DEFAULT,
  3889. // Use a custom interpolation duration for the constant step.
  3890. // See `ufbx_bake_opts.step_custom_duration` and optionally `ufbx_bake_opts.step_custom_epsilon`.
  3891. UFBX_BAKE_STEP_HANDLING_CUSTOM_DURATION,
  3892. // Stepped keyframes are represented as keyframes at the exact same time.
  3893. // Use flags `UFBX_BAKED_KEY_STEP_LEFT` and `UFBX_BAKED_KEY_STEP_RIGHT` to differentiate
  3894. // between the primary key and edge limits.
  3895. UFBX_BAKE_STEP_HANDLING_IDENTICAL_TIME,
  3896. // Represent stepped keyframe times as the previous/next representable `double` value.
  3897. // Using this and robust linear interpolation will handle stepped tangents correctly
  3898. // without having to look at the key flags.
  3899. // NOTE: Casting these values to `float` or otherwise modifying them can collapse
  3900. // the keyframes to have the identical time.
  3901. UFBX_BAKE_STEP_HANDLING_ADJACENT_DOUBLE,
  3902. // Treat all stepped tangents as linearly interpolated.
  3903. UFBX_BAKE_STEP_HANDLING_IGNORE,
  3904. UFBX_ENUM_FORCE_WIDTH(ufbx_bake_step_handling)
  3905. } ufbx_bake_step_handling;
  3906. UFBX_ENUM_TYPE(ufbx_bake_step_handling, UFBX_BAKE_STEP_HANDLING, UFBX_BAKE_STEP_HANDLING_IGNORE);
  3907. typedef struct ufbx_bake_opts {
  3908. uint32_t _begin_zero;
  3909. ufbx_allocator_opts temp_allocator; // < Allocator used during loading
  3910. ufbx_allocator_opts result_allocator; // < Allocator used for the final baked animation
  3911. // Move the keyframe times to start from zero regardless of the animation start time.
  3912. // For example, for an animation spanning between frames [30, 60] will be moved to
  3913. // [0, 30] in the baked animation.
  3914. // NOTE: This is in general not equivalent to subtracting `ufbx_anim.time_begin`
  3915. // from each keyframe, as this trimming is done exactly using internal FBX ticks.
  3916. bool trim_start_time;
  3917. // Samples per second to use for resampling non-linear animation.
  3918. // Default: 30
  3919. double resample_rate;
  3920. // Minimum sample rate to not resample.
  3921. // Many exporters resample animation by default. To avoid double-resampling
  3922. // keyframe rates higher or equal to this will not be resampled.
  3923. // Default: 19.5
  3924. double minimum_sample_rate;
  3925. // Maximum sample rate to use, this will remove keys if they are too close together.
  3926. // Default: unlimited
  3927. double maximum_sample_rate;
  3928. // Bake the raw versions of properties related to transforms.
  3929. bool bake_transform_props;
  3930. // Do not bake node transforms.
  3931. bool skip_node_transforms;
  3932. // Do not resample linear rotation keyframes.
  3933. // FBX interpolates rotation in Euler angles, so this might cause incorrect interpolation.
  3934. bool no_resample_rotation;
  3935. // Ignore layer weight animation.
  3936. bool ignore_layer_weight_animation;
  3937. // Maximum number of segments to generate from one keyframe.
  3938. // Default: 32
  3939. size_t max_keyframe_segments;
  3940. // How to handle stepped tangents.
  3941. ufbx_bake_step_handling step_handling;
  3942. // Interpolation duration used by `UFBX_BAKE_STEP_HANDLING_CUSTOM_DURATION`.
  3943. double step_custom_duration;
  3944. // Interpolation epsilon used by `UFBX_BAKE_STEP_HANDLING_CUSTOM_DURATION`.
  3945. // Defined as the minimum fractional decrease/increase in key time, ie.
  3946. // `time / (1.0 + step_custom_epsilon)` and `time * (1.0 + step_custom_epsilon)`.
  3947. double step_custom_epsilon;
  3948. // Enable key reduction.
  3949. bool key_reduction_enabled;
  3950. // Enable key reduction for non-constant rotations.
  3951. // Assumes rotations will be interpolated using a spherical linear interpolation at runtime.
  3952. bool key_reduction_rotation;
  3953. // Threshold for reducing keys for linear segments.
  3954. // Default `0.000001`, use negative to disable.
  3955. double key_reduction_threshold;
  3956. // Maximum passes over the keys to reduce.
  3957. // Every pass can potentially halve the the amount of keys.
  3958. // Default: `4`
  3959. size_t key_reduction_passes;
  3960. uint32_t _end_zero;
  3961. } ufbx_bake_opts;
  3962. // Options for `ufbx_tessellate_nurbs_curve()`
  3963. // NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++)
  3964. typedef struct ufbx_tessellate_curve_opts {
  3965. uint32_t _begin_zero;
  3966. ufbx_allocator_opts temp_allocator; // < Allocator used during tessellation
  3967. ufbx_allocator_opts result_allocator; // < Allocator used for the final line curve
  3968. // How many segments tessellate each span in `ufbx_nurbs_basis.spans`.
  3969. size_t span_subdivision;
  3970. uint32_t _end_zero;
  3971. } ufbx_tessellate_curve_opts;
  3972. // Options for `ufbx_tessellate_nurbs_surface()`
  3973. // NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++)
  3974. typedef struct ufbx_tessellate_surface_opts {
  3975. uint32_t _begin_zero;
  3976. ufbx_allocator_opts temp_allocator; // < Allocator used during tessellation
  3977. ufbx_allocator_opts result_allocator; // < Allocator used for the final mesh
  3978. // How many segments tessellate each span in `ufbx_nurbs_basis.spans`.
  3979. // NOTE: Default is `4`, _not_ `ufbx_nurbs_surface.span_subdivision_u/v` as that
  3980. // would make it easy to create an FBX file with an absurdly high subdivision
  3981. // rate (similar to mesh subdivision). Please enforce copy the value yourself
  3982. // enforcing whatever limits you deem reasonable.
  3983. size_t span_subdivision_u;
  3984. size_t span_subdivision_v;
  3985. // Skip computing `ufbx_mesh.material_parts[]`
  3986. bool skip_mesh_parts;
  3987. uint32_t _end_zero;
  3988. } ufbx_tessellate_surface_opts;
  3989. // Options for `ufbx_subdivide_mesh()`
  3990. // NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++)
  3991. typedef struct ufbx_subdivide_opts {
  3992. uint32_t _begin_zero;
  3993. ufbx_allocator_opts temp_allocator; // < Allocator used during subdivision
  3994. ufbx_allocator_opts result_allocator; // < Allocator used for the final mesh
  3995. ufbx_subdivision_boundary boundary;
  3996. ufbx_subdivision_boundary uv_boundary;
  3997. // Do not generate normals
  3998. bool ignore_normals;
  3999. // Interpolate existing normals using the subdivision rules
  4000. // instead of generating new normals
  4001. bool interpolate_normals;
  4002. // Subdivide also tangent attributes
  4003. bool interpolate_tangents;
  4004. // Map subdivided vertices into weighted original vertices.
  4005. // NOTE: May be O(n^2) if `max_source_vertices` is not specified!
  4006. bool evaluate_source_vertices;
  4007. // Limit source vertices per subdivided vertex.
  4008. size_t max_source_vertices;
  4009. // Calculate bone influences over subdivided vertices (if applicable).
  4010. // NOTE: May be O(n^2) if `max_skin_weights` is not specified!
  4011. bool evaluate_skin_weights;
  4012. // Limit bone influences per subdivided vertex.
  4013. size_t max_skin_weights;
  4014. // Index of the skin deformer to use for `evaluate_skin_weights`.
  4015. size_t skin_deformer_index;
  4016. uint32_t _end_zero;
  4017. } ufbx_subdivide_opts;
  4018. // Options for `ufbx_load_geometry_cache()`
  4019. // NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++)
  4020. typedef struct ufbx_geometry_cache_opts {
  4021. uint32_t _begin_zero;
  4022. ufbx_allocator_opts temp_allocator; // < Allocator used during loading
  4023. ufbx_allocator_opts result_allocator; // < Allocator used for the final scene
  4024. // External file callbacks (defaults to stdio.h)
  4025. ufbx_open_file_cb open_file_cb;
  4026. // FPS value for converting frame times to seconds
  4027. double frames_per_second;
  4028. // Axis to mirror the geometry by.
  4029. ufbx_mirror_axis mirror_axis;
  4030. // Enable scaling `scale_factor` all geometry by.
  4031. bool use_scale_factor;
  4032. // Factor to scale the geometry by.
  4033. ufbx_real scale_factor;
  4034. uint32_t _end_zero;
  4035. } ufbx_geometry_cache_opts;
  4036. // Options for `ufbx_read_geometry_cache_TYPE()`
  4037. // NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++)
  4038. typedef struct ufbx_geometry_cache_data_opts {
  4039. uint32_t _begin_zero;
  4040. // External file callbacks (defaults to stdio.h)
  4041. ufbx_open_file_cb open_file_cb;
  4042. bool additive;
  4043. bool use_weight;
  4044. ufbx_real weight;
  4045. // Ignore scene transform.
  4046. bool ignore_transform;
  4047. uint32_t _end_zero;
  4048. } ufbx_geometry_cache_data_opts;
  4049. typedef struct ufbx_panic {
  4050. bool did_panic;
  4051. size_t message_length;
  4052. char message[UFBX_PANIC_MESSAGE_LENGTH];
  4053. } ufbx_panic;
  4054. // -- API
  4055. #ifdef __cplusplus
  4056. extern "C" {
  4057. #endif
  4058. // Various zero/empty/identity values
  4059. ufbx_abi_data const ufbx_string ufbx_empty_string;
  4060. ufbx_abi_data const ufbx_blob ufbx_empty_blob;
  4061. ufbx_abi_data const ufbx_matrix ufbx_identity_matrix;
  4062. ufbx_abi_data const ufbx_transform ufbx_identity_transform;
  4063. ufbx_abi_data const ufbx_vec2 ufbx_zero_vec2;
  4064. ufbx_abi_data const ufbx_vec3 ufbx_zero_vec3;
  4065. ufbx_abi_data const ufbx_vec4 ufbx_zero_vec4;
  4066. ufbx_abi_data const ufbx_quat ufbx_identity_quat;
  4067. // Commonly used coordinate axes.
  4068. ufbx_abi_data const ufbx_coordinate_axes ufbx_axes_right_handed_y_up;
  4069. ufbx_abi_data const ufbx_coordinate_axes ufbx_axes_right_handed_z_up;
  4070. ufbx_abi_data const ufbx_coordinate_axes ufbx_axes_left_handed_y_up;
  4071. ufbx_abi_data const ufbx_coordinate_axes ufbx_axes_left_handed_z_up;
  4072. // Sizes of element types. eg `sizeof(ufbx_node)`
  4073. ufbx_abi_data const size_t ufbx_element_type_size[UFBX_ELEMENT_TYPE_COUNT];
  4074. // Version of the source file, comparable to `UFBX_HEADER_VERSION`
  4075. ufbx_abi_data const uint32_t ufbx_source_version;
  4076. // Practically always `true` (see below), if not you need to be careful with threads.
  4077. //
  4078. // Guaranteed to be `true` in _any_ of the following conditions:
  4079. // - ufbx.c has been compiled using: GCC / Clang / MSVC / ICC / EMCC / TCC
  4080. // - ufbx.c has been compiled as C++11 or later
  4081. // - ufbx.c has been compiled as C11 or later with `<stdatomic.h>` support
  4082. //
  4083. // If `false` you can't call the following functions concurrently:
  4084. // ufbx_evaluate_scene()
  4085. // ufbx_free_scene()
  4086. // ufbx_subdivide_mesh()
  4087. // ufbx_tessellate_nurbs_surface()
  4088. // ufbx_free_mesh()
  4089. ufbx_abi bool ufbx_is_thread_safe(void);
  4090. // Load a scene from a `size` byte memory buffer at `data`
  4091. ufbx_abi ufbx_scene *ufbx_load_memory(
  4092. const void *data, size_t data_size,
  4093. const ufbx_load_opts *opts, ufbx_error *error);
  4094. // Load a scene by opening a file named `filename`
  4095. ufbx_abi ufbx_scene *ufbx_load_file(
  4096. const char *filename,
  4097. const ufbx_load_opts *opts, ufbx_error *error);
  4098. ufbx_abi ufbx_scene *ufbx_load_file_len(
  4099. const char *filename, size_t filename_len,
  4100. const ufbx_load_opts *opts, ufbx_error *error);
  4101. // Load a scene by reading from an `FILE *file` stream
  4102. // NOTE: `file` is passed as a `void` pointer to avoid including <stdio.h>
  4103. ufbx_abi ufbx_scene *ufbx_load_stdio(
  4104. void *file,
  4105. const ufbx_load_opts *opts, ufbx_error *error);
  4106. // Load a scene by reading from an `FILE *file` stream with a prefix
  4107. // NOTE: `file` is passed as a `void` pointer to avoid including <stdio.h>
  4108. ufbx_abi ufbx_scene *ufbx_load_stdio_prefix(
  4109. void *file,
  4110. const void *prefix, size_t prefix_size,
  4111. const ufbx_load_opts *opts, ufbx_error *error);
  4112. // Load a scene from a user-specified stream
  4113. ufbx_abi ufbx_scene *ufbx_load_stream(
  4114. const ufbx_stream *stream,
  4115. const ufbx_load_opts *opts, ufbx_error *error);
  4116. // Load a scene from a user-specified stream with a prefix
  4117. ufbx_abi ufbx_scene *ufbx_load_stream_prefix(
  4118. const ufbx_stream *stream,
  4119. const void *prefix, size_t prefix_size,
  4120. const ufbx_load_opts *opts, ufbx_error *error);
  4121. // Free a previously loaded or evaluated scene
  4122. ufbx_abi void ufbx_free_scene(ufbx_scene *scene);
  4123. // Increment `scene` refcount
  4124. ufbx_abi void ufbx_retain_scene(ufbx_scene *scene);
  4125. // Format a textual description of `error`.
  4126. // Always produces a NULL-terminated string to `char dst[dst_size]`, truncating if
  4127. // necessary. Returns the number of characters written not including the NULL terminator.
  4128. ufbx_abi size_t ufbx_format_error(char *dst, size_t dst_size, const ufbx_error *error);
  4129. // Query
  4130. // Find a property `name` from `props`, returns `NULL` if not found.
  4131. // Searches through `ufbx_props.defaults` as well.
  4132. ufbx_abi ufbx_prop *ufbx_find_prop_len(const ufbx_props *props, const char *name, size_t name_len);
  4133. ufbx_abi ufbx_prop *ufbx_find_prop(const ufbx_props *props, const char *name);
  4134. // Utility functions for finding the value of a property, returns `def` if not found.
  4135. // NOTE: For `ufbx_string` you need to ensure the lifetime of the default is
  4136. // sufficient as no copy is made.
  4137. ufbx_abi ufbx_real ufbx_find_real_len(const ufbx_props *props, const char *name, size_t name_len, ufbx_real def);
  4138. ufbx_abi ufbx_real ufbx_find_real(const ufbx_props *props, const char *name, ufbx_real def);
  4139. ufbx_abi ufbx_vec3 ufbx_find_vec3_len(const ufbx_props *props, const char *name, size_t name_len, ufbx_vec3 def);
  4140. ufbx_abi ufbx_vec3 ufbx_find_vec3(const ufbx_props *props, const char *name, ufbx_vec3 def);
  4141. ufbx_abi int64_t ufbx_find_int_len(const ufbx_props *props, const char *name, size_t name_len, int64_t def);
  4142. ufbx_abi int64_t ufbx_find_int(const ufbx_props *props, const char *name, int64_t def);
  4143. ufbx_abi bool ufbx_find_bool_len(const ufbx_props *props, const char *name, size_t name_len, bool def);
  4144. ufbx_abi bool ufbx_find_bool(const ufbx_props *props, const char *name, bool def);
  4145. ufbx_abi ufbx_string ufbx_find_string_len(const ufbx_props *props, const char *name, size_t name_len, ufbx_string def);
  4146. ufbx_abi ufbx_string ufbx_find_string(const ufbx_props *props, const char *name, ufbx_string def);
  4147. ufbx_abi ufbx_blob ufbx_find_blob_len(const ufbx_props *props, const char *name, size_t name_len, ufbx_blob def);
  4148. ufbx_abi ufbx_blob ufbx_find_blob(const ufbx_props *props, const char *name, ufbx_blob def);
  4149. // Find property in `props` with concatendated `parts[num_parts]`.
  4150. ufbx_abi ufbx_prop *ufbx_find_prop_concat(const ufbx_props *props, const ufbx_string *parts, size_t num_parts);
  4151. // Get an element connected to a property.
  4152. ufbx_abi ufbx_element *ufbx_get_prop_element(const ufbx_element *element, const ufbx_prop *prop, ufbx_element_type type);
  4153. // Find an element connected to a property by name.
  4154. ufbx_abi ufbx_element *ufbx_find_prop_element_len(const ufbx_element *element, const char *name, size_t name_len, ufbx_element_type type);
  4155. ufbx_abi ufbx_element *ufbx_find_prop_element(const ufbx_element *element, const char *name, ufbx_element_type type);
  4156. // Find any element of type `type` in `scene` by `name`.
  4157. // For example if you want to find `ufbx_material` named `Mat`:
  4158. // (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "Mat");
  4159. ufbx_abi ufbx_element *ufbx_find_element_len(const ufbx_scene *scene, ufbx_element_type type, const char *name, size_t name_len);
  4160. ufbx_abi ufbx_element *ufbx_find_element(const ufbx_scene *scene, ufbx_element_type type, const char *name);
  4161. // Find node in `scene` by `name` (shorthand for `ufbx_find_element(UFBX_ELEMENT_NODE)`).
  4162. ufbx_abi ufbx_node *ufbx_find_node_len(const ufbx_scene *scene, const char *name, size_t name_len);
  4163. ufbx_abi ufbx_node *ufbx_find_node(const ufbx_scene *scene, const char *name);
  4164. // Find an animation stack in `scene` by `name` (shorthand for `ufbx_find_element(UFBX_ELEMENT_ANIM_STACK)`)
  4165. ufbx_abi ufbx_anim_stack *ufbx_find_anim_stack_len(const ufbx_scene *scene, const char *name, size_t name_len);
  4166. ufbx_abi ufbx_anim_stack *ufbx_find_anim_stack(const ufbx_scene *scene, const char *name);
  4167. // Find a material in `scene` by `name` (shorthand for `ufbx_find_element(UFBX_ELEMENT_MATERIAL)`).
  4168. ufbx_abi ufbx_material *ufbx_find_material_len(const ufbx_scene *scene, const char *name, size_t name_len);
  4169. ufbx_abi ufbx_material *ufbx_find_material(const ufbx_scene *scene, const char *name);
  4170. // Find a single animated property `prop` of `element` in `layer`.
  4171. // Returns `NULL` if not found.
  4172. ufbx_abi ufbx_anim_prop *ufbx_find_anim_prop_len(const ufbx_anim_layer *layer, const ufbx_element *element, const char *prop, size_t prop_len);
  4173. ufbx_abi ufbx_anim_prop *ufbx_find_anim_prop(const ufbx_anim_layer *layer, const ufbx_element *element, const char *prop);
  4174. // Find all animated properties of `element` in `layer`.
  4175. ufbx_abi ufbx_anim_prop_list ufbx_find_anim_props(const ufbx_anim_layer *layer, const ufbx_element *element);
  4176. // Get a matrix that transforms normals in the same way as Autodesk software.
  4177. // NOTE: The resulting normals are slightly incorrect as this function deliberately
  4178. // inverts geometric transformation wrong. For better results use
  4179. // `ufbx_matrix_for_normals(&node->geometry_to_world)`.
  4180. ufbx_abi ufbx_matrix ufbx_get_compatible_matrix_for_normals(const ufbx_node *node);
  4181. // Utility
  4182. // Decompress a DEFLATE compressed buffer.
  4183. // Returns the decompressed size or a negative error code (see source for details).
  4184. // NOTE: You must supply a valid `retain` with `ufbx_inflate_retain.initialized == false`
  4185. // but the rest can be uninitialized.
  4186. ufbx_abi ptrdiff_t ufbx_inflate(void *dst, size_t dst_size, const ufbx_inflate_input *input, ufbx_inflate_retain *retain);
  4187. // Same as `ufbx_open_file()` but compatible with the callback in `ufbx_open_file_fn`.
  4188. // The `user` parameter is actually not used here.
  4189. ufbx_abi bool ufbx_default_open_file(void *user, ufbx_stream *stream, const char *path, size_t path_len, const ufbx_open_file_info *info);
  4190. // Open a `ufbx_stream` from a file.
  4191. // Use `path_len == SIZE_MAX` for NULL terminated string.
  4192. ufbx_abi bool ufbx_open_file(ufbx_stream *stream, const char *path, size_t path_len, const ufbx_open_file_opts *opts, ufbx_error *error);
  4193. ufbx_unsafe ufbx_abi bool ufbx_open_file_ctx(ufbx_stream *stream, ufbx_open_file_context ctx, const char *path, size_t path_len, const ufbx_open_file_opts *opts, ufbx_error *error);
  4194. // NOTE: Uses the default ufbx allocator!
  4195. ufbx_abi bool ufbx_open_memory(ufbx_stream *stream, const void *data, size_t data_size, const ufbx_open_memory_opts *opts, ufbx_error *error);
  4196. ufbx_unsafe ufbx_abi bool ufbx_open_memory_ctx(ufbx_stream *stream, ufbx_open_file_context ctx, const void *data, size_t data_size, const ufbx_open_memory_opts *opts, ufbx_error *error);
  4197. // Animation evaluation
  4198. // Evaluate a single animation `curve` at a `time`.
  4199. // Returns `default_value` only if `curve == NULL` or it has no keyframes.
  4200. ufbx_abi ufbx_real ufbx_evaluate_curve(const ufbx_anim_curve *curve, double time, ufbx_real default_value);
  4201. // Evaluate a value from bundled animation curves.
  4202. ufbx_abi ufbx_real ufbx_evaluate_anim_value_real(const ufbx_anim_value *anim_value, double time);
  4203. ufbx_abi ufbx_vec3 ufbx_evaluate_anim_value_vec3(const ufbx_anim_value *anim_value, double time);
  4204. // Evaluate an animated property `name` from `element` at `time`.
  4205. // NOTE: If the property is not found it will have the flag `UFBX_PROP_FLAG_NOT_FOUND`.
  4206. ufbx_abi ufbx_prop ufbx_evaluate_prop_len(const ufbx_anim *anim, const ufbx_element *element, const char *name, size_t name_len, double time);
  4207. ufbx_abi ufbx_prop ufbx_evaluate_prop(const ufbx_anim *anim, const ufbx_element *element, const char *name, double time);
  4208. // Evaluate all _animated_ properties of `element`.
  4209. // HINT: This function returns an `ufbx_props` structure with the original properties as
  4210. // `ufbx_props.defaults`. This lets you use `ufbx_find_prop/value()` for the results.
  4211. ufbx_abi ufbx_props ufbx_evaluate_props(const ufbx_anim *anim, const ufbx_element *element, double time, ufbx_prop *buffer, size_t buffer_size);
  4212. // Flags to control `ufbx_evaluate_transform_flags()`.
  4213. typedef enum ufbx_transform_flags UFBX_FLAG_REPR {
  4214. // Ignore parent scale helper.
  4215. UFBX_TRANSFORM_FLAG_IGNORE_SCALE_HELPER = 0x1,
  4216. // Ignore componentwise scale.
  4217. // Note that if you don't specify this, ufbx will have to potentially
  4218. // evaluate the entire parent chain in the worst case.
  4219. UFBX_TRANSFORM_FLAG_IGNORE_COMPONENTWISE_SCALE = 0x2,
  4220. // Require explicit components
  4221. UFBX_TRANSFORM_FLAG_EXPLICIT_INCLUDES = 0x4,
  4222. // If `UFBX_TRANSFORM_FLAG_EXPLICIT_INCLUDES`: Evaluate `ufbx_transform.translation`.
  4223. UFBX_TRANSFORM_FLAG_INCLUDE_TRANSLATION = 0x10,
  4224. // If `UFBX_TRANSFORM_FLAG_EXPLICIT_INCLUDES`: Evaluate `ufbx_transform.rotation`.
  4225. UFBX_TRANSFORM_FLAG_INCLUDE_ROTATION = 0x20,
  4226. // If `UFBX_TRANSFORM_FLAG_EXPLICIT_INCLUDES`: Evaluate `ufbx_transform.scale`.
  4227. UFBX_TRANSFORM_FLAG_INCLUDE_SCALE = 0x40,
  4228. UFBX_FLAG_FORCE_WIDTH(UFBX_TRANSFORM_FLAGS)
  4229. } ufbx_transform_flags;
  4230. // Evaluate the animated transform of a node given a time.
  4231. // The returned transform is the local transform of the node (ie. relative to the parent),
  4232. // comparable to `ufbx_node.local_transform`.
  4233. ufbx_abi ufbx_transform ufbx_evaluate_transform(const ufbx_anim *anim, const ufbx_node *node, double time);
  4234. ufbx_abi ufbx_transform ufbx_evaluate_transform_flags(const ufbx_anim *anim, const ufbx_node *node, double time, uint32_t flags);
  4235. // Evaluate the blend shape weight of a blend channel.
  4236. // NOTE: Return value uses `1.0` for full weight, instead of `100.0` that the internal property `UFBX_Weight` uses.
  4237. ufbx_abi ufbx_real ufbx_evaluate_blend_weight(const ufbx_anim *anim, const ufbx_blend_channel *channel, double time);
  4238. // Evaluate the whole `scene` at a specific `time` in the animation `anim`.
  4239. // The returned scene behaves as if it had been exported at a specific time
  4240. // in the specified animation, except that animated elements' properties contain
  4241. // only the animated values, the original ones are in `props->defaults`.
  4242. //
  4243. // NOTE: The returned scene refers to the original `scene` so the original
  4244. // scene cannot be freed until all evaluated scenes are freed.
  4245. ufbx_abi ufbx_scene *ufbx_evaluate_scene(const ufbx_scene *scene, const ufbx_anim *anim, double time, const ufbx_evaluate_opts *opts, ufbx_error *error);
  4246. // Create a custom animation descriptor.
  4247. // `ufbx_anim_opts` is used to specify animation layers and weights.
  4248. // HINT: You can also leave `ufbx_anim_opts.layer_ids[]` empty and only specify
  4249. // overrides to evaluate the scene with different properties or local transforms.
  4250. ufbx_abi ufbx_anim *ufbx_create_anim(const ufbx_scene *scene, const ufbx_anim_opts *opts, ufbx_error *error);
  4251. // Free an animation returned by `ufbx_create_anim()`.
  4252. ufbx_abi void ufbx_free_anim(ufbx_anim *anim);
  4253. // Increase the animation reference count.
  4254. ufbx_abi void ufbx_retain_anim(ufbx_anim *anim);
  4255. // Animation baking
  4256. // "Bake" an animation to linearly interpolated keyframes.
  4257. // Composites the FBX transformation chain into quaternion rotations.
  4258. ufbx_abi ufbx_baked_anim *ufbx_bake_anim(const ufbx_scene *scene, const ufbx_anim *anim, const ufbx_bake_opts *opts, ufbx_error *error);
  4259. ufbx_abi void ufbx_retain_baked_anim(ufbx_baked_anim *bake);
  4260. ufbx_abi void ufbx_free_baked_anim(ufbx_baked_anim *bake);
  4261. ufbx_abi ufbx_baked_node *ufbx_find_baked_node_by_typed_id(ufbx_baked_anim *bake, uint32_t typed_id);
  4262. ufbx_abi ufbx_baked_node *ufbx_find_baked_node(ufbx_baked_anim *bake, ufbx_node *node);
  4263. ufbx_abi ufbx_baked_element *ufbx_find_baked_element_by_element_id(ufbx_baked_anim *bake, uint32_t element_id);
  4264. ufbx_abi ufbx_baked_element *ufbx_find_baked_element(ufbx_baked_anim *bake, ufbx_element *element);
  4265. // Evaluate baked animation `keyframes` at `time`.
  4266. // Internally linearly interpolates between two adjacent keyframes.
  4267. // Handles stepped tangents cleanly, which is not strictly necessary for custom interpolation.
  4268. ufbx_abi ufbx_vec3 ufbx_evaluate_baked_vec3(ufbx_baked_vec3_list keyframes, double time);
  4269. // Evaluate baked animation `keyframes` at `time`.
  4270. // Internally spherically interpolates (`ufbx_quat_slerp()`) between two adjacent keyframes.
  4271. // Handles stepped tangents cleanly, which is not strictly necessary for custom interpolation.
  4272. ufbx_abi ufbx_quat ufbx_evaluate_baked_quat(ufbx_baked_quat_list keyframes, double time);
  4273. // Poses
  4274. // Retrieve the bone pose for `node`.
  4275. // Returns `NULL` if the pose does not contain `node`.
  4276. ufbx_abi ufbx_bone_pose *ufbx_get_bone_pose(const ufbx_pose *pose, const ufbx_node *node);
  4277. // Materials
  4278. // Find a texture for a given material FBX property.
  4279. ufbx_abi ufbx_texture *ufbx_find_prop_texture_len(const ufbx_material *material, const char *name, size_t name_len);
  4280. ufbx_abi ufbx_texture *ufbx_find_prop_texture(const ufbx_material *material, const char *name);
  4281. // Find a texture for a given shader property.
  4282. ufbx_abi ufbx_string ufbx_find_shader_prop_len(const ufbx_shader *shader, const char *name, size_t name_len);
  4283. ufbx_abi ufbx_string ufbx_find_shader_prop(const ufbx_shader *shader, const char *name);
  4284. // Map from a shader property to material property.
  4285. ufbx_abi ufbx_shader_prop_binding_list ufbx_find_shader_prop_bindings_len(const ufbx_shader *shader, const char *name, size_t name_len);
  4286. ufbx_abi ufbx_shader_prop_binding_list ufbx_find_shader_prop_bindings(const ufbx_shader *shader, const char *name);
  4287. // Find an input in a shader texture.
  4288. ufbx_abi ufbx_shader_texture_input *ufbx_find_shader_texture_input_len(const ufbx_shader_texture *shader, const char *name, size_t name_len);
  4289. ufbx_abi ufbx_shader_texture_input *ufbx_find_shader_texture_input(const ufbx_shader_texture *shader, const char *name);
  4290. // Math
  4291. // Returns `true` if `axes` forms a valid coordinate space.
  4292. ufbx_abi bool ufbx_coordinate_axes_valid(ufbx_coordinate_axes axes);
  4293. // Vector math utility functions.
  4294. ufbx_abi ufbx_vec3 ufbx_vec3_normalize(ufbx_vec3 v);
  4295. // Quaternion math utility functions.
  4296. ufbx_abi ufbx_real ufbx_quat_dot(ufbx_quat a, ufbx_quat b);
  4297. ufbx_abi ufbx_quat ufbx_quat_mul(ufbx_quat a, ufbx_quat b);
  4298. ufbx_abi ufbx_quat ufbx_quat_normalize(ufbx_quat q);
  4299. ufbx_abi ufbx_quat ufbx_quat_fix_antipodal(ufbx_quat q, ufbx_quat reference);
  4300. ufbx_abi ufbx_quat ufbx_quat_slerp(ufbx_quat a, ufbx_quat b, ufbx_real t);
  4301. ufbx_abi ufbx_vec3 ufbx_quat_rotate_vec3(ufbx_quat q, ufbx_vec3 v);
  4302. ufbx_abi ufbx_vec3 ufbx_quat_to_euler(ufbx_quat q, ufbx_rotation_order order);
  4303. ufbx_abi ufbx_quat ufbx_euler_to_quat(ufbx_vec3 v, ufbx_rotation_order order);
  4304. // Matrix math utility functions.
  4305. ufbx_abi ufbx_matrix ufbx_matrix_mul(const ufbx_matrix *a, const ufbx_matrix *b);
  4306. ufbx_abi ufbx_real ufbx_matrix_determinant(const ufbx_matrix *m);
  4307. ufbx_abi ufbx_matrix ufbx_matrix_invert(const ufbx_matrix *m);
  4308. // Get a matrix that can be used to transform geometry normals.
  4309. // NOTE: You must normalize the normals after transforming them with this matrix,
  4310. // eg. using `ufbx_vec3_normalize()`.
  4311. // NOTE: This function flips the normals if the determinant is negative.
  4312. ufbx_abi ufbx_matrix ufbx_matrix_for_normals(const ufbx_matrix *m);
  4313. // Matrix transformation utilities.
  4314. ufbx_abi ufbx_vec3 ufbx_transform_position(const ufbx_matrix *m, ufbx_vec3 v);
  4315. ufbx_abi ufbx_vec3 ufbx_transform_direction(const ufbx_matrix *m, ufbx_vec3 v);
  4316. // Conversions between `ufbx_matrix` and `ufbx_transform`.
  4317. ufbx_abi ufbx_matrix ufbx_transform_to_matrix(const ufbx_transform *t);
  4318. ufbx_abi ufbx_transform ufbx_matrix_to_transform(const ufbx_matrix *m);
  4319. // Skinning
  4320. // Get a matrix representing the deformation for a single vertex.
  4321. // Returns `fallback` if the vertex is not skinned.
  4322. ufbx_abi ufbx_matrix ufbx_catch_get_skin_vertex_matrix(ufbx_panic *panic, const ufbx_skin_deformer *skin, size_t vertex, const ufbx_matrix *fallback);
  4323. ufbx_inline ufbx_matrix ufbx_get_skin_vertex_matrix(const ufbx_skin_deformer *skin, size_t vertex, const ufbx_matrix *fallback) {
  4324. return ufbx_catch_get_skin_vertex_matrix(NULL, skin, vertex, fallback);
  4325. }
  4326. // Resolve the index into `ufbx_blend_shape.position_offsets[]` given a vertex.
  4327. // Returns `UFBX_NO_INDEX` if the vertex is not included in the blend shape.
  4328. ufbx_abi uint32_t ufbx_get_blend_shape_offset_index(const ufbx_blend_shape *shape, size_t vertex);
  4329. // Get the offset for a given vertex in the blend shape.
  4330. // Returns `ufbx_zero_vec3` if the vertex is not a included in the blend shape.
  4331. ufbx_abi ufbx_vec3 ufbx_get_blend_shape_vertex_offset(const ufbx_blend_shape *shape, size_t vertex);
  4332. // Get the _current_ blend offset given a blend deformer.
  4333. // NOTE: This depends on the current animated blend weight of the deformer.
  4334. ufbx_abi ufbx_vec3 ufbx_get_blend_vertex_offset(const ufbx_blend_deformer *blend, size_t vertex);
  4335. // Apply the blend shape with `weight` to given vertices.
  4336. ufbx_abi void ufbx_add_blend_shape_vertex_offsets(const ufbx_blend_shape *shape, ufbx_vec3 *vertices, size_t num_vertices, ufbx_real weight);
  4337. // Apply the blend deformer with `weight` to given vertices.
  4338. // NOTE: This depends on the current animated blend weight of the deformer.
  4339. ufbx_abi void ufbx_add_blend_vertex_offsets(const ufbx_blend_deformer *blend, ufbx_vec3 *vertices, size_t num_vertices, ufbx_real weight);
  4340. // Curves/surfaces
  4341. // Low-level utility to evaluate NURBS the basis functions.
  4342. ufbx_abi size_t ufbx_evaluate_nurbs_basis(const ufbx_nurbs_basis *basis, ufbx_real u, ufbx_real *weights, size_t num_weights, ufbx_real *derivatives, size_t num_derivatives);
  4343. // Evaluate a point on a NURBS curve given the parameter `u`.
  4344. ufbx_abi ufbx_curve_point ufbx_evaluate_nurbs_curve(const ufbx_nurbs_curve *curve, ufbx_real u);
  4345. // Evaluate a point on a NURBS surface given the parameter `u` and `v`.
  4346. ufbx_abi ufbx_surface_point ufbx_evaluate_nurbs_surface(const ufbx_nurbs_surface *surface, ufbx_real u, ufbx_real v);
  4347. // Tessellate a NURBS curve into a polyline.
  4348. ufbx_abi ufbx_line_curve *ufbx_tessellate_nurbs_curve(const ufbx_nurbs_curve *curve, const ufbx_tessellate_curve_opts *opts, ufbx_error *error);
  4349. // Tessellate a NURBS surface into a mesh.
  4350. ufbx_abi ufbx_mesh *ufbx_tessellate_nurbs_surface(const ufbx_nurbs_surface *surface, const ufbx_tessellate_surface_opts *opts, ufbx_error *error);
  4351. // Free a line returned by `ufbx_tessellate_nurbs_curve()`.
  4352. ufbx_abi void ufbx_free_line_curve(ufbx_line_curve *curve);
  4353. // Increase the refcount of the line.
  4354. ufbx_abi void ufbx_retain_line_curve(ufbx_line_curve *curve);
  4355. // Mesh Topology
  4356. // Find the face that contains a given `index`.
  4357. // Returns `UFBX_NO_INDEX` if out of bounds.
  4358. ufbx_abi uint32_t ufbx_find_face_index(ufbx_mesh *mesh, size_t index);
  4359. // Triangulate a mesh face, returning the number of triangles.
  4360. // NOTE: You need to space for `(face.num_indices - 2) * 3 - 1` indices!
  4361. // HINT: Using `ufbx_mesh.max_face_triangles * 3` is always safe.
  4362. ufbx_abi uint32_t ufbx_catch_triangulate_face(ufbx_panic *panic, uint32_t *indices, size_t num_indices, const ufbx_mesh *mesh, ufbx_face face);
  4363. ufbx_abi uint32_t ufbx_triangulate_face(uint32_t *indices, size_t num_indices, const ufbx_mesh *mesh, ufbx_face face);
  4364. // Generate the half-edge representation of `mesh` to `topo[mesh->num_indices]`
  4365. ufbx_abi void ufbx_catch_compute_topology(ufbx_panic *panic, const ufbx_mesh *mesh, ufbx_topo_edge *topo, size_t num_topo);
  4366. ufbx_abi void ufbx_compute_topology(const ufbx_mesh *mesh, ufbx_topo_edge *topo, size_t num_topo);
  4367. // Get the next/previous edge around a vertex
  4368. // NOTE: Does not return the half-edge on the opposite side (ie. `topo[index].twin`)
  4369. // Get the next half-edge in `topo`.
  4370. ufbx_abi uint32_t ufbx_catch_topo_next_vertex_edge(ufbx_panic *panic, const ufbx_topo_edge *topo, size_t num_topo, uint32_t index);
  4371. ufbx_abi uint32_t ufbx_topo_next_vertex_edge(const ufbx_topo_edge *topo, size_t num_topo, uint32_t index);
  4372. // Get the previous half-edge in `topo`.
  4373. ufbx_abi uint32_t ufbx_catch_topo_prev_vertex_edge(ufbx_panic *panic, const ufbx_topo_edge *topo, size_t num_topo, uint32_t index);
  4374. ufbx_abi uint32_t ufbx_topo_prev_vertex_edge(const ufbx_topo_edge *topo, size_t num_topo, uint32_t index);
  4375. // Calculate a normal for a given face.
  4376. // The returned normal is weighted by face area.
  4377. ufbx_abi ufbx_vec3 ufbx_catch_get_weighted_face_normal(ufbx_panic *panic, const ufbx_vertex_vec3 *positions, ufbx_face face);
  4378. ufbx_abi ufbx_vec3 ufbx_get_weighted_face_normal(const ufbx_vertex_vec3 *positions, ufbx_face face);
  4379. // Generate indices for normals from the topology.
  4380. // Respects smoothing groups.
  4381. ufbx_abi size_t ufbx_catch_generate_normal_mapping(ufbx_panic *panic, const ufbx_mesh *mesh,
  4382. const ufbx_topo_edge *topo, size_t num_topo,
  4383. uint32_t *normal_indices, size_t num_normal_indices, bool assume_smooth);
  4384. ufbx_abi size_t ufbx_generate_normal_mapping(const ufbx_mesh *mesh,
  4385. const ufbx_topo_edge *topo, size_t num_topo,
  4386. uint32_t *normal_indices, size_t num_normal_indices, bool assume_smooth);
  4387. // Compute normals given normal indices.
  4388. // You can use `ufbx_generate_normal_mapping()` to generate the normal indices.
  4389. ufbx_abi void ufbx_catch_compute_normals(ufbx_panic *panic, const ufbx_mesh *mesh, const ufbx_vertex_vec3 *positions,
  4390. const uint32_t *normal_indices, size_t num_normal_indices,
  4391. ufbx_vec3 *normals, size_t num_normals);
  4392. ufbx_abi void ufbx_compute_normals(const ufbx_mesh *mesh, const ufbx_vertex_vec3 *positions,
  4393. const uint32_t *normal_indices, size_t num_normal_indices,
  4394. ufbx_vec3 *normals, size_t num_normals);
  4395. // Subdivide a mesh using the Catmull-Clark subdivision `level` times.
  4396. ufbx_abi ufbx_mesh *ufbx_subdivide_mesh(const ufbx_mesh *mesh, size_t level, const ufbx_subdivide_opts *opts, ufbx_error *error);
  4397. // Free a mesh returned from `ufbx_subdivide_mesh()` or `ufbx_tessellate_nurbs_surface()`.
  4398. ufbx_abi void ufbx_free_mesh(ufbx_mesh *mesh);
  4399. // Increase the mesh reference count.
  4400. ufbx_abi void ufbx_retain_mesh(ufbx_mesh *mesh);
  4401. // Geometry caches
  4402. // Load geometry cache information from a file.
  4403. // As geometry caches can be massive, this does not actually read the data, but
  4404. // only seeks through the files to form the metadata.
  4405. ufbx_abi ufbx_geometry_cache *ufbx_load_geometry_cache(
  4406. const char *filename,
  4407. const ufbx_geometry_cache_opts *opts, ufbx_error *error);
  4408. ufbx_abi ufbx_geometry_cache *ufbx_load_geometry_cache_len(
  4409. const char *filename, size_t filename_len,
  4410. const ufbx_geometry_cache_opts *opts, ufbx_error *error);
  4411. // Free a geometry cache returned from `ufbx_load_geometry_cache()`.
  4412. ufbx_abi void ufbx_free_geometry_cache(ufbx_geometry_cache *cache);
  4413. // Increase the geometry cache reference count.
  4414. ufbx_abi void ufbx_retain_geometry_cache(ufbx_geometry_cache *cache);
  4415. // Read a frame from a geometry cache.
  4416. ufbx_abi size_t ufbx_read_geometry_cache_real(const ufbx_cache_frame *frame, ufbx_real *data, size_t num_data, const ufbx_geometry_cache_data_opts *opts);
  4417. ufbx_abi size_t ufbx_read_geometry_cache_vec3(const ufbx_cache_frame *frame, ufbx_vec3 *data, size_t num_data, const ufbx_geometry_cache_data_opts *opts);
  4418. // Sample the a geometry cache channel, linearly blending between adjacent frames.
  4419. ufbx_abi size_t ufbx_sample_geometry_cache_real(const ufbx_cache_channel *channel, double time, ufbx_real *data, size_t num_data, const ufbx_geometry_cache_data_opts *opts);
  4420. ufbx_abi size_t ufbx_sample_geometry_cache_vec3(const ufbx_cache_channel *channel, double time, ufbx_vec3 *data, size_t num_data, const ufbx_geometry_cache_data_opts *opts);
  4421. // DOM
  4422. // Find a DOM node given a name.
  4423. ufbx_abi ufbx_dom_node *ufbx_dom_find_len(const ufbx_dom_node *parent, const char *name, size_t name_len);
  4424. ufbx_abi ufbx_dom_node *ufbx_dom_find(const ufbx_dom_node *parent, const char *name);
  4425. // Utility
  4426. // Generate an index buffer for a flat vertex buffer.
  4427. // `streams` specifies one or more vertex data arrays, each stream must contain `num_indices` vertices.
  4428. // This function compacts the data within `streams` in-place, writing the deduplicated indices to `indices`.
  4429. ufbx_abi size_t ufbx_generate_indices(const ufbx_vertex_stream *streams, size_t num_streams, uint32_t *indices, size_t num_indices, const ufbx_allocator_opts *allocator, ufbx_error *error);
  4430. // Thread pool
  4431. // Run a single thread pool task.
  4432. // See `ufbx_thread_pool_run_fn` for more information.
  4433. ufbx_unsafe ufbx_abi void ufbx_thread_pool_run_task(ufbx_thread_pool_context ctx, uint32_t index);
  4434. // Get or set an arbitrary user pointer for the thread pool context.
  4435. // `ufbx_thread_pool_get_user_ptr()` returns `NULL` if unset.
  4436. ufbx_unsafe ufbx_abi void ufbx_thread_pool_set_user_ptr(ufbx_thread_pool_context ctx, void *user_ptr);
  4437. ufbx_unsafe ufbx_abi void *ufbx_thread_pool_get_user_ptr(ufbx_thread_pool_context ctx);
  4438. // -- Inline API
  4439. // Utility functions for reading geometry data for a single index.
  4440. ufbx_abi ufbx_real ufbx_catch_get_vertex_real(ufbx_panic *panic, const ufbx_vertex_real *v, size_t index);
  4441. ufbx_abi ufbx_vec2 ufbx_catch_get_vertex_vec2(ufbx_panic *panic, const ufbx_vertex_vec2 *v, size_t index);
  4442. ufbx_abi ufbx_vec3 ufbx_catch_get_vertex_vec3(ufbx_panic *panic, const ufbx_vertex_vec3 *v, size_t index);
  4443. ufbx_abi ufbx_vec4 ufbx_catch_get_vertex_vec4(ufbx_panic *panic, const ufbx_vertex_vec4 *v, size_t index);
  4444. // Utility functions for reading geometry data for a single index.
  4445. ufbx_inline ufbx_real ufbx_get_vertex_real(const ufbx_vertex_real *v, size_t index) { ufbx_assert(index < v->indices.count); return v->values.data[(int32_t)v->indices.data[index]]; }
  4446. ufbx_inline ufbx_vec2 ufbx_get_vertex_vec2(const ufbx_vertex_vec2 *v, size_t index) { ufbx_assert(index < v->indices.count); return v->values.data[(int32_t)v->indices.data[index]]; }
  4447. ufbx_inline ufbx_vec3 ufbx_get_vertex_vec3(const ufbx_vertex_vec3 *v, size_t index) { ufbx_assert(index < v->indices.count); return v->values.data[(int32_t)v->indices.data[index]]; }
  4448. ufbx_inline ufbx_vec4 ufbx_get_vertex_vec4(const ufbx_vertex_vec4 *v, size_t index) { ufbx_assert(index < v->indices.count); return v->values.data[(int32_t)v->indices.data[index]]; }
  4449. ufbx_abi ufbx_real ufbx_catch_get_vertex_w_vec3(ufbx_panic *panic, const ufbx_vertex_vec3 *v, size_t index);
  4450. ufbx_inline ufbx_real ufbx_get_vertex_w_vec3(const ufbx_vertex_vec3 *v, size_t index) { ufbx_assert(index < v->indices.count); return v->values_w.count > 0 ? v->values_w.data[(int32_t)v->indices.data[index]] : 0.0f; }
  4451. // Functions for converting an untyped `ufbx_element` to a concrete type.
  4452. // Returns `NULL` if the element is not that type.
  4453. ufbx_abi ufbx_unknown *ufbx_as_unknown(const ufbx_element *element);
  4454. ufbx_abi ufbx_node *ufbx_as_node(const ufbx_element *element);
  4455. ufbx_abi ufbx_mesh *ufbx_as_mesh(const ufbx_element *element);
  4456. ufbx_abi ufbx_light *ufbx_as_light(const ufbx_element *element);
  4457. ufbx_abi ufbx_camera *ufbx_as_camera(const ufbx_element *element);
  4458. ufbx_abi ufbx_bone *ufbx_as_bone(const ufbx_element *element);
  4459. ufbx_abi ufbx_empty *ufbx_as_empty(const ufbx_element *element);
  4460. ufbx_abi ufbx_line_curve *ufbx_as_line_curve(const ufbx_element *element);
  4461. ufbx_abi ufbx_nurbs_curve *ufbx_as_nurbs_curve(const ufbx_element *element);
  4462. ufbx_abi ufbx_nurbs_surface *ufbx_as_nurbs_surface(const ufbx_element *element);
  4463. ufbx_abi ufbx_nurbs_trim_surface *ufbx_as_nurbs_trim_surface(const ufbx_element *element);
  4464. ufbx_abi ufbx_nurbs_trim_boundary *ufbx_as_nurbs_trim_boundary(const ufbx_element *element);
  4465. ufbx_abi ufbx_procedural_geometry *ufbx_as_procedural_geometry(const ufbx_element *element);
  4466. ufbx_abi ufbx_stereo_camera *ufbx_as_stereo_camera(const ufbx_element *element);
  4467. ufbx_abi ufbx_camera_switcher *ufbx_as_camera_switcher(const ufbx_element *element);
  4468. ufbx_abi ufbx_marker *ufbx_as_marker(const ufbx_element *element);
  4469. ufbx_abi ufbx_lod_group *ufbx_as_lod_group(const ufbx_element *element);
  4470. ufbx_abi ufbx_skin_deformer *ufbx_as_skin_deformer(const ufbx_element *element);
  4471. ufbx_abi ufbx_skin_cluster *ufbx_as_skin_cluster(const ufbx_element *element);
  4472. ufbx_abi ufbx_blend_deformer *ufbx_as_blend_deformer(const ufbx_element *element);
  4473. ufbx_abi ufbx_blend_channel *ufbx_as_blend_channel(const ufbx_element *element);
  4474. ufbx_abi ufbx_blend_shape *ufbx_as_blend_shape(const ufbx_element *element);
  4475. ufbx_abi ufbx_cache_deformer *ufbx_as_cache_deformer(const ufbx_element *element);
  4476. ufbx_abi ufbx_cache_file *ufbx_as_cache_file(const ufbx_element *element);
  4477. ufbx_abi ufbx_material *ufbx_as_material(const ufbx_element *element);
  4478. ufbx_abi ufbx_texture *ufbx_as_texture(const ufbx_element *element);
  4479. ufbx_abi ufbx_video *ufbx_as_video(const ufbx_element *element);
  4480. ufbx_abi ufbx_shader *ufbx_as_shader(const ufbx_element *element);
  4481. ufbx_abi ufbx_shader_binding *ufbx_as_shader_binding(const ufbx_element *element);
  4482. ufbx_abi ufbx_anim_stack *ufbx_as_anim_stack(const ufbx_element *element);
  4483. ufbx_abi ufbx_anim_layer *ufbx_as_anim_layer(const ufbx_element *element);
  4484. ufbx_abi ufbx_anim_value *ufbx_as_anim_value(const ufbx_element *element);
  4485. ufbx_abi ufbx_anim_curve *ufbx_as_anim_curve(const ufbx_element *element);
  4486. ufbx_abi ufbx_display_layer *ufbx_as_display_layer(const ufbx_element *element);
  4487. ufbx_abi ufbx_selection_set *ufbx_as_selection_set(const ufbx_element *element);
  4488. ufbx_abi ufbx_selection_node *ufbx_as_selection_node(const ufbx_element *element);
  4489. ufbx_abi ufbx_character *ufbx_as_character(const ufbx_element *element);
  4490. ufbx_abi ufbx_constraint *ufbx_as_constraint(const ufbx_element *element);
  4491. ufbx_abi ufbx_audio_layer *ufbx_as_audio_layer(const ufbx_element *element);
  4492. ufbx_abi ufbx_audio_clip *ufbx_as_audio_clip(const ufbx_element *element);
  4493. ufbx_abi ufbx_pose *ufbx_as_pose(const ufbx_element *element);
  4494. ufbx_abi ufbx_metadata_object *ufbx_as_metadata_object(const ufbx_element *element);
  4495. #ifdef __cplusplus
  4496. }
  4497. #endif
  4498. // bindgen-disable
  4499. #if UFBX_CPP11
  4500. struct ufbx_string_view {
  4501. const char *data;
  4502. size_t length;
  4503. ufbx_string_view() : data(nullptr), length(0) { }
  4504. ufbx_string_view(const char *data_, size_t length_) : data(data_), length(length_) { }
  4505. UFBX_CONVERSION_TO_IMPL(ufbx_string_view)
  4506. };
  4507. ufbx_inline ufbx_scene *ufbx_load_file(ufbx_string_view filename, const ufbx_load_opts *opts, ufbx_error *error) { return ufbx_load_file_len(filename.data, filename.length, opts, error); }
  4508. ufbx_inline ufbx_prop *ufbx_find_prop(const ufbx_props *props, ufbx_string_view name) { return ufbx_find_prop_len(props, name.data, name.length); }
  4509. ufbx_inline ufbx_real ufbx_find_real(const ufbx_props *props, ufbx_string_view name, ufbx_real def) { return ufbx_find_real_len(props, name.data, name.length, def); }
  4510. ufbx_inline ufbx_vec3 ufbx_find_vec3(const ufbx_props *props, ufbx_string_view name, ufbx_vec3 def) { return ufbx_find_vec3_len(props, name.data, name.length, def); }
  4511. ufbx_inline int64_t ufbx_find_int(const ufbx_props *props, ufbx_string_view name, int64_t def) { return ufbx_find_int_len(props, name.data, name.length, def); }
  4512. ufbx_inline bool ufbx_find_bool(const ufbx_props *props, ufbx_string_view name, bool def) { return ufbx_find_bool_len(props, name.data, name.length, def); }
  4513. ufbx_inline ufbx_string ufbx_find_string(const ufbx_props *props, ufbx_string_view name, ufbx_string def) { return ufbx_find_string_len(props, name.data, name.length, def); }
  4514. ufbx_inline ufbx_blob ufbx_find_blob(const ufbx_props *props, ufbx_string_view name, ufbx_blob def) { return ufbx_find_blob_len(props, name.data, name.length, def); }
  4515. ufbx_inline ufbx_element *ufbx_find_prop_element(const ufbx_element *element, ufbx_string_view name, ufbx_element_type type) { return ufbx_find_prop_element_len(element, name.data, name.length, type); }
  4516. ufbx_inline ufbx_element *ufbx_find_element(const ufbx_scene *scene, ufbx_element_type type, ufbx_string_view name) { return ufbx_find_element_len(scene, type, name.data, name.length); }
  4517. ufbx_inline ufbx_node *ufbx_find_node(const ufbx_scene *scene, ufbx_string_view name) { return ufbx_find_node_len(scene, name.data, name.length); }
  4518. ufbx_inline ufbx_anim_stack *ufbx_find_anim_stack(const ufbx_scene *scene, ufbx_string_view name) { return ufbx_find_anim_stack_len(scene, name.data, name.length); }
  4519. ufbx_inline ufbx_material *ufbx_find_material(const ufbx_scene *scene, ufbx_string_view name) { return ufbx_find_material_len(scene, name.data, name.length); }
  4520. ufbx_inline ufbx_anim_prop *ufbx_find_anim_prop(const ufbx_anim_layer *layer, const ufbx_element *element, ufbx_string_view prop) { return ufbx_find_anim_prop_len(layer, element, prop.data, prop.length); }
  4521. ufbx_inline ufbx_prop ufbx_evaluate_prop(const ufbx_anim *anim, const ufbx_element *element, ufbx_string_view name, double time) { return ufbx_evaluate_prop_len(anim, element, name.data, name.length, time); }
  4522. ufbx_inline ufbx_texture *ufbx_find_prop_texture(const ufbx_material *material, ufbx_string_view name) { return ufbx_find_prop_texture_len(material, name.data, name.length); }
  4523. ufbx_inline ufbx_string ufbx_find_shader_prop(const ufbx_shader *shader, ufbx_string_view name) { return ufbx_find_shader_prop_len(shader, name.data, name.length); }
  4524. ufbx_inline ufbx_shader_prop_binding_list ufbx_find_shader_prop_bindings(const ufbx_shader *shader, ufbx_string_view name) { return ufbx_find_shader_prop_bindings_len(shader, name.data, name.length); }
  4525. ufbx_inline ufbx_shader_texture_input *ufbx_find_shader_texture_input(const ufbx_shader_texture *shader, ufbx_string_view name) { return ufbx_find_shader_texture_input_len(shader, name.data, name.length); }
  4526. ufbx_inline ufbx_geometry_cache *ufbx_load_geometry_cache(ufbx_string_view filename, const ufbx_geometry_cache_opts *opts, ufbx_error *error) { return ufbx_load_geometry_cache_len(filename.data, filename.length, opts, error); }
  4527. ufbx_inline ufbx_dom_node *ufbx_dom_find(const ufbx_dom_node *parent, ufbx_string_view name) { return ufbx_dom_find_len(parent, name.data, name.length); }
  4528. #endif
  4529. #if UFBX_CPP11
  4530. template <typename T>
  4531. struct ufbx_type_traits { enum { valid = 0 }; };
  4532. template<> struct ufbx_type_traits<ufbx_scene> {
  4533. enum { valid = 1 };
  4534. static void retain(ufbx_scene *ptr) { ufbx_retain_scene(ptr); }
  4535. static void free(ufbx_scene *ptr) { ufbx_free_scene(ptr); }
  4536. };
  4537. template<> struct ufbx_type_traits<ufbx_mesh> {
  4538. enum { valid = 1 };
  4539. static void retain(ufbx_mesh *ptr) { ufbx_retain_mesh(ptr); }
  4540. static void free(ufbx_mesh *ptr) { ufbx_free_mesh(ptr); }
  4541. };
  4542. template<> struct ufbx_type_traits<ufbx_line_curve> {
  4543. enum { valid = 1 };
  4544. static void retain(ufbx_line_curve *ptr) { ufbx_retain_line_curve(ptr); }
  4545. static void free(ufbx_line_curve *ptr) { ufbx_free_line_curve(ptr); }
  4546. };
  4547. template<> struct ufbx_type_traits<ufbx_geometry_cache> {
  4548. enum { valid = 1 };
  4549. static void retain(ufbx_geometry_cache *ptr) { ufbx_retain_geometry_cache(ptr); }
  4550. static void free(ufbx_geometry_cache *ptr) { ufbx_free_geometry_cache(ptr); }
  4551. };
  4552. template<> struct ufbx_type_traits<ufbx_anim> {
  4553. enum { valid = 1 };
  4554. static void retain(ufbx_anim *ptr) { ufbx_retain_anim(ptr); }
  4555. static void free(ufbx_anim *ptr) { ufbx_free_anim(ptr); }
  4556. };
  4557. template<> struct ufbx_type_traits<ufbx_baked_anim> {
  4558. enum { valid = 1 };
  4559. static void retain(ufbx_baked_anim *ptr) { ufbx_retain_baked_anim(ptr); }
  4560. static void free(ufbx_baked_anim *ptr) { ufbx_free_baked_anim(ptr); }
  4561. };
  4562. class ufbx_deleter {
  4563. public:
  4564. template <typename T>
  4565. void operator()(T *ptr) const {
  4566. static_assert(ufbx_type_traits<T>::valid, "ufbx_deleter() unsupported for type");
  4567. ufbx_type_traits<T>::free(ptr);
  4568. }
  4569. };
  4570. // RAII wrapper over refcounted ufbx types.
  4571. // Behaves like `std::unique_ptr<T>`.
  4572. template <typename T>
  4573. class ufbx_unique_ptr {
  4574. T *ptr;
  4575. using traits = ufbx_type_traits<T>;
  4576. static_assert(ufbx_type_traits<T>::valid, "ufbx_unique_ptr unsupported for type");
  4577. public:
  4578. ufbx_unique_ptr() noexcept : ptr(nullptr) { }
  4579. explicit ufbx_unique_ptr(T *ptr_) noexcept : ptr(ptr_) { }
  4580. ufbx_unique_ptr(ufbx_unique_ptr &&ref) noexcept : ptr(ref.ptr) { ref.ptr = nullptr; }
  4581. ~ufbx_unique_ptr() { traits::free(ptr); }
  4582. ufbx_unique_ptr &operator=(ufbx_unique_ptr &&ref) noexcept {
  4583. if (&ref == this) return *this;
  4584. ptr = ref.ptr;
  4585. ref.ptr = nullptr;
  4586. return *this;
  4587. }
  4588. void reset(T *new_ptr=nullptr) noexcept {
  4589. traits::free(ptr);
  4590. ptr = new_ptr;
  4591. }
  4592. void swap(ufbx_unique_ptr &ref) noexcept {
  4593. T *tmp = ptr;
  4594. ptr = ref.ptr;
  4595. ref.ptr = tmp;
  4596. }
  4597. T &operator*() const noexcept { return *ptr; }
  4598. T *operator->() const noexcept { return ptr; }
  4599. T *get() const noexcept { return ptr; }
  4600. explicit operator bool() const noexcept { return ptr != nullptr; }
  4601. };
  4602. // Behaves like `std::shared_ptr<T>` except uses ufbx's internal reference counting,
  4603. // so it is half the size of a standard `shared_ptr` but might be marginally slower.
  4604. template <typename T>
  4605. class ufbx_shared_ptr {
  4606. T *ptr;
  4607. using traits = ufbx_type_traits<T>;
  4608. static_assert(ufbx_type_traits<T>::valid, "ufbx_shared_ptr unsupported for type");
  4609. public:
  4610. ufbx_shared_ptr() noexcept : ptr(nullptr) { }
  4611. explicit ufbx_shared_ptr(T *ptr_) noexcept : ptr(ptr_) { }
  4612. ufbx_shared_ptr(const ufbx_shared_ptr &ref) noexcept : ptr(ref.ptr) { traits::retain(ref.ptr); }
  4613. ufbx_shared_ptr(ufbx_shared_ptr &&ref) noexcept : ptr(ref.ptr) { ref.ptr = nullptr; }
  4614. ~ufbx_shared_ptr() { traits::free(ptr); }
  4615. ufbx_shared_ptr &operator=(const ufbx_shared_ptr &ref) noexcept {
  4616. if (&ref == this) return *this;
  4617. traits::free(ptr);
  4618. traits::retain(ref.ptr);
  4619. ptr = ref.ptr;
  4620. return *this;
  4621. }
  4622. ufbx_shared_ptr &operator=(ufbx_shared_ptr &&ref) noexcept {
  4623. if (&ref == this) return *this;
  4624. ptr = ref.ptr;
  4625. ref.ptr = nullptr;
  4626. return *this;
  4627. }
  4628. void reset(T *new_ptr=nullptr) noexcept {
  4629. traits::free(ptr);
  4630. ptr = new_ptr;
  4631. }
  4632. void swap(ufbx_shared_ptr &ref) noexcept {
  4633. T *tmp = ptr;
  4634. ptr = ref.ptr;
  4635. ref.ptr = tmp;
  4636. }
  4637. T &operator*() const noexcept { return *ptr; }
  4638. T *operator->() const noexcept { return ptr; }
  4639. T *get() const noexcept { return ptr; }
  4640. explicit operator bool() const noexcept { return ptr != nullptr; }
  4641. };
  4642. #endif
  4643. // bindgen-enable
  4644. // -- Properties
  4645. // Names of common properties in `ufbx_props`.
  4646. // Some of these differ from ufbx interpretations.
  4647. // Local translation.
  4648. // Used by: `ufbx_node`
  4649. #define UFBX_Lcl_Translation "Lcl Translation"
  4650. // Local rotation expressed in Euler degrees.
  4651. // Used by: `ufbx_node`
  4652. // The rotation order is defined by the `UFBX_RotationOrder` property.
  4653. #define UFBX_Lcl_Rotation "Lcl Rotation"
  4654. // Local scaling factor, 3D vector.
  4655. // Used by: `ufbx_node`
  4656. #define UFBX_Lcl_Scaling "Lcl Scaling"
  4657. // Euler rotation interpretation, used by `UFBX_Lcl_Rotation`.
  4658. // Used by: `ufbx_node`, enum value `ufbx_rotation_order`.
  4659. #define UFBX_RotationOrder "RotationOrder"
  4660. // Scaling pivot: point around which scaling is performed.
  4661. // Used by: `ufbx_node`.
  4662. #define UFBX_ScalingPivot "ScalingPivot"
  4663. // Scaling pivot: point around which rotation is performed.
  4664. // Used by: `ufbx_node`.
  4665. #define UFBX_RotationPivot "RotationPivot"
  4666. // Scaling offset: translation added after scaling is performed.
  4667. // Used by: `ufbx_node`.
  4668. #define UFBX_ScalingOffset "ScalingOffset"
  4669. // Rotation offset: translation added after rotation is performed.
  4670. // Used by: `ufbx_node`.
  4671. #define UFBX_RotationOffset "RotationOffset"
  4672. // Pre-rotation: Rotation applied _after_ `UFBX_Lcl_Rotation`.
  4673. // Used by: `ufbx_node`.
  4674. // Affected by `UFBX_RotationPivot` but not `UFBX_RotationOrder`.
  4675. #define UFBX_PreRotation "PreRotation"
  4676. // Post-rotation: Rotation applied _before_ `UFBX_Lcl_Rotation`.
  4677. // Used by: `ufbx_node`.
  4678. // Affected by `UFBX_RotationPivot` but not `UFBX_RotationOrder`.
  4679. #define UFBX_PostRotation "PostRotation"
  4680. // Controls whether the node should be displayed or not.
  4681. // Used by: `ufbx_node`.
  4682. #define UFBX_Visibility "Visibility"
  4683. // Weight of an animation layer in percentage (100.0 being full).
  4684. // Used by: `ufbx_anim_layer`.
  4685. #define UFBX_Weight "Weight"
  4686. // Blend shape deformation weight (100.0 being full).
  4687. // Used by: `ufbx_blend_channel`.
  4688. #define UFBX_DeformPercent "DeformPercent"
  4689. #if defined(_MSC_VER)
  4690. #pragma warning(pop)
  4691. #elif defined(__clang__)
  4692. #pragma clang diagnostic pop
  4693. #elif defined(__GNUC__)
  4694. #pragma GCC diagnostic pop
  4695. #endif
  4696. #endif