Пример #1
0
        public void ShatterCell(cpPolyShape shape, cpVect cell, int cell_i, int cell_j, ref WorleyContex context)
        {
            //	printf("cell %dx%d: (% 5.2f, % 5.2f)\n", cell_i, cell_j, cell.x, cell.y);

            cpBody body = shape.body;                             // cpShapeGetBody(shape);

            cpVect[] ping = new cpVect[MAX_VERTEXES_PER_VORONOI]; // cpVect[ (cpVect*)alloca( * sizeof(cpVect));
            cpVect[] pong = new cpVect[MAX_VERTEXES_PER_VORONOI]; //(cpVect*)alloca(MAX_VERTEXES_PER_VORONOI * sizeof(cpVect));

            int count = shape.Count;                              // cpPolyShapeGetCount();

            count = (count > MAX_VERTEXES_PER_VORONOI ? MAX_VERTEXES_PER_VORONOI : count);

            for (int i = 0; i < count; i++)
            {
                ping[i] = body.LocalToWorld(shape.GetVert(i));
            }

            cpPointQueryInfo info = null;

            for (int i = 0; i < context.width; i++)
            {
                for (int j = 0; j < context.height; j++)
                {
                    if (
                        !(i == cell_i && j == cell_j) &&
                        shape.PointQuery(cell, ref info) < 0
                        )
                    {
                        count = ClipCell(shape, cell, i, j, context, ping, pong, count);

                        for (int u = 0; u < pong.Length; u++)
                        {
                            if (pong[u] != null)
                            {
                                ping[u] = new cpVect(pong[u]);
                            }
                        }
                    }
                }
            }

            cpVect centroid = cp.CentroidForPoly(count, ping);
            float  mass     = cp.AreaForPoly(count, ping, 0) * DENSITY;
            float  moment   = cp.MomentForPoly(mass, count, ping, cpVect.cpvneg(centroid), 0);

            cpBody new_body = space.AddBody(new cpBody(mass, moment));

            new_body.SetPosition(centroid);

            new_body.SetPosition(centroid);
            new_body.SetVelocity(body.GetVelocityAtLocalPoint(centroid));
            new_body.SetAngularVelocity(body.GetAngularVelocity());

            cpTransform transform = cpTransform.Translate(cpVect.cpvneg(centroid));
            cpShape     new_shape = space.AddShape(new cpPolyShape(new_body, count, ping, transform, 0));

            // Copy whatever properties you have set on the original shape that are important
            new_shape.SetFriction(shape.GetFriction());
        }
Пример #2
0
        static public cpSpace BouncyTerrainCircles_500(cpSpace space)
        {
            //cpSpace space = BENCH_SPACE_NEW();
            SetSubTitle("BouncyTerrainCircles 500");
            space.SetIterations(10);

            cpVect offset = new cpVect(-320, -240);

            for (int i = 0; i < (bouncy_terrain_verts.Length - 1); i++)
            {
                cpVect  a = bouncy_terrain_verts[i], b = bouncy_terrain_verts[i + 1];
                cpShape shape = space.AddShape(new cpSegmentShape(space.GetStaticBody(), cpVect.cpvadd(a, offset), cpVect.cpvadd(b, offset), 0.0f));
                shape.SetElasticity(1.0f);
            }

            for (int i = 0; i < 500; i++)
            {
                float  radius = 5.0f;
                float  mass   = radius * radius;
                cpBody body   = space.AddBody(new cpBody(mass, cp.MomentForCircle(mass, 0.0f, radius, cpVect.Zero)));
                body.SetPosition(cpVect.cpvadd(cpVect.cpvmult(cp.frand_unit_circle(), 130.0f), cpVect.Zero));
                body.SetVelocity(cpVect.cpvmult(cp.frand_unit_circle(), 50.0f));

                cpShape shape = space.AddShape(new cpCircleShape(body, radius, cpVect.Zero));
                shape.SetElasticity(1.0f);
            }

            return(space);
        }
