Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Lock Softbody Movement & Cut it
#1
I'm making a softbody cutting game. A knife stays above the softbody object (Slime) and can be moved vertically down in a straight motion plane (Y-plane only) by user touch drag to "cut" a piece off the slime. (The knife does not rotate during the motion, only moves up and down). The plane of cutting can be selected by moving the knife above in any horizontal direction. (X-plane only)

I want the spherical slime softbody to appear to be 'frozen' or hovering just above a platform below it (Frozen position and rotation), but STILL be affected by the knife if user touches it (Bend inwards when knife is penetrating the slime). Once the knife penetrates to a deep enough Y-position inside the slime, I use a mesh cutting tool (Ezy Slice) to cut off the mesh at that Y-plane and will instantiate a new softbody (Generating new blueprint and softbody cut piece) which falls off to the platform below.

----

Two questions:

1. How do I lock the position of a softbody upon instantiating it's prefab? What if I want to define my own spawn position and lock the object there? The transform does not seem to be in sync with the object's actual position once it touches anything and slightly moves. (And yes, I have made the 'main' softbody a child of an empty parent object and then tried moving). Currently it seems to move away if the knife touches it from above. 

2. Is the aforementioned kind of mesh cutting possible? The cutting usually works very well with non-softbody regular meshes, but I'm thinking how do I go about cutting off a part of the main softbody considering the original mesh is no longer preserved because of the particle based way Obi softbody works? 

The mesh cutting algorithm is such that at the cutting plane, the original mesh is destroyed and two new meshes are generated preserving their positions with respect to the original object. The cross section of both meshes use the material of original object. 

------

My plan is -

1. When the knife reaches cutting Y-position, Preserve mesh shape of the softbody in it's instantaneous "bent" shape, then pass THAT on to the mesh cutter.

2. Destroy the original softbody, generate two new meshes and their shapes and position being the same as previous state of main softbody, then generate their blueprints and convert them to softbodies, then add gravity to the smaller piece so it falls off to the platform below.

3. The above two steps need to happen at a duration of below 1 second or so. As the mesh cutting works very fast with regular meshes (Any polycount and shape on mobile), the only hindering factor I see here is the time taken to generate blueprint and softbody on runtime.

Will this work?
Reply
#2
(27-05-2020, 06:42 AM)arrnav96 Wrote: I'm making a softbody cutting game. A knife stays above the softbody object (Slime) and can be moved vertically down in a straight motion plane (Y-plane only) by user touch drag to "cut" a piece off the slime. (The knife does not rotate during the motion, only moves up and down). The plane of cutting can be selected by moving the knife above in any horizontal direction. (X-plane only)

I want the spherical slime softbody to appear to be 'frozen' or hovering just above a platform below it (Frozen position and rotation), but STILL be affected by the knife if user touches it (Bend inwards when knife is penetrating the slime). Once the knife penetrates to a deep enough Y-position inside the slime, I use a mesh cutting tool (Ezy Slice) to cut off the mesh at that Y-plane and will instantiate a new softbody (Generating new blueprint and softbody cut piece) which falls off to the platform below.

----

Two questions:

1. How do I lock the position of a softbody upon instantiating it's prefab? What if I want to define my own spawn position and lock the object there? The transform does not seem to be in sync with the object's actual position once it touches anything and slightly moves. (And yes, I have made the 'main' softbody a child of an empty parent object and then tried moving). Currently it seems to move away if the knife touches it from above. 

2. Is the aforementioned kind of mesh cutting possible? The cutting usually works very well with non-softbody regular meshes, but I'm thinking how do I go about cutting off a part of the main softbody considering the original mesh is no longer preserved because of the particle based way Obi softbody works? 

The mesh cutting algorithm is such that at the cutting plane, the original mesh is destroyed and two new meshes are generated preserving their positions with respect to the original object. The cross section of both meshes use the material of original object. 

------

My plan is -

1. When the knife reaches cutting Y-position, Preserve mesh shape of the softbody in it's instantaneous "bent" shape, then pass THAT on to the mesh cutter.

2. Destroy the original softbody, generate two new meshes and their shapes and position being the same as previous state of main softbody, then generate their blueprints and convert them to softbodies, then add gravity to the smaller piece so it falls off to the platform below.

3. The above two steps need to happen at a duration of below 1 second or so. As the mesh cutting works very fast with regular meshes (Any polycount and shape on mobile), the only hindering factor I see here is the time taken to generate blueprint and softbody on runtime.

Will this work?

Hi there,

1.- To "lock" the position of a softbody, you must lock at least one of its particles. Define a particle group in the blueprint editor, then attach it to a transform using a particle attachment.

