Beispiel #1
0
        //public override void Draw(cpDebugDraw m_debugDraw)
        //{
        //    if (m_debugDraw.Flags.HasFlag(cpDrawFlags.Shapes) || m_debugDraw.Flags.HasFlag(cpDrawFlags.All))
        //    {
        //        cpColor color = cp.GetShapeColor(this);
        //        int count = Count;
        //        m_debugDraw.DrawPolygon(GetVertices(), count, color);
        //    }
        //    if (m_debugDraw.Flags.HasFlag(cpDrawFlags.BB) || m_debugDraw.Flags.HasFlag(cpDrawFlags.All))
        //        bb.Draw(m_debugDraw);
        //}
        public static cpPolyShape BoxShape(cpBody body, float width, float height, float radius)
        {
            var hw = width / 2f;
            var hh = height / 2f;

            return BoxShape2(body, new cpBB(-hw, -hh, hw, hh), radius);
        }
Beispiel #2
0
 public cpPivotJoint(cpBody a, cpBody b, cpVect anchorA, cpVect anchorB)
     : base(a, b)
 {
     this.anchorA = anchorA;
     this.anchorB = anchorB;
     this.jAcc = cpVect.Zero;
 }
Beispiel #3
0
        public cpConstraint(cpBody a, cpBody b)
        {
            /// The first body connected to this constraint.
            this.a = a;
            /// The second body connected to this constraint.
            this.b = b;

            this.space = null;

            this.next_a = null;
            this.next_b = null;

            /// The maximum force that this constraint is allowed to use.
            this.maxForce = cp.Infinity;
            /// The rate at which joint error is corrected.
            /// Defaults to pow(1 - 0.1, 60) meaning that it will
            /// correct 10% of the error every 1/60th of a second.
            this.errorBias = cp.cpfpow(1f - 0.1f, 60f);
            /// The maximum rate at which joint error is corrected.
            this.maxBias = cp.Infinity;

            this.collideBodies = true;

            //Not clear
            preSolve = DefaultPreSolve;
            postSolve = DefaultPostSolve;
        }
Beispiel #4
0
        public static void FloodFillComponent(cpBody root, cpBody body)
        {
            // Kinematic bodies cannot be put to sleep and prevent bodies they are touching from sleeping.
            // Static bodies are effectively sleeping all the time.
            if (body.bodyType == cpBodyType.DYNAMIC)
            {
                cpBody other_root = cp.ComponentRoot(body);
                if (other_root == null)
                {
                    cp.componentAdd(root, body);
                    body.eachArbiter((arb, o) =>
                    {
                        FloodFillComponent(root, (body == arb.body_a ?
                            arb.body_b : arb.body_a));

                    }, null);

                    body.eachConstraint((constraint, o) =>
                    {

                        FloodFillComponent(root,
                            (body == constraint.a ? constraint.b : constraint.a));

                    }, null);

                }
                else
                {
                    cp.AssertSoft(other_root == root, "Internal Error: Inconsistency dectected in the contact graph.");
                }
            }
        }
Beispiel #5
0
        public cpSimpleMotor(cpBody a, cpBody b, float rate)
            : base(a, b)
        {
            this.rate = rate;

            this.jAcc = 0.0f;
        }
Beispiel #6
0
        public cpRotaryLimitJoint(cpBody a, cpBody b, float min, float max)
            : base(a, b)
        {
            this.min = min;
            this.max = max;

            this.jAcc = 0.0f;
        }
Beispiel #7
0
        public cpGearJoint(cpBody a, cpBody b, float phase, float ratio)
            : base(a, b)
        {
            this.phase = phase;
            this.ratio = ratio;
            this.ratio_inv = 1 / ratio;

            this.jAcc = 0.0f;
        }
Beispiel #8
0
        public PhysicSprite(cpBody body, cpShape shape)
        {
            _body = body;
            _shape = shape;

            Active = true;

            _body.SetUserData(this);
        }
Beispiel #9
0
        public cpRatchetJoint(cpBody a, cpBody b, float phase, float ratchet)
            : base(a, b)
        {
            this.angle = 0.0f;
            this.phase = phase;
            this.ratchet = ratchet;

            // STATIC_BODY_CHECK
            this.angle = (b != null ? b.a : 0.0f) - (a != null ? a.a : 0.0f);
        }
Beispiel #10
0
        public cpSlideJoint(cpBody a, cpBody b, cpVect anchorA, cpVect anchorB, float min, float max)
            : base(a, b)
        {
            this.anchorA = anchorA;
            this.anchorB = anchorB;
            this.min = min;
            this.max = max;

            this.jnAcc = 0.0f;
        }
