예제 #1
0
 // Compound & Other
 private void CalculateCollisionData(CompoundCollider a, ICollidable b)
 {
     a.colliders.ForEach(collider =>
     {
         ResolveCollision(collider, b);
     });
 }
        public static PhysicsCollider GetEnviromentPhysicsCollider(string name, float scale = 1f)
        {
            PhysicsCollider pc = new PhysicsCollider {
            };

            switch (name)
            {
            case "Kanto|Tree":
                NativeArray <CompoundCollider.ColliderBlobInstance> cs = new NativeArray <CompoundCollider.ColliderBlobInstance>(2, Allocator.TempJob);
                cs[0] = new CompoundCollider.ColliderBlobInstance
                {
                    Collider = CylinderCollider.Create(new CylinderGeometry
                    {
                        Orientation = Quaternion.Euler(new float3(270f, 270f, 0)),
                        Height      = 1f * scale,
                        Radius      = .25f * scale,
                        SideCount   = 20,
                        Center      = new float3(0, .5f, 0) * scale
                    }, new CollisionFilter
                    {
                        BelongsTo    = TriggerEventClass.Collidable,
                        CollidesWith = TriggerEventClass.Collidable,
                        GroupIndex   = 1
                    }),
                    CompoundFromChild = new RigidTransform {
                        rot = quaternion.identity
                    }
                };
                cs[1] = new CompoundCollider.ColliderBlobInstance
                {
                    Collider = CylinderCollider.Create(new CylinderGeometry
                    {
                        Center      = new float3(0, 1.7f, 0) * scale,
                        Orientation = Quaternion.Euler(new float3(90f, 0, 0)),
                        Height      = 1.5f * scale,
                        Radius      = 1f * scale,
                        SideCount   = 20
                    }, new CollisionFilter
                    {
                        BelongsTo    = TriggerEventClass.Collidable,
                        CollidesWith = TriggerEventClass.Collidable,
                        GroupIndex   = 1
                    }),
                    CompoundFromChild = new RigidTransform {
                        rot = quaternion.identity
                    }
                };
                pc = new PhysicsCollider {
                    Value = CompoundCollider.Create(cs)
                };
                cs.Dispose();
                break;

            default:
                Debug.LogWarning("Failed to get collider for \"" + name + "\"");
                break;
            }
            return(pc);
        }
    public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
    {
        var rigComponent = GetComponent <RigComponent>();

        if (rigComponent != null)
        {
            var buffer = dstManager.AddBuffer <PhysicsColliderFollowEntityData>(entity);
            GetData(rigComponent, out Transform[] children, out var shapes);
            //    children = new Transform[0];
            if (children.Length > 1)
            {
                int numberOfValidShapes = GetNumberOfValidShapes(shapes);
                NativeList <CompoundCollider.ColliderBlobInstance> blobs = new NativeList <CompoundCollider.ColliderBlobInstance>(Allocator.TempJob);
                for (int i = 0; i < children.Length; i++)
                {
                    if (shapes[i] != null && shapes[i].enabled)
                    {
                        var shapeExt = children[i].gameObject.GetComponent <PhysicsMaterialsExtensionComponent>();

                        BlobAssetReference <Unity.Physics.Collider> collider = GenerateCollider(shapes[i], shapeExt,
                                                                                                out float3 offsetPosition, out quaternion offsetRotation);
                        blobs.Add(new CompoundCollider.ColliderBlobInstance
                        {
                            CompoundFromChild = new RigidTransform(children[i].rotation, children[i].position - this.transform.position),
                            Collider          = collider
                        });
                        var ltw = new LocalToWorld {
                            Value = new float4x4(children[i].rotation, children[i].position - this.transform.position)
                        };
                        buffer.Add(new PhysicsColliderFollowEntityData
                        {
                            AnimationDataIndex         = i,
                            CompoundColliderChildIndex = blobs.Length - 1,
                            RootTransform             = new RigidTransform(InitialRootRotation, InitialRootPosition),
                            sourceEntity              = conversionSystem.GetPrimaryEntity(shapes[i].gameObject),
                            CompoundColliderDataIsSet = false,
                            Old    = ltw,
                            Offset = ltw
                        });
                        Debug.Log("Setting \"" + children[i].name + "\" to " + (blobs.Length - 1) + " animation index =" + i + ", valid shapes = " + numberOfValidShapes + ", belongs to " + shapes[i].BelongsTo.Value + ", collides with = " + shapes[i].CollidesWith.Value);

                        //   shapes[i].enabled = false;
                    }
                }
                if (blobs.Length > 0)
                {
                    dstManager.AddComponentData(entity, new PhysicsCollider {
                        Value = CompoundCollider.Create(blobs)
                    });
                }

                blobs.Dispose();
            }
            else if (children.Length == 1)
            {
                dstManager.AddComponentData(entity, new PhysicsCollider {
                    Value = GenerateCollider(shapes[0], null, out var a, out var b)
                });
예제 #4
0
        protected override void OnUpdate()
        {
            // A map from entities to arrays of colliders that were not applied to the body during the first pass.
            m_ExtraColliders = new NativeMultiHashMap <ComparableEntity, LeafShapeData>(64, Allocator.Temp); // TODO - add custom data to Physics.Collider?

            // First pass.
            // Convert all editor shape components into colliders, and either apply them to their parent rigid body
            // or store them for building compound colliders in the second pass.
            Entities.ForEach <T>(ConvertShape);

            // Second pass.
            // Merge any leftover colliders into their parent rigid bodies, as compound colliders.
            if (m_ExtraColliders.Length > 0)
            {
                var keys = m_ExtraColliders.GetUniqueKeyArray(Allocator.Temp);
                using (keys.Item1)
                {
                    for (var k = 0; k < keys.Item2; ++k)
                    {
                        ComparableEntity entity = keys.Item1[k];
                        var collider            = DstEntityManager.GetComponentData <PhysicsCollider>(entity.Entity);
                        var children            = new NativeList <CompoundCollider.ColliderBlobInstance>(16, Allocator.Temp);

                        if (collider.IsValid)
                        {
                            // Include the already assigned collider as a child
                            children.Add(new CompoundCollider.ColliderBlobInstance {
                                Collider = collider.Value, CompoundFromChild = RigidTransform.identity
                            });
                        }

                        byte customData = 0;
                        if (m_ExtraColliders.TryGetFirstValue(entity, out var child, out var iterator))
                        {
                            do
                            {
                                children.Add(child.ColliderBlobInstance);
                                customData &= child.CustomFlags; // TODO: Should be |= ??
                            } while (m_ExtraColliders.TryGetNextValue(out child, ref iterator));
                        }

                        collider.Value = CompoundCollider.Create(children);

                        children.Dispose();

                        DstEntityManager.SetComponentData(entity.Entity, collider);

                        if (customData != 0)
                        {
                            DstEntityManager.AddOrSetComponent(entity.Entity, new PhysicsCustomData {
                                Value = customData
                            });
                        }
                    }
                }
            }
            m_ExtraColliders.Dispose();
        }
예제 #5
0
        public void MassProperties_BuiltFromChildren_MatchesExpected()
        {
            void TestCompoundBox(RigidTransform transform)
            {
                // Create a unit box
                var box = BoxCollider.Create(transform.pos, transform.rot, new float3(1, 1, 1), 0.0f);

                // Create a compound of mini boxes, matching the volume of the single box
                var miniBox  = BoxCollider.Create(float3.zero, quaternion.identity, new float3(0.5f, 0.5f, 0.5f), 0.0f);
                var children = new NativeArray <CompoundCollider.ColliderBlobInstance>(8, Allocator.Temp)
                {
                    [0] = new CompoundCollider.ColliderBlobInstance {
                        Collider = miniBox, CompoundFromChild = math.mul(transform, new RigidTransform(quaternion.identity, new float3(+0.25f, +0.25f, +0.25f)))
                    },
                    [1] = new CompoundCollider.ColliderBlobInstance {
                        Collider = miniBox, CompoundFromChild = math.mul(transform, new RigidTransform(quaternion.identity, new float3(-0.25f, +0.25f, +0.25f)))
                    },
                    [2] = new CompoundCollider.ColliderBlobInstance {
                        Collider = miniBox, CompoundFromChild = math.mul(transform, new RigidTransform(quaternion.identity, new float3(+0.25f, -0.25f, +0.25f)))
                    },
                    [3] = new CompoundCollider.ColliderBlobInstance {
                        Collider = miniBox, CompoundFromChild = math.mul(transform, new RigidTransform(quaternion.identity, new float3(+0.25f, +0.25f, -0.25f)))
                    },
                    [4] = new CompoundCollider.ColliderBlobInstance {
                        Collider = miniBox, CompoundFromChild = math.mul(transform, new RigidTransform(quaternion.identity, new float3(-0.25f, -0.25f, +0.25f)))
                    },
                    [5] = new CompoundCollider.ColliderBlobInstance {
                        Collider = miniBox, CompoundFromChild = math.mul(transform, new RigidTransform(quaternion.identity, new float3(+0.25f, -0.25f, -0.25f)))
                    },
                    [6] = new CompoundCollider.ColliderBlobInstance {
                        Collider = miniBox, CompoundFromChild = math.mul(transform, new RigidTransform(quaternion.identity, new float3(-0.25f, +0.25f, -0.25f)))
                    },
                    [7] = new CompoundCollider.ColliderBlobInstance {
                        Collider = miniBox, CompoundFromChild = math.mul(transform, new RigidTransform(quaternion.identity, new float3(-0.25f, -0.25f, -0.25f)))
                    }
                };
                var compound = CompoundCollider.Create(children);

                children.Dispose();

                var boxMassProperties      = box.Value.MassProperties;
                var compoundMassProperties = compound.Value.MassProperties;

                TestUtils.AreEqual(compoundMassProperties.Volume, boxMassProperties.Volume, 1e-3f);
                TestUtils.AreEqual(compoundMassProperties.AngularExpansionFactor, boxMassProperties.AngularExpansionFactor, 1e-3f);
                TestUtils.AreEqual(compoundMassProperties.MassDistribution.Transform.pos, boxMassProperties.MassDistribution.Transform.pos, 1e-3f);
                //TestUtils.AreEqual(compoundMassProperties.MassDistribution.Orientation, boxMassProperties.MassDistribution.Orientation, 1e-3f);   // TODO: Figure out why this differs, and if that is a problem
                TestUtils.AreEqual(compoundMassProperties.MassDistribution.InertiaTensor, boxMassProperties.MassDistribution.InertiaTensor, 1e-3f);
            }

            // Compare box with compound at various transforms
            TestCompoundBox(RigidTransform.identity);
            TestCompoundBox(new RigidTransform(quaternion.identity, new float3(1.0f, 2.0f, 3.0f)));
            TestCompoundBox(new RigidTransform(quaternion.EulerXYZ(0.5f, 1.0f, 1.5f), float3.zero));
            TestCompoundBox(new RigidTransform(quaternion.EulerXYZ(0.5f, 1.0f, 1.5f), new float3(1.0f, 2.0f, 3.0f)));
        }
    public override void CreateScene(CompoundDemoScene sceneSettings)
    {
        //         // Floor
        //         {
        //             BlobAssetReference<Unity.Physics.Collider> collider = Unity.Physics.BoxCollider.Create(new float3(0, -0.1f, 0), Quaternion.identity, new float3(10.0f, 0.1f, 10.0f), 0.05f);
        //             CreatedColliders.Add(collider);
        //             CreateStaticBody(float3.zero, quaternion.identity, collider);
        //         }

        // Dynamic compound
        {
            var box = new BoxGeometry
            {
                Center      = float3.zero,
                Orientation = quaternion.identity,
                Size        = new float3(1),
                BevelRadius = 0.05f
            };

            var sphere = new SphereGeometry
            {
                Center = float3.zero,
                Radius = 0.5f
            };

            var children = new NativeArray <CompoundCollider.ColliderBlobInstance>(3, Allocator.Temp)
            {
                [0] = new CompoundCollider.ColliderBlobInstance
                {
                    CompoundFromChild = new RigidTransform(quaternion.identity, new float3(-1, 0, 0)),
                    Collider          = Unity.Physics.BoxCollider.Create(box)
                },
                [1] = new CompoundCollider.ColliderBlobInstance
                {
                    CompoundFromChild = RigidTransform.identity,
                    Collider          = Unity.Physics.SphereCollider.Create(sphere)
                },
                [2] = new CompoundCollider.ColliderBlobInstance
                {
                    CompoundFromChild = new RigidTransform(quaternion.identity, new float3(1, 0, 0)),
                    Collider          = Unity.Physics.BoxCollider.Create(box)
                }
            };
            foreach (var child in children)
            {
                CreatedColliders.Add(child.Collider);
            }

            BlobAssetReference <Unity.Physics.Collider> collider = CompoundCollider.Create(children);
            CreatedColliders.Add(collider);
            children.Dispose();

            CreateDynamicBody(new float3(0, 1, 0), quaternion.identity, collider, float3.zero, float3.zero, 1.0f);
        }
    }
예제 #7
0
    protected unsafe override void Start()
    {
        //float3 gravity = new float3(0, -9.81f, 0);
        float3 gravity = float3.zero;

        base.init(gravity);

        //         // Floor
        //         {
        //             BlobAssetReference<Unity.Physics.Collider> collider = Unity.Physics.BoxCollider.Create(new float3(0, -0.1f, 0), Quaternion.identity, new float3(10.0f, 0.1f, 10.0f), 0.05f);
        //             CreateStaticBody(float3.zero, quaternion.identity, collider);
        //         }

        // Dynamic compound
        {
            var box = new BoxGeometry
            {
                Center      = float3.zero,
                Orientation = quaternion.identity,
                Size        = new float3(1),
                BevelRadius = 0.05f
            };

            var sphere = new SphereGeometry
            {
                Center = float3.zero,
                Radius = 0.5f
            };

            var children = new NativeArray <CompoundCollider.ColliderBlobInstance>(3, Allocator.Temp)
            {
                [0] = new CompoundCollider.ColliderBlobInstance
                {
                    CompoundFromChild = new RigidTransform(quaternion.identity, new float3(-1, 0, 0)),
                    Collider          = Unity.Physics.BoxCollider.Create(box)
                },
                [1] = new CompoundCollider.ColliderBlobInstance
                {
                    CompoundFromChild = RigidTransform.identity,
                    Collider          = Unity.Physics.SphereCollider.Create(sphere)
                },
                [2] = new CompoundCollider.ColliderBlobInstance
                {
                    CompoundFromChild = new RigidTransform(quaternion.identity, new float3(1, 0, 0)),
                    Collider          = Unity.Physics.BoxCollider.Create(box)
                }
            };

            BlobAssetReference <Unity.Physics.Collider> collider = CompoundCollider.Create(children);
            children.Dispose();

            CreateDynamicBody(new float3(0, 1, 0), quaternion.identity, collider, float3.zero, float3.zero, 1.0f);
        }
    }
예제 #8
0
    private void UpdateBoundsCompound(CompoundCollider collider)
    {
        boundsMin = new Vector2(Mathf.Infinity, Mathf.Infinity);
        boundsMax = new Vector2(Mathf.NegativeInfinity, Mathf.NegativeInfinity);

        collider.colliders.ForEach(col =>
        {
            col.boundingBox.Update();
            SetBoundsMinMaxValues(col.boundingBox.boundsMin, col.boundingBox.boundsMax);
        });
    }
예제 #9
0
    private static PhysicsCollider CreateCompoundCollider(PhysicsCollider c1, PhysicsCollider c2)
    {
        CompoundCollider.ColliderBlobInstance[] colliderArray = new CompoundCollider.ColliderBlobInstance[2];
        colliderArray[0] = new CompoundCollider.ColliderBlobInstance {
            Collider = c1.Value
        };
        colliderArray[1] = new CompoundCollider.ColliderBlobInstance {
            Collider = c2.Value
        };
        NativeArray <CompoundCollider.ColliderBlobInstance> colliderNativeArray = new NativeArray <CompoundCollider.ColliderBlobInstance>(colliderArray, Allocator.TempJob);
        PhysicsCollider compoundCollider = new PhysicsCollider {
            Value = CompoundCollider.Create(colliderNativeArray)
        };

        colliderNativeArray.Dispose();
        return(compoundCollider);
    }
예제 #10
0
    protected virtual void OnDrawGizmos()
    {
        collidables.ForEach(collidable =>
        {
            if (collidable.boundingBox == null)
            {
                return;
            }

            if (collidable is CompoundCollider)
            {
                CompoundCollider cc = collidable as CompoundCollider;
                cc.colliders.ForEach(col => { DrawBoundingBox(col.boundingBox); });
            }

            DrawBoundingBox(collidable.boundingBox);
        });
    }
예제 #11
0
        public static unsafe BlobAssetReference <Collider> GenerateRandomCompound(ref Random rnd)
        {
            int numChildren = rnd.NextInt(1, 10);
            var children    = new NativeArray <CompoundCollider.ColliderBlobInstance>(numChildren, Allocator.Temp);

            for (int i = 0; i < numChildren; i++)
            {
                children[i] = new CompoundCollider.ColliderBlobInstance
                {
                    CompoundFromChild = new RigidTransform
                    {
                        pos = (rnd.NextInt(10) > 0) ? rnd.NextFloat3(-5.0f, 5.0f) : float3.zero,
                        rot = (rnd.NextInt(10) > 0) ? rnd.NextQuaternionRotation() : quaternion.identity
                    },
                    Collider = GenerateRandomCollider(ref rnd)
                };
            }

            return(CompoundCollider.Create(children));
        }
        private BlobAssetReference <Collider> CreateGroundCompoundWith2Children(float3 groundSize)
        {
            var groundCollider1 = BoxCollider.Create(new BoxGeometry {
                Orientation = quaternion.identity, Size = groundSize
            });
            var groundCollider2 = BoxCollider.Create(new BoxGeometry {
                Orientation = quaternion.identity, Size = groundSize
            });
            var instances = new NativeArray <CompoundCollider.ColliderBlobInstance>(2, Allocator.Temp);

            instances[0] = new CompoundCollider.ColliderBlobInstance
            {
                Collider          = groundCollider1,
                CompoundFromChild = RigidTransform.identity
            };
            instances[1] = new CompoundCollider.ColliderBlobInstance
            {
                Collider          = groundCollider2,
                CompoundFromChild = RigidTransform.identity
            };
            return(CompoundCollider.Create(instances));
        }
예제 #13
0
    private void SetCollider()
    {
        colliders = GetComponents <ICollidable>().ToList();

        if (colliders.Count <= 0)
        {
            return;
        }

        if (colliders.Count == 1)
        {
            collider = colliders[0];
        }
        else
        {
            collider = new CompoundCollider(colliders);
        }


        // Calculate Static Parameters for every collider
        colliders.ForEach(collider => SetUpCollider(collider));

        if (collider is CompoundCollider)
        {
            SetUpCollider(collider);
        }

        // Set Static Parameters for the physics body
        mass            = isKinematic ? Mathf.Infinity : collider.mass;
        momentOfInertia = isKinematic ? Mathf.Infinity : collider.momentOfInertia;


        // OnCollision Events Setup
        collider.onCollision += ICollidable_OnCollision;
        collider.onTrigger   += ICollidable_OnTrigger;
    }
예제 #14
0
        /// <summary>
        /// creates and returns the pokemoon's PhysicsCollider
        /// </summary>
        /// <param name="pokemonName">Name of the pokemon</param>
        /// <returns>PhysicsCollider</returns>
        public static PhysicsCollider getPokemonPhysicsCollider(string pokemonName, PokemonEntityData ped,
                                                                CollisionFilter collisionFilter = new CollisionFilter(), float scale = 1f, Unity.Physics.Material material = new Unity.Physics.Material(),
                                                                int groupIndex = 1)
        {
            ///FUTURE UPDATE
            ///allow specific colliders to recieve specific filters and materials!

            //needs collision groups
            PhysicsCollider physicsCollider = new PhysicsCollider {
            };
            Quaternion rotation             = new quaternion();

            //if default collision filter is detected then create one realted to the pokemon
            if (collisionFilter.Equals(new CollisionFilter()))
            {
                Debug.Log("Creating new Collision Filter");
                collisionFilter = new CollisionFilter
                {
                    BelongsTo    = TriggerEventClass.Pokemon | TriggerEventClass.Collidable,
                    CollidesWith = TriggerEventClass.Collidable,
                    GroupIndex   = groupIndex
                };
            }
            if (material.Equals(new Unity.Physics.Material()))
            {
                material = GetPokemonColliderMaterial(StringToPokedexEntry(pokemonName));
            }
            switch (pokemonName)
            {
            case "Cubone":
                var colliders = new NativeArray <CompoundCollider.ColliderBlobInstance>(5, Allocator.Temp);
                colliders[0] = new CompoundCollider.ColliderBlobInstance
                {
                    Collider = Unity.Physics.SphereCollider.Create(new SphereGeometry {
                        Center = new float3(0, 0.27f, 0.03f), Radius = 0.225f
                    }, collisionFilter, material),
                    CompoundFromChild = new RigidTransform {
                        pos = new float3 {
                            x = 0, y = 0, z = 0
                        }, rot = quaternion.identity
                    }
                };
                var a = GenerateCapsuleData(float3.zero, Vector3.right, 0.1f, 0.3f);
                rotation.SetFromToRotation(Vector3.right, new Vector3(0, 90f, 0));
                colliders[1] = new CompoundCollider.ColliderBlobInstance
                {
                    Collider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry {
                        Vertex0 = a.pointA, Vertex1 = a.pointB, Radius = 0.1f
                    }, collisionFilter, material),
                    CompoundFromChild = new RigidTransform {
                        pos = new float3(-0.17f, 0.19f, 0), rot = rotation
                    }
                };
                colliders[2] = new CompoundCollider.ColliderBlobInstance
                {
                    Collider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry {
                        Vertex0 = a.pointA, Vertex1 = a.pointB, Radius = 0.1f
                    }, collisionFilter, material),
                    CompoundFromChild = new RigidTransform {
                        pos = new float3(0.17f, 0.19f, 0), rot = rotation
                    }
                };
                colliders[3] = new CompoundCollider.ColliderBlobInstance
                {
                    Collider = Unity.Physics.SphereCollider.Create(new SphereGeometry {
                        Center = float3.zero, Radius = 0.23f
                    }, collisionFilter, material),
                    CompoundFromChild = new RigidTransform {
                        pos = new float3(0, 0.75f, 0.03f), rot = rotation
                    }
                };
                a            = GenerateCapsuleData(float3.zero, Vector3.right, 0.1f, 0.3f);
                rotation     = Quaternion.Euler(0, 90f, 26f);
                colliders[4] = new CompoundCollider.ColliderBlobInstance
                {
                    Collider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry {
                        Vertex0 = a.pointA, Vertex1 = a.pointB, Radius = 0.1f
                    }, collisionFilter, material),
                    CompoundFromChild = new RigidTransform {
                        pos = new float3(0, 0.63f, 0.33f), rot = rotation
                    }
                };
                physicsCollider = new PhysicsCollider {
                    Value = CompoundCollider.Create(colliders)
                };
                if (scale > 1f)
                {
                    Debug.LogWarning("Cannot scale Cubone");
                }
                colliders.Dispose();
                break;

            case "Electrode":
                Debug.Log("Creating PHysicwsCollider for Electrode");
                physicsCollider = new PhysicsCollider {
                    Value = Unity.Physics.SphereCollider.Create(new SphereGeometry
                    {
                        Center = float3.zero,
                        Radius = ped.Height / 2 * scale
                    },
                                                                collisionFilter,
                                                                material
                                                                )
                };
                break;

            default:
                Debug.LogError("Failed to find collider for pokemon \"" + pokemonName + "\"");
                physicsCollider = new PhysicsCollider
                {
                    Value = Unity.Physics.SphereCollider.Create(new SphereGeometry
                    {
                        Center = float3.zero,
                        Radius = ped.Height / 2 * scale
                    },
                                                                collisionFilter,
                                                                material
                                                                )
                };
                break;
            }
            //		Debug.Log("Returning Physics Collide for \""+pokemonName+"\"");
            return(physicsCollider);
        }
        private void ConvertCompoundColliders()
        {
            Profiler.BeginSample("ConvertCompoundColliders");

            m_nativeColliders  = new NativeList <Collider>(128, Allocator.TempJob);
            m_nativeTransforms = new NativeList <RigidTransform>(128, Allocator.TempJob);
            m_compoundRanges   = new NativeList <int2>(128, Allocator.TempJob);

            //Step 1: Find all colliders and construct parallel arrays
            m_authorings.Clear();
            Entities.WithNone <DontConvertColliderTag>().ForEach((LatiosColliderAuthoring colliderAuthoring) =>
            {
                //Do stuff
                if (colliderAuthoring.colliderType == AuthoringColliderTypes.None)
                {
                    return;
                }
                if (colliderAuthoring.generateFromChildren)
                {
                    m_unityColliders.Clear();
                    colliderAuthoring.GetComponentsInChildren(m_unityColliders);
                    try
                    {
                        CreateChildrenColliders(colliderAuthoring, m_unityColliders, m_nativeColliders, m_nativeTransforms, m_compoundRanges);
                    }
                    catch (Exception e)
                    {
                        DisposeAndThrow(e);
                    }
                }
                else
                {
                    try
                    {
                        CreateChildrenColliders(colliderAuthoring, colliderAuthoring.colliders, m_nativeColliders, m_nativeTransforms, m_compoundRanges);
                    }
                    catch (Exception e)
                    {
                        DisposeAndThrow(e);
                    }
                }
                m_authorings.Add(colliderAuthoring);
            });

            if (m_authorings.Count > 0)
            {
                using (var computationContext = new BlobAssetComputationContext <CompoundColliderComputationData, CompoundColliderBlob>(BlobAssetStore, 128, Allocator.Temp))
                {
                    //Step 2: Compute hashes
                    var hashes = new NativeArray <ColliderTransformHashPair>(m_compoundRanges.Length, Allocator.TempJob);
                    new ComputeCompoundHashesJob
                    {
                        colliders  = m_nativeColliders,
                        transforms = m_nativeTransforms,
                        ranges     = m_compoundRanges,
                        hashes     = hashes
                    }.ScheduleParallel(m_compoundRanges.Length, 1, default).Complete();

                    //Step 3: Check hashes against computationContext to see if blobs need to be built
                    for (int i = 0; i < m_authorings.Count; i++)
                    {
                        var hash = hashes.ReinterpretLoad <Hash128>(i);
                        computationContext.AssociateBlobAssetWithUnityObject(hash, m_authorings[i].gameObject);
                        if (computationContext.NeedToComputeBlobAsset(hash))
                        {
                            computationContext.AddBlobAssetToCompute(hash, new CompoundColliderComputationData
                            {
                                hash  = hash,
                                index = i
                            });
                        }
                    }

                    //Step 4: Dispatch builder job
                    using (var computationData = computationContext.GetSettings(Allocator.TempJob))
                    {
                        new ComputeCompoundBlobs
                        {
                            colliders       = m_nativeColliders,
                            transforms      = m_nativeTransforms,
                            ranges          = m_compoundRanges,
                            computationData = computationData
                        }.ScheduleParallel(computationData.Length, 1, default).Complete();

                        foreach (var data in computationData)
                        {
                            computationContext.AddComputedBlobAsset(data.hash, data.blob);
                        }
                    }

                    //Step 5: Build Collider component
                    var index = 0;
                    Entities.ForEach((LatiosColliderAuthoring colliderAuthoring) =>
                    {
                        computationContext.GetBlobAsset(hashes.ReinterpretLoad <Hash128>(index++), out var blob);

                        var targetEntity = GetPrimaryEntity(colliderAuthoring);

                        float3 scale = colliderAuthoring.transform.lossyScale;
                        if (scale.x != scale.y || scale.x != scale.z)
                        {
                            throw new InvalidOperationException(
                                $"GameObject Conversion Error: Failed to convert {colliderAuthoring}. Only uniform scale is permitted on Compound colliders.");
                        }

                        Collider icdCompound = new CompoundCollider
                        {
                            compoundColliderBlob = blob,
                            scale = scale.x
                        };
                        DstEntityManager.AddComponentData(targetEntity, icdCompound);
                    });

                    hashes.Dispose();
                }
            }

            m_nativeColliders.Dispose();
            m_nativeTransforms.Dispose();
            m_compoundRanges.Dispose();

            Profiler.EndSample();
        }
        private BlobAssetReference <Collider> CreateCollider(ColliderType type)
        {
            int numMeshes = type == ColliderType.Compound ? 2 : 1;

            ColliderMeshes = new Mesh[numMeshes];
            BlobAssetReference <Collider> collider = default;

            switch (type)
            {
            case ColliderType.Sphere:
                collider = SphereCollider.Create(new SphereGeometry
                {
                    Center = float3.zero,
                    Radius = 0.5f
                });
                break;

            case ColliderType.Triangle:
                collider = PolygonCollider.CreateTriangle(k_TriangleVertices[0], k_TriangleVertices[1], k_TriangleVertices[2]);
                break;

            case ColliderType.Quad:
                collider = PolygonCollider.CreateQuad(k_QuadVertices[0], k_QuadVertices[1], k_QuadVertices[2], k_QuadVertices[3]);
                break;

            case ColliderType.Box:
                collider = BoxCollider.Create(new BoxGeometry
                {
                    Center      = float3.zero,
                    Orientation = quaternion.identity,
                    Size        = new float3(1.0f),
                    BevelRadius = 0.0f
                });
                break;

            case ColliderType.Capsule:
                collider = CapsuleCollider.Create(new CapsuleGeometry
                {
                    Vertex0 = new float3(0, -0.5f, 0),
                    Vertex1 = new float3(0, 0.5f, 0),
                    Radius  = 0.5f
                });
                break;

            case ColliderType.Cylinder:
                // TODO: need someone to add
                throw new NotImplementedException();

            case ColliderType.Convex:
                // Tetrahedron
                NativeArray <float3> points = new NativeArray <float3>(k_TetraherdonVertices, Allocator.TempJob);
                collider = ConvexCollider.Create(points, ConvexHullGenerationParameters.Default, CollisionFilter.Default);
                points.Dispose();
                break;

            case ColliderType.Compound:

                var child1 = SphereCollider.Create(new SphereGeometry
                {
                    Center = float3.zero,
                    Radius = 0.5f
                });
                ChildrenColliders.Add(child1);

                var child2 = BoxCollider.Create(new BoxGeometry
                {
                    Center      = float3.zero,
                    Orientation = quaternion.identity,
                    Size        = new float3(1.0f),
                    BevelRadius = 0.0f
                });
                ChildrenColliders.Add(child2);

                NativeArray <ColliderBlobInstance> childrenBlobs = new NativeArray <ColliderBlobInstance>(2, Allocator.TempJob);
                childrenBlobs[0] = new ColliderBlobInstance
                {
                    Collider          = child1,
                    CompoundFromChild = new RigidTransform
                    {
                        pos = new float3(0.5f, 0, 0),
                        rot = quaternion.identity
                    }
                };

                childrenBlobs[1] = new ColliderBlobInstance
                {
                    Collider          = child2,
                    CompoundFromChild = new RigidTransform
                    {
                        pos = new float3(-0.5f, 0, 0),
                        rot = quaternion.identity
                    }
                };

                ColliderMeshes[0] = SceneCreationUtilities.CreateMeshFromCollider(child1);
                ColliderMeshes[1] = SceneCreationUtilities.CreateMeshFromCollider(child2);

                collider = CompoundCollider.Create(childrenBlobs);
                childrenBlobs.Dispose();
                break;

            case ColliderType.Mesh:
                // Tetrahedron mesh
                NativeArray <float3> meshVertices  = new NativeArray <float3>(k_TetraherdonVertices, Allocator.TempJob);
                NativeArray <int3>   meshTriangles = new NativeArray <int3>(k_TetrahedronMeshTriangles, Allocator.TempJob);

                collider = MeshCollider.Create(meshVertices, meshTriangles);
                meshVertices.Dispose();
                meshTriangles.Dispose();
                break;

            case ColliderType.Terrain:
                int2   size  = 2;
                float3 scale = 1;
                Random rand  = new Random(0x9739);

                int numSamples = size.x * size.y;
                var heights    = new NativeArray <float>(numSamples, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                for (int i = 0; i < numSamples; i++)
                {
                    heights[i] = rand.NextFloat(0, 1);
                }
                collider = TerrainCollider.Create(heights, size, scale, TerrainCollider.CollisionMethod.VertexSamples);
                heights.Dispose();
                break;

            default:
                throw new System.NotImplementedException();
            }

            if (ColliderType != ColliderType.Compound)
            {
                ColliderMeshes[0] = SceneCreationUtilities.CreateMeshFromCollider(collider);
            }

            return(collider);
        }
예제 #17
0
        // 生成されたジョイントエンティティを返す。
        public NativeArray <Entity> Convert
            (EntityManager em, Entity posturePrefab, NameAndEntity[] bonePrefabs)
        {
            //var motionClip = this.GetComponent<MotionAuthoring>().MotionClip;//

            var rbTop = this.GetComponentInChildren <Rigidbody>();//

            if (rbTop == null)
            {
                return(new NativeArray <Entity>());              //
            }
            var srcColliders = this.GetComponentsInChildren <UnityEngine.Collider>();



            // 名前とボーンエンティティの組を配列化
            //var qNameAndBone = motionClip.StreamPaths
            //    .Select( x => System.IO.Path.GetFileName( x ) )
            //    .Select( ( name, i ) => (name, i: motionClip.IndexMapFbxToMotion[ i ]) )
            //    .Where( x => x.i != -1 )
            //    .Select( x => (Name:x.name, Entity:bonePrefabs[ x.i ].Entity) )
            //    .Append( (Name:rbTop.name, Entity:posturePrefab) );
            //var namesAndBones = qNameAndBone.ToArray();
            var namesAndBones = bonePrefabs
                                .Append(new NameAndEntity(rbTop.name, posturePrefab));

            // クエリ用コライダの生成
            // ・マテリアルが "xxx overlap collider" という名前になっているものを抽出
            // ・対応するボーンエンティティに専用のコンポーネントデータを付加
            var qQueryableCollider =
                from x in srcColliders
                where x.sharedMaterial != null
                where x.sharedMaterial.name.StartsWith("overlap ")
                join bone in namesAndBones
                on x.name equals bone.Name
                select(bone.Entity, c : x)
            ;

            foreach (var(ent, c) in qQueryableCollider)
            {
                addQuearyableColliderBlobs_(ent, c, 0);
            }


            // コライダとそれが付くべき剛体の組を配列化(同じ剛体に複数のコライダもあり)
            // ・有効でないコライダは除外する
            var qColliderWithParent =
                from collider in srcColliders
                where collider.enabled
                let parent = collider.gameObject
                             .AncestorsAndSelf()
                             .Where(anc => anc.GetComponent <Rigidbody>() != null)
                             .First()
                             select(collider, parent)
            ;
            var collidersWithParent = qColliderWithParent.ToArray();

            // 同じ剛体を親とするコライダをグループ化するクエリ
            var qColliderGroup =
                from x in collidersWithParent
                group x.collider by x.parent
            ;

            // 剛体を持たない子コライダを合成して、コライダコンポーネントデータを生成するクエリ
            var qCompounds =
                from g in qColliderGroup
                select new PhysicsCollider
            {
                Value = createBlobCollider_(srcColliders_: g, parent: g.Key, groupIndex: 0),
            };

            // コライダがついているオブジェクトに相当するボーンのエンティティに、コライダコンポーネントデータを付加
            // ・コライダ不要なら、質量プロパティだけ生成してコライダはつけないようにしたい(未実装)
            var qEntAndComponent =
                from c in (qColliderGroup, qCompounds).Zip()
                join b in namesAndBones
                on c.x.Key.name equals b.Name
                select(b.Entity, c : c.y)
            ;

            foreach (var(ent, c) in qEntAndComponent)
            {
                em.AddComponentData(ent, c);
            }

            // 剛体がついているオブジェクトに相当するボーンのエンティティに、各種コンポーネントデータを付加
            // ・キネマティックは質量ゼロにするが、速度や質量プロパティは付加する。
            // ・コライダがない場合は、球の質量プロパティになる。
            var qRbAndBone =
                from x in this.GetComponentsInChildren <Rigidbody>()
                join b in namesAndBones
                on x.name equals b.Name
                select(rb : x, b.Entity)
            ;

            foreach (var(rb, ent) in qRbAndBone)
            {
                addDynamicComponentData_ByRigidbody_(ent, rb, posturePrefab);
            }
            //return new NativeArray<Entity>(0,Allocator.Temp);


            // ジョイントの生成。両端のオブジェクトに相当するエンティティを特定する。
            // ・ジョイントはエンティティとして生成する。
            //  (コライダと同じエンティティに着けても動作したが、サンプルではこうしている)
            //  (また、ラグドールジョイントはなぜか2つジョイントを返してくるので、同じエンティティには付けられない)
            var qJoint =
                from j in this.GetComponentsInChildren <UnityEngine.Joint>()
                //.Do( x=>Debug.Log(x.name))
                join a in namesAndBones
                on j.name equals a.Name
                join b in namesAndBones
                on j.connectedBody.name equals b.Name
                let jointData = createJointBlob_(j)
                                //select (a, b, j, jointData)
                                select addJointComponentData_(a.Entity, jointData, a.Entity, b.Entity, j.enableCollision)
            ;

            return(qJoint.SelectMany().ToNativeArray(Allocator.Temp));



            // 物理材質に着けられた名前から、特定のコライダを持つコンポーネントデータを生成する。
            void addQuearyableColliderBlobs_
                (Entity ent, UnityEngine.Collider srcCollider, int groupIndex)
            {
                switch (srcCollider.sharedMaterial.name)
                {
                //case "overlap cast":汎用だと1つしかもてない、用途ごとにコンポーネントデータを定義しないといけない
                //{
                //    var blob = createBlobCollider_( new[] { srcCollider }, srcCollider.gameObject, groupIndex );
                //    em.AddComponentData( ent, new GroundHitColliderData { Collider = blob } );
                //    break;
                //}
                case "overlap ground ray":
                {
                    if (srcCollider is UnityEngine.SphereCollider srcSphere)
                    {
                        em.AddComponentData(ent, new GroundHitRayData
                            {
                                Start = srcSphere.center,
                                Ray   = new DirectionAndLength {
                                    value = new float4(math.up() * -1, srcSphere.radius)
                                },                                                                                      // 向きは暫定
                                Filter = LegacyColliderProducer.GetFilter(srcSphere, groupIndex),
                            });
                    }
                    break;
                }

                case "overlap ground sphere":
                {
                    if (srcCollider is UnityEngine.SphereCollider srcSphere)
                    {
                        em.AddComponentData(ent, new GroundHitSphereData
                            {
                                Center   = srcSphere.center,
                                Distance = srcSphere.radius,
                                Filter   = LegacyColliderProducer.GetFilter(srcSphere, groupIndex),
                            });
                    }
                    break;
                }
                }
            }

            BlobAssetReference <Collider> compoundColliderBlobsFromEnumerable_
                (IEnumerable <CompoundCollider.ColliderBlobInstance> src)
            {
                using (var arr = src.ToNativeArray(Allocator.Temp))
                    return(CompoundCollider.Create(arr));
            }

            BlobAssetReference <Collider> createBlobCollider_
                (IEnumerable <UnityEngine.Collider> srcColliders_, GameObject parent, int groupIndex)
            {
                return((srcColliders_.Count() > 1 || srcColliders_.First().gameObject != parent)
                    ? queryBlobInstances_(srcColliders_, parent.transform, groupIndex)
                       .To(compoundColliderBlobsFromEnumerable_)
                    : createColliderBlob_(srcColliders_.First(), groupIndex)
                       );

                IEnumerable <CompoundCollider.ColliderBlobInstance> queryBlobInstances_
                    (IEnumerable <UnityEngine.Collider> srcColliders__, Transform tfParent, int groupIndex_)
                {
                    return
                        (from x in srcColliders__
                         let tfCollider = x.transform
                                          let rtf = new RigidTransform
                    {
                        pos = tfCollider.position - tfParent.position,
                        rot = tfCollider.rotation * Quaternion.Inverse(tfParent.rotation),
                    }
                         select new CompoundCollider.ColliderBlobInstance
                    {
                        Collider = createColliderBlob_(x, groupIndex_),
                        CompoundFromChild = rtf,
                    });
                }
            }

            BlobAssetReference <Collider> createColliderBlob_(UnityEngine.Collider srcCollider, int groupIndex)
            {
                switch (srcCollider)
                {
                case UnityEngine.SphereCollider srcSphere:
                    return(srcSphere.ProduceColliderBlob(groupIndex));

                case UnityEngine.CapsuleCollider srcCapsule:
                    return(srcCapsule.ProduceColliderBlob(groupIndex));

                case UnityEngine.BoxCollider srcBox:
                    return(srcBox.ProduceColliderBlob(groupIndex));
                }
                return(BlobAssetReference <Collider> .Null);
            }

            void addDynamicComponentData_ByRigidbody_(Entity ent, Rigidbody rb, Entity postureEnt)
            {
                var massProp = em.HasComponent <PhysicsCollider>(ent)
                    ? em.GetComponentData <PhysicsCollider>(ent).MassProperties
                    : MassProperties.UnitSphere;

                var physicsMass = rb.isKinematic
                    ? PhysicsMass.CreateKinematic(massProp)
                    : PhysicsMass.CreateDynamic(massProp, rb.mass);

                // XY回転拘束だけ特例で設定する
                var freez_xy = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationZ;

                if (rb.constraints == freez_xy)
                {
                    physicsMass.InverseInertia = new float3(0, 1, 0);
                }

                //if( !rb.isKinematic )
                em.AddComponentData(ent, physicsMass);
                // キネマティックの場合は、つけなくても大丈夫みたい(主にジョイントにとって)
                // が、いちおうつけておく

                //if( !rb.isKinematic )
                em.AddComponentData(ent, new PhysicsVelocity());
                // ジョイント付けると、質量ゼロにしても速度が必要みたい(ないと荒ぶる)
                // もしくは、コライダがあると安定したように見えた

                if (rb.isKinematic || !rb.useGravity)
                {
                    em.AddComponentData(ent, new PhysicsGravityFactor {
                        Value = 0.0f
                    });
                }
                // 質量ゼロにしても、なぜか重力の影響を受け続けるのでオフる

                //if( !rb.isKinematic )
                {
                    em.AddComponentData(ent, new Bone.InitializeData {
                        PostureEntity = postureEnt
                    });
                    em.SetComponentData(ent, new Translation {
                        Value = rb.position
                    });
                    em.SetComponentData(ent, new Rotation {
                        Value = rb.rotation
                    });
                }
            }

            BlobAssetReference <JointData>[] createJointBlob_(UnityEngine.Joint srcJoint)
            {
                switch (srcJoint)
                {
                //case UnityEngine.CharacterJoint srcChJoint when srcChJoint.GetComponent<RagdollJointAuthoring>() != null:
                //{
                //    var srcRagdollJoint = srcChJoint.GetComponent<RagdollJointAuthoring>();
                //    JointData.CreateRagdoll
                //    (
                //        srcRagdollJoint.positionAinA,
                //        srcRagdollJoint.positionBinB,
                //        srcRagdollJoint.twistAxisInA,
                //        srcRagdollJoint.twistAxisInB,
                //        srcRagdollJoint.perpendicularAxisInA,
                //        srcRagdollJoint.perpendicularAxisInB,
                //        math.radians( srcRagdollJoint.maxConeAngle ),
                //        math.radians( srcRagdollJoint.minPerpendicularAngle ),
                //        math.radians( srcRagdollJoint.maxPerpendicularAngle ),
                //        math.radians( srcRagdollJoint.minTwistAngle ),
                //        math.radians( srcRagdollJoint.maxTwistAngle ),
                //        out var jointData0,
                //        out var jointData1
                //    );
                //    return new[] { jointData0, jointData1 };
                //}

                case UnityEngine.CharacterJoint srcChJoint2:
                {
                    var blob = JointData.CreateBallAndSocket(srcChJoint2.anchor, srcChJoint2.connectedAnchor);
                    return(new[] { blob });
                }
                }
                return(new BlobAssetReference <JointData>[] {});
            }

            //unsafe Entity createJoint_
            unsafe Entity[] addJointComponentData_(
                Entity jointEntity,
                BlobAssetReference <JointData>[] jointDataArray,
                Entity entityA, Entity entityB,
                bool isEnableCollision = false
                )
            {
                return((from x in jointDataArray select createJointEntity_(x)).ToArray());


                Entity createJointEntity_(BlobAssetReference <JointData> jd)
                {
                    var ent = em.CreateEntity(typeof(Prefab), typeof(PhysicsJoint));

                    em.SetComponentData(ent,
                                        new PhysicsJoint
                    {
                        //JointData = jd,
                        //EntityA = entityA,
                        //EntityB = entityB,
                        //EnableCollision = ( isEnableCollision ? 1 : 0 )
                    }
                                        );
                    return(ent);
                }
            }
        }
    }
 public void Execute() => Output[0] = CompoundCollider.Create(Children);
