Float 4 For Vectorizedropes
Float 4 For Vectorizedropes
ComponentModel;
using System;
using System.Runtime.CompilerServices;
using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;
using Unity.Mathematics;
namespace GorillaLocomotion.Gameplay
{
[BurstCompile(FloatPrecision.Low, FloatMode.Fast)]
public struct VectorizedSolveRopeJob : IJob
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Dot4(ref float4 ax, ref float4 ay, ref float4 az, ref
float4 bx, ref float4 by, ref float4 bz, ref float4 output)
{
output = ax * bx + ay * by + az * bz;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Length4(ref float4 xVals, ref float4 yVals, ref float4
zVals, ref float4 output)
{
float4 output2 = float4.zero;
Dot4(ref xVals, ref yVals, ref zVals, ref xVals, ref yVals, ref zVals,
ref output2);
output = math.sqrt(output2);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ApplyConstraint()
{
ConstrainRoots();
float4 floatNegOne = math.int4(-1, -1, -1, -1);
for (int i = 0; i < ropeCount; i += 4)
{
for (int j = 0; j < 31; j++)
{
int nodeIndex = i / 4 * 32 + j;
float4 validNodes1 = data.validNodes[nodeIndex];
float4 validNodes2 = data.validNodes[nodeIndex + 1];
if (!(math.lengthsq(validNodes2) < 0.1f))
{
float4 constraintValue = float4.zero;
float4 diffX = data.posX[nodeIndex] - data.posX[nodeIndex +
1];
float4 diffY = data.posY[nodeIndex] - data.posY[nodeIndex +
1];
float4 diffZ = data.posZ[nodeIndex] - data.posZ[nodeIndex +
1];
Length4(ref diffX, ref diffY, ref diffZ, ref
constraintValue);
float4 diffFromDistance = math.abs(constraintValue -
nodeDistance);
float4 signOfDifference = math.sign(constraintValue -
nodeDistance);
constraintValue += validNodes1 - floatNegOne;
float4 ratioX = diffX / constraintValue;
float4 ratioY = diffY / constraintValue;
float4 ratioZ = diffZ / constraintValue;
float4 correction = signOfDifference * ratioX *
diffFromDistance;
float4 correctionY = signOfDifference * ratioY *
diffFromDistance;
float4 correctionZ = signOfDifference * ratioZ *
diffFromDistance;
float4 massRatio1 = data.nodeMass[nodeIndex] /
(data.nodeMass[nodeIndex] + data.nodeMass[nodeIndex + 1]);
float4 massRatio2 = data.nodeMass[nodeIndex + 1] /
(data.nodeMass[nodeIndex] + data.nodeMass[nodeIndex + 1]);
data.posX[nodeIndex] -= correction * validNodes2 *
massRatio1;
data.posY[nodeIndex] -= correctionY * validNodes2 *
massRatio1;
data.posZ[nodeIndex] -= correctionZ * validNodes2 *
massRatio1;
data.posX[nodeIndex + 1] += correction * validNodes2 *
massRatio2;
data.posY[nodeIndex + 1] += correctionY * validNodes2 *
massRatio2;
data.posZ[nodeIndex + 1] += correctionZ * validNodes2 *
massRatio2;
}
}
}
}