Пример #3
0
        public void ClipPoly(cpSpace space, cpShape shp, cpVect n, float dist)
        {
            cpPolyShape shape = (cpPolyShape)shp;

            cpBody body = shape.GetBody();


            int count        = shape.Count;
            int clippedCount = 0;

            cpVect[] clipped = new cpVect[count + 1];

            for (int i = 0, j = count - 1; i < count; j = i, i++)
            {
                cpVect a      = body.LocalToWorld(shape.GetVert(j));
                float  a_dist = cpVect.cpvdot(a, n) - dist;

                if (a_dist < 0)
                {
                    clipped[clippedCount] = a;
                    clippedCount++;
                }

                cpVect b      = body.LocalToWorld(shape.GetVert(i));
                float  b_dist = cpVect.cpvdot(b, n) - dist;

                if (a_dist * b_dist < 0)
                {
                    float t = cp.cpfabs(a_dist) / (cp.cpfabs(a_dist) + cp.cpfabs(b_dist));

                    clipped[clippedCount] = cpVect.cpvlerp(a, b, t);
                    clippedCount++;
                }
            }

            cpVect centroid = cp.CentroidForPoly(clippedCount, clipped);
            float  mass     = cp.AreaForPoly(clippedCount, clipped, 0) * DENSITY;
            float  moment   = cp.MomentForPoly(mass, clippedCount, clipped, cpVect.cpvneg(centroid), 0);

            cpBody new_body = space.AddBody(new cpBody(mass, moment));

            new_body.SetPosition(centroid);
            new_body.SetVelocity(body.GetVelocityAtWorldPoint(centroid));
            new_body.SetAngularVelocity(body.GetAngularVelocity());

            cpTransform transform = cpTransform.Translate(cpVect.cpvneg(centroid));
            cpShape     new_shape = space.AddShape(new cpPolyShape(new_body, clippedCount, clipped, transform, 0));

            // Copy whatever properties you have set on the original shape that are important
            new_shape.SetFriction(shape.GetFriction());
        }
Пример #4
0
        static cpSpace NoCollide(cpSpace space)
        {
            space.SetIterations(10);

            var handler = space.AddCollisionHandler(2, 2);

            //, (a, s, o) => NoCollide_begin(a, s, o), null, null, null);
            handler.beginFunc = NoCollide_begin;
            float radius     = 4.5f;
            var   staticBody = space.GetStaticBody();

            space.AddShape(new cpSegmentShape(staticBody, new cpVect(-330 - radius, -250 - radius), new cpVect(330 + radius, -250 - radius), 0.0f)).SetElasticity(1.0f);
            space.AddShape(new cpSegmentShape(staticBody, new cpVect(330 + radius, 250 + radius), new cpVect(330 + radius, -250 - radius), 0.0f)).SetElasticity(1.0f);
            space.AddShape(new cpSegmentShape(staticBody, new cpVect(330 + radius, 250 + radius), new cpVect(-330 - radius, 250 + radius), 0.0f)).SetElasticity(1.0f);
            space.AddShape(new cpSegmentShape(staticBody, new cpVect(-330 - radius, -250 - radius), new cpVect(-330 - radius, 250 + radius), 0.0f)).SetElasticity(1.0f);

            for (int x = -320; x <= 320; x += 20)
            {
                for (int y = -240; y <= 240; y += 20)
                {
                    space.AddShape(new cpCircleShape(staticBody, radius, new cpVect(x, y)));
                }
            }

            for (int y = 10 - 240; y <= 240; y += 40)
            {
                float  mass = 7.0f;
                cpBody body = space.AddBody(new cpBody(mass, cp.MomentForCircle(mass, 0.0f, radius, cpVect.Zero)));
                body.SetPosition(new cpVect(-320.0f, y));
                body.SetVelocity(new cpVect(100.0f, 0.0f));

                cpShape shape = space.AddShape(new cpCircleShape(body, radius, cpVect.Zero));
                shape.SetElasticity(1.0f);
                shape.SetCollisionType(2);
            }

            for (int x = 30 - 320; x <= 320; x += 40)
            {
                float  mass = 7.0f;
                cpBody body = space.AddBody(new cpBody(mass, cp.MomentForCircle(mass, 0.0f, radius, cpVect.Zero)));

                body.SetPosition(new cpVect(x, -240.0f));
                body.SetVelocity(new cpVect(0.0f, 100.0f));

                cpShape shape = space.AddShape(new cpCircleShape(body, radius, cpVect.Zero));
                shape.SetElasticity(1.0f);
                shape.SetCollisionType(2);
            }
            return(space);
        }
