(22-11-2022, 09:08 PM)nakoustix Wrote: Hi Jose,
thanks for your quick response!
I'm (now) aware of that. Maybe I didn't understand the principle of the simulation "domain" right, but I think, upon further reading, I now do.
What's still confusing me is that an ObiActor will not act the same as a regular child GameObject. You pointed out the TransformPoint etc. methods (which is greatly appreciated), but to me it's still a myracle how i could compensate the change in the simulation since i can't set the local nor world coordinates of the ObiActor (ObiSoftbody in my case) directly since... well it's simulated
I made some small scripts to test this "domain behaviour" and it's clearly not the same with regular unity objects. Pls. see demonstration here: behaviour demo
Hi!
I think you're still confused about the concept of
vector spaces, which is very related to parenting transforms and "pivots": Both setups aren't equivalent: the object in the right (a regular GameObject) has its pivot in the center of the sphere mesh. That its, mesh vertices are laid out around the center of the transform. However the softbody has its pivot to the left of the softbody,
because the softbody has moved to the right of the solver.
Try grabbing your GameObject sphere, parent it under another transform and move it to the right of its parent, then scale the parent transform. This is what's actually happening with the solver and the softbody, and you'll get the exact same behavior as you do with the solver.
(22-11-2022, 09:08 PM)nakoustix Wrote: The scripts are mainly the same, I just grab transforms from different components.
For ObiSolver:
Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Obi;
[RequireComponent(typeof(ObiSolver))]
public class Test_ObiSolverScaler : MonoBehaviour
{
[Range(0.1f, 5f)]
public float scale = 2.0f;
public ObiActor actor;
private ObiSolver solver;
private void Awake()
{
solver = GetComponent<ObiSolver>();
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
Vector3 actorPos = actor.transform.position;
//Debug.Log("ActorPosWorld = " + actorPosWorld);
Vector3 actualScale = transform.localScale;
actualScale.x = scale;
actualScale.y = scale;
actualScale.z = scale;
transform.localScale = actualScale;
actor.transform.localPosition = transform.InverseTransformPoint(actorPos);
}
}
This bit:
Code:
Vector3 actorPos = actor.transform.position;
[...]
actor.transform.localPosition = transform.InverseTransformPoint(actorPos);
Doesn't make much sense. actorPos is already expressed in world space, so you could just do:
Code:
Vector3 actorPos = actor.transform.position;
[...]
actor.transform.position = actorPos;
What I meant about InverseTransformPoint is that you can use it to convert particle positions from solver to local space. So for instance, if you've calculated the center of mass of your softbody (by averaging all particle positions, which are expressed in the solver's local space, just like vertices in a mesh are expressed in the object's local space), you can get its value in world space by using solver.transform.InverseTransformPoint(). This comes in handy when moving softbodies around.
(22-11-2022, 09:08 PM)nakoustix Wrote: I'm just in the dark and really appreciate any help from you guys. Do I really need to update every particle position by hand? (I don't think that's gonna be performant..)
If you want to move/rotate a softbody, yes you need to move/rotate all its particles. There's no other way around it, because unlike a rigid object, a soft object doesn't really have a "pivot" point with respect to which all parts of it are fixed in place.
(22-11-2022, 09:08 PM)nakoustix Wrote: Or is there another way to scale the solver and therefore its simulated bodies and keep them running without positional changes?
Basically you want to:
- Calculate the world space position of all softbodies in the solver, and store them.
- Scale the solver down (all softbodies under it will shrink,
and move towards the solver's center)
- Convert your stored world space positions to the solver's local space, and move the softbodies there. And with "moving a softbody", I mean moving all of its particles.
Conceptually this is exactly the same you'd do with regular Unity objects: imagine you've got several objects parented under a common parent transform, and you want to scale them all without altering their positions: you store their positions prior to scaling, scale the parent, then reset their positions to what they were before scaling.
Let me know if you need further help with this,
kind regards