Пример #1
0
        /// A colliding pair of shapes.
        public cpArbiter(cpShape a, cpShape b)
        {
            this.handler = null;
            this.swapped = false;

            this.handlerA = null;
            this.handlerB = null;

            /// Calculated value to use for the elasticity coefficient.
            /// Override in a pre-solve collision handler for custom behavior.
            this.e = 0;
            /// Calculated value to use for the friction coefficient.
            /// Override in a pre-solve collision handler for custom behavior.
            this.u = 0;
            /// Calculated value to use for applying surface velocities.
            /// Override in a pre-solve collision handler for custom behavior.
            this.surface_vr = cpVect.Zero;

            this.a = a; this.body_a = a.body;
            this.b = b; this.body_b = b.body;

            this.thread_a = new cpArbiterThread(null, null);
            this.thread_b = new cpArbiterThread(null, null);

            this.contacts = new List <cpContact>();

            this.stamp = 0;

            this.state = cpArbiterState.FirstCollision;
        }
Пример #2
0
        // Equal function for arbiterSet.
        public static bool SetEql(cpShape[] shapes, cpArbiter arb)
        {
            cpShape a = shapes[0];
            cpShape b = shapes[1];

            return((a == arb.a && b == arb.b) || (b == arb.a && a == arb.b));
        }
Пример #3
0
 public SupportContext(cpShape shape1, cpShape shape2, Func <cpShape, cpVect, SupportPoint> func1, Func <cpShape, cpVect, SupportPoint> func2)
 {
     this.shape1 = shape1;
     this.shape2 = shape2;
     this.func1  = func1;
     this.func2  = func2;
 }
Пример #4
0
        /// Remove a collision shape from the simulation.
        public void RemoveShape(cpShape shape)
        {
            var body = shape.body;

            cp.AssertHard(ContainsShape(shape), "Cannot remove a shape that was not added to the space. (Removed twice maybe?)");
            cp.AssertSpaceUnlocked(this);

            bool isStatic = body.bodyType == cpBodyType.STATIC;

            if (isStatic)
            {
                body.ActivateStatic(shape);
            }
            else
            {
                body.Activate();
            }

            body.RemoveShape(shape);
            this.FilterArbiters(body, shape);

            (isStatic ? this.staticShapes : this.dynamicShapes).Remove(shape.hashid);

            shape.space  = null;
            shape.hashid = 0;
        }
Пример #5
0
        public static void CircleSegmentQuery(cpShape shape, cpVect center, float r1, cpVect a, cpVect b, float r2, ref cpSegmentQueryInfo info)
        {
            // offset the line to be relative to the circle
            cpVect da   = cpVect.cpvsub(a, center);
            cpVect db   = cpVect.cpvsub(b, center);
            float  rsum = r1 + r2;


            float qa  = cpVect.cpvdot(da, da) - 2 * cpVect.cpvdot(da, db) + cpVect.cpvdot(db, db);
            float qb  = cpVect.cpvdot(da, db) - cpVect.cpvdot(da, da);
            float det = qb * qb - qa * (cpVect.cpvdot(da, da) - rsum * rsum);

            if (det >= 0.0f)
            {
                float t = (-qb - cp.cpfsqrt(det)) / (qa);
                if (0.0f <= t && t <= 1.0f)
                {
                    {
                        cpVect n = cpVect.cpvnormalize(cpVect.cpvlerp(da, db, t));

                        info.shape  = shape;
                        info.point  = cpVect.cpvsub(cpVect.cpvlerp(da, db, t), cpVect.cpvmult(n, r2));
                        info.normal = n;
                        info.alpha  = t;
                    }
                }
            }
        }