예제 #19
0
        public unsafe void CreateCompound_WithRepeatedInputs_ChildrenAreInstances()
        {
            BlobAssetReference <Collider> boxBlob      = default;
            BlobAssetReference <Collider> capsuleBlob  = default;
            BlobAssetReference <Collider> sphereBlob   = default;
            BlobAssetReference <Collider> compoundBlob = default;

            try
            {
                // 3 unique instance inputs
                boxBlob = BoxCollider.Create(new BoxGeometry {
                    Orientation = quaternion.identity, Size = new float3(1)
                });
                capsuleBlob = CapsuleCollider.Create(new CapsuleGeometry {
                    Radius = 0.5f, Vertex0 = new float3(1f), Vertex1 = new float3(-1f)
                });
                sphereBlob = SphereCollider.Create(new SphereGeometry {
                    Radius = 0.5f
                });
                var children = new NativeArray <CompoundCollider.ColliderBlobInstance>(8, Allocator.Temp)
                {
                    [0] = new CompoundCollider.ColliderBlobInstance {
                        Collider = boxBlob, CompoundFromChild = new RigidTransform(quaternion.identity, new float3(0f))
                    },
                    [1] = new CompoundCollider.ColliderBlobInstance {
                        Collider = capsuleBlob, CompoundFromChild = new RigidTransform(quaternion.identity, new float3(1f))
                    },
                    [2] = new CompoundCollider.ColliderBlobInstance {
                        Collider = boxBlob, CompoundFromChild = new RigidTransform(quaternion.identity, new float3(2f))
                    },
                    [3] = new CompoundCollider.ColliderBlobInstance {
                        Collider = sphereBlob, CompoundFromChild = new RigidTransform(quaternion.identity, new float3(3f))
                    },
                    [4] = new CompoundCollider.ColliderBlobInstance {
                        Collider = boxBlob, CompoundFromChild = new RigidTransform(quaternion.identity, new float3(4f))
                    },
                    [5] = new CompoundCollider.ColliderBlobInstance {
                        Collider = capsuleBlob, CompoundFromChild = new RigidTransform(quaternion.identity, new float3(5f))
                    },
                    [6] = new CompoundCollider.ColliderBlobInstance {
                        Collider = boxBlob, CompoundFromChild = new RigidTransform(quaternion.identity, new float3(6f))
                    },
                    [7] = new CompoundCollider.ColliderBlobInstance {
                        Collider = sphereBlob, CompoundFromChild = new RigidTransform(quaternion.identity, new float3(7f))
                    }
                };

                compoundBlob = CompoundCollider.Create(children);

                var compound       = (CompoundCollider *)compoundBlob.GetUnsafePtr();
                var uniqueChildren = new HashSet <long>();
                for (var i = 0; i < compound->Children.Length; i++)
                {
                    uniqueChildren.Add((long)compound->Children[i].Collider);
                }
                Assert.That(uniqueChildren.Count, Is.EqualTo(3));
            }
            finally
            {
                boxBlob.Dispose();
                capsuleBlob.Dispose();
                sphereBlob.Dispose();
                if (compoundBlob.IsCreated)
                {
                    compoundBlob.Dispose();
                }
            }
        }
