Swift 3D Model Animations in ARKit Demystified
By: Michalis Dobekidis
Tags: Animation, Swift, Blender, iOS, 3d Models

Getting the 3D Model ready

Let us download a nice low poly 3D model with baked in animations from online:

This one is excellent for our recipe!

Download the above model in .zip file and save it locally.

Unzip the downloaded file and you should see inside something like this:

Contents of .zip file

Now in blender we open a new General File

Blender New File

And delete the cube by right-clicking on the Cube node on the right panel

Now that we have a clean workspace we can import our model. Click File > Import > .FBX and search for the file Lowpoly_Helicopter1.fbx from the unzipped folder.

You should now have this:

Helicopter 3D Model low poly

But that doesn’t look so nice, so let us add some texture to it.

There are a couple of ways to add texture to the 3D Model, I’m going to show you the easiest one, but its worth noting that learning your way around Blender is a very useful skill.

Texture time! Expand the Helicopter node from the right panel and select the Copter node.

Adding texture to the helicopter

Now select the Texture Tab and then the Base Color option and select Image Texture.

Then browse and find the texture text/Palette.png from the unziped folder and select it. At first you might not see any effect, but switch to Texture Paint tab from top and you should see this:

The end result of a helicopter with texture

Viewing Animations

In order to view the animation of the helicopter simply press the Space key on your keyboard and the rotor of the helicopter will start spinning.

However before we move on to code we should take a note of the total frames of the animation, this will come in handy later on, so to view this switch to Animation tab from the top and select the Helicopter>Propeller node from the right panel, then the following will appear on the bottom animation timeline:

Animation timeline

So we see here that the total frames of the animation is 360 , keep a note of this as we will need it later on.

Export to .dae

In order for us to make use of this model we need to export it in a format that XCode can understand, this is the Collada format or .dae . From the top menu select File > Export > Collada (.dae), that should export two files the helicopter.dae and the Palette.png on your selected destination.

Import to XCode

Now we need to import these files to XCode to make use of them.

Create a new ARKit project

Then proceed and delete the ship.scn and texture.png from the art.scnassets folder.

we don’t need these, we have our own!

Then drag and drop the exported files from blender into that folder.

Now if you select the helicopter.dae file from the left menu you should see something like this:

kinda meh… lets fix it!

Now we need to convert that to .scn file and also do some minor fixes to make it look even better. Select the Editor XCode menu and select the option to conver to convert to scene kit format (.scn)

You should now see a new file (name it helicopter.scn). But it seems kinda dark, lets fix that, select the helicopter.scn file and then the Light node, switch to Attribute inspector on the right-side panel and select as a type: probe

a more nicely lit 3D model

Looks good. If you want to preview the animation hit the Play button on the model preview area.

Export animations from Model

In our root folder we add a helper class called Animations.swift, it looks like this:

The above code will help us create animations with a specific range of AnimationFrames (our example here only uses 1–360, but there are other models with more than one animation baked in and stored in subsequent frames).

In our ViewController.swift we add a single function called loadAnimations and it looks like this:

Now let us break it down and see what this does. First of all lets list of all the things we need it to do:

Find the animation and initially stop it

Create a new animation based on specific animation frames (because some 3D models contain more than one animation in continuous frames)

After 2 seconds start the animation

Play the animation on a loop

Listen for an event when the animation has finished one loop

So first of all we load the model scene and loop through its children nodes recursively.

If one of them contains a non 0 count/length in animationKeys property we move on and fetch the SCNAnimationPlayer associated with the first animation id (returned by item.animationKeys.first )

we create a new animation from frame 1 to 360

If the SCNAnimationPlayer that contains all of the animations exist, we move on and create one of our own with only a select set of AnimationFrames (1 to 360 which is the value we noted from Blender before).

Now that we have created our own SCNAnimationPlayer and we have stopped the baked in one, we have more control over the animation. So let us set it to start after two seconds.

As you might notice we also set some extra properties like repeatCount, blendInDuration, blendOutDuration and animationEvents we do this to add more control to our animation by setting it to infinitely repeat, to more smoothly switch between animations (if we had more than one) and finally we set some listener when the animation completes (keyTime: 1 is 100% of animation played)

The end result!

It was worth the effort!

Useful links:

Enjoy!