protected override void Start()
    {
        base.Start();

        BlobAssetReference <Unity.Physics.Collider> collider = Unity.Physics.BoxCollider.Create(new BoxGeometry
        {
            Center      = float3.zero,
            Orientation = quaternion.identity,
            Size        = new float3(0.25f),
            BevelRadius = 0.0f
        });

        var manager = DefaultWorld.EntityManager;

        // Add a dynamic body constrained to the world that will die
        // Once the dynamic body is destroyed the joint will be invalid
        {
            // Create a dynamic body
            float3 pivotWorld = new float3(-2f, 0, 0);
            Entity body       = CreateDynamicBody(pivotWorld, quaternion.identity, collider, float3.zero, float3.zero, 1.0f);

            // create extra dynamic body to trigger havok sync after the first one is destroyed
            CreateDynamicBody(pivotWorld * 2.0f, quaternion.identity, collider, float3.zero, float3.zero, 1.0f);

            // add timeout on dynamic body after 15 frames.
            manager.AddComponentData(body, new LifeTime {
                Value = 15
            });

            // Create the joint
            float3 pivotLocal  = float3.zero;
            var    joint       = PhysicsJoint.CreateBallAndSocket(pivotLocal, pivotWorld);
            var    jointEntity = CreateJoint(joint, body, Entity.Null);

            // add timeout on joint entity after 30 frames.
            manager.AddComponentData(jointEntity, new LifeTime {
                Value = 30
            });
        }

        // Add two static bodies constrained together
        // The joint is invalid immediately
        {
            // Create a body
            Entity bodyA = CreateStaticBody(new float3(0, 0.0f, 0), quaternion.identity, collider);
            Entity bodyB = CreateStaticBody(new float3(0, 1.0f, 0), quaternion.identity, collider);

            // Create the joint
            float3 pivotLocal  = float3.zero;
            var    joint       = PhysicsJoint.CreateBallAndSocket(pivotLocal, pivotLocal);
            var    jointEntity = CreateJoint(joint, bodyA, bodyB);

            // add timeout on joint entity after 15 frames.
            manager.AddComponentData(jointEntity, new LifeTime {
                Value = 15
            });
        }
    }
Exemple #2
0
 public override void Create(EntityManager entityManager, GameObjectConversionSystem conversionSystem)
 {
     UpdateAuto();
     conversionSystem.World.GetOrCreateSystem <EndJointConversionSystem>().CreateJointEntity(
         this,
         GetConstrainedBodyPair(conversionSystem),
         PhysicsJoint.CreateBallAndSocket(PositionLocal, PositionInConnectedEntity)
         );
 }
