Пример #1
0
    public static void CreateWaist(GameObject torso, GameObject pelvis, out BlobAssetReference <JointData> jointData0, out BlobAssetReference <JointData> jointData1)
    {
        float3 pivotTorso = float3.zero;

        RigidTransform pelvisTransform = new RigidTransform(pelvis.transform.rotation, pelvis.transform.position);
        RigidTransform torsoTransform  = new RigidTransform(torso.transform.rotation, torso.transform.position);

        float3 pivotPelvis = math.transform(math.inverse(pelvisTransform), math.transform(torsoTransform, pivotTorso));
        float3 axisPelvis  = new float3(0, 0, -1);
        float3 axisTorso   = axisPelvis;

        float3 axisPerpendicular = new float3(1, 0, 0);

        float3 perpendicularPelvis = math.rotate(math.inverse(pelvisTransform), axisPerpendicular);
        float3 perpendicularTorso  = math.rotate(math.inverse(torsoTransform), axisPerpendicular);

        float coneAngle          = 0.0872665f;
        var   perpendicularAngle = new FloatRange {
            Max = math.PI
        };
        var twistAngle = new FloatRange(-0.01f, 0.1f);

        var jointFrameTorso = new JointFrame {
            Axis = axisTorso, PerpendicularAxis = perpendicularTorso, Position = pivotTorso
        };
        var jointFramePelvis = new JointFrame {
            Axis = axisPelvis, PerpendicularAxis = perpendicularPelvis, Position = pivotPelvis
        };

        JointData.CreateRagdoll(jointFrameTorso, jointFramePelvis, coneAngle, perpendicularAngle, twistAngle, out jointData0, out jointData1);
    }
Пример #2
0
        public override void Create(EntityManager entityManager, GameObjectConversionSystem conversionSystem)
        {
            if (AutoSetConnected)
            {
                RigidTransform bFromA = math.mul(math.inverse(worldFromB), worldFromA);
                PositionInConnectedEntity          = math.transform(bFromA, PositionLocal);
                TwistAxisInConnectedEntity         = math.mul(bFromA.rot, TwistAxisLocal);
                PerpendicularAxisInConnectedEntity = math.mul(bFromA.rot, PerpendicularAxisLocal);
            }

            JointData.CreateRagdoll(
                new JointFrame {
                Axis = TwistAxisLocal, PerpendicularAxis = PerpendicularAxisLocal, Position = PositionLocal
            },
                new JointFrame {
                Axis = TwistAxisInConnectedEntity, PerpendicularAxis = PerpendicularAxisInConnectedEntity, Position = PositionInConnectedEntity
            },
                math.radians(MaxConeAngle),
                math.radians(new FloatRange(MinPerpendicularAngle, MaxPerpendicularAngle)),
                math.radians(new FloatRange(MinTwistAngle, MaxTwistAngle)),
                out BlobAssetReference <JointData> jointData0,
                out BlobAssetReference <JointData> jointData1
                );

            CreateJointEntity(jointData0, entityManager, conversionSystem);
            CreateJointEntity(jointData1, entityManager, conversionSystem);
        }
Пример #3
0
    public static void CreateHip(GameObject pelvis, GameObject upperLeg, out BlobAssetReference <JointData> jointData0, out BlobAssetReference <JointData> jointData1)
    {
        float upperLegHeight = 2.0f * upperLeg.transform.localScale.y;

        var pelvisTransform   = new RigidTransform(pelvis.transform.rotation, pelvis.transform.position);
        var upperLegTransform = new RigidTransform(upperLeg.transform.rotation, upperLeg.transform.position);

        float3 pivotLeg    = new float3(0, upperLegHeight / 2.0f, 0);
        float3 pivotPelvis = math.transform(math.inverse(pelvisTransform), math.transform(upperLegTransform, pivotLeg));

        float3 twistAxis         = new float3(0, -1, 0);
        float3 perpendicularAxis = new float3(1, 0, 0);

        float3 twistAxisLeg    = math.rotate(math.inverse(upperLegTransform), twistAxis);
        float3 twistAxisPelvis = math.rotate(math.inverse(pelvisTransform), twistAxis);

        float3 perpendicularAxisLeg    = math.rotate(math.inverse(upperLegTransform), perpendicularAxis);
        float3 perpendicularAxisPelvis = math.rotate(math.inverse(pelvisTransform), perpendicularAxis);

        float coneAngle          = math.PI / 4.0f;
        var   perpendicularAngle = new FloatRange(math.PI / 3f, math.PI * 2f / 3f);
        var   twistAngle         = new FloatRange(-0.2f, 0.2f);

        var jointFramePelvis = new JointFrame {
            Axis = twistAxisPelvis, PerpendicularAxis = perpendicularAxisPelvis, Position = pivotPelvis
        };
        var jointFrameLeg = new JointFrame {
            Axis = twistAxisLeg, PerpendicularAxis = perpendicularAxisLeg, Position = pivotLeg
        };

        JointData.CreateRagdoll(jointFramePelvis, jointFrameLeg, coneAngle, perpendicularAngle, twistAngle, out jointData0, out jointData1);
    }