Beispiel #11
0
        public void ActivateBody(cpBody body)
        {
            cp.AssertHard(body.bodyType == cpBodyType.DYNAMIC, "Internal error: Attempting to deactivate a non-dynamic body.");

            if (this.IsLocked)
            {
                // cpSpaceActivateBody() is called again once the space is unlocked
                if (!this.rousedBodies.Contains(body))
                    this.rousedBodies.Add(body);
            }
            else
            {

                cp.AssertSoft(body.nodeRoot == null &&
                    body.nodeNext == null, "Internal error: Activating body non-NULL node pointers.");

                this.dynamicBodies.Add(body);

                body.eachShape((s, o) =>
                {
                    this.staticShapes.Remove(s.hashid);
                    this.dynamicShapes.Insert(s.hashid, s);
                }, null);

                body.eachArbiter((arb, o) =>
                {
                    cpBody bodyA = arb.body_a;

                    // Arbiters are shared between two bodies that are always woken up together.
                    // You only want to restore the arbiter once, so bodyA is arbitrarily chosen to own the arbiter.
                    // The edge case is when static bodies are involved as the static bodies never actually sleep.
                    // If the static body is bodyB then all is good. If the static body is bodyA, that can easily be checked.
                    if (body == bodyA || bodyA.bodyType == cpBodyType.STATIC)
                    {
                        cpShape a = arb.a, b = arb.b;
                        this.cachedArbiters.Add(cp.CP_HASH_PAIR(a.hashid, b.hashid), arb);

                        // Update the arbiter's state
                        arb.stamp = this.stamp;
                        arb.handler = this.LookupHandler(a.type, b.type, defaultHandler);
                        this.arbiters.Add(arb);
                    }

                }, null);

                body.eachConstraint((constraint, o) =>
                {
                    var bodyA = constraint.a;
                    if (body == bodyA || bodyA.bodyType == cpBodyType.STATIC)
                        this.constraints.Add(constraint);

                }, null);

            }
        }
Beispiel #12
0
        public static bool ComponentActive(cpBody root, float threshold)
        {
            //CP_BODY_FOREACH_COMPONENT
            for (var body = root; body != null; body = body.nodeNext)
            {
                if (body.nodeIdleTime < threshold)
                    return true;
            }

            return false;
        }
Beispiel #13
0
		public CCPhysicsShapeInfo(CCPhysicsShape shape)
		{
			_shapes = new List<cpShape>();

			// TODO: Complete member initialization
			_shape = shape;
		
			_body = _sharedBody;

			_group = cp.NO_GROUP; //CP_NO_GROUP ?¿

		}
Beispiel #14
0
        public cpDampedRotarySpring(cpBody a, cpBody b, float restAngle, float stiffness, float damping)
            : base(a, b)
        {
            this.restAngle = restAngle;
            this.stiffness = stiffness;
            this.damping = damping;

            this.springTorqueFunc = defaultSpringTorque;

            this.target_wrn = 0.0f;
            this.w_coef = 0.0f;
            this.iSum = 0.0f;
        }
Beispiel #15
0
        public cpPolyShape ToShape(cpBody body, float radius, cpVect size, int shapeIdx = 0)
        {
            var source = Shapes[shapeIdx];
            var vertices = new cpVect[source.Length];

            for (int i = 0, count = source.Length; i < count; i++)
            {
                var sourceVect = source[i];
                var vect = cpVect.cpv(sourceVect.x * size.x, sourceVect.y * size.y);
                vertices[i] = vect;
            }

            return new cpPolyShape(body, vertices.Length, vertices, radius);
        }
Beispiel #16
0
        public cpPolyShape(cpBody body, int count, cpVect[] verts,
			cpTransform transform, float radius)
            : base(body, new cpShapeMassInfo())
        {
            cpVect[] hullVerts = new cpVect[count];

            // Transform the verts before building the hull in case of a negative scale.
            for (int i = 0; i < count; i++)
                hullVerts[i] = cpTransform.Point(transform, verts[i]);

            int hullCount = cp.ConvexHull(count, hullVerts, ref hullVerts, null, 0.0f);

            InitRaw(hullCount, hullVerts, radius);
        }
Beispiel #17
0
        public cpGrooveJoint(cpBody a, cpBody b, cpVect groove_a, cpVect groove_b, cpVect anchorB)
            : base(a, b)
        {
            this.grv_a = groove_a;
            this.grv_b = groove_b;
            this.grv_n = cpVect.cpvperp(cpVect.cpvnormalize(cpVect.cpvsub(groove_b, groove_a)));
            this.anchorB = anchorB;

            this.grv_tn = null;
            this.clamp = 0.0f;
            this.r1 = this.r2 = null;

            this.jAcc = cpVect.Zero;
            this.bias = null;
        }
		public CCPhysicsShapeInfo(CCPhysicsShape shape)
		{

			_map = new Dictionary<cpShape, CCPhysicsShapeInfo>();
			_shapes = new List<cpShape>();

			// TODO: Complete member initialization
			_shape = shape;

			if (_sharedBody == null)
				_sharedBody = cpBody.NewStatic(); // = cpBodyNewStatic(); ¿¿

			_body = _sharedBody;

			_group = cp.NO_GROUP; //CP_NO_GROUP ?¿
		}
Beispiel #19
0
        public cpDampedSpring(cpBody a, cpBody b, cpVect anchr1, cpVect anchr2, float restLength, float stiffness, float damping)
            : base(a, b)
        {
            this.anchorA = anchr1;
            this.anchorB = anchr2;

            this.restLength = restLength;

            this.stiffness = stiffness;
            this.damping   = damping;

            this.springForceFunc = defaultSpringForce;

            this.target_vrn = this.v_coef = 0;

            this.r1    = this.r2 = null;
            this.nMass = 0;
            this.n     = null;

            this.jAcc = 0f;
        }
