fix issue with collision resolve and non-uniform scale box colliders (fixes #32)
This commit is contained in:
Родитель
f0b583c61b
Коммит
b1de6b28d2
|
@ -180,7 +180,7 @@ namespace Unity.DemoTeam.Hair
|
|||
// capsule | centerA radius centerB __pad
|
||||
// sphere | center radius __pad __pad
|
||||
// torus | center radiusA axis radiusB
|
||||
// cube | __pad __pad __pad __pad
|
||||
// cube | extent __pad __pad __pad
|
||||
|
||||
public Vector3 pA; public float tA;
|
||||
public Vector3 pB; public float tB;
|
||||
|
@ -308,8 +308,7 @@ namespace Unity.DemoTeam.Hair
|
|||
type = RuntimeShape.Type.Cube,
|
||||
data = new RuntimeShape.Data
|
||||
{
|
||||
pA = Vector3.zero,
|
||||
pB = Vector3.one * 0.5f,
|
||||
pA = worldSize * 0.5f,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -640,11 +639,11 @@ namespace Unity.DemoTeam.Hair
|
|||
break;
|
||||
case RuntimeShape.Type.Cube:
|
||||
{
|
||||
var localCenter = data.shape.data.pA;
|
||||
var localExtent = data.shape.data.pB;
|
||||
var localCenter = Vector3.zero;
|
||||
var localExtent = Vector3.one;
|
||||
{
|
||||
Gizmos.matrix = data.xform.matrix;
|
||||
Gizmos.DrawWireCube(localCenter, localExtent * 2.0f);
|
||||
Gizmos.DrawWireCube(localCenter, localExtent);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -161,7 +161,7 @@ namespace Unity.DemoTeam.Hair
|
|||
case HairBoundary.RuntimeShape.Type.Capsule: return SdCapsule(p, data.shape.data);
|
||||
case HairBoundary.RuntimeShape.Type.Sphere: return SdSphere(p, data.shape.data);
|
||||
case HairBoundary.RuntimeShape.Type.Torus: return SdTorus(p, data.shape.data);
|
||||
case HairBoundary.RuntimeShape.Type.Cube: return SdCube(p, Matrix4x4.Inverse(data.xform.matrix));
|
||||
case HairBoundary.RuntimeShape.Type.Cube: return SdCube(p, data.shape.data, Matrix4x4.Inverse(data.xform.matrix.WithoutScale()));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -219,14 +219,15 @@ namespace Unity.DemoTeam.Hair
|
|||
return length(q) - t.y;
|
||||
}
|
||||
|
||||
public static float SdCube(float3 p, in float4x4 invM)
|
||||
public static float SdCube(in float3 p, in HairBoundary.RuntimeShape.Data cube, in float4x4 invM) => SdCube(p, cube.pA, invM);
|
||||
public static float SdCube(float3 p, in float3 extent, in float4x4 invM)
|
||||
{
|
||||
p = mul(invM, float4(p, 1.0f)).xyz;
|
||||
|
||||
// see: "distance functions" by Inigo Quilez
|
||||
// https://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
|
||||
|
||||
float3 b = float3(0.5f, 0.5f, 0.5f);
|
||||
float3 b = extent;
|
||||
float3 q = abs(p) - b;
|
||||
|
||||
return length(max(q, 0.0f)) + min(max(q.x, max(q.y, q.z)), 0.0f);
|
||||
|
|
|
@ -1345,11 +1345,17 @@ namespace Unity.DemoTeam.Hair
|
|||
cbuffer._BoundaryWorldMargin = volumeSettings.collisionMargin * 0.01f;
|
||||
|
||||
// pack boundaries
|
||||
int writeIndexDiscrete = 0;
|
||||
int writeIndexCapsule = writeIndexDiscrete + (int)cbuffer._BoundaryCountDiscrete;
|
||||
int writeIndexSphere = writeIndexCapsule + (int)cbuffer._BoundaryCountCapsule;
|
||||
int writeIndexTorus = writeIndexSphere + (int)cbuffer._BoundaryCountSphere;
|
||||
int writeIndexCube = writeIndexTorus + (int)cbuffer._BoundaryCountTorus;
|
||||
int firstIndexDiscrete = 0;
|
||||
int firstIndexCapsule = firstIndexDiscrete + (int)cbuffer._BoundaryCountDiscrete;
|
||||
int firstIndexSphere = firstIndexCapsule + (int)cbuffer._BoundaryCountCapsule;
|
||||
int firstIndexTorus = firstIndexSphere + (int)cbuffer._BoundaryCountSphere;
|
||||
int firstIndexCube = firstIndexTorus + (int)cbuffer._BoundaryCountTorus;
|
||||
|
||||
int writeIndexDiscrete = firstIndexDiscrete;
|
||||
int writeIndexCapsule = firstIndexCapsule;
|
||||
int writeIndexSphere = firstIndexSphere;
|
||||
int writeIndexTorus = firstIndexTorus;
|
||||
int writeIndexCube = firstIndexCube;
|
||||
int writeCount = 0;
|
||||
|
||||
if (boundarySDFIndex != -1)
|
||||
|
@ -1419,6 +1425,11 @@ namespace Unity.DemoTeam.Hair
|
|||
{
|
||||
ptrMatrixInv[i] = boundaryList[boundarySDFIndex].sdf.worldToUVW;
|
||||
}
|
||||
// world to prim for cube
|
||||
else if (i < cbuffer._BoundaryCountCube + firstIndexCube && i >= firstIndexCube)
|
||||
{
|
||||
ptrMatrixInv[i] = Matrix4x4.Inverse(ptrMatrix[i].WithoutScale());
|
||||
}
|
||||
}
|
||||
|
||||
// update previous frame info
|
||||
|
|
|
@ -53,14 +53,14 @@ float SdTorus(float3 p, const float3 center, const float3 axis, const float radi
|
|||
return length(q) - t.y;
|
||||
}
|
||||
|
||||
float SdCube(float3 p, const float4x4 invM)
|
||||
float SdCube(float3 p, const float3 extent, const float4x4 invM)
|
||||
{
|
||||
p = mul(invM, float4(p, 1.0)).xyz;
|
||||
|
||||
// see: "distance functions" by Inigo Quilez
|
||||
// https://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
|
||||
|
||||
const float3 b = float3(0.5, 0.5, 0.5);
|
||||
const float3 b = extent;
|
||||
const float3 q = abs(p) - b;
|
||||
|
||||
return length(max(q, 0.0)) + min(max(q.x, max(q.y, q.z)), 0.0);
|
||||
|
@ -81,6 +81,11 @@ float SdTorus(const float3 p, const BoundaryShape torus)
|
|||
return SdTorus(p, torus.pA, torus.pB, torus.tA, torus.tB);
|
||||
}
|
||||
|
||||
float SdCube(const float3 p, const BoundaryShape cube, const float4x4 invM)
|
||||
{
|
||||
return SdCube(p, cube.pA, invM);
|
||||
}
|
||||
|
||||
//------------------
|
||||
// boundary queries
|
||||
|
||||
|
@ -113,7 +118,7 @@ float BoundaryDistance(const float3 p)
|
|||
|
||||
for (j += _BoundaryCountCube; i != j; i++)
|
||||
{
|
||||
d = min(d, SdCube(p, _BoundaryMatrixInv[i]));
|
||||
d = min(d, SdCube(p, _BoundaryShape[i], _BoundaryMatrixInv[i]));
|
||||
}
|
||||
|
||||
return d;
|
||||
|
@ -152,7 +157,7 @@ uint BoundarySelect(const float3 p, const float d)
|
|||
|
||||
for (j += _BoundaryCountCube; i != j; i++)
|
||||
{
|
||||
if (d == SdCube(p, _BoundaryMatrixInv[i]))
|
||||
if (d == SdCube(p, _BoundaryShape[i], _BoundaryMatrixInv[i]))
|
||||
index = i;
|
||||
}
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ struct BoundaryShape
|
|||
// capsule | centerA radius centerB __pad
|
||||
// sphere | center radius __pad __pad
|
||||
// torus | center radiusA axis radiusB
|
||||
// cube | __pad __pad __pad __pad
|
||||
// cube | extent __pad __pad __pad
|
||||
|
||||
float3 pA; float tA;
|
||||
float3 pB; float tB;
|
||||
|
|
|
@ -35,6 +35,14 @@ namespace Unity.DemoTeam.Hair
|
|||
}
|
||||
}
|
||||
|
||||
public static class Matrix4x4Extensions
|
||||
{
|
||||
public static Matrix4x4 WithoutScale(this Matrix4x4 value)
|
||||
{
|
||||
return Matrix4x4.TRS(value.GetColumn(3), Quaternion.LookRotation(value.GetColumn(2), value.GetColumn(1)), Vector3.one);
|
||||
}
|
||||
}
|
||||
|
||||
public static class QuaternionExtensions
|
||||
{
|
||||
public static Vector4 ToVector4(this Quaternion value)
|
||||
|
|
Загрузка…
Ссылка в новой задаче