Пример #6
0
        /// Add a collision shape to the simulation.
        /// If the shape is attached to a static body, it will be added as a static shape.
        public cpShape AddShape(cpShape shape)
        {
            var body = shape.body;

            cp.AssertHard(shape.space != this, "You have already added this shape to this space. You must not add it a second time.");
            cp.AssertHard(shape.space == null, "You have already added this shape to another space. You cannot add it to a second.");
            cp.AssertSpaceUnlocked(this);

            bool isStatic = body.bodyType == cpBodyType.STATIC;

            if (!isStatic)
            {
                body.Activate();
            }

            body.AddShape(shape);

            shape.hashid = cp.shapeIDCounter++;

            shape.Update(body.transform);

            (isStatic ? this.staticShapes : this.dynamicShapes).Insert(shape.hashid, shape);
            shape.space = this;

            return(shape);
        }
Пример #7
0
        public void FilterArbiters(cpBody body, cpShape filter)
        {
            List <ulong> safeDelete = new List <ulong>();

            foreach (var hash in this.cachedArbiters)
            {
                cpArbiter arb = hash.Value;

                // Match on the filter shape, or if it's null the filter body
                if (
                    (body == arb.body_a && (filter == arb.a || filter == null)) ||
                    (body == arb.body_b && (filter == arb.b || filter == null))
                    )
                {
                    // Call separate when removing shapes.
                    if (filter != null && arb.state != cpArbiterState.Cached)
                    {
                        arb.state = cpArbiterState.Invalidated;
                        cpCollisionHandler handler = arb.handler;
                        handler.separateFunc(arb, this, handler.userData);
                    }

                    arb.Unthread();
                    this.arbiters.Remove(arb);
                    safeDelete.Add(hash.Key);
                }
            }

            foreach (var item in safeDelete)
            {
                cachedArbiters.Remove(item);
            }
        }
Пример #8
0
        /// Test if a point lies within a shape.
        public static cpContactPointSet Collide(cpShape a, cpShape b, ref List <cpContact> contacts)
        {
            //cpContact[] contacts = new cpContact[cpArbiter.CP_MAX_CONTACTS_PER_ARBITER];
            cpCollisionInfo info = cpCollision.cpCollide(a, b, 0, ref contacts);

            cpContactPointSet set = new cpContactPointSet();

            set.count = info.count;

            set.points = new PointsDistance[set.count];

            // cpCollideShapes() may have swapped the contact order. Flip the normal.
            bool swapped = (a != info.a);

            set.normal = (swapped ? cpVect.cpvneg(info.n) : info.n);

            for (int i = 0; i < info.count; i++)
            {
                cpVect p1 = contacts[i].r1;
                cpVect p2 = contacts[i].r2;

                set.points[i]          = new PointsDistance();
                set.points[i].pointA   = (swapped ? p2 : p1);
                set.points[i].pointB   = (swapped ? p1 : p2);
                set.points[i].distance = cpVect.cpvdot(cpVect.cpvsub(p2, p1), set.normal);
            }

            return(set);
        }
Пример #9
0
        public void RemoveShape(cpShape shape)
        {
            cpShape prev = shape.prev;
            cpShape next = shape.next;

            if (prev != null)
            {
                prev.next = next;
            }
            else
            {
                this.shapeList = next;
            }

            if (next != null)
            {
                next.prev = prev;
            }

            shape.prev = null;
            shape.next = null;

            if (bodyType == cpBodyType.DYNAMIC && shape.massInfo.m > 0.0f)
            {
                AccumulateMassFromShapes();
            }
        }
Пример #10
0
 public void eachShape(Action <cpShape, object> func, object data)
 {
     for (cpShape var = this.shapeList; var != null; var = var.next)
     {
         func(var, data);
     }
 }
Пример #11
0
 public static cpColor GetShapeColor(cpShape shape)
 {
     if (shape.sensor)
     {
         return(new cpColor(128, 128, 128));
     }
     else
     {
         if (shape.body.IsSleeping())
         {
             return(new cpColor(125, 125, 125));
         }
         else if (shape.body.nodeIdleTime > shape.space.sleepTimeThreshold)
         {
             return(new cpColor(170, 170, 170));
         }
         else if (shape.body.bodyType == cpBodyType.STATIC)
         {
             return(new cpColor(75, 75, 75));
         }
         else
         {
             return(styles[(int)shape.hashid % styles.Count]);
         }
     }
 }