Exemple #3
0
    public override void CreateScene(InvalidPhysicsJointExcludeDemoScene sceneSettings)
    {
        float colliderSize = 0.25f;

        BlobAssetReference <Unity.Physics.Collider> collider = Unity.Physics.BoxCollider.Create(new BoxGeometry
        {
            Center      = float3.zero,
            Orientation = quaternion.identity,
            Size        = new float3(colliderSize),
            BevelRadius = 0.0f
        });

        CreatedColliders.Add(collider);

        float timeToSwap = sceneSettings.TimeToSwap;

        var bodyAPos = new float3(2f, 5.0f, 2);
        var bodyBPos = new float3(2f, 6.0f, 2);

        // Add constrained dynamic/dynamic body pair that will have their bodies excluded
        bool buildThisSection = true;

        if (buildThisSection)
        {
            bodyAPos += new float3(1, 0, 0);
            bodyBPos += new float3(1, 0, 0);

            // Create a body
            Entity bodyA = CreateDynamicBody(bodyAPos, quaternion.identity, collider, float3.zero, float3.zero, 1.0f);
            Entity bodyB = CreateDynamicBody(bodyBPos, quaternion.identity, collider, float3.zero, float3.zero, 1.0f);

            for (int i = 0; i < 2; i++)
            {
                // Create the joint
                var joint       = PhysicsJoint.CreateBallAndSocket(new float3(0, colliderSize, 0), new float3(0, -colliderSize, 0));
                var jointEntity = CreateJoint(joint, bodyA, bodyB);

                var pair = EntityManager.GetComponentData <PhysicsConstrainedBodyPair>(jointEntity);
                pair.EnableCollision = 1;
                EntityManager.SetComponentData(jointEntity, pair);
            }

            // add exclude components.
            EntityManager.AddComponentData(bodyA, new InvalidPhysicsJointExcludeBodies {
            });
            EntityManager.AddComponentData(bodyA, new InvalidPhysicsJointExcludeTimerEvent {
                TimeLimit = timeToSwap, Timer = timeToSwap
            });
            EntityManager.AddComponentData(bodyB, new InvalidPhysicsJointExcludeBodies {
            });
            EntityManager.AddComponentData(bodyB, new InvalidPhysicsJointExcludeTimerEvent {
                TimeLimit = timeToSwap, Timer = timeToSwap
            });
        }
    }
    public static PhysicsJoint CreateJoint(GameObject parentBody, GameObject childBody, BasicJointInfo.BasicJointType jointType)
    {
        var bodyPBounds = parentBody.GetComponent <MeshRenderer>().bounds;
        var bodyCBounds = childBody.GetComponent <MeshRenderer>().bounds;

        var pointConPWorld = bodyPBounds.ClosestPoint(bodyCBounds.center);
        var pointPonCWorld = bodyCBounds.ClosestPoint(bodyPBounds.center);

        var bodyPTransform = new RigidTransform(parentBody.transform.rotation, parentBody.transform.position); // was torso
        var bodyCTransform = new RigidTransform(childBody.transform.rotation, childBody.transform.position);   // was head

        PhysicsJoint jointData = default;

        switch (jointType)
        {
        case BasicJointInfo.BasicJointType.BallAndSocket:
        {
            var pivotP = math.transform(math.inverse(bodyPTransform), pointConPWorld);
            var pivotC = math.transform(math.inverse(bodyCTransform), pointConPWorld);
            jointData = PhysicsJoint.CreateBallAndSocket(pivotP, pivotC);
        }
        break;

        case BasicJointInfo.BasicJointType.Distance:
        {
            var pivotP = math.transform(math.inverse(bodyPTransform), pointConPWorld);
            var pivotC = math.transform(math.inverse(bodyCTransform), pointPonCWorld);
            var range  = new FloatRange(0, math.distance(pointConPWorld, pointPonCWorld));
            jointData = PhysicsJoint.CreateLimitedDistance(pivotP, pivotC, range);
        }
        break;

        case BasicJointInfo.BasicJointType.Hinge:
        {
            var commonPivotPointWorld = math.lerp(pointConPWorld, pointPonCWorld, 0.5f);

            // assume a vertical hinge joint
            var axisP = math.rotate(math.inverse(bodyPTransform.rot), math.up());
            var axisC = math.rotate(math.inverse(bodyCTransform.rot), math.up());

            float3 perpendicularAxisA, perpendicularAxisB;
            Math.CalculatePerpendicularNormalized(axisP, out perpendicularAxisA, out _);
            Math.CalculatePerpendicularNormalized(axisC, out perpendicularAxisB, out _);

            var pivotP      = math.transform(math.inverse(bodyPTransform), commonPivotPointWorld);
            var pivotC      = math.transform(math.inverse(bodyCTransform), commonPivotPointWorld);
            var jointFrameP = new BodyFrame {
                Axis = axisP, PerpendicularAxis = perpendicularAxisA, Position = pivotP
            };
            var jointFrameC = new BodyFrame {
                Axis = axisC, PerpendicularAxis = perpendicularAxisB, Position = pivotC
            };
            var range = new FloatRange(math.radians(-90), math.radians(90.0f));
            jointData = PhysicsJoint.CreateLimitedHinge(jointFrameP, jointFrameC, range);
        }
        break;

        default:
            break;
        }
        return(jointData);
    }
    public override void CreateScene(InvalidPhysicsJointDemoScene sceneSettings)
    {
        float colliderSize = 0.25f;

        BlobAssetReference <Collider> collider = BoxCollider.Create(new BoxGeometry
        {
            Center      = float3.zero,
            Orientation = quaternion.identity,
            Size        = new float3(colliderSize),
            BevelRadius = 0.0f
        });

        CreatedColliders.Add(collider);

        // Add a dynamic body constrained to the world that will die
        // Once the dynamic body is destroyed the joint will be invalid
        {
            // Create a dynamic body
            float3 pivotWorld = new float3(-2f, 0, 0);
            Entity body       = CreateDynamicBody(pivotWorld, quaternion.identity, collider, float3.zero, float3.zero, 1.0f);

            // create extra dynamic body to trigger Havok sync after the first one is destroyed
            CreateDynamicBody(pivotWorld * 2.0f, quaternion.identity, collider, float3.zero, float3.zero, 1.0f);

            // add timeout on dynamic body after 15 frames.
            EntityManager.AddComponentData(body, new LifeTime {
                Value = 15
            });

            // Create the joint
            float3 pivotLocal  = float3.zero;
            var    joint       = PhysicsJoint.CreateBallAndSocket(pivotLocal, pivotWorld);
            var    jointEntity = CreateJoint(joint, body, Entity.Null);

            // add timeout on joint entity after 30 frames.
            EntityManager.AddComponentData(jointEntity, new LifeTime {
                Value = 30
            });
        }

        // Add two static bodies constrained together
        // The joint is invalid immediately
        {
            // Create a body
            Entity bodyA = CreateStaticBody(new float3(0, 0.0f, 0), quaternion.identity, collider);
            Entity bodyB = CreateStaticBody(new float3(0, 1.0f, 0), quaternion.identity, collider);

            // Create the joint
            float3 pivotLocal  = float3.zero;
            var    joint       = PhysicsJoint.CreateBallAndSocket(pivotLocal, pivotLocal);
            var    jointEntity = CreateJoint(joint, bodyA, bodyB);

            // add timeout on joint entity after 15 frames.
            EntityManager.AddComponentData(jointEntity, new LifeTime {
                Value = 15
            });
        }

        // Add two dynamic bodies constrained together with 0 dimension
        {
            // Create a body
            Entity bodyA = CreateDynamicBody(new float3(0, 5.0f, 0), quaternion.identity, collider, float3.zero, float3.zero, 1.0f);
            Entity bodyB = CreateDynamicBody(new float3(0, 6.0f, 0), quaternion.identity, collider, float3.zero, float3.zero, 1.0f);

            // Create the joint
            var joint = PhysicsJoint.CreateLimitedDOF(RigidTransform.identity, new bool3(false), new bool3(false));
            CreateJoint(joint, bodyA, bodyB);
        }
    }