예제 #20
0
        protected override void OnUpdate()
        {
            var shapeQuery = EntityManager.CreateEntityQuery(ComponentType.ReadOnly <T>());
            var shapeCount = shapeQuery.CalculateEntityCount();

            // A map from entities to arrays of colliders
            m_ExtraColliders = new NativeMultiHashMap <ComparableEntity, LeafShapeData>(shapeCount, Allocator.Temp);

            // Lists to store input data for deferred convex and mesh jobs
            const int defaultPointsPerShape = 1024;

            m_ConvexColliderJobs   = new NativeList <ConvertConvexColliderInput>(shapeCount, Allocator.TempJob);
            m_ConvexColliderPoints = new NativeList <float3>(shapeCount * defaultPointsPerShape, Allocator.TempJob);

            m_MeshColliderJobs     = new NativeList <ConvertMeshColliderInput>(shapeCount, Allocator.TempJob);
            m_MeshColliderVertices = new NativeList <float3>(shapeCount * defaultPointsPerShape, Allocator.TempJob);
            m_MeshColliderIndices  = new NativeList <int>(shapeCount * defaultPointsPerShape / 2, Allocator.TempJob);

            // First pass.
            // Convert all shape authoring components into colliders, and collect them for each primary body
            Entities.ForEach <T>(ConvertShape);

            // Second pass.
            // Produce all convex and mesh collider blobs in parallel
            const int arrayLength     = 5;
            var       convexColliders =
                new NativeArray <KeyValuePair <Entity, LeafShapeData> >(m_ConvexColliderJobs.Length, Allocator.TempJob);
            var convexJob = new ProduceConvexCollidersJob
            {
                InputParameters = m_ConvexColliderJobs,
                AllPoints       = m_ConvexColliderPoints,
                Output          = convexColliders
            }.Schedule(m_ConvexColliderJobs.Length, arrayLength);

            var meshColliders =
                new NativeArray <KeyValuePair <Entity, LeafShapeData> >(m_MeshColliderJobs.Length, Allocator.TempJob);
            var meshJob = new ProduceMeshCollidersJob
            {
                InputParameters = m_MeshColliderJobs,
                AllVertices     = m_MeshColliderVertices,
                AllIndices      = m_MeshColliderIndices,
                Output          = meshColliders
            }.Schedule(m_MeshColliderJobs.Length, arrayLength);

            JobHandle.CombineDependencies(convexJob, meshJob).Complete();

            AppendLeafShapeDataToShapeMap(convexColliders, m_ExtraColliders, m_ConvexShapes);
            convexColliders.Dispose();

            AppendLeafShapeDataToShapeMap(meshColliders, m_ExtraColliders, m_MeshShapes);
            meshColliders.Dispose();

            // Final pass.
            // Assign PhysicsCollider components to rigid bodies, merging multiples into compounds as needed
            var keys = m_ExtraColliders.GetUniqueKeyArray(Allocator.Temp);

            using (keys.Item1)
            {
                for (var k = 0; k < keys.Item2; ++k)
                {
                    ComparableEntity body = keys.Item1[k];
                    var collider          = DstEntityManager.HasComponent <PhysicsCollider>(body.Entity)
                        ? DstEntityManager.GetComponentData <PhysicsCollider>(body.Entity)
                        : new PhysicsCollider();
                    var children = new NativeList <CompoundCollider.ColliderBlobInstance>(16, Allocator.Temp);

                    // collect any existing valid shapes
                    if (collider.IsValid)
                    {
                        ColliderType colliderType;
                        unsafe { colliderType = collider.ColliderPtr->Type; }

                        // if there is already a compound, add its leaves to the list of children
                        if (colliderType == ColliderType.Compound)
                        {
                            unsafe
                            {
                                var existingChildren = ((CompoundCollider *)collider.ColliderPtr)->Children;
                                for (int i = 0, count = existingChildren.Length; i < count; ++i)
                                {
                                    children.Add(new CompoundCollider.ColliderBlobInstance
                                    {
                                        Collider = BlobAssetReference <Collider> .Create(
                                            existingChildren[i].Collider,
                                            existingChildren[i].Collider->MemorySize
                                            ),
                                        CompoundFromChild = existingChildren[i].CompoundFromChild
                                    });
                                }
                            }
                        }
                        // otherwise add the single collider to the list of children
                        else
                        {
                            children.Add(
                                new CompoundCollider.ColliderBlobInstance
                            {
                                Collider          = collider.Value,
                                CompoundFromChild = RigidTransform.identity
                            }
                                );
                        }
                    }

                    // if collider is already valid, a shape already existed from another system
                    var isSingleShapeOnPrimaryBody = !collider.IsValid;
                    // collect all children found by this system
                    if (m_ExtraColliders.TryGetFirstValue(body, out var child, out var iterator))
                    {
                        do
                        {
                            children.Add(child.ColliderBlobInstance);
                            isSingleShapeOnPrimaryBody &= child.LeafEntity.Equals(body.Entity);
                        } while (m_ExtraColliders.TryGetNextValue(out child, ref iterator));
                    }

                    // if there is a single shape on the primary body, use it as-is, otherwise create a compound
                    // (assume a single leaf should still be a compound so that local offset values in authoring representation are retained)
                    collider.Value = isSingleShapeOnPrimaryBody
                        ? children[0].Collider
                        : CompoundCollider.Create(children);

                    children.Dispose();

                    DstEntityManager.AddOrSetComponent(body.Entity, collider);
                }
            }

            m_ConvexShapes.Clear();
            m_ConvexColliderJobs.Dispose();
            m_ConvexColliderPoints.Dispose();

            m_MeshShapes.Clear();
            m_MeshColliderJobs.Dispose();
            m_MeshColliderVertices.Dispose();
            m_MeshColliderIndices.Dispose();
        }
    public void RebuildCollision()
    {
        List <ChunkComponent> chunkList = new List <ChunkComponent>();
        int colliderCount = 0;

        for (int x = 0; x < sizeX; x++)
        {
            for (int z = 0; z < sizeZ; z++)
            {
                for (int y = 0; y < sizeY; y++)
                {
                    if (chunkComponents[x, y, z] != null || chunkComponents[x, y, z].chunk.getCollisionData() != null)
                    {
                        chunkList.Add(chunkComponents[x, y, z]);
                        colliderCount += chunkComponents[x, y, z].chunk.getCollisionData().Count;
                    }
                }
            }
        }

        BoxGeometry box = new BoxGeometry
        {
            Center      = float3.zero,
            Orientation = quaternion.identity,
            Size        = new float3(0.9f),
            BevelRadius = 0.0f
        };

        Vector3    position      = Vector3.zero;
        quaternion rotation      = quaternion.identity;
        Chunk      chunk         = null;
        int        colliderIndex = 0;

        NativeArray <CompoundCollider.ColliderBlobInstance> colliders = new NativeArray <CompoundCollider.ColliderBlobInstance>(colliderCount, Allocator.Temp);

        for (int i = 0; i < chunkList.Count; i++)
        {
            chunk = chunkList[i].chunk;

            for (int n = 0; n < chunk.getCollisionData().Count; n++)
            {
                float3 center = chunk.getCollisionData().centers[n] + (new Vector3(chunk.getX(), chunk.getY(), chunk.getZ()) * Constants.CHUNK_SIZE) + pivotPoint;
                box.Size = chunk.getCollisionData().sizes[n];

                colliders[colliderIndex] = new CompoundCollider.ColliderBlobInstance
                {
                    CompoundFromChild = new RigidTransform(quaternion.identity, center),
                    Collider          = Unity.Physics.BoxCollider.Create(box)
                };

                colliderIndex++;
            }
        }

        BlobAssetReference <Unity.Physics.Collider> collider = CompoundCollider.Create(colliders);

        GameMaster.Instance.entityManager.SetComponentData(entity, new PhysicsCollider {
            Value = collider
        });

        if (isStatic == false)
        {
            GameMaster.Instance.SetEntityMass(entity, collider, colliders.Length);
        }

        colliders.Dispose();
    }