Пример #4
0
    public static void CreateNeck(GameObject torso, GameObject head, out BlobAssetReference <JointData> jointData0, out BlobAssetReference <JointData> jointData1)
    {
        var   headTransform = head.GetComponent <Transform>();
        float headRadius    = 0.5f * headTransform.localScale.x;

        float3 pivotHead           = new float3(0, -headRadius, 0);
        var    torsoTransform      = torso.GetComponent <Transform>();
        var    torsoRigidTransform = new RigidTransform(torsoTransform.rotation, torsoTransform.position);

        var headRigidTransform = new RigidTransform(headTransform.rotation, headTransform.position);

        float3 pivotTorso         = math.transform(math.inverse(torsoRigidTransform), math.transform(headRigidTransform, pivotHead));
        float3 axis               = new float3(0, 1, 0);
        float3 perpendicular      = new float3(0, 0, 1);
        float  coneAngle          = math.PI / 5.0f;
        var    perpendicularAngle = new FloatRange {
            Max = math.PI
        };
        var twistAngle = new FloatRange(-math.PI / 3f, math.PI / 3f);

        var jointFrameTorso = new JointFrame {
            Axis = axis, PerpendicularAxis = perpendicular, Position = pivotTorso
        };
        var jointFrameHead = new JointFrame {
            Axis = axis, PerpendicularAxis = perpendicular, Position = pivotHead
        };

        JointData.CreateRagdoll(jointFrameTorso, jointFrameHead, coneAngle, perpendicularAngle, twistAngle, out jointData0, out jointData1);
    }
    protected override void Start()
    {
        base.Start();

        // Enable the joint viewer
        SetDebugDisplay(new Unity.Physics.Authoring.PhysicsDebugDisplayData
        {
            DrawJoints = 1
        });

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

        // Make some ragdoll joints
        for (int i = 0; i < 10; i++)
        {
            // Create a body
            Entity body = CreateDynamicBody(
                new float3((i - 4.5f) * 1.0f, 0, 0), quaternion.identity, collider, float3.zero, float3.zero, 1.0f);

            // Create the ragdoll joint
            float3 pivotLocal         = new float3(0, 0.5f, 0);
            float3 pivotInWorld       = math.transform(GetBodyTransform(body), pivotLocal);
            float3 axisLocal          = new float3(0, 1, 0);
            float3 perpendicularLocal = new float3(0, 0, 1);

            quaternion worldFromLocal     = Quaternion.AngleAxis((i - 4.5f) * 20.0f, new float3(0, 0, 1));
            float3     axisWorld          = math.mul(worldFromLocal, axisLocal);
            float3     perpendicularWorld = math.mul(worldFromLocal, perpendicularLocal);

            float maxConeAngle       = (float)math.PI / 4.0f;
            var   perpendicularAngle = new FloatRange(-math.PI / 2f, math.PI / 2f);
            var   twistAngle         = new FloatRange(-math.PI / 8f, math.PI / 8f);

            BlobAssetReference <JointData> ragdoll0, ragdoll1;
            var localFrame = new JointFrame {
                Axis = axisLocal, PerpendicularAxis = perpendicularLocal, Position = pivotLocal
            };
            var worldFrame = new JointFrame {
                Axis = axisWorld, PerpendicularAxis = perpendicularWorld, Position = pivotInWorld
            };
            JointData.CreateRagdoll(localFrame, worldFrame, maxConeAngle, perpendicularAngle, twistAngle, out ragdoll0, out ragdoll1);
            CreateJoint(ragdoll0, body, Entity.Null);
            CreateJoint(ragdoll1, body, Entity.Null);
        }
    }