Пример #12
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;
        }
Пример #13
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;
            }
        }
Пример #14
0
 public cpPointQueryExtendedInfo(cpShape tShape)
 {
     /// The nearest shape, NULL if no shape was within range.
     this.shape = tShape;
     /// The closest point on the shape's surface. (in world space coordinates)
     this.d = cp.Infinity;
     /// The distance to the point. The distance is negative if the point is inside the shape.
     this.n = cpVect.Zero;
 }
Пример #15
0
        public PhysicSprite(cpBody body, cpShape shape)
        {
            _body = body;
            _shape = shape;

            Active = true;

            _body.SetUserData(this);
        }
Пример #16
0
 public cpPointQueryExtendedInfo(cpShape tShape)
 {
     /// The nearest shape, NULL if no shape was within range.
     this.shape = tShape;
     /// The closest point on the shape's surface. (in world space coordinates)
     this.d = cp.Infinity;
     /// The distance to the point. The distance is negative if the point is inside the shape.
     this.n = cpVect.Zero;
 }
Пример #17
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);
            }
        }
Пример #18
0
 public void Set(cpPointQueryInfo newPointInfo)
 {
     /// The nearest shape, NULL if no shape was within range.
     shape = newPointInfo.shape;
     point = newPointInfo.point;
     distance = newPointInfo.distance;
     gradient = newPointInfo.gradient;
     // g = newPointInfo.g;
 }
Пример #19
0
        public cpCollisionInfo(cpShape a, cpShape b, ulong id, cpVect n, List <cpContact> contacts)
        {
            // TODO: Complete member initialization
            this.a  = a;
            this.b  = b;
            this.id = id;
            this.n  = n;

            this.arr = contacts;
        }
Пример #20
0
        public cpSegmentQueryInfo(cpShape shape, cpVect point, cpVect normal, float alpha)
        {
            /// The shape that was hit, NULL if no collision occured.
            this.shape = shape;
            /// The normalized distance along the query segment in the range [0, 1].
            this.alpha = alpha;
            /// The normal of the surface hit.
            this.normal = normal;

            this.point = point;
        }
Пример #21
0
        public cpPointQueryInfo(cpShape shape, cpVect point, float distance, cpVect gradient)
        {
            /// The nearest shape, NULL if no shape was within range.
            this.shape = shape;
            /// The closest point on the shape's surface. (in world space coordinates)
            this.point = point;
            /// The distance to the point. The distance is negative if the point is inside the shape.
            this.distance = distance;

            this.gradient = gradient;
        }
Пример #22
0
        public cpPointQueryInfo(cpShape shape, cpVect point, float distance, cpVect gradient)
        {
            /// The nearest shape, NULL if no shape was within range.
            this.shape = shape;
            /// The closest point on the shape's surface. (in world space coordinates)
            this.point = point;
            /// The distance to the point. The distance is negative if the point is inside the shape.
            this.distance = distance;

            this.gradient = gradient;
        }
Пример #23
0
        public void Set(cpSegmentQueryInfo info1)
        {
            /// The shape that was hit, NULL if no collision occured.
            this.shape = info1.shape;
            /// The normalized distance along the query segment in the range [0, 1].
            this.alpha = info1.alpha;
            /// The normal of the surface hit.
            this.normal = info1.normal;

            this.point = info1.point;
        }
Пример #24
0
        public cpSegmentQueryInfo(cpShape shape, cpVect point, cpVect normal, float alpha)
        {
            /// The shape that was hit, NULL if no collision occured.
            this.shape = shape;
            /// The normalized distance along the query segment in the range [0, 1].
            this.alpha = alpha;
            /// The normal of the surface hit.
            this.normal = normal;

            this.point = point;
        }
Пример #25
0
 /// Return the colliding shapes involved for this arbiter.
 /// The order of their cpSpace.collision_type values will match
 /// the order set when the collision handler was registered.
 public void GetShapes(out cpShape a, out cpShape b)
 {
     if (swapped)
     {
         a = this.b; b = this.a;
     }
     else
     {
         a = this.a;
     } b = this.b;
 }