Beispiel #20
0
        public override void ApplyImpulse(float dt)
        {
            cpBody a = this.a;
            cpBody b = this.b;
            cpVect n = this.n;

            // compute relative velocity
            float vrn = cp.normal_relative_velocity(a, b, this.r1, this.r2, n);

            float jnMax = this.maxForce * dt;

            // compute normal impulse
            float jn    = (this.bias - vrn) * this.nMass;
            float jnOld = this.jnAcc;

            this.jnAcc = cp.cpfclamp(jnOld + jn, -jnMax, jnMax);
            jn         = this.jnAcc - jnOld;

            // apply impulse
            cp.apply_impulses(a, b, this.r1, this.r2, cpVect.cpvmult(n, jn));
        }
Beispiel #21
0
        public override void PreStep(float dt)
        {
            cpBody a = this.a;
            cpBody b = this.b;

            this.r1 = cpTransform.Vect(a.transform, cpVect.cpvsub(this.anchorA, a.cog));
            this.r2 = cpTransform.Vect(b.transform, cpVect.cpvsub(this.anchorB, b.cog));

            cpVect delta = cpVect.cpvsub(cpVect.cpvadd(b.p, this.r2), cpVect.cpvadd(a.p, this.r1));
            float  dist  = cpVect.cpvlength(delta);

            this.n = cpVect.cpvmult(delta, 1.0f / (dist > 0 ? dist : cp.Infinity));

            // calculate mass normal
            this.nMass = 1.0f / cp.k_scalar(a, b, this.r1, this.r2, this.n);

            // calculate bias velocity
            float maxBias = this.maxBias;

            this.bias = cp.cpfclamp(-cp.bias_coef(this.errorBias, dt) * (dist - this.dist) / dt, -maxBias, maxBias);
        }
Beispiel #22
0
        public override void ApplyImpulse(float dt)
        {
            cpBody a = this.a;
            cpBody b = this.b;

            // compute relative rotational velocity
            float wr = b.w - a.w + this.rate;

            float jMax = this.maxForce * dt;

            // compute normal impulse
            float j    = -wr * this.iSum;
            float jOld = this.jAcc;

            this.jAcc = cp.cpfclamp(jOld + j, -jMax, jMax);
            j         = this.jAcc - jOld;

            // apply impulse
            a.w -= j * a.i_inv;
            b.w += j * b.i_inv;
        }
Beispiel #23
0
        public override void ApplyImpulse(float dt)
        {
            cpBody a = this.a;
            cpBody b = this.b;

            cpVect r1 = this.r1;
            cpVect r2 = this.r2;

            // compute relative velocity
            cpVect vr = cp.relative_velocity(a, b, r1, r2);

            // compute normal impulse
            cpVect j    = cpMat2x2.Transform(this.k, cpVect.cpvsub(this.bias, vr));
            cpVect jOld = this.jAcc;

            this.jAcc = cpVect.cpvclamp(cpVect.cpvadd(this.jAcc, j), this.maxForce * dt);
            j         = cpVect.cpvsub(this.jAcc, jOld);

            // apply impulse
            cp.apply_impulses(a, b, this.r1, this.r2, j);
        }
Beispiel #24
0
        public bool ShapeQuery(cpShape shape, Action <cpShape, cpContactPointSet, object> func, object data)
        {
            cpBody            body    = shape.body;
            cpBB              bb      = (body != null ? shape.Update(body.transform) : shape.bb);
            ShapeQueryContext context = new ShapeQueryContext(func, data, false);

            object ctx = (object)context;

            Lock();
            {
                this.staticShapes.Query(shape, bb,
                                        (o1, o2, s, o3) => ShapeQueryFunc(o1 as cpShape, o2 as cpShape, s, (ShapeQueryContext)o3)
                                        , ctx);

                this.dynamicShapes.Query(shape, bb,
                                         (o1, o2, s, o3) => ShapeQueryFunc(o1 as cpShape, o2 as cpShape, s, (ShapeQueryContext)o3)
                                         , ctx);
            } Unlock(true);

            return(((ShapeQueryContext)ctx).anyCollision);
        }
Beispiel #25
0
        public cpDampedSpring(cpBody a, cpBody b, cpVect anchr1, cpVect anchr2, float restLength, float stiffness, float damping)
            : base(a, b)
        {
            this.anchorA = anchr1;
            this.anchorB = anchr2;

            this.restLength = restLength;

            this.stiffness = stiffness;
            this.damping = damping;

            this.springForceFunc = defaultSpringForce;

            this.target_vrn = this.v_coef = 0;

            this.r1 = this.r2 = null;
            this.nMass = 0;
            this.n = null;

            this.jAcc = 0f;
        }
