public override void AddRigidBody(RigidBody body)
        {
            if (!body.IsStaticOrKinematicObject() && 0 == (body.GetFlags() & RigidBodyFlags.BT_DISABLE_WORLD_GRAVITY))
            {
                body.SetGravity(ref m_gravity);
            }

            if (body.GetCollisionShape() != null)
            {
                if (!body.IsStaticObject())
                {
                    m_nonStaticRigidBodies.Add(body);
                }
                else
                {
                    body.SetActivationState(ActivationState.ISLAND_SLEEPING);
                }

                bool isDynamic = !(body.IsStaticObject() || body.IsKinematicObject());
                CollisionFilterGroups collisionFilterGroup = isDynamic ? CollisionFilterGroups.DefaultFilter : CollisionFilterGroups.StaticFilter;
                CollisionFilterGroups collisionFilterMask  = isDynamic ? CollisionFilterGroups.AllFilter : (CollisionFilterGroups.AllFilter ^ CollisionFilterGroups.StaticFilter);

                AddCollisionObject(body, collisionFilterGroup, collisionFilterMask);
            }
        }
        protected virtual void SaveKinematicState(float timeStep)
        {
            ///would like to iterate over m_nonStaticRigidBodies, but unfortunately old API allows
            ///to switch status _after_ adding kinematic objects to the world
            ///fix it for Bullet 3.x release

            int length = m_collisionObjects.Count;

            for (int i = 0; i < length; ++i)
            {
                RigidBody body = RigidBody.Upcast(m_collisionObjects[i]);
                if (body != null && body.GetActivationState() != ActivationState.ISLAND_SLEEPING)
                {
                    if (body.IsKinematicObject())
                    {
                        //to calculate velocities next frame
                        body.SaveKinematicState(timeStep);
                    }
                }
            }
        }