Пример #6
0
    protected override void Start()
    {
        base.Start();

        // Enable the joint viewer
        SetDebugDisplay(new Unity.Physics.Authoring.PhysicsDebugDisplayData
        {
            DrawJoints = 1
        });

        BlobAssetReference <Unity.Physics.Collider> collider = Unity.Physics.BoxCollider.Create(float3.zero, Quaternion.identity, new float3(0.2f, 1.0f, 0.2f), 0.0f);

        // Make some ragdoll joints
        for (int i = 0; i < 10; i++)
        {
            // Create a body
            Entity body = CreateDynamicBody(
                new float3((i - 4.5f) * 1.0f, 0, 0), quaternion.identity, collider, float3.zero, float3.zero, 1.0f);

            // Create the ragdoll joint
            float3 pivotLocal         = new float3(0, 0.5f, 0);
            float3 pivotInWorld       = math.transform(GetBodyTransform(body), pivotLocal);
            float3 axisLocal          = new float3(0, 1, 0);
            float3 perpendicularLocal = new float3(0, 0, 1);

            quaternion worldFromLocal     = Quaternion.AngleAxis((i - 4.5f) * 20.0f, new float3(0, 0, 1));
            float3     axisWorld          = math.mul(worldFromLocal, axisLocal);
            float3     perpendicularWorld = math.mul(worldFromLocal, perpendicularLocal);

            float maxConeAngle          = (float)math.PI / 4.0f;
            float maxPerpendicularAngle = (float)math.PI / 2.0f;
            float minPerpendicularAngle = -maxPerpendicularAngle;
            float maxTwistAngle         = (float)math.PI / 8.0f;
            float minTwistAngle         = -maxTwistAngle;

            BlobAssetReference <JointData> ragdoll0, ragdoll1;
            JointData.CreateRagdoll(pivotLocal, pivotInWorld, axisLocal, axisWorld, perpendicularLocal, perpendicularWorld,
                                    maxConeAngle, minPerpendicularAngle, maxPerpendicularAngle, minTwistAngle, maxTwistAngle,
                                    out ragdoll0, out ragdoll1);
            CreateJoint(ragdoll0, body, Entity.Null);
            CreateJoint(ragdoll1, body, Entity.Null);
        }
    }
        public override unsafe void Create(EntityManager entityManager)
        {
            if (AutoSetConnected)
            {
                RigidTransform bFromA = math.mul(math.inverse(worldFromB), worldFromA);
                PositionInConnectedEntity          = math.transform(bFromA, PositionLocal);
                TwistAxisInConnectedEntity         = math.mul(bFromA.rot, TwistAxisLocal);
                PerpendicularAxisInConnectedEntity = math.mul(bFromA.rot, PerpendicularAxisLocal);
            }

            BlobAssetReference <JointData> jointData0, jointData1;

            JointData.CreateRagdoll(
                PositionLocal, PositionInConnectedEntity, TwistAxisLocal, TwistAxisInConnectedEntity, PerpendicularAxisLocal, PerpendicularAxisInConnectedEntity,
                math.radians(MaxConeAngle), math.radians(MinPerpendicularAngle), math.radians(MaxPerpendicularAngle), math.radians(MinTwistAngle), math.radians(MaxTwistAngle),
                out jointData0, out jointData1);

            CreateJointEntity(jointData0, entityManager);
            CreateJointEntity(jointData1, entityManager);
        }