Beispiel #26
0
        public override void PreStep(float dt)
        {
            cpBody a = this.a;
            cpBody b = this.b;

            float moment = a.i_inv + b.i_inv;

            cp.AssertSoft(moment != 0.0f, "Unsolvable spring.");
            this.iSum = 1.0f / moment;

            this.w_coef     = 1.0f - cp.cpfexp(-this.damping * dt * moment);
            this.target_wrn = 0.0f;

            // apply spring torque
            float j_spring = this.springTorqueFunc(this, a.a - b.a) * dt;

            this.jAcc = j_spring;

            a.w -= j_spring * a.i_inv;
            b.w += j_spring * b.i_inv;
        }
Beispiel #27
0
        public override void ApplyImpulse(float dt)
        {
            cpBody a = this.a;
            cpBody b = this.b;

            cpVect n  = this.n;
            cpVect r1 = this.r1;
            cpVect r2 = this.r2;

            // compute relative velocity
            float vrn = cp.normal_relative_velocity(a, b, r1, r2, n);

            // compute velocity loss from drag
            float v_damp = (this.target_vrn - vrn) * this.v_coef;

            this.target_vrn = vrn + v_damp;

            float j_damp = v_damp * this.nMass;

            this.jAcc += j_damp;
            cp.apply_impulses(a, b, this.r1, this.r2, cpVect.cpvmult(this.n, j_damp));
        }
Beispiel #28
0
        // k1 and k2 are modified by the function to contain the outputs.

        public static cpMat2x2 k_tensor(cpBody a, cpBody b, cpVect r1, cpVect r2)
        {
            float m_sum = a.m_inv + b.m_inv;

            // start with Identity*m_sum
            float k11 = m_sum, k12 = 0.0f;
            float k21 = 0.0f, k22 = m_sum;

            // add the influence from r1
            float a_i_inv = a.i_inv;
            float r1xsq   = r1.x * r1.x * a_i_inv;
            float r1ysq   = r1.y * r1.y * a_i_inv;
            float r1nxy   = -r1.x * r1.y * a_i_inv;

            k11 += r1ysq; k12 += r1nxy;
            k21 += r1nxy; k22 += r1xsq;

            // add the influnce from r2
            float b_i_inv = b.i_inv;
            float r2xsq   = r2.x * r2.x * b_i_inv;
            float r2ysq   = r2.y * r2.y * b_i_inv;
            float r2nxy   = -r2.x * r2.y * b_i_inv;

            k11 += r2ysq; k12 += r2nxy;
            k21 += r2nxy; k22 += r2xsq;

            // invert
            float det = k11 * k22 - k12 * k21;

            cp.AssertSoft(det != 0.0f, "Unsolvable constraint.");

            float det_inv = 1.0f / det;

            return(new cpMat2x2(
                       k22 * det_inv, -k12 * det_inv,
                       -k21 * det_inv, k11 * det_inv
                       ));
        }
Beispiel #29
0
        /// Add a constraint to the simulation.
        public cpConstraint AddConstraint(cpConstraint constraint)
        {
            cp.AssertHard(constraint.space != this, "You have already added this constraint to this space. You must not add it a second time.");
            cp.AssertHard(constraint.space == null, "You have already added this constraint to another space. You cannot add it to a second.");

            cp.AssertSpaceUnlocked(this);

            cpBody a = constraint.a, b = constraint.b;

            cp.AssertHard(a != null && b != null, "Constraint is attached to a NULL body.");

            a.Activate();
            b.Activate();

            this.constraints.Add(constraint);

            // Push onto the heads of the bodies' constraint lists
            constraint.next_a = a.constraintList; a.constraintList = constraint;
            constraint.next_b = b.constraintList; b.constraintList = constraint;
            constraint.space  = this;

            return(constraint);
        }
Beispiel #30
0
        public override void PreStep(float dt)
        {
            cpBody a = this.a;
            cpBody b = this.b;

            float angle   = this.angle;
            float phase   = this.phase;
            float ratchet = this.ratchet;

            float delta = b.a - a.a;
            float diff  = angle - delta;
            float pdist = 0.0f;

            if (diff * ratchet > 0.0f)
            {
                pdist = diff;
            }
            else
            {
                this.angle = cp.cpffloor((delta - phase) / ratchet) * ratchet + phase;
            }

            // calculate moment of inertia coefficient.
            this.iSum = 1.0f / (a.i_inv + b.i_inv);

            // calculate bias velocity
            float maxBias = this.maxBias;

            this.bias = cp.cpfclamp(-cp.bias_coef(this.errorBias, dt) * pdist / dt, -maxBias, maxBias);

            // If the bias is 0, the joint is not at a limit. Reset the impulse.
            if (this.bias == 0)
            {
                this.jAcc = 0.0f;
            }
        }
