|
|
|
|
|
|
|
|
|
|
|
#include "./../../../GPUInstancer/Resources/Compute/Include/PlatformDefines.compute"
|
|
|
|
|
|
|
|
|
|
|
|
#pragma kernel CSCrowdAnimatorController
|
|
|
|
|
|
|
|
|
|
|
|
uniform RWStructuredBuffer<float4> gpuiAnimationData; // index: 0 x -> frameNo1, y -> frameNo2, z -> frameNo3, w -> frameNo4
|
|
|
|
|
|
// index: 1 x -> weight1, y -> weight2, z -> weight3, w -> weight4
|
|
|
|
|
|
|
|
|
|
|
|
uniform StructuredBuffer<float4> gpuiCrowdAnimatorController; // 0 to 4: x -> minFrame, y -> maxFrame (negative if not looping), z -> speed, w -> startTime
|
|
|
|
|
|
|
|
|
|
|
|
uniform uint instanceCount;
|
|
|
|
|
|
uniform float currentTime;
|
|
|
|
|
|
uniform uint frameRate;
|
|
|
|
|
|
|
|
|
|
|
|
#define MIN_SPEED 0.000001f
|
|
|
|
|
|
|
|
|
|
|
|
[numthreads(GPUI_THREADS, 1, 1)]
|
|
|
|
|
|
void CSCrowdAnimatorController(uint3 id : SV_DispatchThreadID)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (id.x >= instanceCount)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
uint animationIndex = id.x * 2;
|
|
|
|
|
|
uint crowdAnimatorIndex = id.x * 4;
|
|
|
|
|
|
|
|
|
|
|
|
float4 animationData = gpuiAnimationData[animationIndex];
|
|
|
|
|
|
|
|
|
|
|
|
float4 crowdAnimatorData = gpuiCrowdAnimatorController[crowdAnimatorIndex];
|
|
|
|
|
|
// If loop is disabled max frame is negative (trick to conserve memory)
|
|
|
|
|
|
int isLooping = sign(crowdAnimatorData.y);
|
|
|
|
|
|
// absolute value
|
|
|
|
|
|
crowdAnimatorData.y = crowdAnimatorData.y * isLooping;
|
|
|
|
|
|
float clipTime = abs(currentTime - crowdAnimatorData.w) * crowdAnimatorData.z;
|
|
|
|
|
|
float clipFrameCount = crowdAnimatorData.y - crowdAnimatorData.x;
|
|
|
|
|
|
float length = clipFrameCount / frameRate;
|
|
|
|
|
|
|
|
|
|
|
|
if (crowdAnimatorData.z > MIN_SPEED)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (isLooping < 0 && clipTime > length)
|
|
|
|
|
|
animationData.x = crowdAnimatorData.y;
|
|
|
|
|
|
else
|
|
|
|
|
|
animationData.x = frac(clipTime / length) * clipFrameCount + crowdAnimatorData.x;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (animationData.y >= 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
crowdAnimatorData = gpuiCrowdAnimatorController[crowdAnimatorIndex + 1];
|
|
|
|
|
|
if (crowdAnimatorData.z > MIN_SPEED)
|
|
|
|
|
|
{
|
|
|
|
|
|
isLooping = sign(crowdAnimatorData.y);
|
|
|
|
|
|
crowdAnimatorData.y = crowdAnimatorData.y * isLooping;
|
|
|
|
|
|
clipTime = abs(currentTime - crowdAnimatorData.w) * crowdAnimatorData.z;
|
|
|
|
|
|
clipFrameCount = crowdAnimatorData.y - crowdAnimatorData.x;
|
|
|
|
|
|
length = clipFrameCount / frameRate;
|
|
|
|
|
|
|
|
|
|
|
|
if (isLooping < 0 && clipTime > length)
|
|
|
|
|
|
animationData.y = crowdAnimatorData.y;
|
|
|
|
|
|
else
|
|
|
|
|
|
animationData.y = frac(clipTime / length) * clipFrameCount + crowdAnimatorData.x;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (animationData.z >= 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
crowdAnimatorData = gpuiCrowdAnimatorController[crowdAnimatorIndex + 2];
|
|
|
|
|
|
if (crowdAnimatorData.z > MIN_SPEED)
|
|
|
|
|
|
{
|
|
|
|
|
|
isLooping = sign(crowdAnimatorData.y);
|
|
|
|
|
|
crowdAnimatorData.y = crowdAnimatorData.y * isLooping;
|
|
|
|
|
|
clipTime = abs(currentTime - crowdAnimatorData.w) * crowdAnimatorData.z;
|
|
|
|
|
|
clipFrameCount = crowdAnimatorData.y - crowdAnimatorData.x;
|
|
|
|
|
|
length = clipFrameCount / frameRate;
|
|
|
|
|
|
|
|
|
|
|
|
if (isLooping < 0 && clipTime > length)
|
|
|
|
|
|
animationData.z = crowdAnimatorData.y;
|
|
|
|
|
|
else
|
|
|
|
|
|
animationData.z = frac(clipTime / length) * clipFrameCount + crowdAnimatorData.x;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (animationData.w >= 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
crowdAnimatorData = gpuiCrowdAnimatorController[crowdAnimatorIndex + 3];
|
|
|
|
|
|
if (crowdAnimatorData.z > MIN_SPEED)
|
|
|
|
|
|
{
|
|
|
|
|
|
isLooping = sign(crowdAnimatorData.y);
|
|
|
|
|
|
crowdAnimatorData.y = crowdAnimatorData.y * isLooping;
|
|
|
|
|
|
clipTime = abs(currentTime - crowdAnimatorData.w) * crowdAnimatorData.z;
|
|
|
|
|
|
clipFrameCount = crowdAnimatorData.y - crowdAnimatorData.x;
|
|
|
|
|
|
length = clipFrameCount / frameRate;
|
|
|
|
|
|
|
|
|
|
|
|
if (isLooping < 0 && clipTime > length)
|
|
|
|
|
|
animationData.w = crowdAnimatorData.y;
|
|
|
|
|
|
else
|
|
|
|
|
|
animationData.w = frac(clipTime / length) * clipFrameCount + crowdAnimatorData.x;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
gpuiAnimationData[animationIndex] = animationData;
|
|
|
|
|
|
}
|