Пример #26
0
        /// Update the collision detection data for a specific shape in the space.
        public void ReindexShape(cpShape shape)
        {
            cp.AssertHard(!IsLocked, "You cannot manually reindex objects while the space is locked. Wait until the current query or step is complete.");

            //var body = shape.body;
            shape.CacheBB();
            //shape.Update(body.GetPosition(), body.GetRotation());

            // attempt to rehash the shape in both hashes
            this.dynamicShapes.ReindexObject(shape, shape.hashid);
            this.staticShapes.ReindexObject(shape, shape.hashid);
        }
Пример #27
0
        //MARK: BB Query Functions

        public ulong BBQueryFunc(BBQueryContext context, cpShape shape, ulong id, object data)
        {
            if (
                !cpShapeFilter.Reject(shape.filter, context.filter) &&
                context.bb.Intersects(shape.bb)
                )
            {
                context.func(shape, data);
            }

            return(id);
        }
Пример #28
0
 public static bool QueryReject(cpShape a, cpShape b)
 {
     return(
         // BBoxes must overlap
         !a.bb.Intersects(b.bb)
         // Don't collide shapes attached to the same body.
         || a.body == b.body
         // Don't collide shapes that are filtered.
         || a.filter.Reject(b.filter)
         // Don't collide bodies if they have a constraint with collideBodies == cpFalse.
         || QueryRejectConstraint(a.body, b.body)
         );
 }
Пример #29
0
        // Wake up any sleeping or idle bodies touching a static body.
        public void ActivateStatic(cpShape filter)
        {
            cp.AssertHard(bodyType == cpBodyType.STATIC, "Body.activateStatic() called on a non-static body.");

            eachArbiter((arb, o) =>
            {
                if (filter == null || filter == arb.a || filter == arb.b)
                {
                    (arb.body_a == this ? arb.body_b : arb.body_a).Activate();
                }
            }, null);
            // TODO should also activate joints!
        }
Пример #30
0
        //MARK: Segment Query Functions

        public float SegmentQueryFunc(SegmentQueryContext context, cpShape shape, object data)
        {
            cpSegmentQueryInfo info = null;

            if (
                !cpShapeFilter.Reject(shape.filter, context.filter) &&
                shape.SegmentQuery(context.start, context.end, context.radius, ref info)
                )
            {
                context.func(shape, info.point, info.normal, info.alpha, data);
            }

            return(1.0f);
        }
Пример #31
0
        public float SegmentQueryFirstFunc(SegmentQueryContext context, cpShape shape, cpSegmentQueryInfo output)
        {
            cpSegmentQueryInfo info = null;

            if (
                !cpShapeFilter.Reject(shape.filter, context.filter) && !shape.sensor &&
                shape.SegmentQuery(context.start, context.end, context.radius, ref info) &&
                info.alpha < output.alpha
                )
            {
                output = info;
            }

            return(output.alpha);
        }
Пример #32
0
        public ulong NearestPointQuery(PointQueryContext context, cpShape shape, ulong id, object data)
        {
            if (
                !cpShapeFilter.Reject(shape.filter, context.filter)
                )
            {
                cpPointQueryInfo info = null;
                shape.PointQuery(context.point, ref info);

                if (info.shape != null && info.distance < context.maxDistance)
                {
                    context.func(shape, info.point, info.distance, info.gradient, data);
                }
            }
            return(id);
        }
Пример #33
0
        //MARK: Collision Functions
        // Collide circle shapes.
        public static void CircleToCircle(cpShape cir1, cpShape cir2, ref cpCollisionInfo info)
        {
            cpCircleShape c1 = (cpCircleShape)cir1;
            cpCircleShape c2 = (cpCircleShape)cir2;

            float mindist = c1.r + c2.r;
            cpVect delta = cpVect.cpvsub(c2.tc, c1.tc);
            float distsq = cpVect.cpvlengthsq(delta);

            if (distsq < mindist * mindist)
            {
                float dist = cp.cpfsqrt(distsq);
                cpVect n = info.n = (dist > 0.0f ? cpVect.cpvmult(delta, 1.0f / dist) : cpVect.cpv(1.0f, 0.0f));
                InfoPushContact(ref info, cpVect.cpvadd(c1.tc, cpVect.cpvmult(n, c1.r)), cpVect.cpvadd(c2.tc, cpVect.cpvmult(n, -c2.r)), 0);
            }
        }
