示例#1
0
        public void ShatterShape(cpPolyShape shape, float cellSize, cpVect focus)
        {
            space.RemoveShape(shape);
            space.RemoveBody(shape.GetBody());

            cpBB bb     = shape.bb;
            int  width  = (int)((bb.r - bb.l) / cellSize) + 1;
            int  height = (int)((bb.t - bb.b) / cellSize) + 1;
            //	printf("Splitting as %dx%d\n", width, height);
            WorleyContex context = new WorleyContex((int)RandomHelper.frand(), cellSize, width, height, bb, focus);

            for (int i = 0; i < context.width; i++)
            {
                for (int j = 0; j < context.height; j++)
                {
                    cpVect cell = WorleyPoint(i, j, ref context);

                    cpPointQueryInfo cp = null;
                    if (shape.PointQuery(cell, ref cp) < 0.0f)
                    {
                        ShatterCell(shape, cell, i, j, ref context);
                    }
                }
            }

            //cpBodyFree(cpShapeGetBody(shape));
            //cpShapeFree(shape);
        }
示例#2
0
        int ClipCell(cpShape shape, cpVect center, int i, int j, WorleyContex context, cpVect[] verts, cpVect[] clipped, int count)
        {
            cpVect other = WorleyPoint(i, j, ref context);
            //	printf("  other %dx%d: (% 5.2f, % 5.2f) ", i, j, other.x, other.y);

            cpPointQueryInfo queryInfo = null;

            if (shape.PointQuery(other, ref queryInfo) > 0.0f)
            {
                for (int x = 0; x < count; x++)
                {
                    clipped[x] = new cpVect(verts[x]);
                }

                return(count);
            }
            else
            {
                //		printf("clipped\n");
            }

            cpVect n    = cpVect.cpvsub(other, center);
            float  dist = cpVect.cpvdot(n, cpVect.cpvlerp(center, other, 0.5f));

            int clipped_count = 0;

            for (j = 0, i = count - 1; j < count; i = j, j++)
            {
                cpVect a      = verts[i];
                float  a_dist = cpVect.cpvdot(a, n) - dist;

                if (a_dist <= 0.0f)
                {
                    clipped[clipped_count] = a;
                    clipped_count++;
                }

                cpVect b      = verts[j];
                float  b_dist = cpVect.cpvdot(b, n) - dist;

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

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

            return(clipped_count);
        }
示例#3
0
        cpVect WorleyPoint(int i, int j, ref WorleyContex context)
        {
            float size   = context.cellSize;
            int   width  = context.width;
            int   height = context.height;
            cpBB  bb     = context.bb;

            //	cpVect fv = cpv(0.5, 0.5);
            cpVect fv = HashVect(i, j, context.seed);

            return(new cpVect(
                       cp.cpflerp(bb.l, bb.r, 0.5f) + size * (i + fv.x - width * 0.5f),
                       cp.cpflerp(bb.b, bb.t, 0.5f) + size * (j + fv.y - height * 0.5f)
                       ));
        }
示例#4
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());
        }