[Example Project] Sphere Collider in Chain Physics
FeaturedHi Everyone!
If you’ve played with our Chain Physics template, you may be wondering how you can prevent your chains from colliding (such as preventing the chain from going through other things, for example, the user’s face).
Like any scripts in the Lens Studio templates, we can dive into the code and modify it to add additional behaviors.
To add this behavior, we can use a very simple idea: If a point in the chain is within the radius of a collider sphere, we’ll push it towards the outside with some force.
To help demonstrate this idea, I’ve opened the Chain Template and set up a chain of spheres:
Let’s open a ChainController script in a script editor.
We’ll add the additional information we need to run our idea. First let’s add a sceneObject, its position will be used as a center of a sphere collider. Then let’s add a colliderForce variable to know how much force we want to push things out. We’ll also add a sizeMultiplier to help the script understand how big the collider is in the scene. Finally we’ll make this functionality optional by adding a boolean:
//@input bool useCollider = false
//@input SceneObject collider {"showIf" : "useCollider"}
//@input float colliderForce {"showIf" : "useCollider"}
//@input float sizeMultiplier {"showIf" : "useCollider"}
More information about Custom UI can be found here
When you save the script, and select a SceneObject with a Chain Controller script, you will see that our new inputs are available in the Inspector panel.
Let’s set them up. I created a collider by clicking AddNew -> Sphere. Also I set a sizeMultiplier that will make my sphere radius to correspond to collider radius. For the default sphere it is 6.0. This will help us edit the collider size by simply scaling it in the scene.
Also I created a new Render Layer called it "Helpers". Objects of this layer are not rendered to any camera but are visible in the viewport.
Finally, let's use these new inputs to add our custom behavior. Go back to the ChainController script and edit an updatePhysics function by adding collider component of force.
if (script.useCollider) {
var colliderPos = global.MathLib.vec3.fromEngine(script.collider.getTransform().getWorldPosition()); //find current collider position
var colliderRadius = colliderTransform.getWorldScale().x * script.sizeMutiplier; // find current collider radius
}
for (var i = 1; i < points.length; i++) {
if (script.useCollider) {
var colliderAcc = vec3.zero();
var dir = points[i].getPosition().sub(colliderPos);
var dist = dir.length - colliderRadius;//find distance to the sphere
if (dist < 0) {
colliderAcc = dir.normalize().uniformScale(script.colliderForce * (-dist));// find collider component of force
}
points[i].update(dt * timeSpeed, acc.add(colliderAcc));
} else {
points[i].update(dt * timeSpeed, acc);
}
}
In this case, let’s use 0.3 for the force. Sometimes the best way to get the best result is to "feel" it out. try playing around with the value of force so that it feels natural to your Lens and chain. The value should be big enough to push the chain point out, but not too big, otherwise it can push links out too hard on each update and cause shakiness.
That’s it! Let’s try to build a Lens with this.
- I imported a 3D model of a braid rigged to the bones. You may find information about how to set it up in this tutorial
- I added and set-up a head binded sphere and used it as a collider. I set the sphere to be actually much bigger to make braids bend along.
- To complete the look I added face stretch, eyes liquify (see Distort Template) and imported a makeup Controller from the Makeup Template.
Have Fun !
Next time I am going to tell you how to set-up a chain pinned by two points.
Very cool! It looks so natural. Thank you for posting this.
Amazing & super helpful! Definitely checking the example.
Hello!
Can you invert the collision so things inside the sphere can't go outside of it?
Worked well thanks!!
Thanks it worked! Note to anyone else: there is a typo in sizeMultiplier (missing an l) and colliderTransform isn't defined, I used script.collider.getTransform()
One of the coolest templates I've come across. Thank you so much for making this!
Olha thank you for the wonderful template! How can I change the sphere to a facemesh instead? Thank you!
Hi, madeka! Thank you!
This example project is using much simplified collision detection that supports only sphere colliders. You could approximate face with 1 or a couple spheres.
Or another way - since the time posted Lens Studio has released a Hair Simulation and Cloth Simulation templates, that use more advanced technique. Maybe you could find something useful there?
Best
Olha
hiii