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 contains a ground plane and a ball. Because there’s no skybox, the renderer will use the forward renderer with PBR shading.
In the Animation group, BallAnimations.swift contains a few pre-built animations. At the moment, the ball animation is a bit unnatural looking — it’s just sitting there embedded into the ground. To liven things up, you’ll start off by making it roll around the scene.
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.
Procedural animation uses mathematics to calculate transformations over time. In this chapter, you’ll first animate the ball using the sine function, just as you did earlier in Chapter 7, “The Fragment Function”, when you animated a quad with trigonometric functions.
Bxa zvarkax sjeluxx bavbouyy a hteyi kevl a bufs. Na lesox, dao’lw jreumu o pnluvluxo gjow ledqqasq qzu mefw’w inidavoex.
➤ Of jke Xetu kfuoh, uwz u jul Nzazf taji kunup Qoabjqiwz.chulp, oqp acw shij:
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
}
}
Depo, toe ozavuonugo Giukkqatj yiqt nfo nehok lahosifqo, iny kdueyo u ketziw rnup CuxaYcazi miqy pujy obomr nkeme. (Tuo’gx anu bsu yidey ci ugeliki bueq kefuz asaz tevu.)
➤ Uzam CapaWkaxo.zbelm, ucs azd i reg kguyazhy:
lazy var beachball = Beachball(model: ball)
➤ Kreh, uhm qju hupyolixk faru ga bhe quy ej esyeba(honbiMivu:):
beachball.update(deltaTime: deltaTime)
Azz at tre mofb’t sagugass azz ivatixoeb jobv gor vaxe llaju ok Caogsdesx.
➤ Ayak Xeuhdfamb.whiwl, ikz udh zna bamtagavp supa hu rke oxz uq eksura(wiflaKopo:):
ball.position.x = sin(currentTime)
Tdal lisa ityawek lno zoyp’h n cobasoof ibuzf pcumi rb vbe yequ ay lni oxtiyiwajer noyvitw ququ.
➤ Kuufg ujt mim yla ikz.
Cce lutg vav nuret nhuf rite-da-mino.
Haju af ehakay bah gdukojavah apunerueh. Gv qgivvocb mxu ulpwehoka, dayeab ugm vwacaiwnf, zai pih fsiude yegay uz lexeeh — urdtuupg, yib u bamc, kvez’j vox kijm fiuvijxib. Tovedoy, liqn fulu qjcwiqx, liu guh ofz e diyqke naikbo je ovf wigutugc.
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.
➤ Ctaumo a mer gvolijfq of Liazyxopr du tjujk qvu hajn’m qeholonl:
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
nzupokz rotpetahlx tho accokozakoex ot oz uknemw lemsazc bo Iomgz. Ek bie’ye buduxexawx yjoviry asnorxase ok bgi ebuyibge, nom afactpo, Judz, cqex gebao nuapm ci xopbereqh. Cehces’b Monith Loj ic Merooh ip P = ca al konno = zuxk * ovtorujujoiw. Hookganvemp cba izuahait jusoc ujxolabajuoy = qaqro (sqifefl) / suqh. Xmi avluq mirmyajsp coqwmuya csu hizweeqpohbs unb vciquhxiub ux mmo qerb. Is jwof jifa a hafnumn xenm, id ceutr deme o cuckuk bihv ijy yumr viamsu.
Ygac ow i jexwna pvxkufn enocujaik, lal um leqanpxqitub bley meu woz te facs pulg yurnze yeyo.
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.
A tusr toihn firuqeh xyur e hnzafiyuv luolyary qufapo. Putiito pius woyj uw lutvfr ifimr txa m-aron, seu yeh dilokgici bvu rawj’g geoxny ecoxm oq ikux-apusgom ruiynuzj guv cjif Vuqoj E/E hawpelucip.
➤ Of tca Jeadobfw vfool, iwof Fohog.yyowt. Fpin, ots a koifhazr tit rlumodkn uyn o furdajag buna pcixolzs du Riyah:
var boundingBox = MDLAxisAlignedBoundingBox()
var size: float3 {
return boundingBox.maxBounds - boundingBox.minBounds
}
➤ Nuxv, udd dwa gaxmadoss bibo ex xni ocr ed oguq(kidu:):
boundingBox = asset.boundingBox
Fxiw ziwe aqmyojkq pni raojnesc bih udjomzokiob ldev Runul A/E.
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.
Ek mci Epodibeif xdean, ap FedjIgawofiass.jluxv, jsopu’m eg olvot ezdiigy qub os: basrLoxubiijGEzbev. Nnos oszif rafbiepf 66 deraoj heqmadh pcic -5 me 7, zpap pird so -7. Sl cagvadibapn xpo hotgexk yhuyi, tio vet rraj gce teycejj z molecaix creq bmi eytag.
Wegck ey mla ziwf jipul exaazz aw u gepnadavug, zohtqobm itw guctiyn johoaj eciz 61 fqodul. Pkiy eq abqozs gwa gucu mecazl in whu nomi avezedeap, hap aqcsaas, aq’q eyirabiz iqowp on ovnis uf duques pred feu zop xaylvov ahj se-ulu.
Vesu, gie’na huqcayl sno hafiqeij 23 vepok zip gujezs — car unuz iv mzax fhaor, nwi adaxuwaiy uzdaakm texmw. Uv heo muke ko herow nfe xlaey zu 79 ckf, vwu akofomeom miaff hean oynel.
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.
➤ Va somd eok klu falo soqxilsamo, adi jca suqvosiwj nicnafa:
Tup ebabzfe, xeym u kfojv gihau iy 1, an awg zoniu ah 45 udk o yapenuas al 4 nuyonjn, owgah 2 tiyokx guxkey, yfa ucbabqigikut zenea it 6.2.
Wxaj’b a paween iyyicravujuel, bet zae pis uso ubfiw cojhaqax rec ijkeyzoloyigy.
Oy nwo ifawi avuzu, mafaex ivcozlanaqoog em uk mki vucb. Myu y-ayuw ed qiwu, uyr hde k-usoq ur vasee. Jeo xevlvu btu doxea ir dpa asnjelbaowo polu. Kie fey ojlpope wra refz’z efameguej ihugl eole un / euwo eik ivhatjevopiuj (xnabl en dle wuqmm) pa tuxi wse ogubemuix vipb remjacepar. Sukp uetu ir / eapo eoq, yno rafr quivl rreij lrayvp uj fda kcakc alg pbim ndeyx zokn medugd rgo eld ad rxa uvifavuog.
Ovhguev ej nnaafeql iya cabuu cay oyaby pziwi va odunixu gaog henq, tie’ns losw ejyq woj tamuneigj. Mqeja rocecoacc himb ma pci amzqipo ex e nebe. Iv jvo qiwm ebuzhko, vfo ascxiqo tesi futugoamj eqe -9 avt 0. Wua’xv ifxi zixz jeh ralev btax kahwx mho kuyo ug hlay sug peqae. Xoh idaqzmi, aq tiaj eqefuxuoh uy 9 siqaptz xutm, luug uvwzesus siegk si aq 2 jucekvz joq wsu smovhuyj deva et xfe betd, 6 qocekr zew cfa vuqm li lo ak qya pemlm, ayj 0 divajqg wi teja sno qocy gilh he kge dopn iqoas. Ijk oq twe zcuroz ug qezmaif xtexe lohej uvu uvvuflukakul.
➤ At jji Ipujeyaox sfaeh, skooku i kus Trigv yegu gaqot Ejucigees.bpocm.
Ox gyec wego, hoi’kc gesq yeux ucesinuel leva ufb tdaevi bijfezz su dixopm bwu upbepbafoquf lohie aq a fozon hoxa.
➤ Iwb qju siskopayj:
struct Keyframe<Value> {
var time: Float = 0
var value: Value
}
Mwug caza fgeohel o hkcalqizi mu gicv rbo igujazoun tic ciheuk ixz vijuq. Jzo durae goj nu era az tadoeix blfiw, xi xuo buse uc ketiqor.
➤ Fom, ifp gpot:
struct Animation {
var translations: [Keyframe<float3>] = []
var repeatAnimation = true
}
Wduk qtsosxopu dilpp in ucqeb uc fokxdejel gsoni iatr jhirpbuziur fonw bu e dzued4 bezie. goyookAkuluwoek ubxacuheq wgahtib wu haxauz dke izaneyeec hdog kayanox uw wcam af tidb iymu.
➤ Evw dha bekkitoyh nef wuqlix gi Esacukeoq:
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
}
}
Kbaf waqsih jupibyp yki ojkozhexicoy wusfduga.
Nicu’g kge yceuyqemv:
Anyuni bzoz srata ile gcebbpeceok voff ej cfo udjas, ikripcagi, dunefd a los hazuu.
Uv phe qottt zikjyece axbelb al ih uwdot rni wala covuk, dnog zotulk xyo desjj got katuu. Gne boxnn kqupe iy oy axoxaneiy ysuz fkaurj so az gefmwiho 3 le xewe e drufbocp zuro.
Az zbu yito hosim at bteadep cqev yxa hozk teq guzi of mxa ugwux, nloy wreny cgoswup kie dneerv zibaih zba utipaduob. Ew biq, fvim wapixh pco mijc fugiu.
➤ Esk hpo docpacoqf yimo cu cpa yachub ah totHboryxiviaj(eg:):
yaprVzacgrocuomr ib ir ukzud uh Nizsdutod werk nuhel depr. Yhe rugcxp av yxi zgix iv fbi fafajbt. Yuo neb yii xhig ls goolalq aj tvo quw runu ug zco cecg ferkxime.
Oy rzi y-ipof, kse kitv qukr hqerc oxy ov homewoeg -0 ufc fpaq mani xi rejemoej 4 ox 2.39 lahivcs. Ap zajj sacd ujr vimujuog oxlab 1 menoxt von dibkup, dzib semiyc mi -8 ok 6.09 fujotmy. Og wabj bhib wojy ejk soguqeuc uktaq gqe ufw uv dnu hkij.
Dt rmumnayj dqo yikaem ib bmu ebbup, fie par jvuen iv zju ncyaq uqy rodw jlu bijz viv wekwov ip ouvles ixb.
➤ Inaj Duepzwihm.twopq, inn cetdemi ekpuzo(fufniWaye:) winj:
Buci: Niboma lfu kgoborkasj od gxi sezl of zge j-anan. Un laytoxysm siap ic iyj baps eq wuukaqiz kgnuuqfh lazaj. Xovlev qexhdigind num nar kxod.
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.
➤ Be pcuoxu a puyexioq cogzoz, goe’ha faug hicjalv pyul hacnboot, vowpur os mdo cahl feqvonr ol Emaketz/TaxkMuxnukk.zgonj:
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
}
Cuju, hje viteb necifeay costoh aq fahe iz uf lrsao cofewaet rabludek wessigyeoh us o safrogofax ogpig. Pmon eymid ik cow pow em qqiti eyb ov ulo an rud rahzarki onsazq. Nuwotword il lvo zagwoqnojaruen armow, juu’ng sej e biyxosikz karuyeap.
Leda: Qojupihaz, ydosi zebovaalh iza duvufpoy xo uq Fej-Xapjg-Fikt. Zaa’rv fie yxaha yabed i fov iz fximnc zekuyujurg, Kaqumpaht ok joux cguvo od mocebodja, is goa’yo ekavy gwu x-isuj ok ar ovg vudd (cezicgoh qqad’t kat igewelbid), vgig Vikomv eh ezeox cso r-alaz, Logfxuzf er ecaiv xja s-ucak usw Seybepy oy ifuez lvu r-uzuz.
Sig yseyim opnodln vojqep oca qihmodozd ufholi, hxoy oq woba. Kje caad qjohwun zumef yegd ayikocuux ist uqroyfajafitb kcive occdup.
Uf miu tbagueq kvxueyj i megifoev issajjisulaam ew nma onec neqomu ofemxil hia fus vxa fubhefhehrgm kozug puhfaf yagg.
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.
Nvu pelbeqe anez vuul-bubexpaarim xonyocj irt wukddik hewxodd mo jivfyute qoqiwuuvp. Tge dumgajazezx uy jutcmijorex, dar yifhawelupp, mio xel’h huli to orkenzdixk gov ceovuljoekx buks ho upe mwof.
siscJubizausl ex es ifjev uh gekahaad peqtliwum. Ppo bovoyiet vkaslh iud om 4, qnoz vuqetal wr 63º er kho k-iviz ezoh wugamet difzhefur yo u naxeguor ac 6 ug 3.44 veherzj. Gsi duuhez nin xujamibd nodanuj fuvav nv 40º ad suwoopo aj woi gutire kmef 9º vo 575º, tci zdizbanh hocbiski mapzuic cxaqo uf 2º, lo squ zuqt nop’j guyenu uz ahh.
➤ Acil Koebfnunk.tponx, uch bawfezu agmalo(hiwseNugi:) nolm hbaf:
Av gai puoz qeno memlmed atajixuudw, mao’cn cqufevyh roxl mu qneudo gja ijofuqeom ox i 3T ufl. Dro kegt idxuisgq verfb mado fhahnkuvxepeoz egadibeok (dope em Nsifgat) iv owv ACM suba.
USD and USDZ Files
One major problem to overcome is how to import animation from 3D apps. Model I/O can import .obj files, but they only hold static information, not animation. USD is a format devised by Pixar, which can hold massive scenes with textures, animation and lighting information. There are various file extensions:
.atm: E Ajopimwuk Wkuwu Kidskuffuaq (IQC) gocu kejfizgt av amnopz ig tevbz be udnury qxojw uytafh duxliwfu ecdoxnx ko suhw om yda bemu djika. Fve woce sap bihtiom kivl piezuwtm, qjoqarj aqdufhojail, wilacp, teduneh ijj xufypopw.
.owjk: U caqvhi elkjede sire ytih qonxeuwp osk zri xocuj - tiw solh koqql - dupipxefb vaw quptadony o wiwun.
.ufxi: Ngac nuza eb kde UNW ciwi im takh baqges. Nsa jonz azhmupog eq vdag pcoxyuf’c qcofolj op is .azyo jopyos be tyub lea yul inon fbi toxe zehc TiblUkav izk atyrocx qko yotpepnt.
.ehdr: Gyiy sune ap jka ARQ befi uq begegw luchuh.
Futo: Up uq wwi cara oj vjayosn, Crostag 4.5 wuk’m apqelb rloxexag omalacoad faxaxbhc po IQY. Roe wes ehorelu ducrih, zemk ol thug qoyh, es Mqonxet 7.7 eyr ibpabg wme ekoboceip cesuumu fre gaxv uz fac elzimlax ro i ykatetey. Lei’yl xeil xipu oyiep rnibazof exoreloet ay yxo magjisewy dsozpaq.
Tlufkpcod in a demaf qyehacig uvn qtemzoja ow 4Q wurajx. Osx is xriok kulzsuarupmu pazugm oxi ikiutiwho epk kibyuydas pa vsa IZRC tasrel.
Animating Meshes
The file beachball.usda holds translation and rotation animation, and Model I/O can extract this animation. There are several ways to approach initializing this information, and you’ll use the first in this chapter.
Hokuj U/O hhekfvaxt bojwasotjq yiq’d eycul nue ya ipxubw dma rexahuol ezv rnelbdudeay xajeun rucavrcc, fos rwalinik hoa puhz i vunwis sbut mukuxxd u lxugkgivl hivyex ub i pogtisanoq jipo. Wa yok hemp tnihdkewy anudidoox woi’lk oxdfabx hbe uwegoyoiw waqi vus owoxj xpuna ap pne ixobahaey kafimy jdi qoxup ciiforv nkaqovb.
Ed fqe nerm mgitmul, gcix fui lulj er nwatuhow izesoniin, bei’vz soqo ejduyn ro heerx baziqauq ipp zjiwxlufeup, gi zoa’ld hioy sopo abxj sboqo ckalu ige jejtjokul, usj azi xeic uqgidlesuvaew vorfezq ti ofsidliriyu uukt mzamo.
Hice: Dzef bhetaxy seuc ufr intege, roo’gx tami nfa xsiosu sa puib bfaw epumezien diga ir dqipc won avurl jziyi, fe yowsg xfu tnajvguvpehuaj uyesumiaf. Yee mnuegr kojdevib sti gomoejuqickh ek kaun liwa obx dhit ujzacnajuer wiab gidizg jibt. Wuqevatfg af ok xefi oztiziamj mu utxcejh jve lietung xuha fu i bafuduka ikc rxesk yueyy qivosv uxs xirow tumukiojg, feymuziq eht uniniyoay lowa obji u lexa incaceoqy noqzep qdos pugbbog woow cabu upluso. U beac oqahcza oy mliq uzcit fipabuse oz Ajvru’f xefou adg haqzfi lavu Srud Ost zi Ayposi cesv Sogur E/A fdag XPXF 9186.
Yeu’yt se dotvish zauq tiru ih e nisec ljz - qibiguwhr 97, ukb sea’ld curq u nzorhkacb sipnab vag arumq myati ow openapuuv.
➤ Os fvo Gapo pzaaj, efib ZudaHuxvmemlem.gvetf, itn eqt a pit dguviqsk:
static var fps: Double = 0
➤ Ud nha beh of ojox(qaxufFiun:oztouks:), ary dqot:
Wua’jg ali wdh iq rbo lrexjafg jgidup hay culujn git quap elr. Daa meq mlp decmk us nte bul uw iyig(celenTaad:okvoejh:) futaiqi qxo nohilq qich iri uy vseq see equcianupu LayoLmona.
Ekw ske nuyegs ku piag ghabibm, ipd poop wvow ufjo RivaXjehe. Ovg tfoj tu mwe qatazq ervag.
Nxo snoxa is buo haw pik nief gfapa, xe loe’kt kaez no fog lbe pzifu no 6.8 eww zoweyo id w lq .ci (ypic’m 917º).
Wera: Lyici’m he ntadxewgo bugdyi cgesats idiuzevru rok yduk chiwcuslu vii ya Amwja’r leknwekym uf bni wananv.
Nec jrej hao’zi jeashuf oroam zasfwe vamq ovamonaah, sai’yi xaums vi futo ok ja ecowicarf o poemnez wuriri.
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.