144 lines
4.3 KiB
HLSL
144 lines
4.3 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "NiagaraBaryCentricUtils.ush"
|
|
|
|
#define DISKELMESH_BONE_INFLUENCES_MAX4 0
|
|
#define DISKELMESH_BONE_INFLUENCES_MAX8 1
|
|
#define DISKELMESH_BONE_INFLUENCES_UNLIMITED 2
|
|
|
|
#ifndef DISKELMESH_BONE_INFLUENCES
|
|
#define DISKELMESH_BONE_INFLUENCES DISKELMESH_BONE_INFLUENCES_UNLIMITED
|
|
#endif
|
|
|
|
#define DISKELMESH_PROBALIAS_FORMAT_64 0 // 64 bits : Float probability : uint alias
|
|
#define DISKELMESH_PROBALIAS_FORMAT_24_8 1 // 32 bits : 8 bits probability : 24 bits alias
|
|
#define DISKELMESH_PROBALIAS_FORMAT_23_9 2 // 32 bits : 9 bits probability : 23 bits alias
|
|
|
|
#ifndef DISKELMESH_PROBALIAS_FORMAT
|
|
#define DISKELMESH_PROBALIAS_FORMAT DISKELMESH_PROBALIAS_FORMAT_64
|
|
#endif
|
|
|
|
#define DISKELMESH_ADJ_INDEX_FORMAT_FULL 0 // 32 bits
|
|
#define DISKELMESH_ADJ_INDEX_FORMAT_HALF 1 // 16 bits
|
|
|
|
#ifndef DISKELMESH_ADJ_INDEX_FORMAT
|
|
#define DISKELMESH_ADJ_INDEX_FORMAT DISKELMESH_ADJ_INDEX_FORMAT_FULL
|
|
#endif
|
|
|
|
#if FEATURE_LEVEL <= FEATURE_LEVEL_ES3_1
|
|
#undef DISKELMESH_ALLOW_DEFORMED
|
|
#define DISKELMESH_ALLOW_DEFORMED 0
|
|
#endif
|
|
|
|
//-TODO: We need to consolodate the random interface inside NiagaraEmitterInstanceShader.usf it's a bit messy at the moment but should follow what FNDIRandomHelper does
|
|
float DISKelMesh_Random(uint S1, uint S2, uint S3)
|
|
{
|
|
return S3 == 0xffffffff ? NiagaraInternalNoise(S1, S2, S3) : rand(1.0f, S1, S2, S3);
|
|
}
|
|
|
|
struct FDISkelMeshSkinnedVertex
|
|
{
|
|
float3 Position;
|
|
float3 PrevPosition;
|
|
float3 TangentX;
|
|
float3 TangentY;
|
|
float3 TangentZ;
|
|
};
|
|
|
|
float3 DISKelMesh_RandomBarycentricCoord(uint Seed1, uint Seed2, uint Seed3)
|
|
{
|
|
float r0 = DISKelMesh_Random(Seed1, Seed2, Seed3);
|
|
float r1 = DISKelMesh_Random(Seed1, Seed2, Seed3);
|
|
float sqrt0 = sqrt(r0);
|
|
float sqrt1 = sqrt(r1);
|
|
return float3(1.0f - sqrt0, sqrt0 * (1.0 - r1), r1 * sqrt0);
|
|
}
|
|
|
|
int4 DISkelMesh_UnpackIndices4x8(uint Packed)
|
|
{
|
|
return int4(Packed & 0xff, Packed >> 8 & 0xff, Packed >> 16 & 0xff, Packed >> 24 & 0xff);
|
|
}
|
|
|
|
int4 DISkelMesh_UnpackIndices4x16(uint PackedA, uint PackedB)
|
|
{
|
|
return int4(PackedA & 0xffff, PackedA >> 16 & 0xffff, PackedB & 0xffff, PackedB >> 16 & 0xffff);
|
|
}
|
|
|
|
float4 DISkelMesh_UnpackWeights4x8(uint Packed)
|
|
{
|
|
return float4(Packed & 0xff, Packed >> 8 & 0xff, Packed >> 16 & 0xff, Packed >> 24 & 0xff) / 255.0f;
|
|
}
|
|
|
|
float4 DISkelMesh_UnpackWeights4x16(uint PackedA, uint PackedB)
|
|
{
|
|
return float4(PackedA & 0xffff, PackedA >> 16 & 0xffff, PackedB & 0xffff, PackedB >> 16 & 0xffff) / 65535.0f;
|
|
}
|
|
|
|
// UvMappingBuffer organized as an array of:
|
|
//struct FFrozenNode
|
|
//{
|
|
// int32 ChildOffsets[4]
|
|
// int32 ElementCount
|
|
// int32 TriangleIndices[]
|
|
//};
|
|
|
|
#define DISkelMesh_ElementCountOffset 4
|
|
#define DISkelMesh_TriangleIndexOffset 5
|
|
#define DISkelMesh_MinValidUvMappingBufferSize 24 // minimum size (in bytes) for a quadtree to have valid data
|
|
|
|
bool DISkelMesh_NormalizedAabbTriangleIntersection(float2 A, float2 B, float2 C)
|
|
{
|
|
float2 TriAabbMin = float2(min3(A.x, B.x, C.x), min3(A.y, B.y, C.y));
|
|
float2 TriAabbMax = float2(max3(A.x, B.x, C.x), max3(A.y, B.y, C.y));
|
|
|
|
if (any(TriAabbMin > 1.0f) || any(TriAabbMax < 0.0f))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
#define AXIS_COUNT 3
|
|
float2 TriangleEdges[AXIS_COUNT] = { C - B, A - C, B - A };
|
|
|
|
for (int i = 0; i < AXIS_COUNT; ++i)
|
|
{
|
|
float2 Axis = TriangleEdges[i].yx * (float2(-1.0f, 0.0f));
|
|
float AabbSegmentMin = min(0.0f, min3(Axis.x, Axis.y, Axis.x + Axis.y));
|
|
float AabbSegmentMax = max(0.0f, max3(Axis.x, Axis.y, Axis.x + Axis.y));
|
|
float TriangleSegmentMin = min3(dot(A, Axis), dot(B, Axis), dot(C, Axis));
|
|
float TriangleSegmentMax = max3(dot(A, Axis), dot(B, Axis), dot(C, Axis));
|
|
if (AabbSegmentMin > TriangleSegmentMax || AabbSegmentMax < TriangleSegmentMin)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
float4 DISKelMesh_QuatSlerp(float4 Quat1, float4 Quat2, float Slerp)
|
|
{
|
|
const float RawCosom = dot(Quat1, Quat2);
|
|
const float Cosom = abs(RawCosom);
|
|
|
|
float Scale0, Scale1;
|
|
if (Cosom < 0.9999f)
|
|
{
|
|
const float Omega = acos(Cosom);
|
|
const float InvSin = 1.f / sin(Omega);
|
|
Scale0 = sin((1.f - Slerp) * Omega) * InvSin;
|
|
Scale1 = sin(Slerp * Omega) * InvSin;
|
|
}
|
|
else
|
|
{
|
|
Scale0 = 1.0f - Slerp;
|
|
Scale1 = Slerp;
|
|
}
|
|
|
|
// In keeping with our flipped Cosom:
|
|
Scale1 = RawCosom >= 0.0f ? Scale1 : -Scale1;
|
|
|
|
return (Scale0 * Quat1) + (Scale1 * Quat2);
|
|
}
|