void Init_ClusterCar()
        {
            //SetAzi(180);
            Vector3 origin = new Vector3(100, 80, 0);
            Quaternion orientation = Quaternion.RotationYawPitchRoll(-(float)Math.PI / 2, 0, 0);
            const float widthf = 8;
            const float widthr = 9;
            const float length = 8;
            const float height = 4;
            Vector3[] wheels = {
                new Vector3(+widthf,-height,+length), // Front left
                new Vector3(-widthf,-height,+length), // Front right
                new Vector3(+widthr,-height,-length), // Rear left
                new Vector3(-widthr,-height,-length), // Rear right
            };
            SoftBody pa = Create_ClusterBunny(Vector3.Zero, Vector3.Zero);
            SoftBody pfl = Create_ClusterTorus(wheels[0], new Vector3(0, 0, (float)Math.PI / 2), new Vector3(2, 4, 2));
            SoftBody pfr = Create_ClusterTorus(wheels[1], new Vector3(0, 0, (float)Math.PI / 2), new Vector3(2, 4, 2));
            SoftBody prl = Create_ClusterTorus(wheels[2], new Vector3(0, 0, (float)Math.PI / 2), new Vector3(2, 5, 2));
            SoftBody prr = Create_ClusterTorus(wheels[3], new Vector3(0, 0, (float)Math.PI / 2), new Vector3(2, 5, 2));

            pfl.Cfg.DynamicFriction =
                pfr.Cfg.DynamicFriction =
                prl.Cfg.DynamicFriction =
                prr.Cfg.DynamicFriction = 1;

            LinearJoint.Specs lspecs = new LinearJoint.Specs();
            lspecs.ConstraintForceMixing = 1;
            lspecs.ErrorReductionParameter = 1;
            lspecs.Position = Vector3.Zero;

            lspecs.Position = wheels[0]; pa.AppendLinearJoint(lspecs, pfl);
            lspecs.Position = wheels[1]; pa.AppendLinearJoint(lspecs, pfr);
            lspecs.Position = wheels[2]; pa.AppendLinearJoint(lspecs, prl);
            lspecs.Position = wheels[3]; pa.AppendLinearJoint(lspecs, prr);

            AngularJoint.Specs aspecs = new AngularJoint.Specs();
            aspecs.ConstraintForceMixing = 1;
            aspecs.ErrorReductionParameter = 1;
            aspecs.Axis = new Vector3(1, 0, 0);

            aspecs.Control = steerControlF;
            pa.AppendAngularJoint(aspecs, pfl);
            pa.AppendAngularJoint(aspecs, pfr);

            aspecs.Control = motorControl;
            pa.AppendAngularJoint(aspecs, prl);
            pa.AppendAngularJoint(aspecs, prr);

            pa.Rotate(orientation);
            pfl.Rotate(orientation);
            pfr.Rotate(orientation);
            prl.Rotate(orientation);
            prr.Rotate(orientation);
            pa.Translate(origin);
            pfl.Translate(origin);
            pfr.Translate(origin);
            prl.Translate(origin);
            prr.Translate(origin);
            pfl.Cfg.PositionIterations =
                pfr.Cfg.PositionIterations =
                prl.Cfg.PositionIterations =
                prr.Cfg.PositionIterations = 1;
            pfl.Clusters[0].Matching =
                pfr.Clusters[0].Matching =
                prl.Clusters[0].Matching =
                prr.Clusters[0].Matching = 0.05f;
            pfl.Clusters[0].NodeDamping =
                pfr.Clusters[0].NodeDamping =
                prl.Clusters[0].NodeDamping =
                prr.Clusters[0].NodeDamping = 0.05f;

            Create_LinearStair(20, new Vector3(0, -8, 0), new Vector3(3, 2, 40));
            Create_RbUpStack(50);
            //autocam=true;
        }
 void Init_ClusterSocket()
 {
     SoftBody psb = Create_ClusterTorus(Vector3.Zero, new Vector3((float)Math.PI / 2, 0, (float)Math.PI / 2));
     RigidBody prb = Create_BigPlate(50, 8);
     psb.Cfg.DynamicFriction = 1;
     LinearJoint.Specs lj = new LinearJoint.Specs();
     lj.Position = new Vector3(0, 5, 0);
     psb.AppendLinearJoint(lj, new Body(prb));
 }
        void Init_ClusterCombine()
        {
            Vector3 sz = new Vector3(2, 4, 2);
            SoftBody psb0 = Create_ClusterTorus(new Vector3(0, 8, 0), new Vector3((float)Math.PI / 2, 0, (float)Math.PI / 2), sz);
            SoftBody psb1 = Create_ClusterTorus(new Vector3(0, 8, 10), new Vector3((float)Math.PI / 2, 0, (float)Math.PI / 2), sz);
            SoftBody[] psbs = new SoftBody[] { psb0, psb1 };
            for (int j = 0; j < 2; ++j)
            {
                psbs[j].Cfg.DynamicFriction = 1;
                psbs[j].Cfg.DynamicFriction = 0;
                psbs[j].Cfg.PositionIterations = 1;
                psbs[j].Clusters[0].Matching = 0.05f;
                psbs[j].Clusters[0].NodeDamping = 0.05f;
            }
            AngularJoint.Specs aj = new AngularJoint.Specs();
            aj.Axis = new Vector3(0, 0, 1);
            aj.Control = motorControl;
            psb0.AppendAngularJoint(aj, psb1);

            LinearJoint.Specs lj = new LinearJoint.Specs();
            lj.Position = new Vector3(0, 8, 5);
            psb0.AppendLinearJoint(lj, psb1);
        }
        void Init_ClusterRobot()
        {
            Vector3 basePos = new Vector3(0, 25, 8);
            SoftBody psb0 = Init_ClusterRobot_CreateBall(basePos + new Vector3(-8, 0, 0));
            SoftBody psb1 = Init_ClusterRobot_CreateBall(basePos + new Vector3(+8, 0, 0));
            SoftBody psb2 = Init_ClusterRobot_CreateBall(basePos + new Vector3(0, 0, +8 * (float)Math.Sqrt(2)));
            Vector3 ctr = (psb0.ClusterCom(0) + psb1.ClusterCom(0) + psb2.ClusterCom(0)) / 3;
            CylinderShape pshp = new CylinderShape(new Vector3(8, 1, 8));
            RigidBody prb = LocalCreateRigidBody(50, Matrix.Translation(ctr + new Vector3(0, 5, 0)), pshp);
            LinearJoint.Specs ls = new LinearJoint.Specs();
            ls.ErrorReductionParameter = 0.5f;
            Body prbBody = new Body(prb);
            ls.Position = psb0.ClusterCom(0); psb0.AppendLinearJoint(ls, prbBody);
            ls.Position = psb1.ClusterCom(0); psb1.AppendLinearJoint(ls, prbBody);
            ls.Position = psb2.ClusterCom(0); psb2.AppendLinearJoint(ls, prbBody);

            BoxShape pbox = new BoxShape(20, 1, 40);
            RigidBody pgrn = LocalCreateRigidBody(0, Matrix.RotationZ(-(float)Math.PI / 4), pbox);
        }