You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
3.9 KiB
Plaintext

4 years ago

#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;
}