Пример #8
0
    public static void CreateShoulder(GameObject torso, GameObject upperArm, out BlobAssetReference <JointData> jointData0, out BlobAssetReference <JointData> jointData1)
    {
        float armLength = 2 * upperArm.transform.localScale.y;

        float sign = math.sign(-upperArm.transform.position.x);

        var torsoRigidTransform    = new RigidTransform(torso.transform.rotation, torso.transform.position);
        var upperArmRigidTransform = new RigidTransform(upperArm.transform.rotation, upperArm.transform.position);

        float3 pivotArm = new float3(sign * armLength / 2.0f, 0, 0);

        pivotArm = math.rotate(math.inverse(upperArmRigidTransform.rot), pivotArm);
        float3 pivotBody = math.transform(math.inverse(torsoRigidTransform), math.transform(upperArmRigidTransform, pivotArm));

        float3 twistAxis         = new float3(-1.0f * sign, 0, 0);
        float3 perpendicularAxis = new float3(0, 0, 1);

        float3 twistAxisArm   = math.rotate(math.inverse(upperArmRigidTransform), twistAxis);
        float3 twistAxisTorso = math.rotate(math.inverse(torsoRigidTransform), twistAxis);

        float3 perpendicularAxisArm   = math.rotate(math.inverse(upperArmRigidTransform), perpendicularAxis);
        float3 perpendicularAxisTorso = math.rotate(math.inverse(torsoRigidTransform), perpendicularAxis);

        float coneAngle          = math.PI / 4.0f;
        var   perpendicularAngle = new FloatRange(math.PI / 6f, math.PI * 5f / 6f);
        var   twistAngle         = new FloatRange(-0.0872665f, 0.0872665f);

        var jointFrameBody = new JointFrame {
            Axis = twistAxisTorso, PerpendicularAxis = perpendicularAxisTorso, Position = pivotBody
        };
        var jointFrameArm = new JointFrame {
            Axis = twistAxisArm, PerpendicularAxis = perpendicularAxisArm, Position = pivotArm
        };

        JointData.CreateRagdoll(jointFrameBody, jointFrameArm, coneAngle, perpendicularAngle, twistAngle, out jointData0, out jointData1);
    }
    private void CreateRagdoll(float3 positionOffset, quaternion rotationOffset, int ragdollIndex = 1, bool internalCollisions = false)
    {
        NativeList <Entity> entities = new NativeList <Entity>(Allocator.Temp);

        // Head
        float  headRadius   = 0.1f;
        float3 headPosition = new float3(0, 1.8f, 0);
        Entity head;

        {
            CollisionFilter filter = internalCollisions ? layerFilter(layer.Head, layer.Torso) : groupFilter(-ragdollIndex);
            BlobAssetReference <Unity.Physics.Collider> collider = Unity.Physics.SphereCollider.Create(float3.zero, headRadius, filter);
            head = CreateDynamicBody(headPosition, quaternion.identity, collider, float3.zero, float3.zero, 5.0f);
        }
        entities.Add(head);

        // Torso
        float3 torsoSize;
        float3 torsoPosition;
        Entity torso;

        {
            //UnityEngine.Mesh torsoMesh = (UnityEngine.Mesh)Resources.Load("torso", typeof(UnityEngine.Mesh));
            torsoSize     = torsoMesh.bounds.size;
            torsoPosition = headPosition - new float3(0, headRadius * 3.0f / 4.0f + torsoSize.y, 0);

            CollisionFilter filter = internalCollisions ? layerFilter(layer.Torso, layer.Thigh | layer.Head | layer.UpperArm | layer.Pelvis) : groupFilter(-ragdollIndex);

            NativeArray <float3> points = new NativeArray <float3>(torsoMesh.vertices.Length, Allocator.Temp);
            for (int i = 0; i < torsoMesh.vertices.Length; i++)
            {
                points[i] = torsoMesh.vertices[i];
            }
            BlobAssetReference <Unity.Physics.Collider> collider = ConvexCollider.Create(points, 0.01f);
            collider.Value.Filter = filter;
            torso = CreateDynamicBody(torsoPosition, quaternion.identity, collider, float3.zero, float3.zero, 20.0f);
        }
        entities.Add(torso);

        // Neck
        {
            float3 pivotHead             = new float3(0, -headRadius, 0);
            float3 pivotBody             = math.transform(math.inverse(GetBodyTransform(torso)), math.transform(GetBodyTransform(head), pivotHead));
            float3 axis                  = new float3(0, 1, 0);
            float3 perpendicular         = new float3(0, 0, 1);
            float  coneAngle             = (float)math.PI / 5.0f;
            float  minPerpendicularAngle = 0.0f;           // unlimited
            float  maxPerpendicularAngle = (float)math.PI; // unlimited
            float  twistAngle            = (float)math.PI / 3.0f;

            BlobAssetReference <JointData> ragdoll0, ragdoll1;
            JointData.CreateRagdoll(pivotHead, pivotBody, axis, axis, perpendicular, perpendicular,
                                    coneAngle, minPerpendicularAngle, maxPerpendicularAngle, -twistAngle, twistAngle,
                                    out ragdoll0, out ragdoll1);
            CreateJoint(ragdoll0, head, torso);
            CreateJoint(ragdoll1, head, torso);
        }

        // Arms
        {
            float           armLength      = 0.25f;
            float           armRadius      = 0.05f;
            CollisionFilter armUpperFilter = internalCollisions ? layerFilter(layer.UpperArm, layer.Torso | layer.Forearm) : groupFilter(-ragdollIndex);
            CollisionFilter armLowerFilter = internalCollisions ? layerFilter(layer.Forearm, layer.UpperArm | layer.Hand) : groupFilter(-ragdollIndex);

            BlobAssetReference <Unity.Physics.Collider> upperArmCollider = Unity.Physics.CapsuleCollider.Create(new float3(-armLength / 2, 0, 0), new float3(armLength / 2, 0, 0), armRadius,
                                                                                                                armUpperFilter);
            BlobAssetReference <Unity.Physics.Collider> foreArmCollider = Unity.Physics.CapsuleCollider.Create(new float3(-armLength / 2, 0, 0), new float3(armLength / 2, 0, 0), armRadius,
                                                                                                               armLowerFilter);

            float           handLength = 0.025f;
            float           handRadius = 0.055f;
            CollisionFilter handFilter = internalCollisions ? layerFilter(layer.Hand, layer.Forearm) : groupFilter(-ragdollIndex);

            BlobAssetReference <Unity.Physics.Collider> handCollider = Unity.Physics.CapsuleCollider.Create(new float3(-handLength / 2, 0, 0), new float3(handLength / 2, 0, 0), handRadius,
                                                                                                            handFilter);

            for (int i = 0; i < 2; i++)
            {
                float s = i * 2 - 1.0f;

                float3 upperArmPosition = torsoPosition + new float3(s * (torsoSize.x + armLength) / 2.0f, 0.9f * torsoSize.y - armRadius, 0.0f);
                Entity upperArm         = CreateDynamicBody(upperArmPosition, quaternion.identity, upperArmCollider, float3.zero, float3.zero, 10.0f);
                float3 foreArmPosition  = upperArmPosition + new float3(armLength * s, 0, 0);
                Entity foreArm          = CreateDynamicBody(foreArmPosition, quaternion.identity, foreArmCollider, float3.zero, float3.zero, 5.0f);
                float3 handPosition     = foreArmPosition + new float3((armLength + handLength) / 2.0f * s, 0, 0);
                Entity hand             = CreateDynamicBody(handPosition, quaternion.identity, handCollider, float3.zero, float3.zero, 2.0f);

                entities.Add(upperArm);
                entities.Add(foreArm);
                entities.Add(hand);

                // shoulder
                {
                    float3 pivotArm              = new float3(-s * armLength / 2.0f, 0, 0);
                    float3 pivotBody             = math.transform(math.inverse(GetBodyTransform(torso)), math.transform(GetBodyTransform(upperArm), pivotArm));
                    float3 axis                  = new float3(s, 0, 0);
                    float3 perpendicular         = new float3(0, 0, 1);
                    float  coneAngle             = (float)math.PI / 2.0f;
                    float  minPerpendicularAngle = 0.0f;
                    float  maxPerpendicularAngle = (float)math.PI / 2.0f;
                    float  twistAngle            = (float)math.PI / 4.0f;

                    BlobAssetReference <JointData> ragdoll0, ragdoll1;
                    JointData.CreateRagdoll(pivotArm, pivotBody, axis, axis, perpendicular, perpendicular,
                                            coneAngle, minPerpendicularAngle, maxPerpendicularAngle, -twistAngle, twistAngle,
                                            out ragdoll0, out ragdoll1);
                    CreateJoint(ragdoll0, upperArm, torso);
                    CreateJoint(ragdoll1, upperArm, torso);
                }

                // elbow
                {
                    float3 pivotUpper    = new float3(s * armLength / 2.0f, 0, 0);
                    float3 pivotFore     = -pivotUpper;
                    float3 axis          = new float3(0, -s, 0);
                    float3 perpendicular = new float3(s, 0, 0);
                    float  minAngle      = 0.0f;
                    float  maxAngle      = 3.0f;

                    BlobAssetReference <JointData> hinge = JointData.CreateLimitedHinge(pivotFore, pivotUpper, axis, axis, perpendicular, perpendicular, minAngle, maxAngle);
                    CreateJoint(hinge, foreArm, upperArm);
                }

                // wrist
                {
                    float3 pivotFore     = new float3(s * armLength / 2.0f, 0, 0);
                    float3 pivotHand     = new float3(-s * handLength / 2.0f, 0, 0);
                    float3 axis          = new float3(0, -s, 0);
                    float3 perpendicular = new float3(s, 0, 0);
                    float  minAngle      = -0.3f;
                    float  maxAngle      = 0.6f;

                    BlobAssetReference <JointData> hinge = JointData.CreateLimitedHinge(pivotHand, pivotFore, axis, axis, perpendicular, perpendicular, minAngle, maxAngle);
                    CreateJoint(hinge, hand, foreArm);
                }
            }
        }

        // Pelvis
        float  pelvisRadius   = 0.08f;
        float  pelvisLength   = 0.22f;
        float3 pelvisPosition = torsoPosition - new float3(0, pelvisRadius * 0.75f, 0.0f);
        Entity pelvis;

        {
            CollisionFilter filter = internalCollisions ? layerFilter(layer.Pelvis, layer.Torso | layer.Thigh) : groupFilter(-ragdollIndex);
            BlobAssetReference <Unity.Physics.Collider> collider = Unity.Physics.CapsuleCollider.Create(new float3(-pelvisLength / 2.0f, 0, 0), new float3(pelvisLength / 2.0f, 0, 0), pelvisRadius,
                                                                                                        filter);
            pelvis = CreateDynamicBody(pelvisPosition, quaternion.identity, collider, float3.zero, float3.zero, 15.0f);
        }
        entities.Add(pelvis);

        // Waist
        {
            float3 pivotTorso            = float3.zero;
            float3 pivotPelvis           = math.transform(math.inverse(GetBodyTransform(pelvis)), math.transform(GetBodyTransform(torso), pivotTorso));
            float3 axis                  = new float3(0, -1, 0);
            float3 perpendicular         = new float3(0, 0, 1);
            float  coneAngle             = 0.1f;
            float  minPerpendicularAngle = -0.1f;
            float  maxPerpendicularAngle = (float)math.PI;
            float  twistAngle            = 0.1f;

            BlobAssetReference <JointData> ragdoll0, ragdoll1;
            JointData.CreateRagdoll(pivotPelvis, pivotTorso, axis, axis, perpendicular, perpendicular,
                                    coneAngle, minPerpendicularAngle, maxPerpendicularAngle, -twistAngle, twistAngle,
                                    out ragdoll0, out ragdoll1);
            CreateJoint(ragdoll0, pelvis, torso);
            CreateJoint(ragdoll1, pelvis, torso);
        }

        // Legs
        {
            float           thighLength = 0.32f;
            float           thighRadius = 0.08f;
            CollisionFilter thighFilter = internalCollisions ? layerFilter(layer.Thigh, layer.Pelvis | layer.Calf) : groupFilter(-ragdollIndex);
            BlobAssetReference <Unity.Physics.Collider> thighCollider = Unity.Physics.CapsuleCollider.Create(new float3(0, -thighLength / 2, 0), new float3(0, thighLength / 2, 0), thighRadius,
                                                                                                             thighFilter);

            float           calfLength = 0.32f;
            float           calfRadius = 0.06f;
            CollisionFilter calfFilter = internalCollisions ? layerFilter(layer.Calf, layer.Thigh | layer.Foot) : groupFilter(-ragdollIndex);
            BlobAssetReference <Unity.Physics.Collider> calfCollider = Unity.Physics.CapsuleCollider.Create(new float3(0, -calfLength / 2, 0), new float3(0, calfLength / 2, 0), calfRadius,
                                                                                                            calfFilter);

            float           footLength = 0.08f;
            float           footRadius = 0.06f;
            CollisionFilter footFilter = internalCollisions ? layerFilter(layer.Foot, layer.Calf) : groupFilter(-ragdollIndex);
            BlobAssetReference <Unity.Physics.Collider> footCollider = Unity.Physics.CapsuleCollider.Create(new float3(0, 0, 0), new float3(0, 0, footLength), footRadius,
                                                                                                            footFilter);

            for (int i = 0; i < 2; i++)
            {
                float s = i * 2 - 1.0f;

                float3 thighPosition = pelvisPosition + new float3(s * pelvisLength / 2.0f, -thighLength / 2.0f, 0.0f);
                Entity thigh         = CreateDynamicBody(thighPosition, quaternion.identity, thighCollider, float3.zero, float3.zero, 10.0f);
                float3 calfPosition  = thighPosition + new float3(0, -(thighLength + calfLength) / 2.0f, 0);
                Entity calf          = CreateDynamicBody(calfPosition, quaternion.identity, calfCollider, float3.zero, float3.zero, 5.0f);
                float3 footPosition  = calfPosition + new float3(0, -calfLength / 2.0f, 0);
                Entity foot          = CreateDynamicBody(footPosition, quaternion.identity, footCollider, float3.zero, float3.zero, 2.0f);

                entities.Add(thigh);
                entities.Add(calf);
                entities.Add(foot);

                // hip
                {
                    float3 pivotThigh            = new float3(0, thighLength / 2.0f, 0);
                    float3 pivotBody             = math.transform(math.inverse(GetBodyTransform(torso)), math.transform(GetBodyTransform(thigh), pivotThigh));
                    float3 axis                  = new float3(0, -1, 0);
                    float3 perpendicular         = new float3(s, 0, 0);
                    float  coneAngle             = (float)math.PI / 4.0f;
                    float  minPerpendicularAngle = 0.0f;
                    float  maxPerpendicularAngle = 0.2f + (float)math.PI / 2.0f;
                    float  twistAngle            = 0.2f;

                    BlobAssetReference <JointData> ragdoll0, ragdoll1;
                    JointData.CreateRagdoll(pivotThigh, pivotBody, axis, axis, perpendicular, perpendicular,
                                            coneAngle, minPerpendicularAngle, maxPerpendicularAngle, -twistAngle, twistAngle,
                                            out ragdoll0, out ragdoll1);
                    CreateJoint(ragdoll0, thigh, torso);
                    CreateJoint(ragdoll1, thigh, torso);
                }

                // knee
                {
                    float3 pivotThigh    = new float3(0, -thighLength / 2.0f, 0);
                    float3 pivotCalf     = math.transform(math.inverse(GetBodyTransform(calf)), math.transform(GetBodyTransform(thigh), pivotThigh));
                    float3 axis          = new float3(-1, 0, 0);
                    float3 perpendicular = new float3(0, 0, 1);
                    float  minAngle      = -1.2f;
                    float  maxAngle      = 0.0f;

                    BlobAssetReference <JointData> hinge = JointData.CreateLimitedHinge(pivotCalf, pivotThigh, axis, axis, perpendicular, perpendicular, minAngle, maxAngle);
                    CreateJoint(hinge, calf, thigh);
                }

                // ankle
                {
                    float3 pivotCalf     = new float3(0, -calfLength / 2.0f, 0);
                    float3 pivotFoot     = float3.zero;
                    float3 axis          = new float3(-1, 0, 0);
                    float3 perpendicular = new float3(0, 0, 1);
                    float  minAngle      = -0.4f;
                    float  maxAngle      = 0.1f;

                    BlobAssetReference <JointData> hinge = JointData.CreateLimitedHinge(pivotFoot, pivotCalf, axis, axis, perpendicular, perpendicular, minAngle, maxAngle);
                    CreateJoint(hinge, foot, calf);
                }
            }
        }

        // reposition with offset information
        if (entities.Length > 0)
        {
            float3 center = float3.zero;
            for (int i = 0; i < entities.Length; i++)
            {
                var e = entities[i];
                center += EntityManager.GetComponentData <Translation>(e).Value;
            }
            center /= entities.Length;
            for (int i = 0; i < entities.Length; i++)
            {
                var         e = entities[i];
                Translation positionComponent = EntityManager.GetComponentData <Translation>(e);
                Rotation    rotationComponent = EntityManager.GetComponentData <Rotation>(e);

                float3     position = positionComponent.Value;
                quaternion rotation = rotationComponent.Value;

                float3 localPosition = position - center;
                localPosition = math.rotate(rotationOffset, localPosition);

                position = localPosition + center + positionOffset;
                rotation = math.mul(rotation, rotationOffset);

                positionComponent.Value = position;
                rotationComponent.Value = rotation;

                EntityManager.SetComponentData <Translation>(e, positionComponent);
                EntityManager.SetComponentData <Rotation>(e, rotationComponent);
            }
        }
    }
