120 lines
2.9 KiB
HLSL
120 lines
2.9 KiB
HLSL
#include "shared/point.hlsl"
|
|
#include "shared/quat-functions.hlsl"
|
|
|
|
cbuffer Params : register(b0)
|
|
{
|
|
float3 SourceExtend;
|
|
float Range;
|
|
|
|
float3 SourcePivot;
|
|
float Offset;
|
|
float Scale;
|
|
float Spin;
|
|
float Twist;
|
|
}
|
|
|
|
cbuffer Params : register(b1)
|
|
{
|
|
int SourceAlignmentAxis;
|
|
int RepeatMode;
|
|
}
|
|
|
|
StructuredBuffer<LegacyPoint> SourcePoints : t0;
|
|
StructuredBuffer<LegacyPoint> Points : t1;
|
|
RWStructuredBuffer<LegacyPoint> ResultPoints : u0;
|
|
|
|
static float Fraction;
|
|
static float3 PosA;
|
|
static float3 PosB;
|
|
static float4x4 OrientationA;
|
|
static float4x4 OrientationB;
|
|
|
|
static const float3 axisScaleFactors[] = {float3(0, 1, 1), float3(1, 0, 1), float3(1, 1, 0)};
|
|
|
|
inline float3 TransformVector(float3 v)
|
|
{
|
|
float3 v2 = v * axisScaleFactors[SourceAlignmentAxis] * Scale + lerp(PosA, PosB, Fraction);
|
|
v2 = lerp(mul(float4(v2 - PosA, 1), OrientationA).xyz + PosA,
|
|
mul(float4(v2 - PosB, 1), OrientationB).xyz + PosB,
|
|
Fraction);
|
|
return v2;
|
|
}
|
|
|
|
inline float3 TransformDirection(float3 v)
|
|
{
|
|
return lerp(mul(float4(v, 0), OrientationA).xyz,
|
|
mul(float4(v, 0), OrientationA).xyz,
|
|
Fraction);
|
|
}
|
|
|
|
inline float4 TransformOrientation(float4 r)
|
|
{
|
|
return qSlerp(mul(r, OrientationA),
|
|
mul(r, OrientationB),
|
|
Fraction);
|
|
}
|
|
|
|
[numthreads(64, 1, 1)] void main(uint3 i : SV_DispatchThreadID)
|
|
{
|
|
uint vertexIndex = i.x;
|
|
|
|
uint vertexCount, stride;
|
|
SourcePoints.GetDimensions(vertexCount, stride);
|
|
if (vertexIndex > vertexCount)
|
|
{
|
|
return;
|
|
}
|
|
|
|
uint pointCount;
|
|
Points.GetDimensions(pointCount, stride);
|
|
|
|
float weight = 1;
|
|
float3 offset;
|
|
|
|
LegacyPoint p = SourcePoints[vertexIndex];
|
|
float3 pos = (p.Position + SourcePivot) / SourceExtend;
|
|
float f = pos[SourceAlignmentAxis];
|
|
|
|
f = f * Range * Scale + Offset + 0.5;
|
|
if (RepeatMode == 1)
|
|
{
|
|
f = mod(f, 1);
|
|
}
|
|
else if (RepeatMode == 2)
|
|
{
|
|
f = saturate(f);
|
|
}
|
|
|
|
float floatIndex = f * pointCount + 0.00001;
|
|
|
|
uint aIndex = (int)clamp(floatIndex, 0, pointCount - 2);
|
|
uint bIndex = aIndex + 1;
|
|
Fraction = floatIndex - aIndex;
|
|
|
|
float4 rotA = Points[aIndex].Rotation;
|
|
float4 rotB = Points[bIndex].Rotation;
|
|
|
|
if (SourceAlignmentAxis == 0)
|
|
{
|
|
float4 rotY = qFromAngleAxis(3.1415 / 2, float3(0, 1, 0));
|
|
rotA = qMul(rotA, rotY);
|
|
rotB = qMul(rotB, rotY);
|
|
}
|
|
else if (SourceAlignmentAxis == 1)
|
|
{
|
|
float4 rotY = qFromAngleAxis(3.1415 / 2, float3(1, 0, 0));
|
|
rotA = qMul(rotA, rotY);
|
|
rotB = qMul(rotB, rotY);
|
|
}
|
|
|
|
OrientationA = transpose(qToMatrix(rotA));
|
|
OrientationB = transpose(qToMatrix(rotB));
|
|
PosA = Points[aIndex].Position;
|
|
PosB = Points[bIndex].Position;
|
|
|
|
p.Position = TransformVector(pos);
|
|
float4 r = p.Rotation;
|
|
p.Rotation = qSlerp(qMul(rotA, r), qMul(rotB, r), Fraction);
|
|
ResultPoints[vertexIndex] = p;
|
|
}
|