private void CreateSchedulers()
 {
     AddScheduler(Threads.GetSequentialTaskScheduler());
     AddScheduler(Threads.GetOpenMPTaskScheduler());
     AddScheduler(Threads.GetTbbTaskScheduler());
     AddScheduler(Threads.GetPplTaskScheduler());
 }
        //Initialize the physics world
        private void InitializeWorld(DynamicsWorld.InternalTickCallback tickCallBack)
        {
            //Collision configuration and dispatcher
            var collisionConfigInfo = new DefaultCollisionConstructionInfo {
                DefaultMaxCollisionAlgorithmPoolSize = 80000,
                DefaultMaxPersistentManifoldPoolSize = 80000
            };

            _collisionConfig = new DefaultCollisionConfiguration(collisionConfigInfo);

            //Solver Type Config
            switch (_solverType)
            {
            case WorldSolverType.SequentialImpulse:
                _constraintSolver    = new MultiBodyConstraintSolver();
                _collisionDispatcher = new CollisionDispatcher(_collisionConfig);
                break;

            case WorldSolverType.NonSmoothNonLinearConjugate:
                _constraintSolver    = new NncgConstraintSolver();
                _collisionDispatcher = new CollisionDispatcher(_collisionConfig);
                break;

            case WorldSolverType.ExperimentalMultiThreaded:     //EXPERIMENTAL
                switch (_schedulerType)
                {
                case TaskSchedulerType.Sequential:
                    Threads.TaskScheduler = Threads.GetSequentialTaskScheduler();
                    break;

                case TaskSchedulerType.OpenMp:
                    Threads.TaskScheduler = Threads.GetOpenMPTaskScheduler();
                    break;

                case TaskSchedulerType.Ppl:
                    Threads.TaskScheduler = Threads.GetPplTaskScheduler();
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
                _threadedSolver = new ConstraintSolverPoolMultiThreaded(_solverThreads);
                Threads.TaskScheduler.NumThreads = _threadPoolSize;
                _collisionDispatcher             = new CollisionDispatcherMultiThreaded(_collisionConfig);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            //Broadphase Type COnfig
            switch (_broadphaseType)
            {
            case WorldBroadphaseType.DynamicAabb:
                _broadphaseInterface = new DbvtBroadphase();
                break;

            case WorldBroadphaseType.AxisSweep:
                _broadphaseInterface = new AxisSweep3(-_axisSweepMargin.ToBullet(), _axisSweepMargin.ToBullet());
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            //Create the physics world
            if (_solverType == WorldSolverType.ExperimentalMultiThreaded)
            {
                _dynamicsWorld = new DiscreteDynamicsWorldMultiThreaded(_collisionDispatcher, _broadphaseInterface, _threadedSolver, _collisionConfig);
            }
            else
            {
                _dynamicsWorld = new DiscreteDynamicsWorld(_collisionDispatcher, _broadphaseInterface, _constraintSolver, _collisionConfig);
            }

            //Configure the physics world
            _dynamicsWorld.SolverInfo.NumIterations = _solverIterations;
            _dynamicsWorld.SolverInfo.SolverMode    = SolverModes.Simd | SolverModes.UseWarmStarting;
            _dynamicsWorld.SetInternalTickCallback(tickCallBack);
            _btGravity = _gravity.ToBullet();
            _dynamicsWorld.SetGravity(ref _btGravity);
            _initlialized = true;
            if (_debugging)
            {
                Debug.Log("<b>Bullet4Unity:</b> Initialized Bullet Physics World");
            }
        }