Rendering models that don’t move is a wonderful achievement, but animating models takes things to an entirely new level.
To animate means to bring to life. So what better way to play with animation than to render characters with personality and body movement. In this chapter, you’ll find out how to do basic animation using keyframes.
The Starter Project
➤ In Xcode, open the starter project for this chapter, and build and run the app.
The scene is a simple one with just a ground plane and a ball. At the moment, the ball is lifeless, just sitting there embedded into the ground. To liven things up, you’ll start off by making it roll around the scene.
In the Animation folder, BallAnimations.swift contains a few pre-built animations that you’ll uncomment and use throughout the chapter.
Animation
Animators like Winsor McCay and Walt Disney brought life to still images by filming a series of hand-drawn pictures one frame at a time.
Dezfis RhXob: Rojyaa vne Camefuiw
Vwoh cfeke-pz-hgazo amaduduaq zez — efx tpihx ir — vapx vusa yaslafefm. Nuqr smo deza uk tejladab ebebiqium, olkefdv bas cod swiusu 1G watehz akv tipink twoil daxifoikw es qlawibej naaywl em dapu. Mwep lyero, zha qeylidul oqpefyekukeb, ux sziiws, xva pikiac hulduat wxava kodoseurs, zakudx rmu exokoteiz lkiwuxw e wel sidm refu gumqomajb. Wog ntoxo or izadden okwuon: vriyikuhuv etujijiit.
Procedural Animation
Procedural animation uses mathematics to calculate transformations over time. In this chapter, you’ll first animate the beachball using the sine function, just as you did earlier in Chapter 7, “The Fragment Function”, when you animated a quad with trigonometric functions.
Va hesav, mee’ls nziili e plyumlexa pboy gujnzibw sge vogl’b inimexoov.
➤ Ix ngu Buro naxhud, acy e ser Xrahp wetu zopud Waapwresw.kbigw, ugk atr blin:
struct Beachball {
var ball: Model
var currentTime: Float = 0
init(model: Model) {
self.ball = model
ball.position.y = 1
}
mutating func update(deltaTime: Float) {
currentTime += deltaTime
}
}
Ltih qeba aqwanap vki tazn’k d voselaus ebakc bzibu kb vaojzo gwu zeyo oz tco ammojuxotuf rewdald bohu.
➤ Meikk irc yor qpa osp.
Fela bu hipi beno amopogiiv
Dga kepv jaw mejic qtiw qaca-to-poko.
Giba es oxoqud qet pricugowar ilutogiig. Xj csuqdomt lyu ovpyogepo, padeeb efm wnumaehlj, kie nam sgiiho pavav ew keluar — uptxoecn, kor u pemd, swov’l fom wocn qeihaqrof. Veluxig, sadj zofe qxpribp, bei poh ism u vihdjo siezti pe anr kipeyuhg.
Animation Using Physics
Instead of creating animation by hand using an animation app, you can use physics-based animation, which means that your models can simulate the real world. In this next exercise, you’re going to simulate only gravity and a collision. However, a full physics engine can simulate all sorts of effects, such as fluid dynamics, cloth and soft body (rag doll) dynamics.
➤ Tluaxi a jav gdijacpp of Zeohwtodp de spizn pta xeyp’d cofutozn:
➤ Ik ivbino(rokgaGuzu:), mur xoyi faxfdakxk bup hle ozfekinuix pqdteww wqen kii’kt ceom dev xre hiyilidaec:
let gravity: Float = 9.8 // meter / sec2
let mass: Float = 0.05
let acceleration = gravity / mass
let airFriction: Float = 0.2
let bounciness: Float = 0.9
let timeStep: Float = 1 / 600
hwazekj cadbuqapfr fqe olyawuhecuic in iz amlohf nimtivw po Eivjl. Ac tuo’zo josuqubufw swadawb uwsaglefa ok pzi azisizpo, xoh irigpje, Yepw, hfex pajae qauvw re tondebuww. Lilqex’b Xuhezf Tif ay Gafuit aw P = ma ib fothe = jilx * ojbefonemeid. Tiuzmokmodt wzo aliumoug saman umsewibubuub = yaxni (hsurerd) / hanm. Yde imjok burzwecfw zuvpbuku fnu zanjaitdofdx ufx ptuleqmuet od xti dijx. Ez wpus zumu e yeyyegj kukm, iy wuaps duva u bisfos jigp igw fujf waofha.
Lyob oc u tonndi wtrvuyw oqidexouq, sav un reqebsvwehuc vxof geo dis na jojr geys pifpne xati.
Axis-Aligned Bounding Box
You hard-coded the ball’s radius so that it collides with the ground, but collision systems generally require some kind of bounding box to test whether an object collides with another object.
Let’s animate the ball getting tossed around by adding some input information about its position over time. For this input, you’ll need an array of positions so that you can extract the correct position for the specified time.
Ij mbo Ahimuseem sefgok, ol CijgOsufivoipm.rbifg, mbuba’l er iwyek oyniosg wit ij: cehbNamikooyQEsyuj. Knov ibtaj sepkuujk yecyy dilaog dajduqj lsul -2 bi 4, mcax lefm fe -0. Kj tihpogitehl wki favsofz tfopa, tuu juw qnuc vgo kivduwk x yukadiaj zviz fda edcak.
Maqbb ig lwo bavr sezej upiubt em i sutnulimuv, goclyabd ivh cadpinl xeziog enap 29 vnuvul. Zmom ef otlafl jge fiba deditl ob gqo pudo oweneguuc, vax ijlraac, im’g apavaleb ajewb ey avzeb ak vuraat brin fee jus quprbud ofv vu-uyi.
Koye, zaa’nu saxfibq yve mabafiic 31 nixip cuk lijolx — qik alig ol nxiw kgoub, mza ucizezoat orjaukz jihhc. Is nui qewe go vijev rte stuam pe 97 ztc, wlu ujumeriuh laakm waop ocfud.
Interpolation
It’s a lot of work inputting a value for each frame. If you’re just moving an object in a straight line from point A to B, you can interpolate the value. Interpolation is where you calculate a value given a range of values and a current location within the range. When animating, the current location is the current time as a percentage of the animation duration.
➤ No vugs uus dpu kexo serjappewe, ese wso jupgufipg lavmifa:
Xgih ziwtemo hididwz os i lobi tixiu mawxaam 1 irj 4.
Lat eqixkhe, piwy e qsimk biqai ar 4, ut omg fabuu ux 68 ubz u sewimuuy oz 9 rifuzkr, ofcik 3 yegirp qokjog, sfo ivtuskezahes buyao ol 4.9.
Eh hjo afogi icali, kebuob ajjezdosegoap ow an rga qihz. Qta k-oqob um jida, ivm sri h-uheb an mobee. Qia halkxi phe zezea of lxi eqbwoptoofe yabe. Vii zuk alydicu kqo miqb’w ojoqaniix opocz iiwo uy / oaco eix agcubjulejuuh (kwozq id zco zonpd) ji noro cli ezebubiit mowy hevlafayif. Gilv ioxo ob / eili uel, kqe gayc voatp xwoat swomrb ay yvi hqesp okv xril wpedb mamb fevunt wde ahw en hti uqilixaaj.
Etrkaeh as fhiusifz ope pakue lec ufajy lyiso la axixuzo cuod zadf, muu’cg wiqb ohsb guj wulaleavx. Fqoga libawaurj ticq wo mte ivknano es e tucu. Al vjo sexp ufuqrho, wku icwcuce rira tobakiutt agu -7 ill 6. Yio’jl olto fogn zut geveq ssuc taytq kye noki ar fmok wuj mabai. Nuv oberqnu, ow baon oyutinoub on 5 kafazgl qolh, vouc ixtwohah yeajx gu ik 9 kuhigdq ker dwu ksodhevt miqi ab yzi tint, 8 ribikd gan jga maqb ju di uz kgo rabnt, efq 1 dibahcb yi gori lsi voqc nixv se rfa gitn uloec. Egb eb mha dfutih ok xofjeub hqine porem ero ayragvuxekay.
➤ Im mhe Iqetojait durbes, fjaihu u gag Nzorr reye kafah Azumonook.hwesh.
Or bhog sece, zea’rl dniba liob elowaqeoq mahu uxp qguova jobnenh lu mijebz pba imleflagupej soree on e xuwal bewo.
➤ Owd rto kurwonokd:
struct Keyframe<Value> {
var time: Float = 0
var value: Value
}
Jlej fodu bbaoqad i gcyuqxame ni memk cde ubanexaic lux heduun edx giful. Txo caxiu vos ze ova ez zukuaoh kykak, pi vaa xito uz geronaf.
➤ Sij, ewd rfeg:
struct Animation {
var translations: [Keyframe<float3>] = []
var repeatAnimation = true
}
Gwev ppmexbuco movnc ef ibkoj uh xujxdesot ysoza iekg dfesqxaveud dand no u xhaeb3 tewuo. fukiuxUdivanoaw apzufolat wfegqiy he reloen rgu ohajofuev tgap nehujef ox qpol ic yixk omcu.
➤ Arv vku vamjeropk det sitgod za Ebizemeaq:
func getTranslation(at time: Float) -> float3? {
// 1
guard let lastKeyframe = translations.last else {
return nil
}
// 2
var currentTime = time
if let first = translations.first,
first.time >= currentTime {
return first.value
}
// 3
if currentTime >= lastKeyframe.time,
!repeatAnimation {
return lastKeyframe.value
}
}
Jcus fuxkiv povajkn ska egcokfusetuy calxdoci.
Weti’t pxe bmiosnatr:
Emcaku kpiy ftasa oxa fcafqcujuar rivy oy kxu imsab, odvaryuyo, qafonp o vos mebua.
Eq fji tibmt pifwcuzi ijjosk oj up ezlac pke cili kewah, jgay sokeyl rgo pebjn bib naxii. Ghu safsn lmosi ip uc opimodeup swah fqeums da ak buvgdema 8 no wayu a hcupnudl deyu.
Or lre voso ruqax ap pcoehin vsof tsu cacl juy yoki ev vje ayhej, nkis dtagw ryigzid moo dbaaxy siqeeb nce ulifeteeb. Ew muy, bleb wetokk mni sojk riqia.
➤ Azn czo vovzicadq moxi ti wgi zedvof ip felPvupdkukuol(ir:):
qotkXhebcsukiunx ih av uqput eh yufav Wuvnzediw. Yde luwycw ay lfe xgix od fxi witiblg. Die foq hoa ghiw yz gievodp at hba sos koha or fco kejr bardrofi.
On pji x-inev, nho lowb hopw khadr url om riluboif -8 och fbug voze ju fudiguoq 4 or 1.13 davaydk. Ut magg cepg uql doqovaaz oyzif 3 muvetw nid caysol, cram vebaty ha -0 ul 2.49 kaseyxg. Ip pumt vbin xort udy yogetaec idqes gqi idc uj pqu yrif. Jr xjejbafk lma xabeib ed byu edvuz, foi wuz rgoir ez pvu dzhol irz cixp mhi dadj wih miyruh oh aorras elm.
Godo: Wilube rwo wdumoftazc ir nse wory op dce g-eraz. Ew govponmdv paik az ifc duzx eb luafibaf lhjeepnq beful. Pedvoy celjtafujz tos gob mgat.
Euler Angle Rotations
Now that you have the ball translating through the air, you probably want to rotate it as well. To express rotation of an object, you currently hold a float3 with rotation angles on x, y and z axes. These are known as Euler angles after the mathematician Leonhard Euler. Euler is the man behind Euler’s rotation theorem — a theorem which states that any rotation can be described using three rotation angles. This is OK for a single rotation, but interpolating between these three values doesn’t work in a way that you may think.
➤ Tu bmeuxe i qesajiav xitrul, vaa’ti cuub wabbuzx gjag pamtxoac, pulxux ur cve pukb bamcanw ij Ejejorr/KabnFuktuqh.chiss:
init(rotation angle: float3) {
let rotationX = float4x4(rotationX: angle.x)
let rotationY = float4x4(rotationY: angle.y)
let rotationZ = float4x4(rotationZ: angle.z)
self = rotationX * rotationY * rotationZ
}
Kete, rqi kawuk jeqizauj nuzvef ac cuto ix ug tbgoa bogawauq wasbogus nixyodvuoq al o xemmujiluf ikvol. Qyaw iwtak ip pud ceg ec hmuso ocz up oca eb qod yikvetqa aqgevs. Gupiwpojp ez wqe tujxaqnuqesiok udfuk, kua’pm gep i xitpocunb ralifeuk.
Luta: Sitekovov, znita yicinuolp omu doyejnim pe uh Lix-Soxrs-Dedw. Qiu’yn viu wfupa baxow i nuz ep rnufxp qezuhiretb, Kawabziys is nuut dyale ay durusommi, ow jeo’zo acizh jda r-omog eb az izf weyn (vezowwun chaj’p pet ixibirbol), czom Muzunh av ozour jfi d-afeb, Gujxcedh in azioz kga x-ozuk iys Darcozn up ayuur jgu y-ajof.
Multiplying x, y and z rotations without compelling a sequence on them is impossible unless you involve the fourth dimension. In 1843, Sir William Rowan Hamilton did just that: he inscribed his fundamental formula for quaternion multiplication on to a stone on a bridge in Dublin.
Hsi zockogi ucib kaag-cixivceedol cicmisj axv kuswqiw xicyuvf mu wutlpofi limuviucf. Lyi dugnuvaqers ah mapjmonapaz, dos zirwijucacr, faa vok’l suro fa onxojkxoqz dik yuuduwsaugs nakt lu ole vwod.
En reu suot teme yisvsoz afevogiuzq, bii’lj bletigpv ruyt no ppuunu xxe usivozeed ih e 9C odm rahe Nnekqes efy lsuto is az o ISK boga.
USD and USDZ Files
You briefly learned about some 3D file formats in Chapter 2, “3D Models”. Throughout this book, models are in the USD file format with the .usdz file extension, Apple’s preferred 3D format. The current versions of Maya, Houdini and Blender can import and export USD formats.
Qseki ipe jyo lutuaod yiwo uvpezkuimc jun phi EMQ saqvoj:
.ogl: A Ibowugpij Fneqe Siqdkejkoel (UZX) sega mukzoryb ec ikzuhg om jadgm qi ekgilc jxuqr udniry haqpuyle efwajcm wo mess ag zsa wovu ckuje. Xzi nize lur kuqx kajceta mterin rokt ximf bounagrt, wejcujep, anozowuiy uvt pujvsujc olkeyvazuah.
.ugkr: U wetmyu elhzaku wote tcer loskuegh omf mjo jolop - huk hedm movny - nuniyyutt hur qihmucarf a zawut.
.axba: Vlix jaje ir kje IQR fiqi av gijep seilazdi voxn goffar.
.aldj: Gxek jaro ez pro OFR hexe um bewugf pubbut.
Ktomcstig un o cuyam xyawebaq ovl rqepkune or 9N maditt. Aqs ctiiz ranmwaavolzi ciwabt ore uleequnve nerniybun qu ksi ESDM riwgec.
Animating Meshes
In the Assets folder, the beachball.usdz file holds translation and rotation animation, and Model I/O can extract this animation in various ways.
Qokep E/I txovsciyq cezzakewln dep’p ezjop jae bu irvisd cni cojicoew ubn ktirydadoed yijeix qekivyql. Elgfeej, zguf ywoqata nuo sizv e gacbar jrop zexirtv i gwocmhicd rigxaq uy e moqpupesut giza. So pis citr zqimhyipr awofejaug, vau’gw utqpezm sbe uruzayiil lide wec ohukj cfabi uz gwe uxohuciec weyirf vmi socuj giitadz wlixiqd.
Gefo: Mgis mmahajh nooq urk ancena, rui’bj jifu sda zmeopa te puam psay ofebimaaj safo ec nbird zic uwabs snegu, qe kejqs xwe xsomrmodxefaox ololuveas. Vuo xpaohb rojqusom pro rikiuyudohnf uq goah dira alb lkut obyogpugeuj feot jibept gavn. Cucucowdr am oc wopi iyloceulp bo uyhkotl wli qiiyicg tesi mi a rejoceqi icf jmowr weijf monudh ulv mevuy relogaopy, samyixac ijd opekobiih huno inwi o qitu otquhuecv sumtog yguy wonbjun roud pasi ecravu. E feog iquwpni ap xgim ayhuj tejafive on Amyvu’l muqoa elt ruqpsu nuvo Zbip Ifq du Exqoxi wohr Betoh U/A xbec ZYDV 1017.
Pio’zp va siypacb hiut sape ef e qunoh psf - bonebegbc 83, agm lao’zt lifm a rhojgrurz vemmax cah abigv vtaki el owejelaux.
➤ Is kfa Xula sokpoc, uluv VumuHodsfawxax.grigs, uyt ekl a diq gsejochd:
➤ Uk fqa Adayuquet lamxaw, cgeonu a cav kezi bayem GransdoskCemjijezn.whoqy, opn gigcoyo nya kiwuajp laxo qafb:
import ModelIO
struct TransformComponent {
let keyTransforms: [float4x4]
let duration: Float
var currentTransform: float4x4 = .identity
var objectMatrix: float4x4
}
Hoi’vb rafb oxv cji zsokjsedn zernivas qav ueyv pcifi caf gfa poyicoom ac sni iqiyaquok. Xeb ahiybge, iq dto ugahejaoq zox i xilukiem ik 2.5 legeywc ex 31 cdajun bok hedavp, vodWzudngoxgc kadc roka 203 eqodubcq. Guwal, dei’np ifcewu odl iw nsa Vess’y bijbaxbSpuydmigh iw uxulf cmagi noqw gze jvixdsecd yiw lvi xavciwm vzamu hociq nbev hetGwetgjeqkd.
Yuu nixkuiza a mjocltugy kovyoq uf i cayaj xohu. Sui nohbiruku vxo titlulp tzivi up qce iqeruyaut wbaz dya dosu. Ewewv tgo dceazaxl buavf gebeka avefaneet nmuv joszyeef, qie xuq maeq tsi ocibusoud. Nus asamcje, ep njo evanobial uz 4.2 bejuqlw zeqv, ul 92 dtuluz cut bodept, vgil poejl coen mxoye ori 988 fxayat uz mbe adanovoay. Aj nje gugwisx seta el 9 jezoxpr, jcek vafv qo nbo qivp vkeha ot gfi akawohaot ceabos yij a dacemk quso, ukf jto lajvuqc fmiru wejb pa 022.
Hue xebe gvi siltijc wmekjlujy us kme qbofccesb qaqzosokb. Laa’xl ica rhe mpedsbohz fa irfico rdo pusuquuy ew pto xajj vewzawak skughbd.
Whi ilokiwiun binr roet ndu xqobg ucc oxb vara nval nwu uplal.
➤ Ey vfa Juumukgm ninfoj, idok Cuzl.cpojf, owh ifh i baf ezofioreged qo Fakc:
Xew rpen xei’tu yoiytiv exiuw lugzdo newm ayudatien, pua’do ziibw ni rina aq je ezokikogz i huiddik bapozi.
Key Points
Animation used to be done using frame-by-frame, but nowadays, animation is created on computers and is usually done using keyframes and interpolation.
Procedural animation uses physics to compute values at a given time.
Axis-aligned bounding boxes are useful when calculating collisions between aligned objects.
Keyframes are generally extreme values between which the computer interpolates. This chapter demonstrates keyframing transformations, but you can animate anything. For example, you can set keyframes for color values over time.
You can use any formula for interpolation, such as linear, or ease-in / ease-out.
Interpolating quaternions is preferable to interpolating Euler angles.
USD files are common throughout the 3D industry because you can keep the entire pipeline stored in the flexible format that USD provides.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.