Beispiel #31
0
        public override void PreStep(float dt)
        {
            cpBody a = this.a;
            cpBody b = this.b;

            this.r1 = cpTransform.Vect(a.transform, cpVect.cpvsub(this.anchorA, a.cog));
            this.r2 = cpTransform.Vect(b.transform, cpVect.cpvsub(this.anchorB, b.cog));

            cpVect delta = cpVect.cpvsub(cpVect.cpvadd(b.p, this.r2), cpVect.cpvadd(a.p, this.r1));
            float  dist  = cpVect.cpvlength(delta);
            float  pdist = 0.0f;

            if (dist > this.max)
            {
                pdist  = dist - this.max;
                this.n = cpVect.cpvnormalize(delta);
            }
            else if (dist < this.min)
            {
                pdist  = this.min - dist;
                this.n = cpVect.cpvneg(cpVect.cpvnormalize(delta));
            }
            else
            {
                this.n     = cpVect.Zero;
                this.jnAcc = 0.0f;
            }

            // calculate mass normal
            this.nMass = 1.0f / cp.k_scalar(a, b, this.r1, this.r2, this.n);

            // calculate bias velocity
            float maxBias = this.maxBias;

            this.bias = cp.cpfclamp(-cp.bias_coef(this.errorBias, dt) * pdist / dt, -maxBias, maxBias);
        }
Beispiel #32
0
 public cpArbiterThread ThreadForBody(cpBody body)
 {
     //TODO: THIS NEEDS RETURN THE ORIGINAL MEMORY REFERENCE IN ARBITER
     if (this.body_a == body)
         return thread_a;
     else
         return thread_b;
 }
Beispiel #33
0
        //public static void UnthreadHelper(cpArbiter arb, cpBody body)
        //{
        //    cpArbiterThread thread = arb.ThreadForBody(body);
        //    cpArbiter prev = thread.prev;
        //    cpArbiter next = thread.next;
        //    // thread_x_y is quite ugly, but it avoids making unnecessary js objects per arbiter.
        //    if (prev != null)
        //    {
        //        cpArbiterThread nextPrev = prev.ThreadForBody(body);
        //        nextPrev.next = next;
        //    }
        //    else if (body.arbiterList == arb)
        //    {
        //        // IFF prev is NULL and body->arbiterList == arb, is arb at the head of the list.
        //        // This function may be called for an arbiter that was never in a list.
        //        // In that case, we need to protect it from wiping out the body->arbiterList pointer.
        //        body.arbiterList = next;
        //    }
        //    if (next != null)
        //    {
        //        cpArbiterThread threadNext = next.ThreadForBody(body);
        //        threadNext.prev = prev;
        //    }
        //    thread.prev = null;
        //    thread.next = null;
        //}
        public static void UnthreadHelper(cpArbiter arb, cpBody body, cpArbiter prev, cpArbiter next)
        {
            // thread_x_y is quite ugly, but it avoids making unnecessary js objects per arbiter.
            if (prev != null)
            {
                // cpArbiterThreadForBody(prev, body)->next = next;
                if (prev.body_a == body)
                {
                    prev.thread_a.next = next;
                }
                else
                {
                    prev.thread_b.next = next;
                }
            }
            else
            {
                body.arbiterList = next;
            }

            if (next != null)
            {
                // cpArbiterThreadForBody(next, body)->prev = prev;
                if (next.body_a == body)
                {
                    next.thread_a.prev = prev;
                }
                else
                {
                    next.thread_b.prev = prev;
                }
            }
        }
Beispiel #34
0
 public virtual cpConstraint Next(cpBody body)
 {
     return(this.a == body ? this.next_a : this.next_b);
 }
Beispiel #35
0
        public void DrawShape(cpShape shape)
        {
            cpBody  body  = shape.body;
            cpColor color = cp.GetShapeColor(shape);;             // ColorForBody(body);


            switch (shape.shapeType)
            {
            case cpShapeType.Circle:
            {
                cpCircleShape circle = (cpCircleShape)shape;

                if (Flags.HasFlag(PhysicsDrawFlags.BB) || Flags.HasFlag(PhysicsDrawFlags.All))
                {
                    Draw(circle.bb);
                }

                if (Flags.HasFlag(PhysicsDrawFlags.Shapes) || Flags.HasFlag(PhysicsDrawFlags.All))
                {
                    Draw(circle, color);
                }
            }
            break;

            case cpShapeType.Segment:
            {
                cpSegmentShape seg = (cpSegmentShape)shape;

                if (Flags.HasFlag(PhysicsDrawFlags.BB) || Flags.HasFlag(PhysicsDrawFlags.All))
                {
                    Draw(seg.bb);
                }

                if (Flags.HasFlag(PhysicsDrawFlags.Shapes) || Flags.HasFlag(PhysicsDrawFlags.All))
                {
                    Draw(seg, color);
                }
            }
            break;

            case cpShapeType.Polygon:
            {
                cpPolyShape poly = (cpPolyShape)shape;


                if (Flags.HasFlag(PhysicsDrawFlags.BB) || Flags.HasFlag(PhysicsDrawFlags.All))
                {
                    Draw(poly.bb);
                }

                if (Flags.HasFlag(PhysicsDrawFlags.Shapes) || Flags.HasFlag(PhysicsDrawFlags.All))
                {
                    Draw(poly, color);
                }
            }
            break;

            default:
                cp.AssertHard(false, "Bad assertion in DrawShape()");
                break;
            }
        }
