I made some variant of particle system what independed on particle count, but i hadn't enogth float precision to make system in stabilised state, so i decided to use double instead of float. But functions DoRoutine and DoCoroutine stucks! First function calculates forces (eg gravity "f[pos].p[0].vy += 0.05f;" that don't want to work too), collisions, and normalizes particles. Second function reregistering particles in gridspace, so if it function will not work i'll see only their spawn position, also if first function willn't apply forces i'll see same. If i use floats i can see that particles are falling, colliding, but sticks together, going to the edges, made theirself as big stick forwarded up at the sides of field. Why some double operations don't work? How i permitted to use doubles with uints? Where is the bug?
Code:
#pragma kernel DoRoutine
struct Part
{
double x,y,vx,vy;
};
struct Field
{
Part p[4];
};
RWStructuredBuffer f;
[numthreads(16,16,1)]
void DoRoutine (uint3 id : SV_DispatchThreadID)
{
uint pos = id.x+id.y*512;
f[pos].p[0].vy += 0.05f;
f[pos].p[1].vy += 0.05f;
f[pos].p[2].vy += 0.05f;
f[pos].p[3].vy += 0.05f;
/* f[pos].p[0].vy /= 1.03f;
f[pos].p[1].vy /= 1.03f;
f[pos].p[2].vy /= 1.03f;
f[pos].p[3].vy /= 1.03f;
f[pos].p[4].vy /= 1.03f;
f[pos].p[5].vy /= 1.03f;
f[pos].p[6].vy /= 1.03f;
f[pos].p[7].vy /= 1.03f;
f[pos].p[0].vx /= 1.03f;
f[pos].p[1].vx /= 1.03f;
f[pos].p[2].vx /= 1.03f;
f[pos].p[3].vx /= 1.03f;
f[pos].p[4].vx /= 1.03f;
f[pos].p[5].vx /= 1.03f;
f[pos].p[6].vx /= 1.03f;
f[pos].p[7].vx /= 1.03f;*/
for(uint i = 0; i < 4; i++)
{
if(f[pos].p[i].x >= 0)
for(uint j = 0; j < 3; j++)
{
for(uint k = 0; k < 3; k++)
{
uint scuko = id.x+k-1+(id.y+j-1)*512;
for(uint l = 0; l < 4; l++)
{
//if(j != 1 && k != 1 && i != l)
//{
if(f[scuko].p[l].x >= 0)
{
double x = f[pos].p[i].x - f[scuko].p[l].x;
double y = f[pos].p[i].y - f[scuko].p[l].y;
double dist = sqrt((float)(x*x+y*y));
//double2 midPnt = double2(f[pos].p[i].x+f[scuko].p[l].x/2,f[pos].p[i].y+f[scuko].p[l].y/2);
if(dist < 1.0 && dist != 0)
{
//if(dist < 0.1) dist = 0.1;
//f[pos].p[i].vx += x/dist/dist*0.2f;
//f[pos].p[i].vy += y/dist/dist*0.2f;
//f[scuko].p[l].vx -= x/dist/dist*0.2f;
//f[scuko].p[l].vy -= y/dist/dist*0.2f;
f[pos].p[i].vx *= 0.8f;
f[pos].p[i].vy *= 0.8f;
f[scuko].p[l].vx *= 0.8f;
f[scuko].p[l].vy *= 0.8f;
f[pos].p[i].x += x/2/dist;
f[pos].p[i].y += y/2/dist;
if(f[pos].p[i].x < 1)
{
f[pos].p[i].vx *= -0.8f;
f[pos].p[i].x = 1;
}
if(f[pos].p[i].y < 1)
{
f[pos].p[i].vy *= -0.8f;
f[pos].p[i].y = 1;
}
if(f[pos].p[i].x > 511)
{
f[pos].p[i].vx *= -0.8f;
f[pos].p[i].x = 511;
}
if(f[pos].p[i].y > 511)
{
f[pos].p[i].vy *= -0.8f;
f[pos].p[i].y = 511;
}
if((uint)(f[pos].p[i].x) != id.x || (uint)(f[pos].p[i].y) != id.y)
{
uint nx = (uint)(f[pos].p[i].x);
uint ny = (uint)(f[pos].p[i].y);
for(uint place = 0; place < 4; place++)
{
if(f[nx+ny*512].p[place].x < 0)
{
f[nx+ny*512].p[place] = f[pos].p[i];
f[pos].p[i].x = -100.0;
break;
}
}
}
}
else if(dist == 0)
{
//f[pos].p[i].x -= 0.5f;
f[pos].p[i].y += 0.5f;
//f[pos].p[i].vx *= 0.4f;
//f[pos].p[i].vy *= 0.4f;
if(f[pos].p[i].x < 1)
{
f[pos].p[i].vx *= -0.8f;
f[pos].p[i].x = 1;
}
if(f[pos].p[i].y < 1)
{
f[pos].p[i].vy *= -0.8f;
f[pos].p[i].y = 1;
}
if(f[pos].p[i].x > 511)
{
f[pos].p[i].vx *= -0.8f;
f[pos].p[i].x = 511;
}
if(f[pos].p[i].y > 511)
{
f[pos].p[i].vy *= -0.8f;
f[pos].p[i].y = 511;
}
if((uint)(f[pos].p[i].x) != id.x || (uint)(f[pos].p[i].y) != id.y)
{
uint nx = (uint)(f[pos].p[i].x);
uint ny = (uint)(f[pos].p[i].y);
for(uint place = 0; place < 4; place++)
{
if(f[nx+ny*512].p[place].x < 0)
{
f[nx+ny*512].p[place] = f[pos].p[i];
f[pos].p[i].x = -100.0f;
break;
}
}
}
}
}
//}
}
}
}
}
for(uint m = 0; m < 4; m++)
{
if(f[pos].p[m].x >= 0)
{
f[pos].p[m].x += f[pos].p[m].vx;
f[pos].p[m].y += f[pos].p[m].vy;
if(f[pos].p[m].x < 1)
{
f[pos].p[m].vx *= -0.8f;
f[pos].p[m].x = 1;
}
if(f[pos].p[m].y < 1)
{
f[pos].p[m].vy *= -0.8f;
f[pos].p[m].y = 1;
}
if(f[pos].p[m].x > 511)
{
f[pos].p[m].vx *= -0.8f;
f[pos].p[m].x = 511;
}
if(f[pos].p[m].y > 511)
{
f[pos].p[m].vy *= -0.8f;
f[pos].p[m].y = 511;
}
}
}
}
#pragma kernel DoCoroutine
[numthreads(1,1,1)]
void DoCoroutine(uint3 id : SV_DispatchThreadID)
{
uint pos = id.x+id.y*512;
for(uint m = 0; m < 4; m++)
{
if(f[pos].p[m].x >= 0)
{
if((uint)(f[pos].p[m].x) != id.x || (uint)(f[pos].p[m].y) != id.y)
{
uint nx = (uint)(f[pos].p[m].x);
uint ny = (uint)(f[pos].p[m].y);
for(uint place = 0; place < 4; place++)
{
if(f[nx+ny*512].p[place].x < 0)
{
f[nx+ny*512].p[place] = f[pos].p[m];
f[pos].p[m].x = -100.0;
break;
}
}
}
}
}
}
#pragma kernel Render
RWTexture2D Screen;
[numthreads(16,16,1)]
void Render (uint3 id : SV_DispatchThreadID)
{
uint pos = id.x + id.y*512;
bool empty = false;
/*for(int i = 0; i < 4; i++)
{
if(f[pos].p[i].x < 0)
{
empty = true;
}
if(f[pos].p[i].x >= 0) Screen[id.xy] = float4(0,0,1,1);
}*/
uint i = 0;
float4 over = float4(.05,.05,.05,1);
if(f[pos].p[0].x >= 0) over += float4(.25,.25,.25,0);
else
{
/*if(f[pos].p[0].x == -100.0)
{
over += double4(0,1,0,0);
f[pos].p[0].x = -1.0;
}*/
empty = true;
}
if(f[pos].p[1].x >= 0) over += float4(.25,.25,.25,0);
else
{
/*if(f[pos].p[1].x == -100.0)
{
over += double4(0,1,0,0);
f[pos].p[1].x = -1.0;
}*/
empty = true;
}
if(f[pos].p[2].x >= 0) over += float4(.25,.25,.25,0);
else
{
/*if(f[pos].p[2].x == -100.0)
{
over += double4(0,1,0,0);
f[pos].p[2].x = -1.0;
}*/
empty = true;
}
if(f[pos].p[3].x >= 0) over += float4(.25,.25,.25,0);
else
{
/*if(f[pos].p[3].x == -100.0)
{
over += double4(0,1,0,0);
f[pos].p[3].x = -1.0;
}*/
empty = true;
}
Screen[id.xy] = over;
if(!empty) Screen[id.xy] = float4(1,0,0,1);
}
#pragma kernel Putis
int putisi, putisj;
float pfx, pfy;
[numthreads(1,1,1)]
void Putis(uint3 id : SV_DispatchThreadID)
{
f[putisi + putisj*512].p[0].x = pfx +0.5;
f[putisi + putisj*512].p[0].y = pfy +0.5;
f[putisi + putisj*512].p[0].vx = 0;
f[putisi + putisj*512].p[0].vy = 0;
}
↧