(14-05-2021, 01:39 PM)ReaperQc Wrote: [ -> ]I get what you are saying, basically, since every particles in the softbody will not move at the same speed, i can't get a single velocity straight out the box, but i can calculate an average? for all these velocity?
Yes, that's basically it
. The average of all particle velocities in the softbody would be the velocity of the "whole" softbody.
In the real world when we talk about some object's velocity, what are we really talking about? For instance: a person running certainly has some velocity, but
where do you measure it? is it the velocity of his right foot? the velocity of his left shoulder? maybe the velocity of his head, or his chest?
What makes sense in most cases is to measure the velocity of the object's
center of mass (often abbreviated as CoM). This is the point at which if you hit the object, it would move in a straight line without rotating. Or, the point at which you would be able to balance the object on a stick. In case of a person, this point is likely near the pelvis.
Eg: if you kick a soccer ball right in its center of mass, it will go straight, no effect. If you hit it off-center, it will rotate as it moves, and as a result it will trace a curve mid-air (due to something called Magnus effect, if you want to look it up)
If you discretize an object (that is, divide it up into small chunks, like particles), you can calculate the position of its center of mass by averaging the position of all individual particles,
weighted by their mass. If you average their velocities instead, weighting them by their mass, you get the
velocity of the center of mass.
(14-05-2021, 01:39 PM)ReaperQc Wrote: [ -> ]but you meant something like
[color=#1256f1][size=small]and by doing a for loop of the velocities
for( int actorIndex = 0; actorIndex < solver.velocitiies.size() ; actorIndex++)
{
vector3 finalVelocity += [color=#1256f1][size=small][font=Tahoma, Verdana, Arial, sans-serif]solver.velocitiies[actorIndex];
}
finalVelocity /= solver.velocities.size();
i didn't test yet, but was this what you meant, am i going in wrong direction with this?
This is fine if all your particles have the same mass, which is often the case. Note that your code iterates trough all particles in the
solver, if you have more than one actor in your solver you will want to iterate over the particles in that actor only.
Some code to calculate the velocity of the CoM. Accounts for different particle masses, and multiple actors in the solver:
Code:
using UnityEngine;
using Obi;
[RequireComponent(typeof(ObiActor))]
public class ActorCOM : MonoBehaviour {
ObiActor actor;
public Vector4 vel;
void Awake(){
actor = GetComponent<ObiActor>();
}
void FixedUpdate(){
if (actor == null || !actor.isLoaded)
return;
vel = Vector4.zero;
float massAccumulator = 0;
// Iterate over all particles in an actor:
for (int i = 0; i < actor.solverIndices.Length; ++i){
// retrieve the particle index in the solver:
int solverIndex = actor.solverIndices[i];
// look up the inverse mass of this particle:
float invMass = actor.solver.invMasses[solverIndex];
// accumulate it:
if (invMass > 0)
{
massAccumulator += 1.0f / invMass; // TODO: watch out for division by zero here!
vel += actor.solver.velocities[solverIndex] / invMass;
}
}
vel /= massAccumulator;
}
}