29-08-2024, 12:02 PM
(This post was last modified: 29-08-2024, 12:07 PM by josemendez.)
(29-08-2024, 11:37 AM)PlatonSk Wrote: I’m trying to get the position of a particle at runtime using
Code:for (int i = 0; i < actor.activeParticleCount; i++)
{
var solverIndex = actor.solverIndices[i];
var particlePos = actor.GetParticlePosition(solverIndex);
}
However, when the solver backend is set to GPU, it returns the position from the blueprint instead of the current position in the simulation.
Is this a bug?
If not, how can I retrieve the particle's position using the GPU (and is it even possible)?
Hi,
Not a bug. See "Modifying data in the CPU when using the Compute backend" in the manual:
Quote:Obi will automatically upload particle data to the GPU at the start of every simulation step (only those data lists that have been modified by the CPU since the last time they were uploaded). However, it will only automatically read positions and velocities back from the GPU at the end of each step for performance reasons. If you want to read any other data from the CPU (eg. colors or user data) you need to manually ask Obi to read this data back from the GPU. Note this is also necessary if you're going to modify this data on the CPU, otherwise you would be working with stale data.
GetParticlePosition() returns data from the solver.renderablePositions array, which is used for rendering on the GPU and not read back to the CPU by default as it's not necessary for the normal simulation cycle (the difference with solver.positions is that solver.renderablePositions includes any interpolation/extrapolation performed during frames where a simulation step does not take place). As mentioned above, only solver.positions and solver.velocities are read back by default.
- If you're retrieving the particle position for simulation purposes, read from solver.positions instead.
- If you want to read renderable positions (either by using solver.renderablePositions or GetParticlePosition()), call Readback() and WaitForReadback() as explained in the link above:
Code:
Readbacks in Obi are an asynchronous operation. To start reading data back from the GPU, call Readback() on the desired particle data list. You can then use WaitForReadback() to make the CPU wait for the current readback to be complete.
It is advisable to call WaitForReadback() as far away from Readback() as possible, to avoid long waits while the requested data travels from GPU to CPU. Ideally, Readback() should be called right after a simulation step has been dispatched to the GPU, and WaitForReadback() right after a step has been completed. ObiSolver provides two callback events for this purpose: OnRequestReadback and OnSimulationEnd. ObiActors expose two virtual methods for the same purpose: RequestReadback() and SimulationEnd().
let me know if you need further help!
kind regards