LiquidFun Tutorial with Metal and Swift – Part 1

In this LiquidFun tutorial, you’ll learn how to simulate water on iOS using LiquidFun, and render it on screen with Metal and Swift. By Allen Tan.

Leave a rating/review
Save for later
Share
You are currently viewing page 3 of 3 of this article. Click here to view the first page.

Where’s My Water?

Congratulations! You’ve just added an invisible particle system to your invisible physics world.

Of course, invisible particle systems, while potentially useful to create certain effects, are pretty anti-climatic. Unfortunately, you still have a ways to go before you can draw your water particles onscreen, but in the meantime you can at least print out the positions of the particles in your system to confirm they exist.

Go to LiquidFun.h and add the following method declarations:

+ (int)particleCountForSystem:(void *)particleSystem;
+ (void *)particlePositionsForSystem:(void *)particleSystem;

Quickly switch to LiquidFun.mm and add the following implementations of those methods:

+ (int)particleCountForSystem:(void *)particleSystem {
  return ((b2ParticleSystem *)particleSystem)->GetParticleCount();
}

+ (void *)particlePositionsForSystem:(void *)particleSystem {
  return ((b2ParticleSystem *)particleSystem)->GetPositionBuffer();
}

These are both Objective-C pass-through methods for their C++ counterparts. particleCountForSystem: returns the number of particles currently alive in a particle system, while particlePositionsForSystem: returns a pointer to the array of b2Vec2 positions of these particles. Once again, you return void * because Swift doesn’t know about the b2Vec2 type.

Now open ViewController.swift and add the following method:

func printParticleInfo() {
  let count = Int(LiquidFun.particleCountForSystem(particleSystem))
  println("There are \(count) particles present")
  
  let positions = UnsafePointer<Vector2D>(LiquidFun.particlePositionsForSystem(particleSystem))
  
  for i in 0..<count {
    let position = positions[i]
    println("particle: \(i) position: (\(position.x), \(position.y))")
  }
}

And add a call to this method at the end of viewDidLoad:

printParticleInfo()

You call printParticleInfo to log how many particles were created and their positions in your physics world. particlePositionsForSystem returns a pointer to an array of type void * (originally b2Vec2), so you typecast it to a Vector2D array pointer instead, allowing you to access each element's properties.

Note that directly converting one structure to another like this is a dangerous thing to do, but in this case, Vector2D and b2Vec2 are similar enough that it works.

Build and run, and look at the developer console.

log_particles

Hello, particles!

Note: When creating a group of particles in a box, LiquidFun creates the particles (.75 * particle diameter) units apart from one another by default. It produces particles from the center outward, and creates any particle whose center falls within the defined shape.

Where to Go From Here?

So far, you’ve learned how to integrate LiquidFun with Swift, and in the process, you’ve created an invisible liquid particle system. Now it’s time to take a breather.

Here’s the sample project with all of the code from this LiquidFun tutorial.

From this point on, you have multiple options for how to render your LiquidFun particles onscreen. You could use a Sprite Kit particle system and manually map the positions of your LiquidFun particles to it, or you could roll your own particle system using OpenGL ES. For this tutorial series, you’ll use Apple's Metal graphics API for the task.

When you're ready, move on to Part 2 of this series, where you’ll render a LiquidFun particle system using Metal.

In the meantime, if you have any questions or comments about this part, please join the forum discussion below!

Allen Tan

Contributors

Allen Tan

Author

Over 300 content creators. Join our team.