internal static void GetBakedMeshProperties( this PhysicsShapeAuthoring shape, NativeList <float3> pointCloud, NativeList <int3> triangles, out Hash128 hashedInputs ) { using (var inputs = new NativeList <HashableShapeInputs>(8, Allocator.TempJob)) { shape.GetMeshProperties(pointCloud, triangles, true, inputs); shape.BakePoints(pointCloud); using (var hash = new NativeArray <Hash128>(1, Allocator.TempJob)) using (var allSkinIndices = new NativeArray <int>(0, Allocator.TempJob)) using (var allBlendShapeWeights = new NativeArray <float>(0, Allocator.TempJob)) { var job = new GetShapeInputsHashJob { Result = hash, ForceUniqueIdentifier = (uint)(shape.ForceUnique ? shape.GetInstanceID() : 0), Material = shape.GetMaterial(), CollisionFilter = shape.GetFilter(), BakeFromShape = shape.GetLocalToShapeMatrix(), Inputs = inputs, AllSkinIndices = allSkinIndices, AllBlendShapeWeights = allBlendShapeWeights }; job.Run(); hashedInputs = hash[0]; } } }
internal static void SetBakedCylinderSize(this PhysicsShapeAuthoring shape, float height, float radius, float bevelRadius) { var cylinder = shape.GetCylinderProperties(out EulerAngles orientation); var center = cylinder.Center; var bakeToShape = BakeCylinderJob.GetBakeToShape(shape, center, orientation); var scale = bakeToShape.DecomposeScale(); var newRadius = radius / math.cmax(scale.xy); if (math.abs(cylinder.Radius - newRadius) > kMinimumChange) { cylinder.Radius = newRadius; } if (math.abs(cylinder.BevelRadius - bevelRadius) > kMinimumChange) { cylinder.BevelRadius = bevelRadius; } var newHeight = math.max(0, height / scale.z); if (math.abs(cylinder.Height - newHeight) > kMinimumChange) { cylinder.Height = newHeight; } shape.SetCylinder(cylinder, orientation); }
internal static Hash128 GetBakedConvexInputs(this PhysicsShapeAuthoring shape, HashSet <UnityEngine.Mesh> meshAssets) { using (var inputs = new NativeList <HashableShapeInputs>(8, Allocator.TempJob)) using (var allSkinIndices = new NativeList <int>(4096, Allocator.TempJob)) using (var allBlendShapeWeights = new NativeList <float>(64, Allocator.TempJob)) { shape.GetConvexHullProperties(default, true, inputs, allSkinIndices, allBlendShapeWeights, meshAssets);
internal static void GetBakedMeshProperties( this PhysicsShapeAuthoring shape, NativeList <float3> pointCloud, NativeList <int> triangles ) { shape.GetMeshProperties(pointCloud, triangles); shape.BakePoints(pointCloud); }
internal static void SetBakedBoxSize(this PhysicsShapeAuthoring shape, float3 size, float bevelRadius) { var box = shape.GetBoxProperties(out var orientation); var center = box.Center; var prevSize = math.abs(box.Size); size = math.abs(size); var bakeToShape = BakeBoxJob.GetBakeToShape(shape, center, orientation); var scale = bakeToShape.DecomposeScale(); size /= scale; if (math.abs(size[0] - prevSize[0]) < kMinimumChange) { size[0] = prevSize[0]; } if (math.abs(size[1] - prevSize[1]) < kMinimumChange) { size[1] = prevSize[1]; } if (math.abs(size[2] - prevSize[2]) < kMinimumChange) { size[2] = prevSize[2]; } box.BevelRadius = bevelRadius; box.Size = size; shape.SetBox(box, orientation); }
public static float4x4 GetBakeToShape(PhysicsShapeAuthoring shape, float3 center, EulerAngles orientation) { var transform = shape.transform; var localToWorld = (float4x4)transform.localToWorldMatrix; var shapeToWorld = shape.GetShapeToWorldMatrix(); return(GetBakeToShape(localToWorld, shapeToWorld, ref center, ref orientation)); }
internal static CapsuleGeometry GetBakedCapsuleProperties( this PhysicsShapeAuthoring shape, out float3 center, out float height, out EulerAngles orientation ) { var capsule = shape.GetCapsuleProperties(out orientation); return(capsule.BakeToBodySpace(shape.transform.localToWorldMatrix, shape.GetShapeToWorldMatrix(), out center, out height, ref orientation)); }
internal static CollisionFilter GetFilter(this PhysicsShapeAuthoring shape) { // TODO: determine optimal workflow for specifying group index return(new CollisionFilter { BelongsTo = shape.BelongsTo.Value, CollidesWith = shape.CollidesWith.Value }); }
internal static BoxGeometry GetBakedBoxProperties(this PhysicsShapeAuthoring shape) { var box = shape.GetBoxProperties(out var orientation); var center = box.Center; var size = box.Size; var bevelRadius = box.BevelRadius; var localToWorld = (float4x4)shape.transform.localToWorldMatrix; float4x4 bakeToShape; var basisPriority = k_DefaultAxisPriority; var sheared = localToWorld.HasShear(); if (localToWorld.HasNonUniformScale() || sheared) { if (sheared) { var basisToWorld = GetBasisToWorldMatrix(shape.transform.localToWorldMatrix, center, orientation, size); basisPriority = GetBasisAxisPriority(basisToWorld); } bakeToShape = GetPrimitiveBakeToShapeMatrix(shape, ref center, ref orientation, size, basisPriority); var s = new float3( math.length(bakeToShape[basisPriority[2]]), math.length(bakeToShape[basisPriority[1]]), math.length(bakeToShape[basisPriority[0]]) ); bevelRadius *= math.cmin(s / size); size = s; } else { bakeToShape = GetPrimitiveBakeToShapeMatrix(shape, ref center, ref orientation, 1f, basisPriority); var s = new float3( math.length(bakeToShape.c0), math.length(bakeToShape.c1), math.length(bakeToShape.c2) ); bevelRadius *= math.cmin(s); size *= s; } return(new BoxGeometry { Center = center, Orientation = orientation, Size = size, BevelRadius = bevelRadius }); }
internal static void GetBakedPlaneProperties( this PhysicsShapeAuthoring shape, out float3 vertex0, out float3 vertex1, out float3 vertex2, out float3 vertex3 ) { shape.GetPlaneProperties(out var center, out var size, out EulerAngles orientation); BakeToBodySpace( center, size, orientation, shape.transform.localToWorldMatrix, shape.GetShapeToWorldMatrix(), out vertex0, out vertex1, out vertex2, out vertex3 ); }
internal static void GetBakedConvexProperties( this PhysicsShapeAuthoring shape, NativeList <float3> pointCloud, out ConvexHullGenerationParameters generationParameters, out Hash128 hashedInputs ) { using (var inputs = new NativeList <HashableShapeInputs>(8, Allocator.TempJob)) using (var allSkinIndices = new NativeList <int>(4096, Allocator.TempJob)) using (var allBlendShapeWeights = new NativeList <float>(64, Allocator.TempJob)) { shape.GetConvexHullProperties(pointCloud, true, inputs, allSkinIndices, allBlendShapeWeights); shape.BakePoints(pointCloud); // compute convex radius var center = float3.zero; var orientation = EulerAngles.Default; var localToWorld = shape.transform.localToWorldMatrix; var shapeToWorld = shape.GetShapeToWorldMatrix(); var bakeToShape = GetPrimitiveBakeToShapeMatrix(localToWorld, shapeToWorld, ref center, ref orientation, 1f, k_DefaultAxisPriority); using (var aabb = new NativeArray <Aabb>(1, Allocator.TempJob)) { new GetAabbJob { Points = pointCloud, Aabb = aabb }.Run(); HashableShapeInputs.GetQuantizedTransformations(bakeToShape, aabb[0], out bakeToShape); } var s = new float3(math.length(bakeToShape[0]), math.length(bakeToShape[1]), math.length(bakeToShape[2])); generationParameters = shape.ConvexHullGenerationParameters; generationParameters.SimplificationTolerance = math.max( ConvexHullGenerationParametersExtensions.k_MinRecommendedSimplificationTolerance, math.cmax(s) * generationParameters.SimplificationTolerance ); generationParameters.BevelRadius *= math.cmin(s); using (var hash = new NativeArray <Hash128>(1, Allocator.TempJob)) { var job = new GetShapeInputsHashJob { Result = hash, ForceUniqueIdentifier = (uint)(shape.ForceUnique ? shape.GetInstanceID() : 0), GenerationParameters = generationParameters, Material = shape.GetMaterial(), CollisionFilter = shape.GetFilter(), BakeFromShape = shape.GetLocalToShapeMatrix(), Inputs = inputs, AllSkinIndices = allSkinIndices, AllBlendShapeWeights = allBlendShapeWeights }; job.Run(); hashedInputs = hash[0]; } } }
internal static void GetBakedPlaneProperties( this PhysicsShapeAuthoring shape, out float3 vertex0, out float3 vertex1, out float3 vertex2, out float3 vertex3 ) { GetPlanePoints(shape, out vertex0, out vertex1, out vertex2, out vertex3); var localToShape = shape.GetLocalToShapeMatrix(); vertex0 = math.mul(localToShape, new float4(vertex0, 1f)).xyz; vertex1 = math.mul(localToShape, new float4(vertex1, 1f)).xyz; vertex2 = math.mul(localToShape, new float4(vertex2, 1f)).xyz; vertex3 = math.mul(localToShape, new float4(vertex3, 1f)).xyz; }
internal static void GetPlanePoints( this PhysicsShapeAuthoring shape, out float3 vertex0, out float3 vertex1, out float3 vertex2, out float3 vertex3 ) { shape.GetPlaneProperties(out var center, out var size, out EulerAngles orientation); 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)); }
internal static Material GetMaterial(this PhysicsShapeAuthoring shape) { // TODO: TBD how we will author editor content for other shape flags return(new Material { Friction = shape.Friction.Value, FrictionCombinePolicy = shape.Friction.CombineMode, Restitution = shape.Restitution.Value, RestitutionCombinePolicy = shape.Restitution.CombineMode, CollisionResponse = shape.CollisionResponse, CustomTags = shape.CustomTags.Value }); }
public GetActiveChildrenScope(PhysicsShapeAuthoring shape, Transform root) { m_Disposed = false; m_Shape = shape; m_Root = root; m_PrimaryBody = PhysicsShapeExtensions.GetPrimaryBody(root.gameObject); m_CheckIfComponentBelongsToShape = root.transform.IsChildOf(shape.transform); if (s_BufferUsed) { throw new InvalidOperationException($"Cannot nest two {GetType()}"); } s_BufferUsed = true; root.GetComponentsInChildren(true, s_Buffer); }
// matrix to transform point on a primitive from bake space into space of the shape static float4x4 GetPrimitiveBakeToShapeMatrix( PhysicsShapeAuthoring shape, ref float3 center, ref EulerAngles orientation, float3 scale, int3 basisPriority ) { if ( basisPriority.x == basisPriority.y || basisPriority.x == basisPriority.z || basisPriority.y == basisPriority.z ) { throw new ArgumentException(nameof(basisPriority)); } var localToBasis = float4x4.TRS(center, orientation, scale); // correct for imprecision in cases of no scale to prevent e.g., convex radius from being altered if (scale.Equals(new float3(1f))) { localToBasis.c0 = math.normalizesafe(localToBasis.c0); localToBasis.c1 = math.normalizesafe(localToBasis.c1); localToBasis.c2 = math.normalizesafe(localToBasis.c2); } var localToBake = math.mul(shape.transform.localToWorldMatrix, localToBasis); if (localToBake.HasNonUniformScale() || localToBake.HasShear()) { // deskew second longest axis with respect to longest axis localToBake[basisPriority[1]] = DeskewSecondaryAxis(localToBake[basisPriority[0]], localToBake[basisPriority[1]]); // recompute third axes from first two var n2 = math.normalizesafe( new float4(math.cross(localToBake[basisPriority[0]].xyz, localToBake[basisPriority[1]].xyz), 0f) ); localToBake[basisPriority[2]] = n2 * math.dot(localToBake[basisPriority[2]], n2); } var bakeToShape = math.mul(math.inverse(shape.GetShapeToWorldMatrix()), localToBake); // transform baked center/orientation (i.e. primitive basis) into shape space orientation.SetValue( quaternion.LookRotationSafe(bakeToShape[basisPriority[0]].xyz, bakeToShape[basisPriority[1]].xyz) ); center = bakeToShape.c3.xyz; return(bakeToShape); }
internal static void SetBakedSphereRadius(this PhysicsShapeAuthoring shape, float radius) { var sphere = shape.GetSphereProperties(out EulerAngles eulerAngles); var center = sphere.Center; radius = math.abs(radius); var basisToWorld = GetBasisToWorldMatrix(shape.transform.localToWorldMatrix, center, eulerAngles, 1f); var basisPriority = basisToWorld.HasShear() ? GetBasisAxisPriority(basisToWorld) : k_DefaultAxisPriority; var bakeToShape = GetPrimitiveBakeToShapeMatrix(shape.transform.localToWorldMatrix, shape.GetShapeToWorldMatrix(), ref center, ref eulerAngles, 1f, basisPriority); var scale = math.cmax(bakeToShape.DecomposeScale()); var newRadius = radius / scale; sphere.Radius = newRadius; shape.SetSphere(sphere); }
internal static CapsuleGeometry GetBakedCapsuleProperties( this PhysicsShapeAuthoring shape, out float3 center, out float height, out EulerAngles orientation ) { var capsule = shape.GetCapsuleProperties(out orientation); var radius = capsule.Radius; center = capsule.GetCenter(); height = capsule.GetHeight(); var s = new float3(radius * 2f, radius * 2f, height); var localToWorld = (float4x4)shape.transform.localToWorldMatrix; var basisToWorld = GetBasisToWorldMatrix(localToWorld, center, orientation, s); var basisPriority = k_DefaultAxisPriority; var sheared = localToWorld.HasShear(); if (localToWorld.HasNonUniformScale() || sheared) { if (sheared) { basisPriority = GetBasisAxisPriority(basisToWorld); } MakeZAxisPrimaryBasis(ref basisPriority); } var bakeToShape = GetPrimitiveBakeToShapeMatrix(shape, ref center, ref orientation, 1f, basisPriority); height *= math.length(bakeToShape.c2); radius *= math.max(math.length(bakeToShape.c0), math.length(bakeToShape.c1)); var axis = math.mul(orientation, new float3 { z = 1f }); var endPoint = axis * math.max(0f, 0.5f * height - radius); return(new CapsuleGeometry { Vertex0 = center + endPoint, Vertex1 = center - endPoint, Radius = radius }); }
internal static CylinderGeometry GetBakedCylinderProperties(this PhysicsShapeAuthoring shape) { var cylinder = shape.GetCylinderProperties(out var orientation); var center = cylinder.Center; var height = cylinder.Height; var radius = cylinder.Radius; var size = new float3(radius * 2f, radius * 2f, height); var localToWorld = (float4x4)shape.transform.localToWorldMatrix; var basisToWorld = GetBasisToWorldMatrix(localToWorld, center, orientation, size); var basisPriority = k_DefaultAxisPriority; var sheared = localToWorld.HasShear(); if (localToWorld.HasNonUniformScale() || sheared) { if (sheared) { basisPriority = GetBasisAxisPriority(basisToWorld); } MakeZAxisPrimaryBasis(ref basisPriority); } var bakeToShape = GetPrimitiveBakeToShapeMatrix(shape, ref center, ref orientation, 1f, basisPriority); height *= math.length(bakeToShape.c2); radius *= math.max(math.length(bakeToShape.c0), math.length(bakeToShape.c1)); var s = new float3( math.length(bakeToShape[basisPriority[2]]), math.length(bakeToShape[basisPriority[1]]), math.length(bakeToShape[basisPriority[0]]) ); return(new CylinderGeometry { Center = center, Orientation = orientation, Height = height, Radius = radius, BevelRadius = math.min(cylinder.BevelRadius * math.cmax(s / size), height * 0.5f), SideCount = cylinder.SideCount }); }
internal static SphereGeometry GetBakedSphereProperties(this PhysicsShapeAuthoring shape, out EulerAngles orientation) { var sphere = shape.GetSphereProperties(out orientation); var center = sphere.Center; var radius = sphere.Radius; var basisToWorld = GetBasisToWorldMatrix(shape.transform.localToWorldMatrix, center, orientation, 1f); var basisPriority = basisToWorld.HasShear() ? GetBasisAxisPriority(basisToWorld) : k_DefaultAxisPriority; var bakeToShape = GetPrimitiveBakeToShapeMatrix(shape, ref center, ref orientation, 1f, basisPriority); radius *= math.cmax( new float3(math.length(bakeToShape.c0), math.length(bakeToShape.c1), math.length(bakeToShape.c2)) ); return(new SphereGeometry { Center = center, Radius = radius }); }
internal 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); }
internal static void GetBakedConvexProperties( this PhysicsShapeAuthoring shape, NativeList <float3> pointCloud, out ConvexHullGenerationParameters generationParameters ) { shape.GetConvexHullProperties(pointCloud); shape.BakePoints(pointCloud); // compute convex radius var center = float3.zero; var orientation = EulerAngles.Default; var bakeToShape = GetPrimitiveBakeToShapeMatrix(shape, ref center, ref orientation, 1f, k_DefaultAxisPriority); var s = new float3(math.length(bakeToShape[0]), math.length(bakeToShape[1]), math.length(bakeToShape[2])); generationParameters = shape.ConvexHullGenerationParameters; generationParameters.SimplificationTolerance = math.max( ConvexHullGenerationParametersExtensions.k_MinRecommendedSimplificationTolerance, math.cmax(s) * generationParameters.SimplificationTolerance ); generationParameters.BevelRadius *= math.cmin(s); }
internal static Material GetMaterial(this PhysicsShapeAuthoring shape) { // TODO: TBD how we will author editor content for other shape flags var flags = new Material.MaterialFlags(); if (shape.IsTrigger) { flags = Material.MaterialFlags.IsTrigger; } else if (shape.RaisesCollisionEvents) { flags = Material.MaterialFlags.EnableCollisionEvents; } return(new Material { Friction = shape.Friction.Value, FrictionCombinePolicy = shape.Friction.CombineMode, Restitution = shape.Restitution.Value, RestitutionCombinePolicy = shape.Restitution.CombineMode, Flags = flags, CustomTags = shape.CustomTags.Value }); }
internal static void SetBakedCapsuleSize(this PhysicsShapeAuthoring shape, float height, float radius) { var capsule = shape.GetCapsuleProperties(); var center = capsule.Center; var bakeToShape = BakeCapsuleJob.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 BoxGeometry GetBakedBoxProperties(this PhysicsShapeAuthoring shape) { var box = shape.GetBoxProperties(out var orientation); return(box.BakeToBodySpace(shape.transform.localToWorldMatrix, shape.GetShapeToWorldMatrix(), orientation)); }
internal static SphereGeometry GetBakedSphereProperties(this PhysicsShapeAuthoring shape, out EulerAngles orientation) { var sphere = shape.GetSphereProperties(out orientation); return(sphere.BakeToBodySpace(shape.transform.localToWorldMatrix, shape.GetShapeToWorldMatrix(), ref orientation)); }
internal static GameObject GetPrimaryBody(this PhysicsShapeAuthoring shape) => GetPrimaryBody(shape.gameObject);
internal static CylinderGeometry GetBakedCylinderProperties(this PhysicsShapeAuthoring shape) { var cylinder = shape.GetCylinderProperties(out var orientation); return(cylinder.BakeToBodySpace(shape.transform.localToWorldMatrix, shape.GetShapeToWorldMatrix(), orientation)); }
internal static CapsuleGeometryAuthoring GetBakedCapsuleProperties(this PhysicsShapeAuthoring shape) { var capsule = shape.GetCapsuleProperties(); return(capsule.BakeToBodySpace(shape.transform.localToWorldMatrix, shape.GetShapeToWorldMatrix())); }