Reputation: 13
I am doing a simulation of the lungs on Unity. I have a signal of the volume that control my lung object which is sampled for 60 seconds. When I run it, it finishes the entire signal in few seconds. However, I need the simulation to be in real-time and run for the entire 60 seconds. I don't want to run it in slow motion because it doesn't look realistic.
private int i = 0; // initialize iterator
void Update()
{
if (i < MainFlow.Length)
{
float f = (float)MainFlow[i]; // value of current volume
float k = f + 2.5f; // adding initial volume
transform.localScale = new Vector3(k, k, k);
i++;
}
else
{
i = 1;
}
}
Upvotes: 0
Views: 113
Reputation: 632
You're going to need to know the framerate of your simulation. If it's 1500 samples in 60 seconds, that's presumably 25Hz. You can then sample two of the MainFlow values each frame and interpolate between them to produce a smooth output.
Something like this:
float frequency = 25.0f;
float simulationTime = Time.time * frequency;
int firstFrameIndex = Mathf.Clamp(Mathf.FloorToInt(simulationTime), 0, MainFlow.length);
int secondFrameIndex = Mathf.Clamp(firstFrameIndex + 1, 0, MainFlow.length);
float fraction = simulationTime - firstFrameIndex;
float sample1 = (float)MainFlow[firstFrameIndex];
float sample2 = (float)MainFlow[secondFrameIndex];
float k = Mathf.Lerp(sample1, sample2, fraction) + 2.5f;
transform.localScale = new Vector3(k, k, k);
Upvotes: 1
Reputation: 111
Your current implementation is frame rate dependent, the more fps you get, the faster the simulation will be.
I would instead start a coroutine to have more control. Let's say MainFlow contains 1200 samples for a total of 60s, this means the sample rate is 20 Hz (samples/second). So you should process 20 samples per second or in other words, 1 sample per 1/20 second.
So:
private float secondsPerSample;
private void Start()
{
float sampleRate = MainFlow.Length / 60f;
secondsPerSample = 1 / sampleRate;
StartCoroutine(Process());
}
private IEnumerator Process()
{
for (int i = 0; i < MainFlow.Length; i++)
{
float f = (float) MainFlow[i]; // value of current volume
float k = f + 2.5f; // adding initial volume
transform.localScale = new Vector3(k, k, k); i++;
yield return new WaitForSeconds(secondsPerSample);
}
yield return Process();
}
Edit: My answer will run the simulation exactly like it is sampled. If you want to interpolate it instead, eAi's answer will probably help you.
Upvotes: 0