Beispiel #36
0
        public cpCircleShape(cpBody body, float radius, cpVect offset)
            : base(body, cpShapeMassInfo.cpCircleShapeMassInfo(0.0f, radius, offset))
        {
            this.c = offset;
            this.r = radius;

            this.shapeType = cpShapeType.Circle;
        }
Beispiel #37
0
        public cpShape(cpBody body, cpShapeMassInfo massInfo)
        {
            /// The rigid body this collision shape is attached to.
            this.body = body;

            this.massInfo = massInfo;

            /// The current bounding box of the shape.
            /// The current bounding box of the shape.
            ///
            //this.bb_l = this.bb_b = this.bb_r = this.bb_t = 0;
            this.bb = new cpBB(0, 0, 0, 0);

            //this.hashid = (cp.shapeIDCounter++).ToString();

            /// Sensor flag.
            /// Sensor shapes call collision callbacks but don't produce collisions.
            this.sensor = false;

            filter = new cpShapeFilter(cp.NO_GROUP, cp.ALL_CATEGORIES, cp.ALL_CATEGORIES);

            /// Coefficient of restitution. (elasticity)
            this.e = 0;
            /// Coefficient of friction.
            this.u = 0;
            /// Surface velocity used when solving for friction.
            this.surfaceV = cpVect.Zero;

            /// Collision type of this shape used when picking collision handlers.
            this.type = 0;

            this.space = null;
        }
Beispiel #38
0
        public cpArbiter Next(cpBody body)
        {
            var next = (this.body_a == body ? this.thread_a.next : this.thread_b.next);

            return(next == this ? null : next);
        }
Beispiel #39
0
 public static void apply_bias_impulse(cpBody body, cpVect j, cpVect r)
 {
     body.v_bias  = cpVect.cpvadd(body.v_bias, cpVect.cpvmult(j, body.m_inv));
     body.w_bias += body.i_inv * cpVect.cpvcross(r, j);
 }
Beispiel #40
0
 /// Test if a rigid body has been added to the space.
 public bool ContainsBody(cpBody body)
 {
     return(body.space == this);
 }
Beispiel #41
0
 public static float SetAngle(cpBody body, float angle)
 {
     body.a = angle;
     body.AssertSaneBody();
     return(angle);
 }
Beispiel #42
0
 public static cpBody ComponentRoot(cpBody body)
 {
     return(body != null ? body.nodeRoot : null);
 }
Beispiel #43
0
 public static void apply_bias_impulses(cpBody a, cpBody b, cpVect r1, cpVect r2, cpVect j)
 {
     apply_bias_impulse(a, cpVect.cpvneg(j), r1);
     apply_bias_impulse(b, j, r2);
 }
Beispiel #44
0
 public cpArbiter Next(cpBody body)
 {
     var next = (this.body_a == body ? this.thread_a.next : this.thread_b.next);
     return next == this ? null : next;
 }
Beispiel #45
0
 public cpComponentNode(cpBody root, cpBody next, float idleTime)
 {
     this.root     = root;
     this.next     = next;
     this.idleTime = idleTime;
 }
Beispiel #46
0
 public static float normal_relative_velocity(cpBody a, cpBody b, cpVect r1, cpVect r2, cpVect n)
 {
     return(cpVect.cpvdot(relative_velocity(a, b, r1, r2), n));
 }
Beispiel #47
0
        public void ProcessComponents(float dt)
        {
            var sleep  = (this.sleepTimeThreshold != cp.Infinity);
            var bodies = this.dynamicBodies;

            // These checks can be removed at some stage (if DEBUG == undefined)
            for (var i = 0; i < bodies.Count; i++)
            {
                var body = bodies[i];

                cp.AssertSoft(body.nodeNext == null, "Internal Error: Dangling next pointer detected in contact graph.");
                cp.AssertSoft(body.nodeRoot == null, "Internal Error: Dangling root pointer detected in contact graph.");
            }

            // Calculate the kinetic energy of all the bodies
            if (sleep)
            {
                var dv   = this.idleSpeedThreshold;
                var dvsq = (dv != 0 ? dv * dv : cpVect.cpvlengthsq(this.gravity) * dt * dt);

                for (var i = 0; i < bodies.Count; i++)
                {
                    // TODO should make a separate array for kinematic bodies.
                    if (bodies[i].bodyType != cpBodyType.DYNAMIC)
                    {
                        continue;
                    }

                    // Need to deal with infinite mass objects
                    var keThreshold = (dvsq > 0 ? bodies[i].m * dvsq : 0.0f);
                    bodies[i].nodeIdleTime = (bodies[i].KineticEnergy() > keThreshold ? 0 : bodies[i].nodeIdleTime + dt);
                }
            }

            // Awaken any sleeping bodies found and then push arbiters to the bodies' lists.

            List <cpArbiter> arbiters = this.arbiters; // new List<cpArbiter>();
            var count = arbiters.Count;                //FIX: we cannot read the count values of the array because it changes inside

            for (int i = 0; i < count; i++)
            {
                cpArbiter arb = arbiters[i];
                cpBody    a = arb.body_a, b = arb.body_b;

                if (sleep)
                {
                    if (b.bodyType == cpBodyType.KINEMATIC || a.IsSleeping())
                    {
                        a.Activate();
                    }

                    if (a.bodyType == cpBodyType.KINEMATIC || b.IsSleeping())
                    {
                        b.Activate();
                    }
                }

                a.PushArbiter(arb);
                b.PushArbiter(arb);
            }

            if (sleep)
            {
                // Bodies should be held active if connected by a joint to a non-static rouge body.
                var constraints = this.constraints;
                for (var i = 0; i < constraints.Count; i++)
                {
                    cpConstraint constraint = constraints[i];
                    cpBody       a = constraint.a, b = constraint.b;

                    if (b.bodyType == cpBodyType.KINEMATIC)
                    {
                        a.Activate();
                    }

                    if (a.bodyType == cpBodyType.KINEMATIC)
                    {
                        b.Activate();
                    }
                }

                // Generate components and deactivate sleeping ones
                for (var i = 0; i < bodies.Count;)
                {
                    var body = bodies[i];

                    if (cp.ComponentRoot(body) == null)
                    {
                        // Body not in a component yet. Perform a DFS to flood fill mark
                        // the component in the contact graph using this body as the root.
                        FloodFillComponent(body, body);

                        // Check if the component should be put to sleep.
                        if (!ComponentActive(body, this.sleepTimeThreshold))
                        {
                            this.sleepingComponents.Add(body);
                            //CP_BODY_FOREACH_COMPONENT
                            for (var other = body; other != null; other = other.nodeNext)
                            {
                                this.DeactivateBody(other);
                            }

                            // deactivateBody() removed the current body from the list.
                            // Skip incrementing the index counter.
                            continue;
                        }
                    }

                    i++;

                    // Only sleeping bodies retain their component node pointers.
                    body.nodeRoot = null;
                    body.nodeNext = null;
                }
            }
        }
