WX-Game1/Assets/Samples/Unity Physics/1.3.10/Custom Physics Authoring/Unity.Physics.Custom/Utilities/BakeGeometryJobsExtensions.cs

127 lines
5.2 KiB
C#

using Unity.Collections;
using Unity.Jobs;
using Unity.Mathematics;
namespace Unity.Physics.Authoring
{
static partial class PhysicsShapeExtensions
{
public static class BakeBoxJobExtension
{
internal static float4x4 GetBakeToShape(PhysicsShapeAuthoring shape, float3 center, EulerAngles orientation)
{
var transform = shape.transform;
var localToWorld = (float4x4)transform.localToWorldMatrix;
var shapeToWorld = shape.GetShapeToWorldMatrix();
quaternion tmpOri = orientation;
return Math.GetBakeToShape(localToWorld, shapeToWorld, ref center,
ref tmpOri);
}
}
public static class BakeCapsuleJobExtension
{
internal static float4x4 GetBakeToShape(PhysicsShapeAuthoring shape, float3 center, EulerAngles orientation)
{
var transform = shape.transform;
var localToWorld = (float4x4)transform.localToWorldMatrix;
var shapeToWorld = shape.GetShapeToWorldMatrix();
quaternion tmpOri = orientation;
return Math.GetBakeToShape(localToWorld, shapeToWorld, ref center,
ref tmpOri, bakeUniformScale: true, makeZAxisPrimaryBasis: true);
}
}
public static void SetBakedCapsuleSize(this PhysicsShapeAuthoring shape, float height, float radius)
{
var capsule = shape.GetCapsuleProperties();
var center = capsule.Center;
var bakeToShape = BakeCapsuleJobExtension.GetBakeToShape(shape, center, capsule.OrientationEuler);
var scale = bakeToShape.DecomposeScale();
var newRadius = radius / math.cmax(scale.xy);
if (math.abs(capsule.Radius - newRadius) > kMinimumChange)
capsule.Radius = newRadius;
height /= scale.z;
if (math.abs(math.length(capsule.Height - height)) > kMinimumChange)
capsule.Height = height;
shape.SetCapsule(capsule);
}
internal static CapsuleGeometryAuthoring BakeToBodySpace(
this CapsuleGeometryAuthoring capsule, float4x4 localToWorld, float4x4 shapeToWorld, bool bakeUniformScale = true
)
{
using (var geometry = new NativeArray<CapsuleGeometryAuthoring>(1, Allocator.TempJob) { [0] = capsule })
{
var job = new BakeCapsuleJob
{
Capsule = geometry,
LocalToWorld = localToWorld,
ShapeToWorld = shapeToWorld,
BakeUniformScale = bakeUniformScale
};
job.Run();
return geometry[0];
}
}
public static class BakeCylinderJobExtension
{
internal static float4x4 GetBakeToShape(PhysicsShapeAuthoring shape, float3 center, EulerAngles orientation)
{
var transform = shape.transform;
var localToWorld = (float4x4)transform.localToWorldMatrix;
var shapeToWorld = shape.GetShapeToWorldMatrix();
quaternion tmpOri = orientation;
return Math.GetBakeToShape(localToWorld, shapeToWorld, ref center,
ref tmpOri, bakeUniformScale: true, makeZAxisPrimaryBasis: true);
}
}
public static CylinderGeometry GetBakedCylinderProperties(this PhysicsShapeAuthoring shape)
{
var cylinder = shape.GetCylinderProperties(out var orientation);
return cylinder.BakeToBodySpace(shape.transform.localToWorldMatrix, shape.GetShapeToWorldMatrix(),
orientation);
}
public static void SetBakedSphereRadius(this PhysicsShapeAuthoring shape, float radius)
{
var sphere = shape.GetSphereProperties(out EulerAngles eulerAngles);
quaternion orientation = eulerAngles;
var center = sphere.Center;
radius = math.abs(radius);
var basisToWorld = Math.GetBasisToWorldMatrix(shape.transform.localToWorldMatrix, center, orientation, 1f);
var basisPriority = basisToWorld.HasShear() ? Math.GetBasisAxisPriority(basisToWorld) : Math.Constants.DefaultAxisPriority;
var bakeToShape = Math.GetPrimitiveBakeToShapeMatrix(shape.transform.localToWorldMatrix, shape.GetShapeToWorldMatrix(), ref center, ref orientation, basisPriority);
var scale = math.cmax(bakeToShape.DecomposeScale());
var newRadius = radius / scale;
sphere.Radius = newRadius;
shape.SetSphere(sphere);
}
public static void SetBakedPlaneSize(this PhysicsShapeAuthoring shape, float2 size)
{
shape.GetPlaneProperties(out var center, out var planeSize, out EulerAngles orientation);
var prevSize = math.abs(planeSize);
size = math.abs(size);
if (math.abs(size[0] - prevSize[0]) < kMinimumChange) size[0] = prevSize[0];
if (math.abs(size[1] - prevSize[1]) < kMinimumChange) size[1] = prevSize[1];
planeSize = size;
shape.SetPlane(center, planeSize, orientation);
}
}
}