Example #1
0
        public bool StickyPreSolve(cpArbiter arb, object data)
        {
            // We want to fudge the collisions a bit to allow shapes to overlap more.
            // This simulates their squishy sticky surface, and more importantly
            // keeps them from separating and destroying the joint.

            // Track the deepest collision point and use that to determine if a rigid collision should occur.
            float deepest = cp.Infinity;

            // Grab the contact set and iterate over them.
            cpContactPointSet contacts = arb.GetContactPointSet();

            for (int i = 0; i < contacts.count; i++)
            {
                // Sink the contact points into the surface of each shape.
                contacts.points[i].pointA = cpVect.cpvsub(contacts.points[i].pointA, cpVect.cpvmult(contacts.normal, STICK_SENSOR_THICKNESS));
                contacts.points[i].pointB = cpVect.cpvadd(contacts.points[i].pointB, cpVect.cpvmult(contacts.normal, STICK_SENSOR_THICKNESS));
                deepest = cp.cpfmin(deepest, contacts.points[i].distance);                // + 2.0f*STICK_SENSOR_THICKNESS);
            }

            // Set the new contact point data.
            arb.SetContactPointSet(ref contacts);

            // If the shapes are overlapping enough, then create a
            // joint that sticks them together at the first contact point.
            if (arb.GetUserData() == null && deepest <= 0.0f)
            {
                cpBody bodyA, bodyB;
                arb.GetBodies(out bodyA, out bodyB);

                // Create a joint at the contact point to hold the body in place.
                cpVect anchorA = bodyA.WorldToLocal(contacts.points[0].pointA);
                cpVect anchorB = bodyB.WorldToLocal(contacts.points[0].pointB);

                cpConstraint joint = new cpPivotJoint(bodyA, bodyB, anchorA, anchorB);

                // Give it a finite force for the stickyness.
                joint.SetMaxForce(3e3f);


                // Schedule a post-step() callback to add the joint.
                space.AddPostStepCallback(
                    (s, o1, o2) => PostStepAddJoint(joint, null),
                    joint, null);

                // Store the joint on the arbiter so we can remove it later.
                arb.SetUserData(joint);
            }

            // Position correction and velocity are handled separately so changing
            // the overlap distance alone won't prevent the collision from occuring.
            // Explicitly the collision for this frame if the shapes don't overlap using the new distance.
            return(deepest <= 0.0f);

            // Lots more that you could improve upon here as well:
            // * Modify the joint over time to make it plastic.
            // * Modify the joint in the post-step to make it conditionally plastic (like clay).
            // * Track a joint for the deepest contact point instead of the first.
            // * Track a joint for each contact point. (more complicated since you only get one data pointer).
        }
Example #2
0
    private void Draw(cpPivotJoint constraint)
    {
        cpVect a = cpTransform.Point(constraint.a.transform, constraint.GetAnchorA());
        cpVect b = cpTransform.Point(constraint.b.transform, constraint.GetAnchorB());

        //DrawSegment(a, b, 1, cpColor.Grey);
        DrawDot(a, 3, CONSTRAINT_COLOR);
        DrawDot(b, 3, CONSTRAINT_COLOR);
    }
Example #3
0
        //static PhysicsJointPin* ruct(PhysicsBody* a, PhysicsBody* b,  cpVect anchr);
        #region PROTECTED FUNC


        protected bool Init(CCPhysicsBody a, CCPhysicsBody b, CCPoint anchr)
        {
            if (!base.Init(a, b))
            {
                return(false);
            }


            cpConstraint joint = new cpPivotJoint(GetBodyInfo(a).Body, GetBodyInfo(b).Body,
                                                  PhysicsHelper.CCPointToCpVect(anchr));

            if (joint == null)
            {
                return(false);
            }

            _info.Add(joint);

            return(true);
        }
Example #4
0
        protected bool Init(CCPhysicsBody a, CCPhysicsBody b, CCPoint anchr)
        {
            if (!base.Init(a, b))
            {
                return(false);
            }

            GetBodyNode(a).Position = anchr;
            GetBodyNode(b).Position = anchr;

            // add a pivot joint to fixed two body together
            //cpConstraint joint = cpPivotJoint.cpPivotJointNew(getBodyInfo(a).getBody(),
            //                                       getBodyInfo(b).getBody(),
            //                                      anchr);

            cpConstraint joint = new cpPivotJoint(GetBodyInfo(a).Body, GetBodyInfo(b).Body, PhysicsHelper.CCPointToCpVect(anchr));

            if (joint == null)
            {
                return(false);
            }

            _info.Add(joint);


            // add a gear joint to make two body have the same rotation.
            joint = new cpGearJoint(GetBodyInfo(a).Body, GetBodyInfo(b).Body, 0, 1);

            if (joint == null)
            {
                return(false);
            }

            _info.Add(joint);

            SetCollisionEnable(false);

            return(true);
        }