Beispiel #48
0
        /// Allocate and initialize a cpBody.
        public static cpBody New(float mass, float moment)
        {
            cpBody tmp = new cpBody(mass, moment);

            return(tmp);
        }
Beispiel #49
0
 public cpPolyShape(cpBody body, int count, cpVect[] verts, float radius)
     : base(body, new cpShapeMassInfo())
 {
     InitRaw(count, verts, radius);
 }
Beispiel #50
0
 public void GetBodies(out cpBody a, out cpBody b)
 {
     cpShape shape_a, shape_b;
     GetShapes(out shape_a, out shape_b);
     a = shape_a.body;
     b = shape_b.body;
 }
Beispiel #51
0
        public static cpPolyShape BoxShape2(cpBody body, cpBB box, float radius)
        {
            cpVect[] verts = new cpVect[] {
            new cpVect(box.r, box.b),
            new cpVect(box.r, box.t),
            new cpVect(box.l, box.t),
            new cpVect(box.l, box.b),
            };

            return new cpPolyShape(body, 4, verts, radius);
        }
Beispiel #52
0
        public void Update(cpCollisionInfo info, cpSpace space)
        {
            cpShape a = info.a, b = info.b;

            // For collisions between two similar primitive types, the order could have been swapped since the last frame.
            this.a = a; this.body_a = a.body;
            this.b = b; this.body_b = b.body;

            // Iterate over the possible pairs to look for hash value matches.
            for (int i = 0; i < info.count; i++)
            {
                cpContact con = info.arr[i];

                // r1 and r2 store absolute offsets at init time.
                // Need to convert them to relative offsets.
                con.r1 = cpVect.cpvsub(con.r1, a.body.p);
                con.r2 = cpVect.cpvsub(con.r2, b.body.p);

                // Cached impulses are not zeroed at init time.
                con.jnAcc = con.jtAcc = 0.0f;

                for (int j = 0; j < this.Count; j++)
                {
                    cpContact old = this.contacts[j];

                    // This could trigger false positives, but is fairly unlikely nor serious if it does.
                    if (con.hash == old.hash)
                    {
                        // Copy the persistant contact information.
                        con.jnAcc = old.jnAcc;
                        con.jtAcc = old.jtAcc;
                    }
                }
            }
            //TODO: revise
            this.contacts = info.arr.ToList();
            //this.count = info.count;
            this.n = info.n;

            this.e = a.e * b.e;
            this.u = a.u * b.u;

            cpVect surface_vr = cpVect.cpvsub(b.surfaceV, a.surfaceV);

            this.surface_vr = cpVect.cpvsub(surface_vr, cpVect.cpvmult(info.n, cpVect.cpvdot(surface_vr, info.n)));

            ulong typeA = info.a.type, typeB = info.b.type;
            cpCollisionHandler defaultHandler = space.defaultHandler;
            cpCollisionHandler handler        = this.handler = space.LookupHandler(typeA, typeB, defaultHandler);

            // Check if the types match, but don't swap for a default handler which use the wildcard for type A.
            bool swapped = this.swapped = (typeA != handler.typeA && handler.typeA != cp.WILDCARD_COLLISION_TYPE);

            if (handler != defaultHandler || space.usesWildcards)
            {
                // The order of the main handler swaps the wildcard handlers too. Uffda.
                this.handlerA = space.LookupHandler(swapped ? typeB : typeA, cp.WILDCARD_COLLISION_TYPE, cpCollisionHandler.cpCollisionHandlerDoNothing);
                this.handlerB = space.LookupHandler(swapped ? typeA : typeB, cp.WILDCARD_COLLISION_TYPE, cpCollisionHandler.cpCollisionHandlerDoNothing);
            }

            // mark it as new if it's been cached
            if (this.state == cpArbiterState.Cached)
            {
                this.state = cpArbiterState.FirstCollision;
            }
        }