Пример #5
0
        void add_box()
        {
            const float size = 10;
            const float mass = 1;

            cpVect[] verts = new cpVect[] {
                new cpVect(-size, -size),
                new cpVect(-size, size),
                new cpVect(size, size),
                new cpVect(size, -size)
            };


            float  radius = cpVect.cpvlength(new cpVect(size, size));
            cpVect pos    = rand_pos(radius);

            cpBody body = space.AddBody(new cpBody(mass, cp.MomentForPoly(mass, 4, verts, cpVect.Zero, 0.0f)));

            body.SetVelocityUpdateFunc(
                (s, f1, f2) => planetGravityVelocityFunc(body, s, f1, f2)
                );

            body.SetPosition(pos);

            // Set the box's velocity to put it into a circular orbit from its
            // starting position.
            float r = cpVect.cpvlength(pos);
            float v = cp.cpfsqrt(gravityStrength / r) / r;

            body.SetVelocity(cpVect.cpvmult(cpVect.cpvperp(pos), v));

            // Set the box's angular velocity to match its orbital period and
            // align its initial angle with its position.
            body.SetAngularVelocity(v);
            body.SetAngle(cp.cpfatan2(pos.y, pos.x));

            cpShape shape = space.AddShape(new cpPolyShape(body, 4, verts, cpTransform.Identity, 0.0f));             //cpTransformIdentity

            shape.SetElasticity(0);
            shape.SetFriction(0.7f);
        }
Пример #6
0
        static public cpSpace BouncyTerrainHexagons_500(cpSpace space)
        {
            SetSubTitle("BouncyTerrainHexagons 500");
            //cpSpace space = BENCH_SPACE_NEW();
            space.SetIterations(10);

            cpVect offset = new cpVect(-320, -240);

            for (int i = 0; i < (bouncy_terrain_verts.Length - 1); i++)
            {
                cpVect  a = bouncy_terrain_verts[i], b = bouncy_terrain_verts[i + 1];
                cpShape shape = space.AddShape(new cpSegmentShape(space.GetStaticBody(), cpVect.cpvadd(a, offset), cpVect.cpvadd(b, offset), 0.0f));
                shape.SetElasticity(1.0f);
            }

            float radius = 5.0f;

            cpVect[] hexagon = new cpVect[6];
            for (int i = 0; i < 6; i++)
            {
                float angle = -(float)Math.PI * 2.0f * i / 6.0f;
                hexagon[i] = cpVect.cpvmult(cpVect.cpv(cp.cpfcos(angle), cp.cpfsin(angle)), radius - bevel);
            }

            for (int i = 0; i < 500; i++)
            {
                float  mass = radius * radius;
                cpBody body = space.AddBody(new cpBody(mass, cp.MomentForPoly(mass, 6, hexagon, cpVect.Zero, 0.0f)));
                body.SetPosition(cpVect.cpvadd(cpVect.cpvmult(cp.frand_unit_circle(), 130.0f), cpVect.Zero));
                body.SetVelocity(cpVect.cpvmult(cp.frand_unit_circle(), 50.0f));

                cpShape shape = space.AddShape(new cpPolyShape(body, 6, hexagon, cpTransform.Identity, bevel));
                shape.SetElasticity(1.0f);
            }

            return(space);
        }
