protected override void OnInitializePhysics()
        {
            // collision configuration contains default setup for memory, collision setup
            CollisionConf = new DefaultCollisionConfiguration();
            Dispatcher = new CollisionDispatcher(CollisionConf);

            Broadphase = new AxisSweep3(new Vector3(-1000, -1000, -1000), new Vector3(1000, 1000, 1000));
            Solver = new SequentialImpulseConstraintSolver();

            World = new DiscreteDynamicsWorld(Dispatcher, Broadphase, Solver, CollisionConf);
            World.DispatchInfo.AllowedCcdPenetration = 0.0001f;
            //World.Gravity = Freelook.Up * -10.0f;

            Matrix startTransform = Matrix.Translation(10.210098f, -1.6433364f, 16.453260f);
            ghostObject = new PairCachingGhostObject();
            ghostObject.WorldTransform = startTransform;
            Broadphase.OverlappingPairCache.SetInternalGhostPairCallback(new GhostPairCallback());

            const float characterHeight = 1.75f;
            const float characterWidth = 1.75f;
            ConvexShape capsule = new CapsuleShape(characterWidth, characterHeight);
            ghostObject.CollisionShape = capsule;
            ghostObject.CollisionFlags = CollisionFlags.CharacterObject;

            const float stepHeight = 0.35f;
            character = new KinematicCharacterController(ghostObject, capsule, stepHeight);

            BspLoader bspLoader = new BspLoader();
            bspLoader.LoadBspFile("data/BspDemo.bsp");
            BspConverter bsp2Bullet = new BspToBulletConverter(this);
            bsp2Bullet.ConvertBsp(bspLoader, 0.1f);

            World.AddCollisionObject(ghostObject, CollisionFilterGroups.CharacterFilter, CollisionFilterGroups.StaticFilter | CollisionFilterGroups.DefaultFilter);

            World.AddAction(character);

            convexResultCallback = new ClosestConvexResultCallback();
            convexResultCallback.CollisionFilterMask = (short)CollisionFilterGroups.StaticFilter;
            cameraSphere = new SphereShape(0.2f);
        }
        internal override bool _BuildCollisionObject()
        {
            BPhysicsWorld world = BPhysicsWorld.Get();
            if (m_collisionObject != null)
            {
                if (isInWorld && world != null)
                {
                    isInWorld = false;
                    world.RemoveCollisionObject(m_collisionObject);
                }
            }

            if (transform.localScale != UnityEngine.Vector3.one)
            {
                Debug.LogError("The local scale on this collision shape is not one. Bullet physics does not support scaling on a rigid body world transform. Instead alter the dimensions of the CollisionShape.");
            }

            m_collisionShape = GetComponent<BCollisionShape>();
            if (m_collisionShape == null)
            {
                Debug.LogError("There was no collision shape component attached to this BRigidBody. " + name);
                return false;
            }
            if (!(m_collisionShape.GetCollisionShape() is ConvexShape))
            {
                Debug.LogError("The CollisionShape on this BCharacterController was not a convex shape. " + name);
                return false;
            }

            m_collisionShape.GetCollisionShape();
            if (m_collisionObject == null)
            {
                m_collisionObject = new PairCachingGhostObject();
                m_collisionObject.CollisionShape = m_collisionShape.GetCollisionShape();
                m_collisionObject.CollisionFlags = m_collisionFlags;
                m_characterController = new KinematicCharacterController((PairCachingGhostObject)m_collisionObject, (ConvexShape)m_collisionShape.GetCollisionShape(), stepHeight, upAxis);
                BulletSharp.Math.Matrix worldTrans;
                BulletSharp.Math.Quaternion q = transform.rotation.ToBullet();
                BulletSharp.Math.Matrix.RotationQuaternion(ref q, out worldTrans);
                worldTrans.Origin = transform.position.ToBullet();
                m_collisionObject.WorldTransform = worldTrans;
                m_collisionObject.UserObject = this;
                //world.world.AddCollisionObject(m_collisionObject, CollisionFilterGroups.CharacterFilter, CollisionFilterGroups.StaticFilter | CollisionFilterGroups.DefaultFilter);
                //((DynamicsWorld)world.world).AddAction(m_characterController);
            }
            else {
                m_collisionObject.CollisionShape = m_collisionShape.GetCollisionShape();
                m_collisionObject.CollisionFlags = m_collisionFlags;
                if (m_characterController != null)
                {
                    world.RemoveAction(m_characterController);
                }
                m_characterController = new KinematicCharacterController((PairCachingGhostObject)m_collisionObject, (ConvexShape)m_collisionShape.GetCollisionShape(), stepHeight, upAxis);
                BulletSharp.Math.Matrix worldTrans;
                BulletSharp.Math.Quaternion q = transform.rotation.ToBullet();
                BulletSharp.Math.Matrix.RotationQuaternion(ref q, out worldTrans);
                worldTrans.Origin = transform.position.ToBullet();
                m_collisionObject.WorldTransform = worldTrans;
                m_collisionObject.UserObject = this;
            }
            return true;
        }