Пример #34
0
        public void AddShape(cpShape shape)
        {
            //this.shapeList.Add(shape);

            cpShape next = this.shapeList;

            if (next != null)
            {
                next.prev = shape;
            }

            shape.next     = next;
            this.shapeList = shape;

            if (shape.massInfo.m > 0.0f)
            {
                AccumulateMassFromShapes();
            }
        }
Пример #35
0
        /// <summary>
        /// CREATES A BODY WITH MASS AND INERTIA
        /// </summary>
        /// <param name="mass"></param>
        /// <param name="moment"></param>
        public cpBody(float mass, float moment)
        {
            transform = new cpTransform();

            this.cog   = cpVect.Zero;
            this.space = null;

            this.shapeList      = null;
            this.arbiterList    = null;          // These are both wacky linked lists.
            this.constraintList = null;

            velocity_func = UpdateVelocity;
            position_func = UpdatePosition;

            // This stuff is used to track information on the collision graph.
            this.nodeRoot     = null;
            this.nodeNext     = null;
            this.nodeIdleTime = 0;

            /// Position of the rigid body's center of gravity.
            this.p = cpVect.Zero;
            /// Velocity of the rigid body's center of gravity.
            this.v = cpVect.Zero;
            /// Force acting on the rigid body's center of gravity.
            this.f = cpVect.Zero;


            /// Angular velocity of the body around it's center of gravity in radians/second.
            this.w = 0;
            /// Torque applied to the body around it's center of gravity.
            this.t = 0;

            // This stuff is all private.
            this.v_bias = cpVect.Zero;             //x = this.v_biasy = 0;
            this.w_bias = 0;

            this.userData = null;

            this.SetMass(mass);
            this.SetMoment(moment);
            this.SetAngle(0.0f);
        }
Пример #36
0
        public ulong NearestPointQueryNearest(object ctx, cpShape shape, ulong id, ref object outp)
        {
            PointQueryContext context = (PointQueryContext)ctx;
            cpPointQueryInfo  output  = (cpPointQueryInfo)outp;

            if (
                !cpShapeFilter.Reject(shape.filter, context.filter) && !shape.sensor
                )
            {
                cpPointQueryInfo info = null;
                shape.PointQuery(context.point, ref info);

                if (info.distance < output.distance)
                {
                    outp = (object)info;
                }
            }

            return(id);
        }
Пример #37
0
		public static void GetShapesAtPointFunc(cpShape shape, float distance, CCPoint point, ref List<CCPhysicsShape> arr)
		{
			CCPhysicsShapeInfo it;

			cp.AssertWarn(!CCPhysicsShapeInfo.Map.TryGetValue(shape, out it));

			arr.Add(it.getShape());  // (it.second.getShape());

		}
Пример #38
0
		public static void QueryRectCallbackFunc(cpShape shape, CCRectQueryCallbackInfo info)
		{
			CCPhysicsShapeInfo it;

			cp.AssertWarn(!CCPhysicsShapeInfo.Map.TryGetValue(shape, out it));

			if (!continues)
			{
				return;
			}

			continues = info.func(info.world, it.getShape(), info.data);

		}
Пример #39
0
		public static void QueryPointFunc(cpShape shape, float distance, CCPoint point, ref CCPointQueryCallbackInfo info)
		{
			CCPhysicsShapeInfo it;

			cp.AssertWarn(!CCPhysicsShapeInfo.Map.TryGetValue(shape, out it));

			continues = info.func(info.world, it.getShape(), info.data);
		}
