You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
107 lines
3.9 KiB
107 lines
3.9 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.VFX;
|
|
|
|
namespace UnityEditor.VFX.Block
|
|
{
|
|
class CollisionOrientedBox : CollisionShapeBase
|
|
{
|
|
public class InputProperties
|
|
{
|
|
[Tooltip("Sets the oriented box with which particles can collide.")]
|
|
public OrientedBox box = OrientedBox.defaultValue;
|
|
}
|
|
|
|
public override IEnumerable<VFXNamedExpression> GetParameters(CollisionBase collisionBase, IEnumerable<VFXNamedExpression> collisionBaseParameters)
|
|
{
|
|
foreach (var parameter in collisionBaseParameters)
|
|
{
|
|
if (parameter.name == nameof(InputProperties.box))
|
|
{
|
|
yield return new VFXNamedExpression(VFXOperatorUtility.IsTRSMatrixZeroScaled(parameter.exp), "isZeroScaled");
|
|
VFXExpression finalTransform = parameter.exp;
|
|
VFXExpression scale = new VFXExpressionAbs(new VFXExpressionExtractScaleFromMatrix(finalTransform));
|
|
yield return new VFXNamedExpression(VFXOperatorUtility.Reciprocal(scale), "invScale");
|
|
yield return new VFXNamedExpression(scale, "scale");
|
|
yield return new VFXNamedExpression(finalTransform, "fieldTransform");
|
|
yield return new VFXNamedExpression(new VFXExpressionInverseTRSMatrix(parameter.exp), "invFieldTransform");
|
|
continue;
|
|
}
|
|
|
|
yield return parameter;
|
|
}
|
|
}
|
|
|
|
public override string GetSource(CollisionBase collisionBase)
|
|
{
|
|
var Source = string.Format("const bool kUseParticleRadius = {0};",
|
|
collisionBase.radiusMode == CollisionBase.RadiusMode.None ? "false" : "true");
|
|
Source += @"
|
|
if (isZeroScaled)
|
|
return;
|
|
|
|
float3 nextPos = position + deltaTime * velocity;
|
|
float3 tNextPos = mul(invFieldTransform, float4(nextPos, 1.0f)).xyz;
|
|
float3 halfBoxSize = 0.5f + radius * invScale * colliderSign;
|
|
|
|
float3 tDelta = mul(invFieldTransform, float4(deltaTime * velocity, 0)).xyz;
|
|
float3 tPos = mul(invFieldTransform, float4(position, 1.0f)).xyz;
|
|
|
|
";
|
|
|
|
if (collisionBase.mode == CollisionBase.Mode.Solid)
|
|
Source += @"
|
|
if(DistanceToBox(tPos, halfBoxSize) <= length(tDelta)) //Potential hit
|
|
{
|
|
if(DistanceToBox(tPos, halfBoxSize) >= 0)
|
|
{
|
|
";
|
|
else
|
|
Source += @"
|
|
if(any(abs(tNextPos) > halfBoxSize))
|
|
{
|
|
if( all(abs(tPos) <= halfBoxSize) )
|
|
{
|
|
";
|
|
Source += @"
|
|
hit = RayBoxIntersection(tPos, tDelta, halfBoxSize, colliderSign, tHit, hitNormal);
|
|
tPos += tHit * tDelta;
|
|
}
|
|
else
|
|
{";
|
|
if (collisionBase.mode == CollisionBase.Mode.Solid)
|
|
Source += @"
|
|
float3 distanceToEdge = abs(tPos) - halfBoxSize;
|
|
float3 absDistanceToEdge = abs(distanceToEdge) * scale;
|
|
|
|
float3 tPosSign = float3(FastSign(tPos.x), FastSign(tPos.y), FastSign(tPos.z));
|
|
if (absDistanceToEdge.x < absDistanceToEdge.y && absDistanceToEdge.x < absDistanceToEdge.z)
|
|
hitNormal = float3(tPosSign.x, 0.0f, 0.0f);
|
|
else if (absDistanceToEdge.y < absDistanceToEdge.z)
|
|
hitNormal = float3(0.0f, tPosSign.y, 0.0f);
|
|
else
|
|
hitNormal = float3(0.0f, 0.0f, tPosSign.z);
|
|
|
|
hitNormal *= colliderSign;
|
|
tPos -= hitNormal * distanceToEdge;
|
|
hit = true;
|
|
}";
|
|
else
|
|
Source += @"
|
|
float3 distanceToEdge = max(0,abs(tPos) - halfBoxSize);
|
|
|
|
float3 tPosSign = float3(FastSign(tPos.x), FastSign(tPos.y), FastSign(tPos.z));
|
|
hitNormal = -normalize(tPosSign * distanceToEdge);
|
|
tPos -= distanceToEdge * tPosSign ;
|
|
hit = true;
|
|
}";
|
|
|
|
Source += @"
|
|
hitPos = mul(fieldTransform, float4(tPos.xyz, 1.0f)).xyz;
|
|
hitNormal = VFXSafeNormalize(mul(float4(hitNormal, 0.0f), invFieldTransform).xyz);
|
|
}";
|
|
return Source;
|
|
}
|
|
}
|
|
}
|