Beispiel #53
0
        public cpSegmentShape(cpBody body, cpVect a, cpVect b, float r)
            : base(body, cpShapeMassInfo.cpSegmentShapeMassInfo(0.0f, a, b, r))
        {
            this.a = a;
            this.b = b;

            this.n = cpVect.cpvrperp(cpVect.vnormalize(cpVect.cpvsub(b, a)));

            this.r = r;

            this.a_tangent = cpVect.Zero;
            this.b_tangent = cpVect.Zero;

            this.shapeType = cpShapeType.Segment;
        }
Beispiel #54
0
 public static cpArbiterThread ThreadForBody(cpArbiter arb, cpBody body)
 {
     return(arb.body_a == body ? arb.thread_a : arb.thread_b);
 }
Beispiel #55
0
 public void SetBody(cpBody body)
 {
     cp.AssertHard(!Active(), "You cannot change the body on an active shape. You must remove the shape from the space before changing the body.");
     this.body = body;
 }
Beispiel #56
0
 public cpArbiter Next(cpBody body)
 {
     return(this.body_a == body ? this.thread_a.next : this.thread_b.next);
 }
Beispiel #57
0
 public cpPivotJoint(cpBody a, cpBody b, cpVect pivot)
     : this(a, b,
            (a != null ? a.WorldToLocal(pivot) : pivot),
            (b != null ? b.WorldToLocal(pivot) : pivot))
 {
 }
Beispiel #58
0
 public cpPolyShape(cpBody body, int count, cpVect[] verts, float radius)
     : base(body, new cpShapeMassInfo())
 {
     InitRaw(count, verts, radius);
 }
Beispiel #59
0
        public static float k_scalar_body(cpBody body, cpVect r, cpVect n)
        {
            var rcn = cpVect.cpvcross(r, n);

            return(body.m_inv + body.i_inv * rcn * rcn);
        }
Beispiel #60
0
        public void Update(cpCollisionInfo info, cpSpace space)
        {
            cpShape a = info.a, b = info.b;

            // For collisions between two similar primitive types, the order could have been swapped since the last frame.
            this.a = a; this.body_a = a.body;
            this.b = b; this.body_b = b.body;

            // Iterate over the possible pairs to look for hash value matches.
            for (int i = 0; i < info.count; i++)
            {
                cpContact con = info.arr[i];

                // r1 and r2 store absolute offsets at init time.
                // Need to convert them to relative offsets.
                con.r1 = cpVect.cpvsub(con.r1, a.body.p);
                con.r2 = cpVect.cpvsub(con.r2, b.body.p);

                // Cached impulses are not zeroed at init time.
                con.jnAcc = con.jtAcc = 0.0f;

                for (int j = 0; j < this.Count; j++)
                {
                    cpContact old = this.contacts[j];

                    // This could trigger false positives, but is fairly unlikely nor serious if it does.
                    if (con.hash == old.hash)
                    {
                        // Copy the persistant contact information.
                        con.jnAcc = old.jnAcc;
                        con.jtAcc = old.jtAcc;
                    }
                }
            }
            //TODO: revise
            this.contacts = info.arr.ToList();
            //this.count = info.count;
            this.n = info.n;

            this.e = a.e * b.e;
            this.u = a.u * b.u;

            cpVect surface_vr = cpVect.cpvsub(b.surfaceV, a.surfaceV);
            this.surface_vr = cpVect.cpvsub(surface_vr, cpVect.cpvmult(info.n, cpVect.cpvdot(surface_vr, info.n)));

            ulong typeA = info.a.type, typeB = info.b.type;
            cpCollisionHandler defaultHandler = space.defaultHandler;
            cpCollisionHandler handler = this.handler = space.LookupHandler(typeA, typeB, defaultHandler);

            // Check if the types match, but don't swap for a default handler which use the wildcard for type A.
            bool swapped = this.swapped = (typeA != handler.typeA && handler.typeA != cp.WILDCARD_COLLISION_TYPE);

            if (handler != defaultHandler || space.usesWildcards)
            {
                // The order of the main handler swaps the wildcard handlers too. Uffda.
                this.handlerA = space.LookupHandler(swapped ? typeB : typeA, cp.WILDCARD_COLLISION_TYPE, cpCollisionHandler.cpCollisionHandlerDoNothing);
                this.handlerB = space.LookupHandler(swapped ? typeA : typeB, cp.WILDCARD_COLLISION_TYPE, cpCollisionHandler.cpCollisionHandlerDoNothing);
            }

            // mark it as new if it's been cached
            if (this.state == cpArbiterState.Cached)
                this.state = cpArbiterState.FirstCollision;
        }