Пример #10
0
        public void JointDataCreateRagdollTest()
        {
            var positionAinA          = new float3(0.0f, 1.0f, 2.0f);
            var positionBinB          = new float3(1.0f, 0.0f, 3.0f);
            var twistAxisInA          = new float3(1.0f, 0.0f, 0.0f);
            var twistAxisInB          = new float3(1.0f, 0.0f, 0.0f);
            var perpendicularInA      = new float3(0.0f, 1.0f, 0.0f);
            var perpendicularInB      = new float3(0.0f, 1.0f, 0.0f);
            var maxConeAngle          = 0.8f;
            var minPerpendicularAngle = 0.1f;
            var maxPerpendicularAngle = 1.1f;
            var minTwistAngle         = 0.2f;
            var maxTwistAngle         = 1.2f;

            BlobAssetReference <JointData> jointData0;
            BlobAssetReference <JointData> jointData1;

            JointData.CreateRagdoll(positionAinA, positionBinB, twistAxisInA, twistAxisInB, perpendicularInA, perpendicularInB,
                                    maxConeAngle, minPerpendicularAngle, maxPerpendicularAngle, minTwistAngle, maxTwistAngle,
                                    out jointData0, out jointData1);

            var joint0 = jointData0.Value;

            Assert.AreEqual(positionAinA, joint0.AFromJoint.Translation);
            Assert.AreEqual(positionBinB, joint0.BFromJoint.Translation);
            Assert.AreEqual(1, joint0.Version);
            Assert.AreEqual(2, joint0.NumConstraints);

            var twistConstraint = jointData0.Value.Constraints[0];

            Assert.AreEqual(new bool3(true, false, false), twistConstraint.ConstrainedAxes);
            Assert.AreEqual(ConstraintType.Angular, twistConstraint.Type);
            Assert.AreEqual(0.2f, twistConstraint.Min);
            Assert.AreEqual(1.2f, twistConstraint.Max);
            Assert.AreEqual(Constraint.DefaultSpringFrequency, twistConstraint.SpringFrequency);
            Assert.AreEqual(Constraint.DefaultSpringDamping, twistConstraint.SpringDamping);

            var coneConstraint0 = jointData0.Value.Constraints[1];

            Assert.AreEqual(new bool3(false, true, true), coneConstraint0.ConstrainedAxes);
            Assert.AreEqual(ConstraintType.Angular, coneConstraint0.Type);
            Assert.AreEqual(0.0f, coneConstraint0.Min);
            Assert.AreEqual(0.8f, coneConstraint0.Max);
            Assert.AreEqual(Constraint.DefaultSpringFrequency, coneConstraint0.SpringFrequency);
            Assert.AreEqual(Constraint.DefaultSpringDamping, coneConstraint0.SpringDamping);

            var joint1 = jointData1.Value;

            Assert.AreEqual(positionAinA, joint1.AFromJoint.Translation);
            Assert.AreEqual(positionBinB, joint1.BFromJoint.Translation);
            Assert.AreEqual(1, joint1.Version);
            Assert.AreEqual(2, joint1.NumConstraints);

            var coneConstraint1 = jointData0.Value.Constraints[0];

            Assert.AreEqual(new bool3(true, false, false), coneConstraint1.ConstrainedAxes);
            Assert.AreEqual(ConstraintType.Angular, coneConstraint1.Type);
            Assert.AreEqual(0.2f, coneConstraint1.Min);
            Assert.AreEqual(1.2f, coneConstraint1.Max);
            Assert.AreEqual(Constraint.DefaultSpringFrequency, coneConstraint1.SpringFrequency);
            Assert.AreEqual(Constraint.DefaultSpringDamping, coneConstraint1.SpringDamping);

            var ballAndSocketConstraint = jointData0.Value.Constraints[1];

            Assert.AreEqual(new bool3(false, true, true), ballAndSocketConstraint.ConstrainedAxes);
            Assert.AreEqual(ConstraintType.Angular, ballAndSocketConstraint.Type);
            Assert.AreEqual(0.0f, ballAndSocketConstraint.Min);
            Assert.AreEqual(0.8f, ballAndSocketConstraint.Max);
            Assert.AreEqual(Constraint.DefaultSpringFrequency, ballAndSocketConstraint.SpringFrequency);
            Assert.AreEqual(Constraint.DefaultSpringDamping, ballAndSocketConstraint.SpringDamping);
        }