Пример #7
0
        public override void Update(float dt)
        {
            base.Update(dt);

            float coef = (2.0f + ChipmunkDemoKeyboard.y) / 3.0f;
            float rate = ChipmunkDemoKeyboard.x * 30.0f * coef;

            motor.SetRate(rate);
            motor.SetMaxForce(rate > 0 ? 1000000.0f : 0.0f);

            space.Step(dt);

            for (int i = 0; i < numBalls; i++)
            {
                cpBody ball = balls[i];
                cpVect pos  = ball.GetPosition();

                if (pos.x > 320.0f)
                {
                    ball.SetVelocity(cpVect.Zero);
                    ball.SetPosition(new cpVect(-224.0f, 200.0f));
                }
            }
        }
Пример #8
0
        public override void OnEnter()
        {
            base.OnEnter();
            space.SetIterations(30);
            space.SetGravity(new cpVect(0, -500));
            space.SetSleepTimeThreshold(0.5f);
            space.SetCollisionSlop(0.5f);
            var staticBody = space.GetStaticBody();

            // Create segments around the edge of the screen.
            var shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(-320, -240), new cpVect(-320, 240), 0.0f));

            shape.SetElasticity(1.0f);
            shape.SetFriction(1.0f);
            shape.SetFilter(NOT_GRABBABLE_FILTER);

            shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(320, -240), new cpVect(320, 240), 0.0f));
            shape.SetElasticity(1.0f);
            shape.SetFriction(1.0f);
            shape.SetFilter(NOT_GRABBABLE_FILTER);

            shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(-320, -240), new cpVect(320, -240), 0.0f));
            shape.SetElasticity(1.0f);
            shape.SetFriction(1.0f);
            shape.SetFilter(NOT_GRABBABLE_FILTER);

            shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(-320, 240), new cpVect(320, 240), 0.0f));
            shape.SetElasticity(1.0f);
            shape.SetFriction(1.0f);
            shape.SetFilter(NOT_GRABBABLE_FILTER);

            {
                // Add the edges of the bucket
                var bb     = new cpBB(-300, -200, 100, 0);
                var radius = 5.0f;

                shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(bb.l, bb.b), new cpVect(bb.l, bb.t), radius));
                shape.SetElasticity(1.0f);
                shape.SetFriction(1.0f);
                shape.SetFilter(NOT_GRABBABLE_FILTER);

                shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(bb.r, bb.b), new cpVect(bb.r, bb.t), radius));
                shape.SetElasticity(1.0f);
                shape.SetFriction(1.0f);
                shape.SetFilter(NOT_GRABBABLE_FILTER);

                shape = space.AddShape(new cpSegmentShape(staticBody, new cpVect(bb.l, bb.b), new cpVect(bb.r, bb.b), radius));
                shape.SetElasticity(1.0f);
                shape.SetFriction(1.0f);
                shape.SetFilter(NOT_GRABBABLE_FILTER);

                // Add the sensor for the water.
                shape = space.AddShape(cpPolyShape.BoxShape2(staticBody, bb, 0.0f));
                shape.SetSensor(true);
                shape.SetCollisionType(1);
            }
            {
                float width  = 200.0f;
                float height = 50.0f;
                float mass   = 0.3f * FLUID_DENSITY * width * height;
                var   moment = cp.MomentForBox(mass, width, height);

                cpBody body = space.AddBody(new cpBody(mass, moment));
                body.SetPosition(new cpVect(-50, -100));
                body.SetVelocity(new cpVect(0, -100));
                body.SetAngularVelocity(1);

                shape = space.AddShape(cpPolyShape.BoxShape(body, width, height, 0.0f));
                shape.SetFriction(0.8f);
            }

            {
                float width  = 40.0f;
                float height = width * 2;
                float mass   = 0.3f * FLUID_DENSITY * width * height;
                float moment = cp.MomentForBox(mass, width, height);

                cpBody body = space.AddBody(new cpBody(mass, moment));
                body.SetPosition(new cpVect(-200, -50));
                body.SetVelocity(new cpVect(0, -100));
                body.SetAngularVelocity(1);

                shape = space.AddShape(cpPolyShape.BoxShape(body, width, height, 0.0f));
                shape.SetFriction(0.8f);
            }

            cpCollisionHandler handler = space.AddCollisionHandler(1, 0);

            handler.preSolveFunc = waterPreSolve;
            Schedule();
        }