286 lines
10 KiB
C#
286 lines
10 KiB
C#
using Unity.Burst;
|
|
using Unity.Collections;
|
|
using Unity.Jobs;
|
|
using Unity.Mathematics;
|
|
using UnityEngine;
|
|
|
|
namespace Unity.Physics.Authoring
|
|
{
|
|
static partial class PhysicsShapeExtensions
|
|
{
|
|
#region Box
|
|
[BurstCompile]
|
|
internal struct BakeBoxJob : IJob
|
|
{
|
|
public NativeArray<BoxGeometry> Box;
|
|
|
|
public float4x4 LocalToWorld;
|
|
public float4x4 ShapeToWorld;
|
|
public EulerAngles Orientation;
|
|
public bool BakeUniformScale;
|
|
|
|
public void Execute()
|
|
{
|
|
var center = Box[0].Center;
|
|
var size = Box[0].Size;
|
|
var bevelRadius = Box[0].BevelRadius;
|
|
quaternion orientation = Orientation;
|
|
|
|
var bakeToShape = Math.GetBakeToShape(LocalToWorld, ShapeToWorld, ref center, ref orientation, BakeUniformScale);
|
|
bakeToShape = math.mul(bakeToShape, float4x4.Scale(size));
|
|
|
|
var scale = bakeToShape.DecomposeScale();
|
|
|
|
size = scale;
|
|
|
|
Box[0] = new BoxGeometry
|
|
{
|
|
Center = center,
|
|
Orientation = orientation,
|
|
Size = size,
|
|
BevelRadius = math.clamp(bevelRadius, 0f, 0.5f * math.cmin(size)),
|
|
};
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Capsule
|
|
[BurstCompile]
|
|
internal struct BakeCapsuleJob : IJob
|
|
{
|
|
public NativeArray<CapsuleGeometryAuthoring> Capsule;
|
|
|
|
public float4x4 LocalToWorld;
|
|
public float4x4 ShapeToWorld;
|
|
public bool BakeUniformScale;
|
|
|
|
public void Execute()
|
|
{
|
|
var radius = Capsule[0].Radius;
|
|
var center = Capsule[0].Center;
|
|
var height = Capsule[0].Height;
|
|
quaternion orientation = Capsule[0].OrientationEuler;
|
|
|
|
var bakeToShape = Math.GetBakeToShape(LocalToWorld, ShapeToWorld, ref center, ref orientation, BakeUniformScale, makeZAxisPrimaryBasis: true);
|
|
var scale = bakeToShape.DecomposeScale();
|
|
|
|
radius *= math.cmax(scale.xy);
|
|
height = math.max(0, height * scale.z);
|
|
|
|
Capsule[0] = new CapsuleGeometryAuthoring
|
|
{
|
|
OrientationEuler = orientation,
|
|
Center = center,
|
|
Height = height,
|
|
Radius = radius
|
|
};
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Cylinder
|
|
[BurstCompile]
|
|
internal struct BakeCylinderJob : IJob
|
|
{
|
|
public NativeArray<CylinderGeometry> Cylinder;
|
|
|
|
public float4x4 LocalToWorld;
|
|
public float4x4 ShapeToWorld;
|
|
public EulerAngles Orientation;
|
|
public bool BakeUniformScale;
|
|
|
|
public void Execute()
|
|
{
|
|
var center = Cylinder[0].Center;
|
|
var height = Cylinder[0].Height;
|
|
var radius = Cylinder[0].Radius;
|
|
var bevelRadius = Cylinder[0].BevelRadius;
|
|
quaternion orientation = Orientation;
|
|
|
|
var bakeToShape = Math.GetBakeToShape(LocalToWorld, ShapeToWorld, ref center, ref orientation, BakeUniformScale, makeZAxisPrimaryBasis: true);
|
|
var scale = bakeToShape.DecomposeScale();
|
|
|
|
height *= scale.z;
|
|
radius *= math.cmax(scale.xy);
|
|
|
|
Cylinder[0] = new CylinderGeometry
|
|
{
|
|
Center = center,
|
|
Orientation = orientation,
|
|
Height = height,
|
|
Radius = radius,
|
|
BevelRadius = math.min(bevelRadius, math.min(height * 0.5f, radius)),
|
|
SideCount = Cylinder[0].SideCount
|
|
};
|
|
}
|
|
}
|
|
|
|
internal static CylinderGeometry BakeToBodySpace(
|
|
this CylinderGeometry cylinder, float4x4 localToWorld, float4x4 shapeToWorld, EulerAngles orientation, bool bakeUniformScale = true
|
|
)
|
|
{
|
|
using (var geometry = new NativeArray<CylinderGeometry>(1, Allocator.TempJob) { [0] = cylinder })
|
|
{
|
|
var job = new BakeCylinderJob
|
|
{
|
|
Cylinder = geometry,
|
|
LocalToWorld = localToWorld,
|
|
ShapeToWorld = shapeToWorld,
|
|
Orientation = orientation,
|
|
BakeUniformScale = bakeUniformScale
|
|
};
|
|
job.Run();
|
|
return geometry[0];
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
#region Sphere
|
|
[BurstCompile]
|
|
struct BakeSphereJob : IJob
|
|
{
|
|
public NativeArray<SphereGeometry> Sphere;
|
|
public NativeArray<EulerAngles> Orientation;
|
|
public float4x4 LocalToWorld;
|
|
public float4x4 ShapeToWorld;
|
|
public bool BakeUniformScale;
|
|
|
|
public void Execute()
|
|
{
|
|
var center = Sphere[0].Center;
|
|
var radius = Sphere[0].Radius;
|
|
quaternion orientation = Orientation[0];
|
|
|
|
var basisToWorld = Math.GetBasisToWorldMatrix(LocalToWorld, center, orientation, 1f);
|
|
var basisPriority = basisToWorld.HasShear() ? Math.GetBasisAxisPriority(basisToWorld) : Math.Constants.DefaultAxisPriority;
|
|
var bakeToShape = Math.GetPrimitiveBakeToShapeMatrix(LocalToWorld, ShapeToWorld, ref center, ref orientation, basisPriority, BakeUniformScale);
|
|
|
|
radius *= math.cmax(bakeToShape.DecomposeScale());
|
|
|
|
Sphere[0] = new SphereGeometry
|
|
{
|
|
Center = center,
|
|
Radius = radius
|
|
};
|
|
Orientation[0] = orientation;
|
|
}
|
|
}
|
|
|
|
internal static SphereGeometry BakeToBodySpace(
|
|
this SphereGeometry sphere, float4x4 localToWorld, float4x4 shapeToWorld, ref EulerAngles orientation, bool bakeUniformScale = true
|
|
)
|
|
{
|
|
using (var geometry = new NativeArray<SphereGeometry>(1, Allocator.TempJob) { [0] = sphere })
|
|
using (var outOrientation = new NativeArray<EulerAngles>(1, Allocator.TempJob) { [0] = orientation })
|
|
{
|
|
var job = new BakeSphereJob
|
|
{
|
|
Sphere = geometry,
|
|
Orientation = outOrientation,
|
|
LocalToWorld = localToWorld,
|
|
ShapeToWorld = shapeToWorld,
|
|
BakeUniformScale = bakeUniformScale
|
|
};
|
|
job.Run();
|
|
orientation = outOrientation[0];
|
|
return geometry[0];
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Plane
|
|
|
|
[BurstCompile]
|
|
struct BakePlaneJob : IJob
|
|
{
|
|
public NativeArray<float3x4> Vertices;
|
|
public float3 Center;
|
|
public float2 Size;
|
|
public EulerAngles Orientation;
|
|
public float4x4 BakeFromShape;
|
|
|
|
public void Execute()
|
|
{
|
|
var v = Vertices[0];
|
|
GetPlanePoints(Center, Size, Orientation, out v.c0, out v.c1, out v.c2, out v.c3);
|
|
v.c0 = math.mul(BakeFromShape, new float4(v.c0, 1f)).xyz;
|
|
v.c1 = math.mul(BakeFromShape, new float4(v.c1, 1f)).xyz;
|
|
v.c2 = math.mul(BakeFromShape, new float4(v.c2, 1f)).xyz;
|
|
v.c3 = math.mul(BakeFromShape, new float4(v.c3, 1f)).xyz;
|
|
Vertices[0] = v;
|
|
}
|
|
}
|
|
|
|
internal static void BakeToBodySpace(
|
|
float3 center, float2 size, EulerAngles orientation, float4x4 bakeFromShape,
|
|
out float3 vertex0, out float3 vertex1, out float3 vertex2, out float3 vertex3
|
|
)
|
|
{
|
|
using (var geometry = new NativeArray<float3x4>(1, Allocator.TempJob))
|
|
{
|
|
var job = new BakePlaneJob
|
|
{
|
|
Vertices = geometry,
|
|
Center = center,
|
|
Size = size,
|
|
Orientation = orientation,
|
|
BakeFromShape = bakeFromShape
|
|
};
|
|
job.Run();
|
|
vertex0 = geometry[0].c0;
|
|
vertex1 = geometry[0].c1;
|
|
vertex2 = geometry[0].c2;
|
|
vertex3 = geometry[0].c3;
|
|
}
|
|
}
|
|
|
|
internal static void GetPlanePoints(
|
|
float3 center, float2 size, EulerAngles orientation,
|
|
out float3 vertex0, out float3 vertex1, out float3 vertex2, out float3 vertex3
|
|
)
|
|
{
|
|
var sizeYUp = math.float3(size.x, 0, size.y);
|
|
|
|
vertex0 = center + math.mul(orientation, sizeYUp * math.float3(-0.5f, 0, 0.5f));
|
|
vertex1 = center + math.mul(orientation, sizeYUp * math.float3(0.5f, 0, 0.5f));
|
|
vertex2 = center + math.mul(orientation, sizeYUp * math.float3(0.5f, 0, -0.5f));
|
|
vertex3 = center + math.mul(orientation, sizeYUp * math.float3(-0.5f, 0, -0.5f));
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ShapeInputHash
|
|
#if !(UNITY_ANDROID && !UNITY_64) // !Android32
|
|
// Getting memory alignment errors from HashUtility.Hash128 on Android32
|
|
[BurstCompile]
|
|
#endif
|
|
internal struct GetShapeInputsHashJob : IJob
|
|
{
|
|
public NativeArray<Hash128> Result;
|
|
|
|
public uint ForceUniqueIdentifier;
|
|
public ConvexHullGenerationParameters GenerationParameters;
|
|
public Material Material;
|
|
public CollisionFilter CollisionFilter;
|
|
public float4x4 BakeFromShape;
|
|
|
|
[ReadOnly] public NativeArray<HashableShapeInputs> Inputs;
|
|
[ReadOnly] public NativeArray<int> AllSkinIndices;
|
|
[ReadOnly] public NativeArray<float> AllBlendShapeWeights;
|
|
|
|
public void Execute()
|
|
{
|
|
Result[0] = HashableShapeInputs.GetHash128(
|
|
ForceUniqueIdentifier, GenerationParameters, Material, CollisionFilter, BakeFromShape,
|
|
Inputs, AllSkinIndices, AllBlendShapeWeights
|
|
);
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|