/* Ċ Open ĠAsset ĠImport ĠLibrary Ġ( assimp ) Ċ ---------------------------------------------------------------------- Ċ Ċ Copyright Ġ( c ) Ġ 2 0 0 6 - 2 0 1 7 , Ġass imp Ġteam Ċ Ċ All Ġrights Ġreserved . Ċ Ċ Red ist ribution Ġand Ġuse Ġof Ġthis Ġsoftware Ġin Ġsource Ġand Ġbinary Ġforms , Ċ with Ġor Ġwithout Ġmodification , Ġare Ġpermitted Ġprovided Ġthat Ġthe Ċ following Ġconditions Ġare Ġmet : Ċ Ċ * ĠRedistributions Ġof Ġsource Ġcode Ġmust Ġretain Ġthe Ġabove ĊĠ Ġcopyright Ġnotice , Ġthis Ġlist Ġof Ġconditions Ġand Ġthe ĊĠ Ġfollowing Ġdisclaimer . Ċ Ċ * ĠRedistributions Ġin Ġbinary Ġform Ġmust Ġreproduce Ġthe Ġabove ĊĠ Ġcopyright Ġnotice , Ġthis Ġlist Ġof Ġconditions Ġand Ġthe ĊĠ Ġfollowing Ġdisclaimer Ġin Ġthe Ġdocumentation Ġand / or Ġother ĊĠ Ġmaterials Ġprovided Ġwith Ġthe Ġdistribution . Ċ Ċ * ĠNeither Ġthe Ġname Ġof Ġthe Ġass imp Ġteam , Ġnor Ġthe Ġnames Ġof Ġits ĊĠ Ġcontributors Ġmay Ġbe Ġused Ġto Ġendorse Ġor Ġpromote Ġproducts ĊĠ Ġderived Ġfrom Ġthis Ġsoftware Ġwithout Ġspecific Ġprior ĊĠ Ġwritten Ġpermission Ġof Ġthe Ġass imp Ġteam . Ċ Ċ THIS ĠSOFTWARE ĠIS ĠPROVIDED ĠBY ĠTHE ĠCOPYRIGHT ĠHOLDERS ĠAND ĠCONTRIBUTORS Ċ " AS ĠIS " ĠAND ĠANY ĠEXPRESS ĠOR ĠIMPLIED ĠWARRANTIES , ĠINCLUDING , ĠBUT ĠNOT Ċ LIMIT ED ĠTO , ĠTHE ĠIMPLIED ĠWARRANTIES ĠOF ĠMERCHANTABILITY ĠAND ĠFITNESS ĠFOR Ċ A ĠPARTICULAR ĠPURPOSE ĠARE ĠDISCLAIMED . ĠIN ĠNO ĠEVENT ĠSHALL ĠTHE ĠCOPYRIGHT Ċ OWNER ĠOR ĠCONTRIBUTORS ĠBE ĠLIABLE ĠFOR ĠANY ĠDIRECT , ĠINDIRECT , ĠINCIDENTAL , Ċ SPECIAL , ĠEXEMPLARY , ĠOR ĠCONSEQUENTIAL ĠDAMAGES Ġ( INCLUDING , ĠBUT ĠNOT Ċ LIMIT ED ĠTO , ĠPROCUREMENT ĠOF ĠSUBSTITUTE ĠGOODS ĠOR ĠSERVICES ; ĠLOSS ĠOF ĠUSE , Ċ DATA , ĠOR ĠPROFITS ; ĠOR ĠBUSINESS ĠINTERRUPTION ) ĠHOWEVER ĠCAUSED ĠAND ĠON ĠANY Ċ THE ORY ĠOF ĠLIABILITY , ĠWHETHER ĠIN ĠCONTRACT , ĠSTRICT ĠLIABILITY , ĠOR ĠTORT Ċ ( INCLUDING ĠNEGLIGENCE ĠOR ĠOTHERWISE ) ĠARISING ĠIN ĠANY ĠWAY ĠOUT ĠOF ĠTHE ĠUSE Ċ OF ĠTHIS ĠSOFTWARE , ĠEVEN ĠIF ĠADVISED ĠOF ĠTHE ĠPOSSIBILITY ĠOF ĠSUCH ĠDAMAGE . Ċ Ċ ---------------------------------------------------------------------- Ċ */ Ċ Ċ package Ġass imp . format . md 5 Ċ Ċ import Ġass imp .* Ċ import Ġass imp . format . Ai Config Ċ import Ġglm _. detail . Random . int Ċ import Ġglm _. i Ċ import Ġuno . buffer . destroy Ċ import Ġjava . io . BufferedReader Ċ import Ġjava . io . File Ċ import Ġjava . io . IOException Ċ import Ġjava . net . URI Ċ import Ġjava . nio . Buffer Ċ import Ġjava . nio . ByteBuffer Ċ import Ġkotlin . math . sqrt Ċ Ċ // ĠMinimum Ġweight Ġvalue . ĠWe ights Ġinside Ġ[- n Ġ... Ġn ] Ġare Ġignored Ċ val ĠAI _ MD 5 _ WEIGHT _ EPS ILON Ġ= Ġ 1 e - 5 f Ċ Ċ /** ĠImport er Ġclass Ġfor Ġthe ĠMD 5 Ġfile Ġformat Ġ*/ Ċ class ĠMd 5 Importer Ġ: ĠBase Importer () Ġ{ ĊĊĠĠĠ Ġ/** ĠPath Ġto Ġthe Ġfile , Ġexcluding Ġthe Ġfile Ġextension Ġbut Ġwith Ġthe Ġdot Ġ*/ ĊĠĠĠ Ġvar Ġfile Ġ= Ġ"" ĊĠĠĠ Ġ/** ĠBuffer Ġto Ġhold Ġthe Ġloaded Ġfile Ġ*/ ĊĠĠĠ Ġvar Ġbuffer Ġ= ĠArrayList < String >() ĊĠĠĠ Ġ/** ĠSize Ġof Ġthe Ġfile Ġ*/ ĊĠĠĠ Ġvar ĠfileSize Ġ= Ġ 0 ĊĠĠĠ Ġ/** ĠCurrent Ġline Ġnumber . ĠFor Ġdebugging Ġpurposes Ġ*/ ĊĠĠĠ Ġvar Ġi LineNumber Ġ= Ġ 0 ĊĠĠĠ Ġ/** ĠScene Ġto Ġbe Ġfilled Ġ*/ ĊĠĠĠ Ġvar Ġscene : ĠA i Scene ? Ġ= Ġnull ĊĠĠĠ Ġ/** Ġtrue Ġif Ġa ĠMD 5 MESH Ġfile Ġhas Ġalready Ġbeen Ġparsed Ġ*/ ĊĠĠĠ Ġvar Ġhad MD 5 Mesh Ġ= Ġfalse ĊĠĠĠ Ġ/** Ġtrue Ġif Ġa ĠMD 5 ANIM Ġfile Ġhas Ġalready Ġbeen Ġparsed Ġ*/ ĊĠĠĠ Ġvar Ġhad MD 5 Anim Ġ= Ġfalse ĊĠĠĠ Ġ/** Ġtrue Ġif Ġa ĠMD 5 CAMERA Ġfile Ġhas Ġalready Ġbeen Ġparsed Ġ*/ ĊĠĠĠ Ġvar Ġhad MD 5 Camera Ġ= Ġfalse ĊĠĠĠ Ġ/** Ġconfiguration Ġoption : Ġprevent Ġanim Ġauto load Ġ*/ ĊĠĠĠ Ġvar Ġconfig No Auto Load Ġ= Ġfalse ĊĊĠĠĠ Ġoverride Ġfun Ġcan Read ( file : ĠString , Ġio System : ĠIO System , Ġcheck Sig : ĠBoolean ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġextension Ġ= Ġget Extension ( file ) ĊĠĠĠĠĠĠĠ Ġif Ġ( extension Ġ== Ġ" md 5 anim " Ġ|| Ġextension Ġ== Ġ" md 5 mesh " Ġ|| Ġextension Ġ== Ġ" md 5 camera ") Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġelse Ġif Ġ( extension . isNotEmpty () Ġ|| Ġcheck Sig ) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠ ĠTODO () Ġsilent ed Ġto Ġpass Ġtests Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġconst Ġchar * Ġtokens [] Ġ= Ġ{" MD 5 Version "}; Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠSearch File Header For Token ( p IO Handler , p File , tokens , 1 ); ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠReturn Ġimporter Ġmeta Ġinformation . ĊĠĠĠĠ Ġ* ĠSee ĠBase Importer :: info Ġfor Ġthe Ġdetails ĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġval Ġinfo ĊĠĠĠĠĠĠĠ Ġget () Ġ= ĠA i Importer Desc ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname Ġ= Ġ" Do om Ġ 3 Ġ/ ĠMD 5 ĠMesh ĠImport er ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflags Ġ= ĠA i Importer Flags . Support Binary Fl avour . i , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile Extensions Ġ= ĠlistOf (" md 5 mesh ", Ġ" md 5 camera ", Ġ" md 5 anim ") ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠ Ġ/** ĠCalled Ġprior Ġto ĠRead File (). ĊĠĠĠĠ Ġ* Ġ ĠThe Ġfunction Ġis Ġa Ġrequest Ġto Ġthe Ġimporter Ġto Ġupdate Ġits Ġconfiguration Ġbas ing Ġon Ġthe ĠImport er 's Ġconfiguration ĊĠĠĠĠ Ġ* Ġ Ġproperty Ġlist . ĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġsetup Properties ( imp : ĠImport er ) Ġ{ ĊĠĠĠĠĠĠĠ Ġconfig No Auto Load Ġ= Ġimp [ Ai Config . Import . MD 5 _ NO _ ANIM _ AUTO LOAD ] Ġ?: Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠImports Ġthe Ġgiven Ġfile Ġinto Ġthe Ġgiven Ġscene Ġstructure . ĊĠĠĠĠ Ġ* Ġ ĠSee ĠBase Importer :: intern ReadFile () Ġfor Ġdetails ĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġintern ReadFile ( file : ĠString , Ġio System : ĠIO System , Ġscene : ĠA i Scene ) Ġ{ ĊĊĠĠĠĠĠĠĠ Ġthis . scene Ġ= Ġscene ĊĠĠĠĠĠĠĠ Ġhad MD 5 Mesh Ġ= Ġfalse Ġ// ĠTODO Ġremove ? ĊĠĠĠĠĠĠĠ Ġhad MD 5 Anim Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġhad MD 5 Camera Ġ= Ġfalse ĊĊĠĠĠĠĠĠĠ Ġval Ġextension Ġ= Ġget Extension ( file ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġremove Ġthe Ġfile Ġextension ĊĠĠĠĠĠĠĠ Ġval Ġpos Ġ= Ġfile . lastIndexOf ('.') ĊĠĠĠĠĠĠĠ Ġthis . file Ġ= Ġif Ġ( pos Ġ== Ġ- 1 ) Ġfile Ġelse Ġfile . substring ( 0 , Ġpos Ġ+ Ġ 1 ) ĊĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( extension Ġ== Ġ" md 5 camera ") Ġload MD 5 Camera File ( io System ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġif Ġ( config No Auto Load Ġ|| Ġextension Ġ== Ġ" md 5 anim ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġdetermine Ġfile Ġextension Ġand Ġprocess Ġjust Ġ* one * Ġfile ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( extension . isEmpty ()) Ġthrow ĠError (" Failure , Ġneed Ġfile Ġextension Ġto Ġdetermine ĠMD 5 Ġpart Ġtype ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( extension Ġ== Ġ" md 5 anim ") Ġload MD 5 Anim File ( io System ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġif Ġ( extension Ġ== Ġ" md 5 mesh ") Ġload MD 5 Mesh File ( io System ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġload MD 5 Mesh File ( io System ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġload MD 5 Anim File ( io System ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exc : ĠException ) Ġ{ Ġ// Ġstd :: exception , ĠAss imp :: Dead ly Import Error ĊĠĠĠĠĠĠĠĠĠĠĠ Ġun load File From Memory () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠError ( exc ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// Ġmake Ġsure Ġwe Ġhave Ġat Ġleast Ġone Ġfile ĊĠĠĠĠĠĠĠ Ġif Ġ(! had MD 5 Mesh Ġ&& Ġ! had MD 5 Anim Ġ&& Ġ! had MD 5 Camera ) Ġthrow ĠError (" Failed Ġto Ġread Ġvalid Ġcontents Ġout Ġof Ġthis ĠMD 5 * Ġfile ") ĊĠĠĠĠĠĠĠ Ġ// ĠNow Ġrotate Ġthe Ġwhole Ġscene Ġ 9 0 Ġdegrees Ġaround Ġthe Ġx Ġaxis Ġto Ġmatch Ġour Ġinternal Ġcoordinate Ġsystem ĊĠĠĠĠĠĠĠ Ġscene . root Node . transformation . put ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 1 f , Ġ 0 f , Ġ 0 f , Ġ 0 f , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 0 f , Ġ 0 f , Ġ- 1 f , Ġ 0 f , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 0 f , Ġ 1 f , Ġ 0 f , Ġ 0 f , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 0 f , Ġ 0 f , Ġ 0 f , Ġ 1 f ) ĊĠĠĠĠĠĠĠ Ġ// Ġthe Ġoutput Ġscene Ġwouldn 't Ġpass Ġthe Ġvalidation Ġwithout Ġthis Ġflag ĊĠĠĠĠĠĠĠ Ġif Ġ(! had MD 5 Mesh ) Ġscene . flags Ġ= Ġscene . flags Ġor ĠAI _ SC ENE _ FLAGS _ IN COMPLETE ĊĠĠĠĠĠĠĠ Ġ// Ġclean Ġthe Ġinstance Ġ-- Ġthe ĠBase Importer Ġinstance Ġmay Ġbe Ġreused Ġlater . ĊĠĠĠĠĠĠĠ Ġun load File From Memory () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠLoad Ġa Ġ*. MD 5 MESH Ġfile . ĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġload MD 5 Mesh File ( io System : ĠIO System ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// val Ġfile Ġ= ĠFile ( file Ġ+ Ġ" md 5 mesh ") ĊĠĠĠĠĠĠĠ Ġval Ġio File Ġ: ĠIO Stream ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġio File Ġ= Ġio System . open ( file Ġ+ Ġ" md 5 mesh ") ĊĠĠĠĠĠĠĠ Ġ} Ġcatch ( e Ġ: ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCheck Ġwhether Ġwe Ġcan Ġread Ġfrom Ġthe Ġfile ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . warn Ġ{ Ġ" Failed Ġto Ġaccess ĠMD 5 MESH Ġfile : Ġ$ file " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġload File Into Memory ( io File . reader ()) ĊĠĠĠĠĠĠĠ Ġhad MD 5 Mesh Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠ Ġ// Ġnow Ġconstruct Ġa Ġparser Ġand Ġparse Ġthe Ġfile ĊĠĠĠĠĠĠĠ Ġval Ġparser Ġ= ĠMD 5 Parser ( buffer ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġload Ġthe Ġmesh Ġinformation Ġfrom Ġit ĊĠĠĠĠĠĠĠ Ġval Ġmesh Parser Ġ= ĠMD 5 Mesh Parser ( parser . sections ) ĊĊĠĠĠĠĠĠĠ Ġval Ġscene Ġ= Ġscene !! ĊĊĠĠĠĠĠĠĠ Ġ// Ġcreate Ġthe Ġbone Ġhierarchy Ġ- Ġfirst Ġthe Ġroot Ġnode Ġand Ġdummy Ġnodes Ġfor Ġall Ġmeshes ĊĠĠĠĠĠĠĠ Ġscene . root Node Ġ= ĠA i Node ("< MD 5 _ Root > "). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnum Children Ġ= Ġ 2 ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġchildren . add ( Ai Node (). apply Ġ{ Ġname Ġ= Ġ"< MD 5 _ Mesh >" Ġ}) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġbuild Ġthe Ġhierarchy Ġfrom Ġthe ĠMD 5 MESH Ġfile ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchildren . add ( Ai Node (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname Ġ= Ġ"< MD 5 _ Hierarchy >" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġattach Child s _ Mesh (- 1 , Ġthis , Ġmesh Parser . joints ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġscene . root Node . children [ 0 ]. parent Ġ= Ġscene . root Node ĊĠĠĠĠĠĠĠ Ġscene . root Node . children [ 1 ]. parent Ġ= Ġscene . root Node ĊĊĠĠĠĠĠĠĠ Ġ// ĠFIX : ĠMD 5 Ġfiles Ġexported Ġfrom ĠBl ender Ġcan Ġhave Ġempty Ġmeshes ĊĠĠĠĠĠĠĠ Ġscene . num Materials Ġ= Ġmesh Parser . meshes . filter Ġ{ Ġit . faces . isNotEmpty () Ġ&& Ġit . vertices . isNotEmpty () Ġ}. count () ĊĊĠĠĠĠĠĠĠ Ġ// Ġgenerate Ġall Ġmeshes ĊĠĠĠĠĠĠĠ Ġscene . num Mes hes Ġ= Ġscene . num Materials ĊĊĠĠĠĠĠĠĠ Ġ// Ġ Ġstorage Ġfor Ġnode Ġmesh Ġindices ĊĠĠĠĠĠĠĠ Ġwith ( scene . root Node . children [ 0 ]) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnum Mes hes Ġ= Ġscene . num Mes hes ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmeshes Ġ= ĠInt Array ( num Mes hes , Ġ{ Ġit Ġ}) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġvar Ġn Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġmesh Parser . meshes . filter Ġ{ Ġit . faces . isNotEmpty () Ġ|| Ġit . vertices . isNotEmpty () Ġ}. forEach Ġ{ Ġsrc Ġ-> ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmesh Ġ= ĠA i Mesh () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġscene . meshes . add ( mesh . apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprimitive Types Ġ= ĠA i Primitive Type . TRI ANGLE . i ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġgenerate Ġunique Ġvertices Ġin Ġour Ġinternal Ġverbose Ġformat ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmake Data Unique ( src ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnum Vertices Ġ= Ġsrc . vertices . size ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcopy Ġtexture Ġcoordinates ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmesh . texture Coords . add ( Mutable List ( src . vertices . size , Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwith ( src . vertices [ it ]) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfloat ArrayOf ( uv . x , Ġ 1 f Ġ- Ġuv . y ) Ġ// ĠD 3 D Ġto ĠOpenGL ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ})) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġsort Ġall Ġbone Ġweights Ġ- Ġper Ġbone ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpi Count Ġ= ĠInt Array ( mesh Parser . joints . size ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġsrc . vertices . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( w Ġin Ġit . first Weight Ġuntil Ġit . first Weight Ġ+ Ġit . num Weights ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdesc Ġ= Ġsrc . weights [ w ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/* ĠFIX Ġfor Ġsome Ġinvalid Ġexport ers Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(!( desc . weight Ġ< ĠAI _ MD 5 _ WEIGHT _ EPS ILON Ġ&& Ġdesc . weight Ġ>= Ġ- AI _ MD 5 _ WEIGHT _ EPS ILON )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ++ pi Count [ desc . bone ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcheck Ġhow Ġmany Ġwe Ġwill Ġneed ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( p Ġin Ġ 0 Ġuntil Ġmesh Parser . joints . size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( pi Count [ p ] Ġ!= Ġ 0 ) Ġmesh . num B ones ++ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( mesh . num B ones Ġ!= Ġ 0 ) Ġ{ Ġ// Ġjust Ġfor Ġsafety ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġh Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( q Ġin Ġmesh Parser . joints . indices ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( pi Count [ q ] Ġ== Ġ 0 ) Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmesh . bones . add ( A iB one (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnum Weights Ġ= Ġpi Count [ q ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġweights Ġ= ĠMutable List ( num Weights , Ġ{ ĠA i Vertex Weight () Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname Ġ= Ġmesh Parser . joints [ q ]. name ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoffset Matrix Ġput Ġmesh Parser . joints [ q ]. inv Transform ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġstore Ġthe Ġindex Ġfor Ġlater Ġuse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbone Src Ġ= Ġmesh Parser . joints [ q ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbone Src . map Ġ= Ġh ++ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcompute Ġw - component Ġof Ġquaternion ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbone Src . rotation Qu at ĠconvertTo Ġbone Src . rotation Qu at Converted ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġp vi Ġ= Ġ- 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( it Ġin Ġsrc . vertices ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcompute Ġthe Ġfinal Ġvertex Ġposition Ġfrom Ġall Ġsingle Ġweights ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpv Ġ= ĠA i Vector 3 D () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmesh . vertices . add ( pv ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġp vi ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthere Ġare Ġmodels Ġwhich Ġhave Ġweights Ġwhich Ġdon 't Ġsum Ġto Ġ 1 Ġ... ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsum Ġ= Ġ( it . first Weight Ġuntil Ġit . first Weight Ġ+ Ġit . num Weights ). map Ġ{ Ġsrc . weights [ it ]. weight Ġ}. sum () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( sum Ġ== Ġ 0 f ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . error Ġ{ Ġ" MD 5 MESH : ĠThe Ġsum Ġof Ġall Ġvertex Ġbone Ġweights Ġis Ġ 0 " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġprocess Ġbone Ġweights ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( w Ġin Ġit . first Weight Ġuntil Ġit . first Weight Ġ+ Ġit . num Weights ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( w Ġ>= Ġsrc . weights . size ) Ġthrow ĠError (" MD 5 MESH : ĠInvalid Ġweight Ġindex ") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdesc Ġ= Ġsrc . weights [ w ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( desc . weight Ġ< ĠAI _ MD 5 _ WEIGHT _ EPS ILON Ġ&& Ġdesc . weight Ġ>= Ġ- AI _ MD 5 _ WEIGHT _ EPS ILON ) Ġcontinue ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Weight Ġ= Ġdesc . weight Ġ/ Ġsum ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġtransform Ġthe Ġlocal Ġposition Ġinto Ġworld space ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbone Src Ġ= Ġmesh Parser . joints [ desc . bone ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġv Ġ= Ġbone Src . rotation Qu at Converted Ġrotate Ġdesc . offset Position ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġuse Ġthe Ġoriginal Ġweight Ġto Ġcompute Ġthe Ġvertex Ġposition Ġ( some ĠMD 5 s Ġseem Ġto Ġdepend Ġon Ġthe Ġinvalid Ġweight Ġvalues Ġ...) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpv Ġ+= Ġ( bone Src . position XYZ Ġ+ Ġv ) Ġ* Ġdesc . weight ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmesh . bones [ bone Src . map ]. weights [ p vi ]. apply Ġ{ Ġvertex Id Ġ= Ġp vi ; Ġweight Ġ= Ġnew Weight ; Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/* Ġ Ġnow Ġsetup Ġall Ġfaces Ġ- Ġwe Ġcan Ġdirectly Ġcopy Ġthe Ġlist ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( how ever , Ġtake Ġcare Ġthat Ġthe Ġai Face Ġdestructor Ġdoesn 't Ġdelete Ġthe Ġm Indices Ġarray ) ĠĠĠĠĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmesh . num Faces Ġ= Ġsrc . faces . size Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( c Ġin Ġ 0 Ġuntil Ġmesh . num Faces ) ĠTODO Ġcheck ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmesh . faces . addAll ( src . faces ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġgenerate Ġa Ġmaterial Ġfor Ġthe Ġmesh ĊĠĠĠĠĠĠĠĠĠĠĠ Ġscene . materials . add ( Ai Material (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/* Ġ Ġinsert Ġthe Ġtypical Ġdo om 3 Ġtextures : ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġn nn _ local . t ga Ġ Ġ- Ġnormal Ġmap ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġn nn _ h . t ga ĠĠĠĠĠ Ġ- Ġheight Ġmap ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġn nn _ s . t ga ĠĠĠĠĠ Ġ- Ġspecular Ġmap ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġn nn _ d . t ga ĠĠĠĠĠ Ġ- Ġdiffuse Ġmap Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( src . shader . isNotEmpty () Ġ&& Ġ! src . shader . contains ('. ')) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtextures . add ( Ai Material . Texture ( type Ġ= ĠA i Texture . Type . normals , Ġfile Ġ= Ġ"${ src . shader }_ local . t ga ")) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtextures . add ( Ai Material . Texture ( type Ġ= ĠA i Texture . Type . specular , Ġfile Ġ= Ġ"${ src . shader }_ s . t ga ")) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtextures . add ( Ai Material . Texture ( type Ġ= ĠA i Texture . Type . diffuse , Ġfile Ġ= Ġ"${ src . shader }_ d . t ga ")) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtextures . add ( Ai Material . Texture ( type Ġ= ĠA i Texture . Type . height , Ġfile Ġ= Ġ"${ src . shader }_ h . t ga ")) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġset Ġthis Ġalso Ġas Ġmaterial Ġname ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname Ġ= Ġsrc . shader ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġtextures . add ( Ai Material . Texture ( file Ġ= Ġsrc . shader )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmesh . material Index Ġ= Ġn ++ ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġin fix Ġfun ĠA i Quaternion . rotate ( v : ĠA i Vector 3 D ): ĠA i Vector 3 D Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġq 2 Ġ= ĠA i Quaternion ( 0 f , Ġv ) ĊĠĠĠĠĠĠĠ Ġval Ġq inv Ġ= ĠA i Quaternion ( this ). apply Ġ{ Ġconj ug ate Assign () Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġq Ġ= Ġtimes ( q 2 ) ĊĠĠĠĠĠĠĠ Ġq Ġtimes Assign Ġq inv ĊĠĠĠĠĠĠĠ Ġreturn ĠA i Vector 3 D ( q . x , Ġq . y , Ġq . z ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠLoad Ġa Ġ*. MD 5 ANIM Ġfile . ĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġload MD 5 Anim File ( io System : ĠIO System ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġio File Ġ: ĠIO Stream ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġio File Ġ= Ġio System . open ( file Ġ+ Ġ" md 5 anim ") ĊĠĠĠĠĠĠĠ Ġ} Ġcatch ( e Ġ: ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCheck Ġwhether Ġwe Ġcan Ġread Ġfrom Ġthe Ġfile ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . warn Ġ{ Ġ" Failed Ġto Ġaccess ĠMD 5 ANIM Ġfile : Ġ$ file " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġload File Into Memory ( io File . reader ()) ĊĊĠĠĠĠĠĠĠ Ġ// Ġparse Ġthe Ġbasic Ġfile Ġstructure ĊĠĠĠĠĠĠĠ Ġval Ġparser Ġ= ĠMD 5 Parser ( buffer ) ĊĠĠĠĠĠĠĠ ĠTODO () ĊĠĠĠĠĠĠĠ Ġ// Ġload Ġthe Ġanimation Ġinformation Ġfrom Ġthe Ġparse Ġtree Ċ // ĠĠĠĠĠĠĠ Ġval Ġanim Parser Ġ= ĠMD 5 Anim Parser Ġ( parser . sections ) Ċ // Ċ // ĠĠĠĠĠĠĠ Ġ// Ġgenerate Ġand Ġfill Ġthe Ġoutput Ġanimation Ċ // ĠĠĠĠĠĠĠ Ġif Ġ( anim Parser . m Animated B ones . empty () Ġ|| Ġanim Parser . m Frames . empty () Ġ|| Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġanim Parser . m Base Frames . size () Ġ!= Ġanim Parser . m Animated B ones . size ()) Ġ Ġ{ Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ ĠDefault Logger :: get ()-> error (" MD 5 ANIM : ĠNo Ġframes Ġor Ġanimated Ġbones Ġloaded ") Ċ // ĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġelse Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġb H ad MD 5 Anim Ġ= Ġtrue Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġp Scene -> m Animations Ġ= Ġnew Ġai Animation *[ p Scene -> m Num Animations Ġ= Ġ 1 ] Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġai Animation * Ġanim Ġ= Ġp Scene -> m Animations [ 0 ] Ġ= Ġnew Ġai Animation () Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġanim -> m Num Channels Ġ= Ġ( unsigned Ġint ) anim Parser . m Animated B ones . size () Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġanim -> m Channels Ġ= Ġnew Ġai Node Anim *[ anim -> m Num Channels ] Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( unsigned Ġint Ġi Ġ= Ġ 0 ; Ġi Ġ< Ġanim -> m Num Channels ;++ i ) ĠĠĠ Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġai Node Anim * Ġnode Ġ= Ġanim -> m Channels [ i ] Ġ= Ġnew Ġai Node Anim () Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnode -> m NodeName Ġ= Ġai String ( Ġanim Parser . m Animated B ones [ i ]. m Name Ġ) Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġallocate Ġstorage Ġfor Ġthe Ġkey frames Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnode -> m Position Keys Ġ= Ġnew Ġai Vector Key [ anim Parser . m Frames . size ()] Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnode -> m Rotation Keys Ġ= Ġnew Ġai Qu at Key [ anim Parser . m Frames . size ()] Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ 1 Ġtick Ġ== Ġ 1 Ġframe Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġanim -> m Ticks PerSecond Ġ= Ġanim Parser . f Frame Rate Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( Frame List :: const _ iterator Ġiter Ġ= Ġanim Parser . m Frames . begin (), Ġiter End Ġ= Ġanim Parser . m Frames . end (); iter Ġ!= Ġiter End ;++ iter ){ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdouble Ġd Time Ġ= Ġ( double )( * iter ). i Index Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġai Node Anim ** Ġpc Anim Node Ġ= Ġanim -> m Channels Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! (* iter ). m Values . empty () Ġ|| Ġiter Ġ== Ġanim Parser . m Frames . begin ()) Ġ/* Ġbe Ġsure Ġwe Ġhave Ġat Ġleast Ġone Ġframe Ġ*/ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġnow Ġprocess Ġall Ġvalues Ġin Ġthere Ġ... Ġread Ġall Ġjoint s Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMD 5 :: Base Frame Desc * Ġpc Base Frame Ġ= Ġ& anim Parser . m Base Frames [ 0 ] Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( Anim Bone List :: const _ iterator Ġiter 2 Ġ= Ġanim Parser . m Animated B ones . begin (); Ġiter 2 Ġ!= Ġanim Parser . m Animated B ones . end (); ++ iter 2 , Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ++ pc Anim Node , ++ pc Base Frame ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ((* iter 2 ). i First Key Index Ġ>= Ġ(* iter ). m Values . size ()) Ġ{ Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠAllow Ġfor Ġempty Ġframes Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ((* iter 2 ). i Flags Ġ!= Ġ 0 ) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠDead ly Import Error (" MD 5 : ĠKey frame Ġindex Ġis Ġout Ġof Ġrange ") Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconst Ġfloat * Ġfp Cur Ġ= Ġ& (* iter ). m Values [ (* iter 2 ). i First Key Index ] Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġai Node Anim * Ġpc Cur Anim Bone Ġ= Ġ* pc Anim Node Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġai Vector Key * Ġv Key Ġ= Ġ& pc Cur Anim Bone -> m Position Keys [ pc Cur Anim Bone -> m Num Position Keys ++] Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġai Qu at Key * Ġq Key Ġ= Ġ& pc Cur Anim Bone -> m Rotation Keys Ġ Ġ[ pc Cur Anim Bone -> m Num Rotation Keys ++] Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġai Vector 3 D Ġv Temp Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġtranslation al Ġcomponent Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( unsigned Ġint Ġi Ġ= Ġ 0 ; Ġi Ġ< Ġ 3 ; Ġ++ i ) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ((* iter 2 ). i Flags Ġ& Ġ( 1 u Ġ<< Ġi )) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġv Key -> m Value [ i ] Ġ= Ġ Ġ* fp Cur ++ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġv Key -> m Value [ i ] Ġ= Ġpc Base Frame -> v Position XYZ [ i ] Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġorientation Ġcomponent Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( unsigned Ġint Ġi Ġ= Ġ 0 ; Ġi Ġ< Ġ 3 ; Ġ++ i ) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ((* iter 2 ). i Flags Ġ& Ġ( 8 u Ġ<< Ġi )) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġv Temp [ i ] Ġ= Ġ Ġ* fp Cur ++ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġv Temp [ i ] Ġ= Ġpc Base Frame -> v Rotation Qu at [ i ] Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMD 5 :: Convert Quaternion ( v Temp , Ġq Key -> m Value ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġq Key -> m Time Ġ= Ġv Key -> m Time Ġ= Ġd Time Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcompute Ġthe Ġduration Ġof Ġthe Ġanimation Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġanim -> m Duration Ġ= Ġstd :: max ( d Time , anim -> m Duration ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġwe Ġdidn 't Ġbuild Ġthe Ġhierarchy Ġyet Ġ( == Ġwe Ġdidn 't Ġload Ġa ĠMD 5 MESH ), Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġconstruct Ġit Ġnow Ġfrom Ġthe Ġdata Ġgiven Ġin Ġthe ĠMD 5 ANIM . Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! p Scene -> m Root Node ) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġp Scene -> m Root Node Ġ= Ġnew Ġai Node () Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġp Scene -> m Root Node -> m Name . Set ("< MD 5 _ Hierarchy >") Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAttach Child s _ Anim (- 1 , p Scene -> m Root Node , anim Parser . m Animated B ones ,( const Ġai Node Anim **) anim -> m Channels ) Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCall ĠS keleton Mesh Builder Ġto Ġconstruct Ġa Ġmesh Ġto Ġrepresent Ġthe Ġshape Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( p Scene -> m Root Node -> m Num Children ) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠS keleton Mesh Builder Ġskeleton _ maker ( p Scene , p Scene -> m Root Node -> m Children [ 0 ]) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠLoad Ġa Ġ*. MD 5 CAMERA Ġfile . ĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġload MD 5 Camera File ( io System : ĠIO System ): ĠNothing Ġ= ĠTODO () ĊĊĠĠĠ Ġ/** ĠConstruct Ġnode Ġhierarchy Ġfrom Ġa Ġgiven ĠMD 5 ANIM ĊĠĠĠĠ Ġ* Ġ Ġ@ param Ġi Parent ID ĠCurrent Ġparent ĠID ĊĠĠĠĠ Ġ* Ġ Ġ@ param Ġpi Parent ĠParent Ġnode Ġto Ġattach Ġto ĊĠĠĠĠ Ġ* Ġ Ġ@ param Ġbones ĠInput Ġbones ĊĠĠĠĠ Ġ* Ġ Ġ@ param Ġnode _ anim s ĠGenerated Ġnode Ġanimations ĊĠĠĠĠ Ġ*/ Ċ // ĠĠĠ Ġvoid ĠAttach Child s _ Anim Ġ( int Ġi Parent ID , Ġai Node * Ġpi Parent , ĠAnim Bone List & Ġbones , Ġconst Ġai Node Anim ** Ġnode _ anim s ) ĊĊĠĠĠ Ġ/** ĠConstruct Ġnode Ġhierarchy Ġfrom Ġa Ġgiven ĠMD 5 MESH ĊĠĠĠĠ Ġ* Ġ Ġ@ param Ġi Parent ID ĠCurrent Ġparent ĠID ĊĠĠĠĠ Ġ* Ġ Ġ@ param Ġpi Parent ĠParent Ġnode Ġto Ġattach Ġto ĊĠĠĠĠ Ġ* Ġ Ġ@ param Ġbones ĠInput Ġbones ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġattach Child s _ Mesh ( parentId : ĠInt , Ġparent : ĠA i Node , Ġbones : ĠArrayList < Bone Desc >) Ġ{ ĊĠĠĠĠĠĠĠ Ġassert ( parent . num Children Ġ== Ġ 0 ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠFirst Ġfind Ġout Ġhow Ġmany Ġchildren Ġwe 'll Ġhave ĊĠĠĠĠĠĠĠ Ġparent . num Children Ġ= Ġbones . filter Indexed Ġ{ Ġi , Ġb Ġ-> ĠparentId Ġ!= Ġi Ġ&& Ġb . parent Index Ġ== ĠparentId Ġ}. count () ĊĠĠĠĠĠĠĠ Ġif Ġ( parent . num Children Ġ!= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbones . forEach Indexed Ġ{ Ġi , Ġb Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ( avoid Ġinfinite Ġrecursion ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( parentId Ġ!= Ġi Ġ&& Ġb . parent Index Ġ== ĠparentId ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpc Ġ= ĠA i Node () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġsetup Ġa Ġnew Ġnode ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparent . children . add ( pc . apply Ġ{ Ġname Ġ= Ġb . name Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpc . parent Ġ= Ġparent ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġget Ġthe Ġtransformation Ġmatrix Ġfrom Ġrotation Ġand Ġtranslation al Ġcomponents ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġquat Ġ= ĠA i Quaternion () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġb . rotation Qu at ĠconvertTo Ġquat ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwith ( b . transform ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput ( Ai Matrix 4 x 4 ( quat . mat )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġd 0 Ġ= Ġb . position XYZ . x ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġd 1 Ġ= Ġb . position XYZ . y ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġd 2 Ġ= Ġb . position XYZ . z ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġstore Ġit Ġfor Ġlater Ġuse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġb . inv Transform Ġput Ġb . transform ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpc . transformation Ġput Ġb . transform ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġb . inv Transform . inverse Assign () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/* Ġ Ġthe Ġtransformations Ġfor Ġeach Ġbone Ġare Ġabsolute , Ġso Ġwe Ġneed Ġto Ġmultiply Ġthem Ġwith Ġthe Ġinverse Ġof ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthe Ġabsolute Ġmatrix Ġof Ġthe Ġparent Ġjoint ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(- 1 Ġ!= ĠparentId ) Ġpc . transformation Ġput Ġbones [ parentId ]. inv Transform Ġ* Ġpc . transformation ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġadd Ġchildren Ġto Ġthis Ġnode , Ġtoo ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġattach Child s _ Mesh ( i , Ġpc , Ġbones ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġundo Ġoffset Ġcomput ations Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 Ġuntil Ġparent . num Children ) Ġparent . children . remove At ( parent . children . last Index ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠBuild Ġunique Ġvertex Ġbuffers Ġfrom Ġa Ġgiven ĠMD 5 ANIM ĊĠĠĠĠ Ġ* Ġ Ġ@ param Ġmesh Src ĠInput Ġdata ĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġmake Data Unique ( mesh Src : ĠMesh Desc ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġab H ad Ġ= ĠBoolean Array ( mesh Src . vertices . size ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġallocate Ġenough Ġstorage Ġto Ġkeep Ġthe Ġoutput Ġstructures ĊĠĠĠĠĠĠĠ Ġval Ġi New Num Ġ= Ġmesh Src . faces . size Ġ* Ġ 3 ĊĠĠĠĠĠĠĠ Ġvar Ġi New Index Ġ= Ġmesh Src . vertices . size ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġmesh Src . vertices . size Ġuntil Ġi New Num ) Ġmesh Src . vertices . add ( Vertex Desc ()) ĊĊĠĠĠĠĠĠĠ Ġmesh Src . faces . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 .. 2 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it [ 0 ] Ġ>= Ġmesh Src . vertices . size ) Ġthrow ĠError (" MD 5 MESH : ĠInvalid Ġvertex Ġindex ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( ab H ad [ it [ i ]]) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġgenerate Ġa Ġnew Ġvertex ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmesh Src . vertices [ i New Index ] Ġ= Ġmesh Src . vertices [ it [ i ]] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit [ i ] Ġ= Ġi New Index ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġab H ad [ it [ i ]] Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġswap Ġface Ġorder ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġt Ġ= Ġit [ 0 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit [ 0 ] Ġ= Ġit [ 2 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit [ 2 ] Ġ= Ġt ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠLoad Ġthe Ġcontents Ġof Ġa Ġspecific Ġfile Ġinto Ġmemory Ġand ĊĠĠĠĠ Ġ* Ġ Ġalloc ates Ġa Ġbuffer Ġto Ġkeep Ġit . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ Ġm Buffer Ġis Ġmodified Ġto Ġpoint Ġto Ġthis Ġbuffer . ĊĠĠĠĠ Ġ* Ġ Ġ@ param Ġp File ĠFile Ġstream Ġto Ġbe Ġread ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġload File Into Memory ( file : ĠBufferedReader ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġun load Ġthe Ġprevious Ġbuffer , Ġif Ġany ĊĠĠĠĠĠĠĠ Ġun load File From Memory () ĊĊĠĠĠĠĠĠĠ Ġ// file Size Ġ= Ġfile . length (). i ĊĠĠĠĠĠĠĠ Ġ// assert ( file Size Ġ!= Ġ 0 ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġallocate Ġstorage Ġand Ġcopy Ġthe Ġcontents Ġof Ġthe Ġfile Ġto Ġa Ġmemory Ġbuffer ĊĠĠĠĠĠĠĠ Ġfile . read Lines () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġnow Ġremove Ġall Ġline Ġcomments Ġfrom Ġthe Ġfile ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġ! it . startsWith ("// ") Ġ&& Ġit . isNotEmpty () Ġ&& Ġit . isNotBlank () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . trim () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. to Collection ( buffer ) ĊĠĠĠĠĠĠĠ Ġi LineNumber Ġ= Ġ 1 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠUn load Ġthe Ġcurrent Ġmemory Ġbuffer Ġ*/ ĊĠĠĠ Ġfun Ġun load File From Memory () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġdelete Ġthe Ġfile Ġbuffer ĊĠĠĠĠĠĠĠ Ġbuffer . clear () ĊĠĠĠĠĠĠĠ ĠfileSize Ġ= Ġ 0 ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** ĠConvert Ġa Ġquaternion Ġto Ġits Ġusual Ġrepresentation Ġ*/ Ċ infix Ġfun ĠA i Vector 3 D . convertTo ( out : ĠA i Quaternion ) Ġ{ ĊĠĠĠ Ġout . x Ġ= Ġx ĊĠĠĠ Ġout . y Ġ= Ġy ĊĠĠĠ Ġout . z Ġ= Ġz ĊĠĠĠ Ġval Ġt Ġ= Ġ 1 f Ġ- Ġx Ġ* Ġx Ġ- Ġy Ġ* Ġy Ġ- Ġz Ġ* Ġz ĊĠĠĠ Ġif Ġ( t Ġ< Ġ 0 f ) Ġout . w Ġ= Ġ 0 f ĊĠĠĠ Ġelse Ġout . w Ġ= Ġsqrt ( t ) ĊĠĠĠ Ġ// ĠAss imp Ġconvention . ĊĠĠĠ Ġout . w Ġ*= Ġ- 1 f Ċ } Ċ Ċ /** ĠReturns Ġa Ġmatrix Ġrepresentation Ġof Ġthe Ġquaternion Ġ*/ Ċ val ĠA i Quaternion . mat ĊĠĠĠ Ġget () Ġ= ĠA i Matrix 3 x 3 (). apply Ġ{ ĊĠĠĠĠĠĠĠ Ġa 0 Ġ= Ġ 1 f Ġ- Ġ 2 f Ġ* Ġ( y Ġ* Ġy Ġ+ Ġz Ġ* Ġz ) ĊĠĠĠĠĠĠĠ Ġb 0 Ġ= Ġ 2 f Ġ* Ġ( x Ġ* Ġy Ġ- Ġz Ġ* Ġw ) ĊĠĠĠĠĠĠĠ Ġc 0 Ġ= Ġ 2 f Ġ* Ġ( x Ġ* Ġz Ġ+ Ġy Ġ* Ġw ) ĊĠĠĠĠĠĠĠ Ġa 1 Ġ= Ġ 2 f Ġ* Ġ( x Ġ* Ġy Ġ+ Ġz Ġ* Ġw ) ĊĠĠĠĠĠĠĠ Ġb 1 Ġ= Ġ 1 f Ġ- Ġ 2 f Ġ* Ġ( x Ġ* Ġx Ġ+ Ġz Ġ* Ġz ) ĊĠĠĠĠĠĠĠ Ġc 1 Ġ= Ġ 2 f Ġ* Ġ( y Ġ* Ġz Ġ- Ġx Ġ* Ġw ) ĊĠĠĠĠĠĠĠ Ġa 2 Ġ= Ġ 2 f Ġ* Ġ( x Ġ* Ġz Ġ- Ġy Ġ* Ġw ) ĊĠĠĠĠĠĠĠ Ġb 2 Ġ= Ġ 2 f Ġ* Ġ( y Ġ* Ġz Ġ+ Ġx Ġ* Ġw ) ĊĠĠĠĠĠĠĠ Ġc 2 Ġ= Ġ 1 f Ġ- Ġ 2 f Ġ* Ġ( x Ġ* Ġx Ġ+ Ġy Ġ* Ġy ) ĊĠĠĠ Ġ}