2.- Mesh cutting using the plan you outline (feed the mesh in its deformed state, split it, generate two new blueprints from the two chunks) should work, but probably not in realtime unless your softbody is extremely simple. Blueprint generation performance is far from realtime, there's a reason why it is a coroutine: you generally dispatch it, then wait a while for it to be done. You mention a < 1 second delay is acceptable, this will depend a lot on how many particles/vertices you have and how large your cluster radius is.
Reply
#3
(27-05-2020, 09:11 AM)josemendez Wrote: Hi there,

1.- To "lock" the position of a softbody, you must lock at least one of its particles. Define a particle group in the blueprint editor, then attach it to a transform using a particle attachment.

2.- Mesh cutting using the plan you outline (feed the mesh in its deformed state, split it, generate two new blueprints from the two chunks) should work, but probably not in realtime unless your softbody is extremely simple. Blueprint generation performance is far from realtime, there's a reason why it is a coroutine: you generally dispatch it, then wait a while for it to be done. You mention a < 1 second delay is acceptable, this will depend a lot on how many particles/vertices you have and how large your cluster radius is.

Well that sounds great,

I'm using the default Sphere (pCube1) mesh supplied in Obi Common Samples for the Slime main object. That's the one I need to cut. As I see in inspector, it has 486 vertices and I'm using it's default blueprint settings -

Do you think this is performant enough for typical mid-2017 to 2020 mobile devices?

Again, about 1-2 seconds delay can be acceptable as I can use graphical tricks to hide the delay.

Also, How can I access the deformed mesh in realtime?


Attached Files Thumbnail(s)
   
Reply
#4
(27-05-2020, 09:51 AM)arrnav96 Wrote: Well that sounds great,

I'm using the default Sphere (pCube1) mesh supplied in Obi Common Samples for the Slime main object. That's the one I need to cut. As I see in inspector, it has 486 vertices and I'm using it's default blueprint settings -

Do you think this is performant enough for typical mid-2017 to 2020 mobile devices?

Again, about 1-2 seconds delay can be acceptable as I can use graphical tricks to hide the delay.

It's hard to tell without actually trying. Make a simple test scene that generates a blueprint for your sphere, and measure how long it takes for it to be completed in the device.

Keep in mind that coroutines != jobs, they're not run in a separate thread, so completing a coroutine asynchronously obviously takes longer than synchronously. So if you want to do other things (such as visual effects on screen to "hide" the wait) while the coroutine completes, it will take longer to complete that if you just called coroutine.MoveNext() in a loop.

(27-05-2020, 09:51 AM)arrnav96 Wrote: Also, How can I access the deformed mesh in realtime?

The deformed mesh is done using a SkinnedMeshRenderer, so you access it in the usual Unity way: calling BakeMesh.
https://docs.unity3d.com/ScriptReference...eMesh.html
Reply
#5
(27-05-2020, 10:03 AM)josemendez Wrote: It's hard to tell without actually trying. Make a simple test scene that generates a blueprint for your sphere, and measure how long it takes for it to be completed in the device.

Keep in mind that coroutines != jobs, they're not run in a separate thread, so completing a coroutine asynchronously obviously takes longer than synchronously. So if you want to do other things (such as visual effects on screen to "hide" the wait) while the coroutine completes, it will take longer to complete that if you just called coroutine.MoveNext() in a loop.


The deformed mesh is done using a SkinnedMeshRenderer, so you access it in the usual Unity way: calling BakeMesh.
https://docs.unity3d.com/ScriptReference...eMesh.html

Thankyou! You've almost answered everything, just one last thing,

If I'm locking for example the bottom and top particle to lock the object, then cut the object (splitting to two softbodies), how do I lock one of them again in runtime? The bigger piece needs to stay hovering, while smaller one falls off so no locking required in that.

Also, at runtime, how would I group and lock particles without the editor? How would I know which particle I'm locking by code?
Reply
#6
(27-05-2020, 10:39 AM)arrnav96 Wrote: Thankyou! You've almost answered everything, just one last thing,

If I'm locking for example the bottom and top particle to lock the object, then cut the object (splitting to two softbodies), how do I lock one of them again in runtime? The bigger piece needs to stay hovering, while smaller one falls off so no locking required in that.

Also, at runtime, how would I group and lock particles without the editor? How would I know which particle I'm locking by code?

"Locking" a particle basically means setting its mass to infinite. Which is equivalent to setting its inverse mass to zero, Obi internally works with inverse masses to avoid dealing with nasty Inf/NaN values. Setting the velocity to zero is usually also needed, to keep the particle from moving if they already had some momentum.

The ObiParticleAttachment simply wraps this all up nicely for you: It finds all particles in a particle group, stores their old inverse mass, and sets both their inverse mass and velocity to zero. When the attachment is deactivated, it also takes care of resetting their inverse masses to whatever values they had. It also sets the position of the now "locked" particles to match the transform they're attached to.

