void UpdateRigitBody(double secs, Vector3D parentVelocity)
 {
     if (!RB.Update(secs, rb =>
     {
         if (secs > 1e-3)
         {
             return(false);
         }
         var dif = (rb.position - rb._position).Length;
         if (dif > Radius / 5)
         {
             return(false);
         }
         if (!Blocks.IsCollidable(rb.position, out int cur_x, out int cur_y))
         {
             //bool rollback = false;
             const double rollbackSpeed = 0.1;
             const double bounce = 0.1;
             {
                 int x = 0, y = 0;
                 Point3D cp;
                 cp = rb.position + new Vector3D(-Radius, 0, 0);
                 if (Blocks.IsCollidable(cp, out x, out y))
                 {
                     if (x == cur_x - 1 && !Blocks.IsCollidable(cur_x, y) && rb.velocity.X < 0)//collide left, +x force. t=(cp.x*-Sin(theta)+cp.y*-Cos(theta)), (v.x+f/m) + (omega+f*t/I)*t = -b*(v.x + omega*t), f*(1/m+t^2/I)=(-b-1)*(v.x+omega*t)
                     {
                         var f = (-bounce - 1) * (rb.velocity.X) / (1.0 / rb.mass);
                         rb.velocity.X += f / rb.mass;
                         //rollback = true;
                         rb.position.X += secs * rollbackSpeed;
                     }
                 }
                 cp = rb.position + new Vector3D(Radius, 0, 0);
                 if (Blocks.IsCollidable(cp, out x, out y))
                 {
                     if (x == cur_x + 1 && !Blocks.IsCollidable(cur_x, y) && rb.velocity.X > 0)//collide right, -x force. t=(cp.x*-Sin(theta)+cp.y*-Cos(theta)), (v.x-f/m) + (omega-f*t/I)*t = -b*(v.x + omega*t), f*(-1/m-t^2/I)=(-b-1)*(v.x+omega*t)
                     {
                         var f = (-bounce - 1) * (rb.velocity.X) / (-1.0 / rb.mass);
                         rb.velocity.X -= f / rb.mass;
                         //rollback = true;
                         rb.position.X -= secs * rollbackSpeed;
                     }
                 }
                 cp = rb.position + new Vector3D(0, -Radius, 0);
                 if (Blocks.IsCollidable(cp, out x, out y))
                 {
                     if (y == cur_y - 1 && !Blocks.IsCollidable(x, cur_y) && rb.velocity.Y < 0)//collide down, +y force. t=(cp.y*-Sin(theta)+cp.x*Cos(theta)), (v.y+f/m) + (omega+f*t/I)*t = -b*(v.y + omega*t), f*(1/m+t^2/I)=(-b-1)*(v.y+omega*t)
                     {
                         var f = (-bounce - 1) * (rb.velocity.Y) / (1.0 / rb.mass);
                         rb.velocity.Y += f / rb.mass;
                         //rollback = true;
                         rb.position.Y += secs * rollbackSpeed;
                         onGround = 0.1;
                     }
                 }
                 cp = rb.position + new Vector3D(0, Radius, 0);
                 if (Blocks.IsCollidable(cp, out x, out y))
                 {
                     if (y == cur_y + 1 && !Blocks.IsCollidable(x, cur_y) && rb.velocity.Y > 0)//collide up, -y force. t=(cp.y*-Sin(theta)+cp.x*Cos(theta)), (v.y-f/m) + (omega-f*t/I)*t = -b*(v.y + omega*t), f*(-1/m-t^2/I)=(-b-1)*(v.y+omega*t)
                     {
                         var f = (-bounce - 1) * (rb.velocity.Y) / (-1.0 / rb.mass);
                         rb.velocity.Y -= f / rb.mass;
                         //rollback = true;
                         rb.position.Y -= secs * rollbackSpeed;
                     }
                 }
             }
             //if(false)
             {
                 Blocks.IsCollidable(rb.position + new Vector3D(Blocks.Width / 2, Blocks.Height / 2, 0), out int cross_x, out int cross_y);
                 var vectorToCross = new Vector3D((Blocks.Anchor.X + Blocks.Width * cross_x) - rb.position.X, (Blocks.Anchor.Y + Blocks.Height * cross_y) - rb.position.Y, 0);
                 if (0 < vectorToCross.Length && vectorToCross.Length < Radius && Vector3D.DotProduct(rb.velocity, vectorToCross) > 0)
                 {
                     int x = vectorToCross.X < 0 ? cross_x - 1 : cross_x;
                     int y = vectorToCross.Y < 0 ? cross_y - 1 : cross_y;
                     if (Blocks.IsCollidable(x, y))
                     {
                         ///(v+a*c)。c=-b*(v。c)
                         ///(vx+a*cx)*cx+(vy+a*cy)*cy=-b*(vx*cx+vy*cy)
                         ///a(cx*cx+cy*cy)+vx*cx+vy*cy=-b*(vx*cx+vy*cy)
                         ///a=(-b*(vx*cx+vy*cy)-(vx*cx+vy*cy))/(cx*cx+cy*cy)
                         double a = ((-bounce - 1) * Vector3D.DotProduct(rb.velocity, vectorToCross)) / Vector3D.DotProduct(vectorToCross, vectorToCross);
                         rb.velocity += a * vectorToCross;
                         //rollback = true;
                         rb.position += -vectorToCross / vectorToCross.Length * secs * rollbackSpeed;
                     }
                 }
             }
             //if (rollback) rb.position = rb._position;
             //System.Diagnostics.Trace.WriteLine($"position: {rb.position}, \tvelocity: {rb.velocity}, \ttheta: {rb.theta}, \tomega: {rb.omega}");
         }
         return(true);
     }))