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);
        }
Beispiel #3
0
        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);
            }
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        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
     );
Beispiel #14
0
        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);
        }