Given that you're not working with pre-made particle groups defined in editor, I think it would be easier for you to deal with particles directly. You'll need to find which particles you want to lock by checking their position (or any other attribute that helps you identify them), then setting their inverse mass to zero. See:
http://obi.virtualmethodstudio.com/tutor...icles.html
Reply
#7
(27-05-2020, 10:47 AM)josemendez Wrote: "Locking" a particle basically means setting its mass to infinite. Which is equivalent to setting its inverse mass to zero, Obi internally works with inverse masses to avoid dealing with nasty Inf/NaN values. Setting the velocity to zero is usually also needed, to keep the particle from moving if they already had some momentum.

The ObiParticleAttachment simply wraps this all up nicely for you: It finds all particles in a particle group, stores their old inverse mass, and sets both their inverse mass and velocity to zero. When the attachment is deactivated, it also takes care of resetting their inverse masses to whatever values they had. It also sets the position of the now "locked" particles to match the transform they're attached to.

Given that you're not working with pre-made particle groups defined in editor, I think it would be easier for you to deal with particles directly. You'll need to find which particles you want to lock by checking their position (or any other attribute that helps you identify them), then setting their inverse mass to zero. See:
http://obi.virtualmethodstudio.com/tutor...icles.html

Hmm, in that case I have an idea. What if I keep all particles initially locked as slime spawns, then check which particle the knife collider touches as knife is moved, then unlock (remove from locking group) only that particle which is touched by knife collider? Is there a way to detect particle indice based on a box collider collision? 

I have tried the locking now and it works, but then the softbody behaviour is completely gone as the slime particles no longer react to knife touch on it.

The desired behavior is the slime should stay in air, while still being "pressed" visually by the knife before the cut.
Reply
#8
(27-05-2020, 10:59 AM)arrnav96 Wrote: Hmm, in that case I have an idea. What if I keep all particles initially locked as slime spawns, then check which particle the knife collider touches as knife is moved, then unlock (remove from locking group) only that particle which is touched by knife collider? Is there a way to detect particle indice based on a box collider collision? 

I have tried the locking now and it works, but then the softbody behaviour is completely gone as the slime particles no longer react to knife touch on it.

The desired behavior is the slime should stay in air, while still being "pressed" visually by the knife before the cut.

Yes, you can get the particle indices involved in collisions. See:
http://obi.virtualmethodstudio.com/tutor...sions.html

From what you describe, full locking of particles won't actually solve your problem. A locked particle ceases to react to all dynamics (nor forces, no gravity, no wind, nothing) it is fully immovable.

If you want the softbody to deform due to external forces, but keep these forces from moving it away from a location (without any part of it being actually attached to something), you're going to need to get clever about it:

The center of mass of a deformable object can usually be regarded as its "center", for most purposes. You could calculate the center of mass each frame (there's a snippet that does this here: http://obi.virtualmethodstudio.com/tutor...icles.html), calculate how much it has moved since the last frame, then translate all particles back by the same amount. If my intuition is right, this will have the effect of keeping the center of mass of the object "locked" in the same place, while keeping particles free.

An alternate, easier solution if you can manage it, is to just calculate the center of mass and then keep the camera pointing at it. If there's no background or the background moves together with the camera, it would look as if the softbody was not moving at all.
Reply
#9
(27-05-2020, 11:13 AM)josemendez Wrote: Yes, you can get the particle indices involved in collisions. See:
http://obi.virtualmethodstudio.com/tutor...sions.html

From what you describe, full locking of particles won't actually solve your problem. A locked particle ceases to react to all dynamics (nor forces, no gravity, no wind, nothing) it is fully immovable.

If you want the softbody to deform due to external forces, but keep these forces from moving it away from a location (without any part of it being actually attached to something), you're going to need to get clever about it:

The center of mass of a deformable object can usually be regarded as its "center", for most purposes. You could calculate the center of mass each frame (there's a snippet that does this here: http://obi.virtualmethodstudio.com/tutor...icles.html), calculate how much it has moved since the last frame, then translate all particles back by the same amount. If my intuition is right, this will have the effect of keeping the center of mass of the object "locked" in the same place, while keeping particles free.

An alternate, easier solution if you can manage it, is to just calculate the center of mass and then keep the camera pointing at it. If there's no background or the background moves together with the camera, it would look as if the softbody was not moving at all.

I'll try this now, but adding that COM code snippet, at the "if (actor == null || !actor.InSolver)" line of that code under OnDrawGizmos() I get this error inside Unity -

"ObiActor' does not contain a definition for 'InSolver' and no accessible extension method 'InSolver' accepting a first argument of type 'ObiActor' could be found (are you missing a using directive or an assembly reference?)"

Now I know for a fact that InSolver is defined in the API under ObiActor class, then why is Unity throwing me this error suddenly? (Mind you, things have been imported correctly and no prior errors in Obi Scenes)
Reply
#10
My bad, in 5.0 and up, the equivalent to InSolver is "isLoaded". You can see all other snippets in the page using it, instead of InSolver. I just updated the snippet to reflect this.
Reply