Background
When developing a game engine, we usually use a data-oriented design for optimal memory and computing performance.
Take the particle system as an example.
In a particle system, we have many particles, and each particle can have several attributes, such as positions, velocities, etc.
A typical implementation in C ++ would be:
struct Particle { float positionX, positionY, positionZ; float velocityX, velocityY, velocityZ; float mass;
One of the problems with this implementation is that the attributes of the particles alternate with each other. This memory layout is not a cache and may not be suitable for SIMD calculations.
Instead of data-driven design, we write the following code:
struct ParticleAttribute { size_t size; size_t alignment; const char* semantic; }; struct ParticleSystem { ParticleSystem( size_t numParticles, const ParticleAttribute* attributes, size_t bufferSize) { for (size_t i = 0; i < numAttributes; ++i) { bufferSize += attributes[i].size * numParticles;
Now we have only one distribution, and each attribute is constantly in memory. To simulate particles, we can write the following code:
symplecticEuler(ps.getAttribute("positionX"), ps.getAttribute("velocityX"), dt);
The getAttribute function will get the start address of a specific attribute.
Question
I would like to know how to implement this in Rust.
My idea is to first create a class called ParticleSystem that takes several ParticleAttribute to calculate the total size of the buffer, then allocate memory for the buffer. I think this can be done in Rust's secure code.
The next step is to implement the getAttribute function, which will return a link to the start address of a specific attribute. I need your help here. How to get the source address with an offset and apply it to the desired type (for example, float *) and transfer this raw pointer to the mutable link in Rust?
Also, I think I should wrap this raw pointer to a mutable array reference, because I need to use SIMD lib to load four elements through this link. How to achieve this with Rust?
Update: Provide additional attribute information. The number and details of attributes are determined at runtime. Attribute types may vary, but I think we should only support primitives (f32, f64, ints ...).