Omar Moussa
Omar Moussa

Reputation: 13

How to run a 60-seconds signal in real time?

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

Answers (2)

eAi
eAi

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

Linus
Linus

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

Related Questions