When looping through a NativeArray of float4[]
, and wanting to set one of the 'fields' of each float4 (let's say y
) to a value, it doesn't seem immediately possible because it's a temporary value.
this:
NativeArray<float4> naFloat4s ;
void Start ( ) {
naFloat4s = new NativeArray<float4> ( 96000, Allocator.Persistent ) ;
}
void MakeNoise ( ) {
for ( int i = 0 ; i < naFloat4s.Length ; i++ ) {
naFloat4s[i].y = Random.Range ( - 1f, 1f ) ;
}
}
Generates the complaint about it being a temporary value of a struct, can't be set.
How is this problem most performantly overcome such that there's no garbage created and the NativeArray and Burst/Jobs can do their utmost to get through this process for tens of thousands of settings as fast as possible?
Note: the random used here is just an example. Presume there's something else there generating something more interesting.
Also note, when doing this, the other values (in this case x, z and w) must remain unchanged. They're still useful, as they are. The need is to change just one of the values in the float4, throughout the array.
Edit: Fixed floats in range, as per Sir Hugo's comment.
In response to comment by sir Hugo regarding pointer to float in float4:
I got the pointer to the individual float working, by doing this:
void LoopDemoWithPointerToFloatOfFloat4_NativeArray() {
int samples = 2000;
int size_T = UnsafeUtility.SizeOf<float4> ( ) ;
int size_F = UnsafeUtility.SizeOf<float> ( ) ;
int mStepr = size_F * 1 ; // 1 is y's index value in the float4 struct
IntPtr dstPtr = ( IntPtr )NativeArrayUnsafeUtility
.GetUnsafeBufferPointerWithoutChecks ( naFloat4s ) ;
for ( int i = 0 ; i < samples ; i++ ) {
unsafe {
float* yOffset = (float*) (dstPtr + i * size_T + mStepr);
*yOffset = (float)i ;
}
}
}
Haven't had a chance to check the speed, it seems fast.
Need to create a rig to test various with StopWatch....
Updated example of usage:
var p = (float4*)noizADSR.GetUnsafePtr ( );
float stepDekay = 1f / dekayLength ;
ptr = (float*)(p + attakFinish); ptr += nID;
j = overlapping;
for ( int i = attakFinish ; i < noizeLength ; i++, j++, ptr += 4 ) {
*ptr = dekayCrv.Evaluate( j * stepDekay) ;
}