Пример #40
0
		public static void QueryPointFunc(cpShape shape, float distance, CCPoint point, ref CCPointQueryCallbackInfo info)
		{
			CCPhysicsShapeInfo it;

			cp.AssertWarn(!CCPhysicsShapeInfo.Map.TryGetValue(shape, out it));

			Continues = info.Function(info.World, it.Shape, info.Data);
		}
Пример #41
0
		public static void RayCastCallbackFunc(cpShape shape, float t, CCPoint n, ref CCRayCastCallbackInfo info)
		{
			if (!continues)
			{
				return;
			}

			CCPhysicsShapeInfo it;

			cp.AssertWarn(!CCPhysicsShapeInfo.Map.TryGetValue(shape, out it));

			CCPhysicsRayCastInfo callbackInfo = new CCPhysicsRayCastInfo(
		it.getShape(),
		info.p1,
		info.p2,
		new CCPoint(info.p1.X + (info.p2.X - info.p1.X) * t, info.p1.Y + (info.p2.Y - info.p1.Y) * t),
		 new CCPoint(n.Y, n.Y),
		t, null
	);

			continues = info.func(info.world, callbackInfo, info.data);
		}
Пример #42
0
 /// Return the colliding shapes involved for this arbiter.
 /// The order of their cpSpace.collision_type values will match
 /// the order set when the collision handler was registered.
 public void GetShapes(out cpShape a, out cpShape b)
 {
     if (swapped)
     {
         a = this.b; b = this.a;
     }
     else
         a = this.a; b = this.b;
 }
Пример #43
0
		public static void QueryRectCallbackFunc(cpShape shape, CCRectQueryCallbackInfo info)
		{
			CCPhysicsShapeInfo it;

			cp.AssertWarn(!CCPhysicsShapeInfo.Map.TryGetValue(shape, out it));

			if (!Continues)
			{
				return;
			}

			Continues = info.Function(info.World, it.Shape, info.Data);

		}
Пример #44
0
        public ulong NearestPointQuery(PointQueryContext context, cpShape shape, ulong id, object data)
        {
            if (
                !cpShapeFilter.Reject(shape.filter, context.filter)
            )
            {
                cpPointQueryInfo info = null;
                shape.PointQuery(context.point, ref info);

                if (info.shape != null && info.distance < context.maxDistance)
                    context.func(shape, info.point, info.distance, info.gradient, data);
            }
            return id;
        }
Пример #45
0
        //MARK: BB Query Functions
        public ulong BBQueryFunc(BBQueryContext context, cpShape shape, ulong id, object data)
        {
            if (
                !cpShapeFilter.Reject(shape.filter, context.filter) &&
                context.bb.Intersects(shape.bb)
            )
            {
                context.func(shape, data);
            }

            return id;
        }
Пример #46
0
        public float SegmentQueryFirstFunc(SegmentQueryContext context, cpShape shape, cpSegmentQueryInfo output)
        {
            cpSegmentQueryInfo info = null;

            if (
                !cpShapeFilter.Reject(shape.filter, context.filter) && !shape.sensor &&
                shape.SegmentQuery(context.start, context.end, context.radius, ref info) &&
                info.alpha < output.alpha
            )
            {
                output = info;
            }

            return output.alpha;
        }
Пример #47
0
        public ulong NearestPointQueryNearest(object ctx, cpShape shape, ulong id, ref object outp)
        {
            PointQueryContext context = (PointQueryContext)ctx;
            cpPointQueryInfo output = (cpPointQueryInfo)outp;

            if (
                !cpShapeFilter.Reject(shape.filter, context.filter) && !shape.sensor
            )
            {
                cpPointQueryInfo info = null;
                shape.PointQuery(context.point, ref info);

                if (info.distance < output.distance)
                    outp = (object)info;
            }

            return id;
        }
Пример #48
0
        public void Set(cpSegmentQueryInfo info1)
        {
            /// The shape that was hit, NULL if no collision occured.
            this.shape = info1.shape;
            /// The normalized distance along the query segment in the range [0, 1].
            this.alpha = info1.alpha;
            /// The normal of the surface hit.
            this.normal = info1.normal;

            this.point = info1.point;
        }
