internal override ShapeComputationData GenerateComputationData( LegacyBox shape, ColliderInstance colliderInstance, NativeList <float3> allConvexHullPoints, NativeList <float3> allMeshVertices, NativeList <int3> allMeshTriangles ) { var res = base.GenerateComputationData(shape, colliderInstance, allConvexHullPoints, allMeshVertices, allMeshTriangles); res.ShapeType = ShapeType.Box; var shapeLocalToWorld = shape.transform.localToWorldMatrix; var worldCenter = math.mul(shapeLocalToWorld, new float4(shape.center, 1f)); var transformRotation = shape.transform.rotation; var rigidBodyTransform = Math.DecomposeRigidBodyTransform(shapeLocalToWorld); var shapeFromWorld = math.inverse(new float4x4(rigidBodyTransform)); var orientationFixup = math.inverse(math.mul(math.inverse(transformRotation), rigidBodyTransform.rot)); var geometry = new BoxGeometry { Center = math.mul(shapeFromWorld, worldCenter).xyz, Orientation = orientationFixup }; var linearScale = float4x4.TRS(float3.zero, math.inverse(orientationFixup), shape.transform.lossyScale).DecomposeScale(); geometry.Size = math.abs(shape.size * linearScale); geometry.BevelRadius = math.min(ConvexHullGenerationParameters.Default.BevelRadius, math.cmin(geometry.Size) * 0.5f); res.BoxProperties = geometry; return(res); }
internal override ShapeComputationData GenerateComputationData( LegacySphere shape, ColliderInstance colliderInstance, NativeList <float3> allConvexHullPoints, NativeList <float3> allMeshVertices, NativeList <int3> allMeshTriangles ) { var res = base.GenerateComputationData(shape, colliderInstance, allConvexHullPoints, allMeshVertices, allMeshTriangles); res.ShapeType = ShapeType.Sphere; var shapeLocalToWorld = shape.transform.localToWorldMatrix; var worldCenter = math.mul(shapeLocalToWorld, new float4(shape.center, 1f)); var transformRotation = shape.transform.rotation; var rigidBodyTransform = Math.DecomposeRigidBodyTransform(shapeLocalToWorld); var orientationFixup = math.inverse(math.mul(math.inverse(transformRotation), rigidBodyTransform.rot)); var shapeFromWorld = math.inverse(new float4x4(rigidBodyTransform)); var center = math.mul(shapeFromWorld, worldCenter).xyz; var linearScale = float4x4.TRS(float3.zero, math.inverse(orientationFixup), shape.transform.lossyScale).DecomposeScale(); var radius = shape.radius * math.cmax(math.abs(linearScale)); res.SphereProperties = new SphereGeometry { Center = center, Radius = radius }; return(res); }
void GetInputDataFromAuthoringComponent(T shape) { if (!ShouldConvertShape(shape)) { return; } var body = GetPrimaryBody(shape); var instance = new ColliderInstance { AuthoringComponentId = shape.GetInstanceID(), BodyEntity = GetPrimaryEntity(body), ShapeEntity = GetPrimaryEntity(shape), BodyFromShape = ColliderInstance.GetCompoundFromChild(shape.transform, body.transform) }; var data = GenerateComputationData(shape, instance, m_ConvexColliderPoints, m_MeshColliderVertices, m_MeshColliderTriangles); data.Instance.ConvertedAuthoringComponentIndex = m_EndColliderConversionSystem.PushAuthoringComponent(shape); data.Instance.ConvertedBodyTransformIndex = m_EndColliderConversionSystem.PushAuthoringComponent(body.transform); m_ShapeComputationData.Add(data); if (body == shape.gameObject) { DstEntityManager.RemoveParentAndSetWorldTranslationAndRotation(instance.BodyEntity, body.transform); } }
internal override ShapeComputationData GenerateComputationData( LegacyCapsule shape, ColliderInstance colliderInstance, NativeList <float3> allConvexHullPoints, NativeList <float3> allMeshVertices, NativeList <int3> allMeshTriangles ) { var res = base.GenerateComputationData(shape, colliderInstance, allConvexHullPoints, allMeshVertices, allMeshTriangles); res.ShapeType = ShapeType.Capsule; var linearScale = (float3)shape.transform.lossyScale; // radius is max of the two non-height axes var radius = shape.radius * math.cmax(new float3(math.abs(linearScale)) { [shape.direction] = 0f }); var ax = new float3 { [shape.direction] = 1f }; var vertex = ax * (0.5f * shape.height); var rt = new RigidTransform(shape.transform.rotation, shape.transform.position); var worldCenter = math.mul(shape.transform.localToWorldMatrix, new float4(shape.center, 0f)); var offset = math.mul(math.inverse(new float4x4(rt)), worldCenter).xyz - shape.center * math.abs(linearScale); var v0 = offset + ((float3)shape.center + vertex) * math.abs(linearScale) - ax * radius; var v1 = offset + ((float3)shape.center - vertex) * math.abs(linearScale) + ax * radius; res.CapsuleProperties = new CapsuleGeometry { Vertex0 = v0, Vertex1 = v1, Radius = radius }; return(res); }
internal override ShapeComputationData GenerateComputationData( LegacyBox shape, ColliderInstance colliderInstance, NativeList <float3> allConvexHullPoints, NativeList <float3> allMeshVertices, NativeList <int3> allMeshTriangles ) { var res = base.GenerateComputationData(shape, colliderInstance, allConvexHullPoints, allMeshVertices, allMeshTriangles); res.ShapeType = ShapeType.Box; var worldCenter = math.mul(shape.transform.localToWorldMatrix, new float4(shape.center, 1f)); var shapeFromWorld = math.inverse( new float4x4(new RigidTransform(shape.transform.rotation, shape.transform.position)) ); var geometry = new BoxGeometry { Center = math.mul(shapeFromWorld, worldCenter).xyz, Orientation = quaternion.identity }; var linearScale = (float3)shape.transform.lossyScale; geometry.Size = math.abs(shape.size * linearScale); geometry.BevelRadius = math.min(ConvexHullGenerationParameters.Default.BevelRadius, math.cmin(geometry.Size) * 0.5f); res.BoxProperties = geometry; return(res); }
internal override ShapeComputationData GenerateComputationData( T shape, ColliderInstance colliderInstance, NativeList <float3> allConvexHullPoints, NativeList <float3> allMeshVertices, NativeList <int3> allMeshTriangles ) { return(new ShapeComputationData { Instance = colliderInstance, Material = ProduceMaterial(shape), CollisionFilter = ProduceCollisionFilter(shape) }); }
internal override ShapeComputationData GenerateComputationData( LegacyMesh shape, ColliderInstance colliderInstance, NativeList <float3> allConvexHullPoints, NativeList <float3> allMeshVertices, NativeList <int3> allMeshTriangles, HashSet <UnityEngine.Mesh> meshAssets ) { if (shape.sharedMesh == null) { throw new InvalidOperationException( $"No {nameof(LegacyMesh.sharedMesh)} assigned to {typeof(MeshCollider)} on {shape.name}." ); } if (!shape.sharedMesh.IsValidForConversion(shape.gameObject)) { throw new InvalidOperationException( $"Mesh '{shape.sharedMesh}' assigned to {typeof(MeshCollider)} on {shape.name} is not readable. Ensure that you have enabled Read/Write on its import settings." ); } meshAssets.Add(shape.sharedMesh); var res = base.GenerateComputationData(shape, colliderInstance, allConvexHullPoints, allMeshVertices, allMeshTriangles, meshAssets); if (shape.convex) { res.ShapeType = ShapeType.ConvexHull; res.ConvexHullProperties.Material = res.Material; res.ConvexHullProperties.Filter = res.CollisionFilter; res.ConvexHullProperties.GenerationParameters = ConvexHullGenerationParameters.Default; } else { res.ShapeType = ShapeType.Mesh; res.MeshProperties.Material = res.Material; res.MeshProperties.Filter = res.CollisionFilter; res.ConvexHullProperties.GenerationParameters = default; } var transform = shape.transform; var rigidBodyTransform = Math.DecomposeRigidBodyTransform(transform.localToWorldMatrix); var bakeFromShape = math.mul(math.inverse(new float4x4(rigidBodyTransform)), transform.localToWorldMatrix); res.Instance.Hash = HashableShapeInputs.GetHash128( 0u, res.ConvexHullProperties.GenerationParameters, res.Material, res.CollisionFilter, bakeFromShape, new NativeArray <HashableShapeInputs>(1, Allocator.Temp) { [0] = HashableShapeInputs.FromMesh(shape.sharedMesh, float4x4.identity) },
void GetInputDataFromAuthoringComponent(T shape) { var body = GetPrimaryBody(shape); var instance = new ColliderInstance { AuthoringComponentId = shape.GetInstanceID(), BodyEntity = GetPrimaryEntity(body), ShapeEntity = GetPrimaryEntity(shape), BodyFromShape = ColliderInstance.GetCompoundFromChild(shape.transform, body.transform) }; var data = GenerateComputationData(shape, instance, m_ConvexColliderPoints, m_MeshColliderVertices, m_MeshColliderTriangles, m_MeshAssets); data.Instance.ConvertedAuthoringComponentIndex = m_EndColliderConversionSystem.PushAuthoringComponent(shape); data.Instance.ConvertedBodyTransformIndex = m_EndColliderConversionSystem.PushAuthoringComponent(body.transform); m_ShapeComputationData.Add(data); if (BlobComputationContext.NeedToComputeBlobAsset(data.Instance.Hash)) { if (data.ShapeType == ShapeType.ConvexHull) { m_ConvexColliderJobs.TryAdd(data.Instance.Hash, data.ConvexHullProperties); } else if (data.ShapeType == ShapeType.Mesh) { m_MeshColliderJobs.TryAdd(data.Instance.Hash, data.MeshProperties); } } foreach (var mesh in m_MeshAssets) { if (mesh != null) { DeclareAssetDependency(shape.gameObject, mesh); } } m_MeshAssets.Clear(); if (body == shape.gameObject) { DstEntityManager.PostProcessTransformComponents(instance.BodyEntity, body.transform, BodyMotionType.Static); } }
internal override ShapeComputationData GenerateComputationData( LegacyCapsule shape, ColliderInstance colliderInstance, NativeList <float3> allConvexHullPoints, NativeList <float3> allMeshVertices, NativeList <int3> allMeshTriangles, HashSet <UnityEngine.Mesh> meshAssets ) { var res = base.GenerateComputationData(shape, colliderInstance, allConvexHullPoints, allMeshVertices, allMeshTriangles, meshAssets); res.ShapeType = ShapeType.Capsule; var shapeLocalToWorld = (float4x4)shape.transform.localToWorldMatrix; var transformRotation = shape.transform.rotation; var rigidBodyTransform = Math.DecomposeRigidBodyTransform(shapeLocalToWorld); var orientationFixup = math.inverse(math.mul(math.inverse(transformRotation), rigidBodyTransform.rot)); var linearScale = float4x4.TRS(float3.zero, math.inverse(orientationFixup), shape.transform.lossyScale).DecomposeScale(); // radius is max of the two non-height axes var radius = shape.radius * math.cmax(new float3(math.abs(linearScale)) { [shape.direction] = 0f }); var ax = new float3 { [shape.direction] = 1f }; var vertex = ax * (0.5f * shape.height); var worldCenter = math.mul(shapeLocalToWorld, new float4(shape.center, 0f)); var offset = math.mul(math.inverse(new float4x4(rigidBodyTransform)), worldCenter).xyz - shape.center * math.abs(linearScale); var v0 = math.mul(orientationFixup, offset + ((float3)shape.center + vertex) * math.abs(linearScale) - ax * radius); var v1 = math.mul(orientationFixup, offset + ((float3)shape.center - vertex) * math.abs(linearScale) + ax * radius); res.CapsuleProperties = new CapsuleGeometry { Vertex0 = v0, Vertex1 = v1, Radius = radius }; return(res); }
internal override ShapeComputationData GenerateComputationData( LegacySphere shape, ColliderInstance colliderInstance, NativeList <float3> allConvexHullPoints, NativeList <float3> allMeshVertices, NativeList <int3> allMeshTriangles ) { var res = base.GenerateComputationData(shape, colliderInstance, allConvexHullPoints, allMeshVertices, allMeshTriangles); res.ShapeType = ShapeType.Sphere; var worldCenter = math.mul(shape.transform.localToWorldMatrix, new float4(shape.center, 1f)); var shapeFromWorld = math.inverse( new float4x4(new RigidTransform(shape.transform.rotation, shape.transform.position)) ); var center = math.mul(shapeFromWorld, worldCenter).xyz; var linearScale = (float3)shape.transform.lossyScale; var radius = shape.radius * math.cmax(math.abs(linearScale)); res.SphereProperties = new SphereGeometry { Center = center, Radius = radius }; return(res); }
internal override ShapeComputationData GenerateComputationData( PhysicsShapeAuthoring shape, ColliderInstance colliderInstance, NativeList <float3> allConvexHullPoints, NativeList <float3> allMeshVertices, NativeList <int3> allMeshTriangles ) { var res = new ShapeComputationData(); res.Instance = colliderInstance; res.Material = ProduceMaterial(shape); res.CollisionFilter = ProduceCollisionFilter(shape); res.ForceUniqueIdentifier = shape.ForceUnique ? (uint)shape.GetInstanceID() : 0u; var transform = shape.transform; var localToWorld = transform.localToWorldMatrix; var shapeToWorld = shape.GetShapeToWorldMatrix(); EulerAngles orientation; res.ShapeType = shape.ShapeType; switch (shape.ShapeType) { case ShapeType.Box: { res.BoxProperties = shape.GetBoxProperties(out orientation) .BakeToBodySpace(localToWorld, shapeToWorld, orientation); break; } case ShapeType.Capsule: { res.CapsuleProperties = shape.GetCapsuleProperties() .BakeToBodySpace(localToWorld, shapeToWorld) .ToRuntime(); break; } case ShapeType.Sphere: { res.SphereProperties = shape.GetSphereProperties(out orientation) .BakeToBodySpace(localToWorld, shapeToWorld, ref orientation); break; } case ShapeType.Cylinder: { res.CylinderProperties = shape.GetCylinderProperties(out orientation) .BakeToBodySpace(localToWorld, shapeToWorld, orientation); break; } case ShapeType.Plane: { shape.GetPlaneProperties(out var center, out var size, out orientation); PhysicsShapeExtensions.BakeToBodySpace( center, size, orientation, localToWorld, shapeToWorld, out res.PlaneVertices.c0, out res.PlaneVertices.c1, out res.PlaneVertices.c2, out res.PlaneVertices.c3 ); break; } case ShapeType.ConvexHull: { res.ConvexHullProperties.Filter = res.CollisionFilter; res.ConvexHullProperties.Material = res.Material; res.ConvexHullProperties.GenerationParameters = shape.ConvexHullGenerationParameters.ToRunTime(); res.Instance.Hash = shape.GetBakedConvexInputs(); if (BlobComputationContext.NeedToComputeBlobAsset(res.Instance.Hash)) { if (TryGetRegisteredConvexInputs(res.Instance.Hash, out var convexInputs)) { res.ConvexHullProperties.PointCount = convexInputs.PointCount; res.ConvexHullProperties.PointsStart = convexInputs.PointsStart; } else { using (var pointCloud = new NativeList <float3>(65535, Allocator.Temp)) { shape.GetBakedConvexProperties(pointCloud); if (pointCloud.Length == 0) { throw new InvalidOperationException( $"No vertices associated with {shape.name}. Add a {typeof(MeshFilter)} component or assign a readable {nameof(PhysicsShapeAuthoring.CustomMesh)}." ); } res.ConvexHullProperties.PointCount = pointCloud.Length; res.ConvexHullProperties.PointsStart = allConvexHullPoints.Length; allConvexHullPoints.AddRange(pointCloud); } } } break; } case ShapeType.Mesh: { res.MeshProperties.Filter = res.CollisionFilter; res.MeshProperties.Material = res.Material; res.Instance.Hash = shape.GetBakedMeshInputs(); if (BlobComputationContext.NeedToComputeBlobAsset(res.Instance.Hash)) { if (TryGetRegisteredMeshInputs(res.Instance.Hash, out var meshInputs)) { res.MeshProperties.VerticesStart = meshInputs.VerticesStart; res.MeshProperties.VertexCount = meshInputs.VertexCount; res.MeshProperties.TrianglesStart = meshInputs.TrianglesStart; res.MeshProperties.TriangleCount = meshInputs.TriangleCount; } else { const int defaultVertexCount = 2048; using (var vertices = new NativeList <float3>(defaultVertexCount, Allocator.Temp)) using (var triangles = new NativeList <int3>(defaultVertexCount - 2, Allocator.Temp)) { shape.GetBakedMeshProperties(vertices, triangles); if (vertices.Length == 0 || triangles.Length == 0) { throw new InvalidOperationException( $"Invalid mesh data associated with {shape.name}. " + $"Add a {typeof(MeshFilter)} component or assign a {nameof(PhysicsShapeAuthoring.CustomMesh)}. " + "Ensure that you have enabled Read/Write on the mesh's import settings." ); } res.MeshProperties.VerticesStart = allMeshVertices.Length; res.MeshProperties.VertexCount = vertices.Length; res.MeshProperties.TrianglesStart = allMeshTriangles.Length; res.MeshProperties.TriangleCount = triangles.Length; allMeshVertices.AddRange(vertices); allMeshTriangles.AddRange(triangles); } } } break; } } return(res); }
internal void SetLeafDirty(ColliderInstance leaf) => m_ChangedLeavesByBody.Add(leaf.BodyEntity, leaf);
internal abstract ShapeComputationData GenerateComputationData( T shape, ColliderInstance colliderInstance, NativeList <float3> allConvexHullPoints, NativeList <float3> allMeshVertices, NativeList <int3> allMeshTriangles, HashSet <UnityMesh> meshAssets );
internal override ShapeComputationData GenerateComputationData( LegacyMesh shape, ColliderInstance colliderInstance, NativeList <float3> allConvexHullPoints, NativeList <float3> allMeshVertices, NativeList <int3> allMeshTriangles ) { if (shape.sharedMesh == null) { throw new InvalidOperationException( $"No {nameof(LegacyMesh.sharedMesh)} assigned to {typeof(MeshCollider)} on {shape.name}." ); } if (!shape.sharedMesh.IsValidForConversion(shape.gameObject)) { throw new InvalidOperationException( $"Mesh '{shape.sharedMesh}' assigned to {typeof(MeshCollider)} on {shape.name} is not readable. Ensure that you have enabled Read/Write on its import settings." ); } var res = base.GenerateComputationData(shape, colliderInstance, allConvexHullPoints, allMeshVertices, allMeshTriangles); shape.sharedMesh.GetVertices(m_Vertices); var shapeFromWorld = math.inverse( new float4x4(new RigidTransform(shape.transform.rotation, shape.transform.position)) ); var pointCloud = new NativeList <float3>(shape.sharedMesh.vertexCount, Allocator.Temp); for (int i = 0, count = m_Vertices.Count; i < count; ++i) { var worldPt = math.mul(shape.transform.localToWorldMatrix, new float4(m_Vertices[i], 1f)); pointCloud.Add(math.mul(shapeFromWorld, worldPt).xyz); } if (shape.convex) { res.ShapeType = ShapeType.ConvexHull; res.ConvexHullProperties = new ConvexInput { GenerationParameters = ConvexHullGenerationParameters.Default, PointsStart = allConvexHullPoints.Length, PointCount = pointCloud.Length, Filter = res.CollisionFilter, Material = res.Material }; allConvexHullPoints.AddRange(pointCloud); } else { var indices = new NativeArray <int>(shape.sharedMesh.triangles, Allocator.Temp); var triangles = indices.Reinterpret <int3>(UnsafeUtility.SizeOf <int>()); if (pointCloud.Length == 0 || triangles.Length == 0) { throw new InvalidOperationException( $"Invalid mesh data associated with {shape.name}. " + "Ensure that you have enabled Read/Write on the mesh's import settings." ); } res.ShapeType = ShapeType.Mesh; res.MeshProperties = new MeshInput { VerticesStart = allMeshVertices.Length, VertexCount = pointCloud.Length, TrianglesStart = allMeshTriangles.Length, TriangleCount = triangles.Length, Filter = res.CollisionFilter, Material = res.Material }; allMeshVertices.AddRange(pointCloud); allMeshTriangles.AddRange(triangles); } return(res); }