Exemple #6
0
    public override void CreateScene(InvalidPhysicsJointSwapDemoScene sceneSettings)
    {
        float colliderSize = 0.25f;

        BlobAssetReference <Unity.Physics.Collider> collider = Unity.Physics.BoxCollider.Create(new BoxGeometry
        {
            Center      = float3.zero,
            Orientation = quaternion.identity,
            Size        = new float3(colliderSize),
            BevelRadius = 0.0f
        });

        CreatedColliders.Add(collider);

        float timeToSwap = 0.25f;

        // Add two constrained dynamic bodies that will have their bodies swapped
        bool buildThisSection = true;

        if (buildThisSection)
        {
            // Create a body
            Entity bodyA = CreateDynamicBody(new float3(2f, 5.0f, 0), quaternion.identity, collider, float3.zero, float3.zero, 1.0f);
            Entity bodyB = CreateDynamicBody(new float3(2f, 6.0f, 0), quaternion.identity, collider, float3.zero, float3.zero, 1.0f);

            for (int i = 0; i < 2; i++)
            {
                // Create the joint
                var joint       = PhysicsJoint.CreateBallAndSocket(new float3(0, colliderSize, 0), new float3(0, -colliderSize, 0));
                var jointEntity = CreateJoint(joint, bodyA, bodyB);

                var pair = EntityManager.GetComponentData <PhysicsConstrainedBodyPair>(jointEntity);
                pair.EnableCollision = 1;
                EntityManager.SetComponentData(jointEntity, pair);

                if (1 == i)
                {
                    // add swap and timer components.
                    EntityManager.AddComponentData(jointEntity, new InvalidPhysicsJointSwapBodies {
                    });
                    EntityManager.AddComponentData(jointEntity, new InvalidPhysicsJointSwapTimerEvent {
                        TimeLimit = timeToSwap, Timer = timeToSwap
                    });
                }
            }

            EntityManager.AddComponentData(bodyA, new InvalidPhysicsJointKillBodies {
            });
            EntityManager.AddComponentData(bodyA, new InvalidPhysicsJointSwapTimerEvent {
                TimeLimit = timeToSwap * 2.0f, Timer = timeToSwap * 2.0f
            });
        }

        // Add constrained static/dynamic body pair that will have their bodies swapped
        buildThisSection = true;
        if (buildThisSection)
        {
            // Create a body
            var    staticTransform = new RigidTransform(quaternion.identity, new float3(3f, 5.0f, 0));
            Entity bodyS           = CreateStaticBody(staticTransform.pos, staticTransform.rot, collider);
            Entity bodyD           = CreateDynamicBody(new float3(3f, 6.0f, 0), quaternion.identity, collider, float3.zero, float3.zero, 1.0f);

            for (int i = 0; i < 2; i++)
            {
                // Create the joint
                var joint       = PhysicsJoint.CreateBallAndSocket(new float3(0, colliderSize, 0), new float3(0, -colliderSize, 0));
                var jointEntity = CreateJoint(joint, bodyS, bodyD);

                var pair = EntityManager.GetComponentData <PhysicsConstrainedBodyPair>(jointEntity);
                pair.EnableCollision = 1;
                EntityManager.SetComponentData(jointEntity, pair);
            }

            // add swap and timer components.
            EntityManager.AddComponentData(bodyS, new InvalidPhysicsJointSwapMotionType {
                OriginalTransform = staticTransform
            });
            EntityManager.AddComponentData(bodyS, new InvalidPhysicsJointSwapTimerEvent {
                TimeLimit = timeToSwap, Timer = timeToSwap
            });
        }
    }
    public override void CreateScene(SoftJointDemoScene sceneSettings)
    {
        // Make soft ball and sockets
        {
            BlobAssetReference <Unity.Physics.Collider> collider = Unity.Physics.BoxCollider.Create(new BoxGeometry
            {
                Center      = float3.zero,
                Orientation = quaternion.identity,
                Size        = new float3(0.2f, 0.2f, 0.2f),
                BevelRadius = 0.0f
            });
            CreatedColliders.Add(collider);

            // Make joints with different spring frequency.  The leftmost joint should oscillate at 0.5hz, the next at 1hz, the next at 1.5hz, etc.
            for (int i = 0; i < 10; i++)
            {
                // Create a body
                float3 position = new float3((i - 4.5f) * 1.0f, 0, 0);
                float3 velocity = new float3(0, -10.0f, 0);
                Entity body     = CreateDynamicBody(
                    position, quaternion.identity, collider, velocity, float3.zero, 1.0f);

                // Create the ball and socket joint
                float3 pivotLocal   = float3.zero;
                float3 pivotInWorld = math.transform(GetBodyTransform(body), pivotLocal);

                var jointData   = PhysicsJoint.CreateBallAndSocket(pivotLocal, pivotInWorld);
                var constraints = jointData.GetConstraints();
                var constraint  = constraints[0];
                // Choose a small damping value instead of 0 to improve stability of the joints
                constraint.SpringDamping   = 0.05f;
                constraint.SpringFrequency = 0.5f * (float)(i + 1);
                constraints[0]             = constraint;
                jointData.SetConstraints(constraints);

                CreateJoint(jointData, body, Entity.Null);
            }
        }

        //Make soft limited hinges
        {
            BlobAssetReference <Unity.Physics.Collider> collider = Unity.Physics.BoxCollider.Create(new BoxGeometry
            {
                Center      = float3.zero,
                Orientation = quaternion.identity,
                Size        = new float3(0.4f, 0.1f, 0.6f),
                BevelRadius = 0.0f
            });
            CreatedColliders.Add(collider);

            // First row has soft limit with hard hinge + pivot, second row has everything soft
            for (int j = 0; j < 2; j++)
            {
                for (int i = 0; i < 10; i++)
                {
                    // Create a body
                    float3 position        = new float3((i - 4.5f) * 1.0f, 0, (j + 1) * 3.0f);
                    float3 velocity        = new float3(0, -10.0f, 0);
                    float3 angularVelocity = new float3(0, 0, -10.0f);
                    Entity body            = CreateDynamicBody(
                        position, quaternion.identity, collider, velocity, angularVelocity, 1.0f);

                    // Create the limited hinge joint
                    float3 pivotLocal           = new float3(0, 0, 0);
                    float3 pivotInWorld         = math.transform(GetBodyTransform(body), pivotLocal);
                    float3 axisLocal            = new float3(0, 0, 1);
                    float3 axisInWorld          = axisLocal;
                    float3 perpendicularLocal   = new float3(0, 1, 0);
                    float3 perpendicularInWorld = perpendicularLocal;

                    var frameLocal = new BodyFrame {
                        Axis = axisLocal, PerpendicularAxis = perpendicularLocal, Position = pivotLocal
                    };
                    var frameWorld = new BodyFrame {
                        Axis = axisInWorld, PerpendicularAxis = perpendicularInWorld, Position = pivotInWorld
                    };
                    var jointData = PhysicsJoint.CreateLimitedHinge(frameLocal, frameWorld, default);

                    // First constraint is the limit, next two are the hinge and pivot
                    var constraints = jointData.GetConstraints();
                    for (int k = 0; k < 1 + 2 * j; k++)
                    {
                        var constraint = constraints[k];
                        // Choose a small damping value instead of 0 to improve stability of the joints
                        constraint.SpringDamping   = 0.05f;
                        constraint.SpringFrequency = 0.5f * (i + 1);
                        constraints[k]             = constraint;
                    }
                    jointData.SetConstraints(constraints);

                    CreateJoint(jointData, body, Entity.Null);
                }
            }
        }

        // Make a soft prismatic
        {
            BlobAssetReference <Unity.Physics.Collider> collider = Unity.Physics.BoxCollider.Create(new BoxGeometry
            {
                Center      = float3.zero,
                Orientation = quaternion.identity,
                Size        = new float3(0.2f, 0.2f, 0.2f),
                BevelRadius = 0.0f
            });
            CreatedColliders.Add(collider);

            // Create a body
            float3 position = new float3(0, 0, 9.0f);
            float3 velocity = new float3(50.0f, 0, 0);
            Entity body     = CreateDynamicBody(
                position, quaternion.identity, collider, velocity, float3.zero, 1.0f);

            // Create the prismatic joint
            float3 pivotLocal           = float3.zero;
            float3 pivotInWorld         = math.transform(GetBodyTransform(body), pivotLocal);
            float3 axisLocal            = new float3(1, 0, 0);
            float3 axisInWorld          = axisLocal;
            float3 perpendicularLocal   = new float3(0, 1, 0);
            float3 perpendicularInWorld = perpendicularLocal;

            var localFrame = new BodyFrame {
                Axis = axisLocal, PerpendicularAxis = perpendicularLocal, Position = pivotLocal
            };
            var worldFrame = new BodyFrame {
                Axis = axisInWorld, PerpendicularAxis = perpendicularInWorld, Position = pivotInWorld
            };
            var jointData   = PhysicsJoint.CreatePrismatic(localFrame, worldFrame, new FloatRange(-2f, 2f));
            var constraints = jointData.GetConstraints();
            var constraint  = constraints[0];
            // Choose a small damping value instead of 0 to improve stability of the joints
            constraint.SpringDamping   = 0.05f;
            constraint.SpringFrequency = 5.0f;
            constraints[0]             = constraint;
            jointData.SetConstraints(constraints);
            CreateJoint(jointData, body, Entity.Null);
        }
    }