Пример #49
0
        public ulong ShapeQueryFunc(cpShape a, cpShape b, ulong id, ShapeQueryContext context)
        {
            if (cpShapeFilter.Reject(a.filter, b.filter) || a == b) return id;

            List<cpContact> contacts = new List<cpContact>();
            cpContactPointSet set = cpShape.Collide(a, b, ref contacts);

            if (set.count > 0)
            {
                if (context.func != null) context.func(b, set, context.data);
                context.anyCollision = !(a.sensor || b.sensor);
            }
            return id;
        }
Пример #50
0
 public static void UpdateFunc(cpShape shape, object unused)
 {
     shape.CacheBB();
 }
Пример #51
0
        public cpCollisionInfo(cpShape a, cpShape b, ulong id, cpVect n, List<cpContact> contacts)
        {
            // TODO: Complete member initialization
            this.a = a;
            this.b = b;
            this.id = id;
            this.n = n;

            this.arr = contacts;
        }
Пример #52
0
		public static void RayCastCallbackFunc(cpShape shape, float t, CCPoint n, ref CCRayCastCallbackInfo info)
		{
			if (!Continues)
			{
				return;
			}

			CCPhysicsShapeInfo it;

			cp.AssertWarn(!CCPhysicsShapeInfo.Map.TryGetValue(shape, out it));

			CCPhysicsRayCastInfo callbackInfo = new CCPhysicsRayCastInfo(
        		it.Shape,
        		info.Pont1,
        		info.Point2,
        		new CCPoint(info.Pont1.X + (info.Point2.X - info.Pont1.X) * t, info.Pont1.Y + (info.Point2.Y - info.Pont1.Y) * t),
        		 new CCPoint(n.Y, n.Y),
        		t, null
        	);

			Continues = info.Function(info.World, callbackInfo, info.Data);
		}
Пример #53
0
        /// Test if a point lies within a shape.
        public static cpContactPointSet Collide(cpShape a, cpShape b, ref List<cpContact> contacts)
        {
            //cpContact[] contacts = new cpContact[cpArbiter.CP_MAX_CONTACTS_PER_ARBITER];
            cpCollisionInfo info = cpCollision.cpCollide(a, b, 0, ref contacts);

            cpContactPointSet set = new cpContactPointSet();
            set.count = info.count;

            set.points = new PointsDistance[set.count];

            // cpCollideShapes() may have swapped the contact order. Flip the normal.
            bool swapped = (a != info.a);
            set.normal = (swapped ? cpVect.cpvneg(info.n) : info.n);

            for (int i = 0; i < info.count; i++)
            {
                cpVect p1 = contacts[i].r1;
                cpVect p2 = contacts[i].r2;

                set.points[i] = new PointsDistance();
                set.points[i].pointA = (swapped ? p2 : p1);
                set.points[i].pointB = (swapped ? p1 : p2);
                set.points[i].distance = cpVect.cpvdot(cpVect.cpvsub(p2, p1), set.normal);
            }

            return set;
        }
Пример #54
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;
        }
Пример #55
0
 public cpContactPointSet Collide(cpShape b, ref List<cpContact> contacts)
 {
     return Collide(this, b, ref contacts);
 }
Пример #56
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;
 }
Пример #57
0
        //MARK: Segment Query Functions
        public float SegmentQueryFunc(SegmentQueryContext context, cpShape shape, object data)
        {
            cpSegmentQueryInfo info = null;

            if (
                !cpShapeFilter.Reject(shape.filter, context.filter) &&
                shape.SegmentQuery(context.start, context.end, context.radius, ref info)
            )
            {
                context.func(shape, info.point, info.normal, info.alpha, data);
            }

            return 1.0f;
        }
Пример #58
0
 // Equal function for arbiterSet.
 public static bool SetEql(cpShape[] shapes, cpArbiter arb)
 {
     cpShape a = shapes[0];
     cpShape b = shapes[1];
     return ((a == arb.a && b == arb.b) || (b == arb.a && a == arb.b));
 }
Пример #59
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;
			}
		}
Пример #60
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;
        }