void hkDefaultDemo::addOrRemoveThreads()
{
	//
	// Add/remove threads
	//
	if (m_env->m_window)
	{
		if (m_jobThreadPool)
		{
			if (m_env->m_window->getKeyboard().wasKeyPressed('T') ||
				m_env->m_window->getGamePad(0).wasButtonPressed(HKG_PAD_BUTTON_R1) )
			{
				int num = m_jobThreadPool->getNumThreads();

				hkHardwareInfo info;
				hkGetHardwareInfo(info);
				if (num < info.m_numThreads - 1) num++;
				m_jobThreadPool->setNumThreads( num );
			}
			if ( m_env->m_window->getKeyboard().wasKeyPressed('G') ||
				m_env->m_window->getGamePad(0).wasButtonPressed(HKG_PAD_BUTTON_R2) )
			{
				int num = m_jobThreadPool->getNumThreads();
				if (num > 0) num--;
				m_jobThreadPool->setNumThreads( num );
			}
		}
	}
}
bool XkPhysicsWorldImpl::initializeImpl()
{
        m_memoryRouter = hkMemoryInitUtil::initDefault(hkMallocAllocator::m_defaultMallocAllocator,
                hkMemorySystem::FrameInfo(500*1024));

        hkBaseSystem::init(m_memoryRouter, errorReport);

        hkHardwareInfo hwInfo;
        hkGetHardwareInfo(hwInfo);

        m_nThreadUsed = hwInfo.m_numThreads;

        hkCpuJobThreadPoolCinfo threadPoolCinfo;
        threadPoolCinfo.m_numThreads = m_nThreadUsed - 1;

        threadPoolCinfo.m_timerBufferPerThreadAllocation = 200000;
        m_threadPool = new hkCpuJobThreadPool(threadPoolCinfo);

        hkJobQueueCinfo info;
        info.m_jobQueueHwSetup.m_numCpuThreads = m_nThreadUsed;
        m_jobQueue = new hkJobQueue(info);

        hkMonitorStream::getInstance().resize(200000);
        
        return createPhysicsWorld();
}
/// Initialize multi-threading sharedThreadData and create threads.
vHavokCpuJobThreadPool::vHavokCpuJobThreadPool(const vHavokCpuJobThreadPoolCinfo& ci)
{
    m_isRunning = false;
    m_threadName = ci.m_threadName;
    m_stackSize = ci.m_stackSize;

    m_sharedThreadData.m_localHavokStackSize = ci.m_havokStackSize;
    m_sharedThreadData.m_timerBufferAllocation = ci.m_timerBufferPerThreadAllocation;

    int numThreads = ci.m_numThreads;
    if (numThreads >= MAX_NUM_THREADS)
    {
        HK_WARN( 0xf0defd23, "You requested 6 or more threads, this is not supported by vHavokCpuJobThreadPool" );
        numThreads = MAX_NUM_THREADS - 1;
    }

    m_sharedThreadData.m_numThreads = numThreads;

    m_sharedThreadData.m_OnWorkerThreadCreatedPtr = ci.m_OnWorkerThreadCreatedPtr;
    m_sharedThreadData.m_OnWorkerThreadFinishedPtr = ci.m_OnWorkerThreadFinishedPtr;

#if defined(HK_PLATFORM_XBOX360)
    int numCores = 3;
    int numThreadsPerCore = 2;
#elif defined(HK_PLATFORM_WIN32)
    hkHardwareInfo info;
    hkGetHardwareInfo( info );
    int numCores = info.m_numThreads; //This reports actual cores - ignoring hyperthreading
    int numThreadsPerCore = 1;
    numCores /= numThreadsPerCore;
#endif

    for (int i = 0; i < numThreads; i++ )
    {
        WorkerThreadData& data = m_workerThreads[i];
        data.m_sharedThreadData = &m_sharedThreadData;
        data.m_threadId = i + 1; // don't start with thread 0 (assume that is the calling thread)
        data.m_monitorStreamBegin = HK_NULL;
        data.m_monitorStreamEnd = HK_NULL;
        data.m_killThread = false;
        data.m_clearTimers = false;

#if defined(HK_PLATFORM_XBOX360) || defined(HK_PLATFORM_WIN32)
        if (ci.m_hardwareThreadIds.getSize() > 0)
        {
            HK_ASSERT2( 0x975fe134, ci.m_hardwareThreadIds.getSize() >= numThreads, "If you initialize hardware thread ids, you must give an ID to all threads");
            data.m_hardwareThreadId = ci.m_hardwareThreadIds[i];
        }
        else
        {
            //X360: { 2,4,1,3,5, 0, 2,4,.. }
            int procGroup = (data.m_threadId % numCores) * numThreadsPerCore;
            data.m_hardwareThreadId = procGroup + (numThreadsPerCore > 1? ((data.m_threadId / numCores) % numThreadsPerCore) : 0 );
        }
#endif

        data.m_thread.startThread( &hkWorkerThreadFunc, &data, m_threadName, m_stackSize );
    }
    hkReferencedObject::setLockMode( hkReferencedObject::LOCK_MODE_AUTO);
}
Example #4
0
CWorld::CWorld(void)
{
	m_pWorld = 0;
	m_pMemoryRouter = 0;
	m_collisionFilter = 0;
	m_pCell = 0;

	m_suspended = 0;
	
	_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
	m_pMemoryRouter = hkMemoryInitUtil::initDefault( hkMallocAllocator::m_defaultMallocAllocator, hkMemorySystem::FrameInfo( 128 * 1024 * 1024 ) );
	hkBaseSystem::init( m_pMemoryRouter, errorReport );
	m_threadInit.insert(GetCurrentThreadId());
		
	int numThreads = 1;
	hkHardwareInfo hwInfo;
	hkGetHardwareInfo(hwInfo);
	numThreads = hwInfo.m_numThreads*2;
	LogInfo("System run with %d threads", numThreads);

	hkJobQueueCinfo jobQueueInfo;
	jobQueueInfo.m_jobQueueHwSetup.m_numCpuThreads = numThreads+1;
	m_jobQueue = new hkJobQueue(jobQueueInfo);
	
	hkCpuJobThreadPoolCinfo jobPoolInfo;
	jobPoolInfo.m_numThreads = numThreads;
	m_jobThreadPool = new hkCpuJobThreadPool(jobPoolInfo);

	hkpWorldCinfo info;
	info.m_gravity.set(0, 0, -9.8);
	//info.m_gravity.set(0, 0, 0);
	info.setBroadPhaseWorldSize(1e+6);
	info.m_broadPhaseType = hkpWorldCinfo::BROADPHASE_TYPE_SAP;
	info.m_broadPhaseBorderBehaviour = hkpWorldCinfo::BROADPHASE_BORDER_DO_NOTHING;
	info.setupSolverInfo(hkpWorldCinfo::SOLVER_TYPE_8ITERS_HARD);
	info.m_simulationType = hkpWorldCinfo::SIMULATION_TYPE_MULTITHREADED;
	info.m_enableDeactivation = false;

	m_pWorld = new hkpWorld(info);
	m_pWorld->markForWrite();
	
	auto* pFilter = new hkpConstraintCollisionFilter(new MyGroupFilter);
	m_collisionFilter = pFilter;
	m_pWorld->setCollisionFilter(pFilter);
	pFilter->init(m_pWorld);

	hkpWorld::registerWithJobQueue(m_jobQueue);
	hkpConstraintStabilizationUtil::setConstraintsSolvingMethod(m_pWorld, hkpConstraintAtom::METHOD_STABILIZED);
	hkpAgentRegisterUtil::registerAllAgents(m_pWorld->getCollisionDispatcher());
	
	m_pWorld->unmarkForWrite();
	
	m_timeLastUpdate = *timeStamp;

	LogInfo("Havok simulated world created.");
}
Example #5
0
	Physics_Manager::Physics_Manager() : levelComplete( false ), ballInVent( false )
	{
		// initialize base system and memory
		hkMemoryRouter *memoryRouter = hkMemoryInitUtil::initDefault();
		hkBaseSystem::init( memoryRouter, errorReport );

		// initialize multithreading classes
		// we will cap the number of threads used
		int totalNumThreadsUsed;

		// get number of physical threads
		hkHardwareInfo hwInfo;
		hkGetHardwareInfo( hwInfo );
		totalNumThreadsUsed = hwInfo.m_numThreads;

		// use one less that that since we must use one for the simulation
		hkCpuJobThreadPoolCinfo threadPoolCinfo;
		threadPoolCinfo.m_numThreads = totalNumThreadsUsed - 1;

		// This line enables timers collection, by allocating 200 Kb per thread.  If you leave this at its default (0),
		// timer collection will not be enabled.
		threadPoolCinfo.m_timerBufferPerThreadAllocation = 200000;
		threadPool = new hkCpuJobThreadPool( threadPoolCinfo );

		// We also need to create a Job queue. This job queue will be used by all Havok modules to run multithreaded work.
		// Here we only use it for physics.
		hkJobQueueCinfo info;
		info.m_jobQueueHwSetup.m_numCpuThreads = totalNumThreadsUsed;
		jobQueue = new hkJobQueue( info );

		// enable monitors for thread
		// monitor have been enabled for thread pool threads already
		hkMonitorStream::getInstance().resize( 200000 );

		// this hold global simulation parameters (gravity, etc.)
		// gravity (most important attribute for this app) defaults to -9.8 m/s^2
		hkpWorldCinfo worldInfo;
		worldInfo.m_gravity = hkVector4( 0, -1.f, 0 );
		worldInfo.m_simulationType = hkpWorldCinfo::SIMULATION_TYPE_CONTINUOUS;
		//worldInfo.m_simulationType = hkpWorldCinfo::SIMULATION_TYPE_MULTITHREADED;

		// flag objects that fall out of the world to be automatically removed
		worldInfo.m_broadPhaseBorderBehaviour = hkpWorldCinfo::BROADPHASE_BORDER_REMOVE_ENTITY;
		worldInfo.m_collisionTolerance = 0.01f;

		world = new hkpWorld( worldInfo );

		// register all collision agents
		hkpAgentRegisterUtil::registerAllAgents( world->getCollisionDispatcher() );

		// register all modules we will run multi-threaded with job queue
		world->registerWithJobQueue( jobQueue );

		#if defined(_DEBUG) | defined(DEBUG)
		// now initialize the visual debugger
		hkArray<hkProcessContext*> contexts;

		// register physics specific visual debugger processes
		context = new hkpPhysicsContext();
		//all physics viewers
		hkpPhysicsContext::registerAllPhysicsProcesses();
		//add physics world so viewers can see it
		context->addWorld( world );
		contexts.pushBack( context );

		// we're single threading, so disable checks
		world->setMultithreadedAccessChecking( hkpWorld::MT_ACCESS_CHECKING_DISABLED );

		// init the debugger
		vdb = new hkVisualDebugger( contexts );
		vdb->serve();
		#endif

		world->addWorldPostSimulationListener( this );
	}
void PhysicsWrapper::Init()
{
	hkMemoryRouter* memoryRouter = hkMemoryInitUtil::initDefault();
	hkBaseSystem::init( memoryRouter, errorReport );
	setupComplete = false;
		//
		// Initialize the multi-threading classes, hkJobQueue, and hkJobThreadPool
		//

		// They can be used for all Havok multithreading tasks. In this exmaple we only show how to use
		// them for physics, but you can reference other multithreading demos in the demo framework
		// to see how to multithread other products. The model of usage is the same as for physics.
		// The hkThreadpool has a specified number of threads that can run Havok jobs.  These can work
		// alongside the main thread to perform any Havok multi-threadable computations.
		// The model for running Havok tasks in Spus and in auxilary threads is identical.  It is encapsulated in the
		// class hkJobThreadPool.  On PLAYSTATION(R)3 we initialize the SPU version of this class, which is simply a SPURS taskset.
		// On other multi-threaded platforms we initialize the CPU version of this class, hkCpuJobThreadPool, which creates a pool of threads
		// that run in exactly the same way.  On the PLAYSTATION(R)3 we could also create a hkCpuJobThreadPool.  However, it is only
		// necessary (and advisable) to use one Havok PPU thread for maximum efficiency. In this case we simply use this main thread
		// for this purpose, and so do not create a hkCpuJobThreadPool.
//		hkJobThreadPool* threadPool;

		// We can cap the number of threads used - here we use the maximum for whatever multithreaded platform we are running on. This variable is
		// set in the following code sections.
		int totalNumThreadsUsed;

		// Get the number of physical threads available on the system
		hkHardwareInfo hwInfo;
		hkGetHardwareInfo(hwInfo);
		totalNumThreadsUsed = hwInfo.m_numThreads;

		// We use one less than this for our thread pool, because we must also use this thread for our simulation
		hkCpuJobThreadPoolCinfo threadPoolCinfo;
		threadPoolCinfo.m_numThreads = totalNumThreadsUsed - 1;

		// This line enables timers collection, by allocating 200 Kb per thread.  If you leave this at its default (0),
		// timer collection will not be enabled.
		threadPoolCinfo.m_timerBufferPerThreadAllocation = 200000;
		threadPool = new hkCpuJobThreadPool( threadPoolCinfo );

		// We also need to create a Job queue. This job queue will be used by all Havok modules to run multithreaded work.
		// Here we only use it for physics.
		hkJobQueueCinfo info;
		info.m_jobQueueHwSetup.m_numCpuThreads = totalNumThreadsUsed;
		jobQueue = new hkJobQueue(info);

		//
		// Enable monitors for this thread.
		//

		// Monitors have been enabled for thread pool threads already (see above comment).
		hkMonitorStream::getInstance().resize(200000);

		//
		// <PHYSICS-ONLY>: Create the physics world.
		// At this point you would initialize any other Havok modules you are using.
		//
		
		{
			// The world cinfo contains global simulation parameters, including gravity, solver settings etc.
			hkpWorldCinfo worldInfo;

			// Set the simulation type of the world to multi-threaded.
			worldInfo.m_simulationType = hkpWorldCinfo::SIMULATION_TYPE_MULTITHREADED;

			// Flag objects that fall "out of the world" to be automatically removed - just necessary for this physics scene
			worldInfo.m_broadPhaseBorderBehaviour = hkpWorldCinfo::BROADPHASE_BORDER_REMOVE_ENTITY;

			physicsWorld = new hkpWorld(worldInfo);

			// Disable deactivation, so that you can view timers in the VDB. This should not be done in your game.
			physicsWorld->m_wantDeactivation = false;


			// When the simulation type is SIMULATION_TYPE_MULTITHREADED, in the debug build, the sdk performs checks
			// to make sure only one thread is modifying the world at once to prevent multithreaded bugs. Each thread
			// must call markForRead / markForWrite before it modifies the world to enable these checks.
			physicsWorld->markForWrite();
			physicsWorld->setGravity(hkVector4(0.0f, -9.8f, 0.0f));


			// Register all collision agents, even though only box - box will be used in this particular example.
			// It's important to register collision agents before adding any entities to the world.
			hkpAgentRegisterUtil::registerAllAgents( physicsWorld->getCollisionDispatcher() );

			// We need to register all modules we will be running multi-threaded with the job queue
			physicsWorld->registerWithJobQueue( jobQueue );
		}
}
int HK_CALL main(int argc, const char** argv)
{
    //
    // Do platform specific initialization
    //
#if !defined(HK_PLATFORM_WIN32)
    extern void initPlatform();
    initPlatform();
#endif



    //
    // Initialize the base system including our memory system
    //

    hkPoolMemory* memoryManager = new hkPoolMemory();
    hkThreadMemory* threadMemory = new hkThreadMemory(memoryManager);
    hkBaseSystem::init( memoryManager, threadMemory, errorReport );
    memoryManager->removeReference();

    // We now initialize the stack area to 100k (fast temporary memory to be used by the engine).
    char* stackBuffer;
    {
        int stackSize = 0x100000;
        stackBuffer = hkAllocate<char>( stackSize, HK_MEMORY_CLASS_BASE);
        hkThreadMemory::getInstance().setStackArea( stackBuffer, stackSize);
    }

    {

        //
        // Initialize the multi-threading classes, hkJobQueue, and hkJobThreadPool
        //

        // They can be used for all Havok multithreading tasks. In this exmaple we only show how to use
        // them for physics, but you can reference other multithreading demos in the demo framework
        // to see how to multithread other products. The model of usage is the same as for physics.
        // The hkThreadpool has a specified number of threads that can run Havok jobs.  These can work
        // alongside the main thread to perform any Havok multi-threadable computations.
        // The model for running Havok tasks in Spus and in auxilary threads is identical.  It is encapsulated in the
        // class hkJobThreadPool.  On PLAYSTATION(R)3 we initialize the SPU version of this class, which is simply a SPURS taskset.
        // On other multi-threaded platforms we initialize the CPU version of this class, hkCpuJobThreadPool, which creates a pool of threads
        // that run in exactly the same way.  On the PLAYSTATION(R)3 we could also create a hkCpuJobThreadPool.  However, it is only
        // necessary (and advisable) to use one Havok PPU thread for maximum efficiency. In this case we simply use this main thread
        // for this purpose, and so do not create a hkCpuJobThreadPool.
        hkJobThreadPool* threadPool;

        // We can cap the number of threads used - here we use the maximum for whatever multithreaded platform we are running on. This variable is
        // set in the following code sections.
        int totalNumThreadsUsed;

#if defined HK_PLATFORM_PS3_PPU

        hkSpuJobThreadPoolCinfo threadPoolCinfo;

        extern CellSpurs* initSpurs();
        HK_CELL_SPURS* spurs = initSpurs();

        hkSpuUtil* spuUtil = new hkSpuUtil( spurs );

        spuUtil->attachHelperThreadToSpurs();
        threadPoolCinfo.m_spuUtil = spuUtil;
        threadPoolCinfo.m_numSpus = 6; // Use all 6 SPUs for this example

        totalNumThreadsUsed = 1; // only use one CPU thread for PS3.

        // This line enables timers collection, by allocating 200 Kb per thread.  If you leave this at its default (0),
        // timer collection will not be enabled.
        threadPoolCinfo.m_perSpuMontiorBufferSize = 200000;
        threadPool = new hkSpuJobThreadPool( threadPoolCinfo );
        spuUtil->removeReference();

#else

        // Get the number of physical threads available on the system
        hkHardwareInfo hwInfo;
        hkGetHardwareInfo(hwInfo);
        totalNumThreadsUsed = hwInfo.m_numThreads;

        // We use one less than this for our thread pool, because we must also use this thread for our simulation
        hkCpuJobThreadPoolCinfo threadPoolCinfo;
        threadPoolCinfo.m_numThreads = totalNumThreadsUsed - 1;

        // This line enables timers collection, by allocating 200 Kb per thread.  If you leave this at its default (0),
        // timer collection will not be enabled.
        threadPoolCinfo.m_timerBufferPerThreadAllocation = 200000;
        threadPool = new hkCpuJobThreadPool( threadPoolCinfo );

#endif

        // We also need to create a Job queue. This job queue will be used by all Havok modules to run multithreaded work.
        // Here we only use it for physics.
        hkJobQueueCinfo info;
        info.m_jobQueueHwSetup.m_numCpuThreads = totalNumThreadsUsed;
        hkJobQueue* jobQueue = new hkJobQueue(info);

        //
        // Enable monitors for this thread.
        //

        // Monitors have been enabled for thread pool threads already (see above comment).
        hkMonitorStream::getInstance().resize(200000);



        //
        // <PHYSICS-ONLY>: Create the physics world.
        // At this point you would initialize any other Havok modules you are using.
        //
        hkpWorld* physicsWorld;
        {
            // The world cinfo contains global simulation parameters, including gravity, solver settings etc.
            hkpWorldCinfo worldInfo;

            // Set the simulation type of the world to multi-threaded.
            worldInfo.m_simulationType = hkpWorldCinfo::SIMULATION_TYPE_MULTITHREADED;

            // Flag objects that fall "out of the world" to be automatically removed - just necessary for this physics scene
            worldInfo.m_broadPhaseBorderBehaviour = hkpWorldCinfo::BROADPHASE_BORDER_REMOVE_ENTITY;

            physicsWorld = new hkpWorld(worldInfo);

            // Disable deactivation, so that you can view timers in the VDB. This should not be done in your game.
            physicsWorld->m_wantDeactivation = false;


            // When the simulation type is SIMULATION_TYPE_MULTITHREADED, in the debug build, the sdk performs checks
            // to make sure only one thread is modifying the world at once to prevent multithreaded bugs. Each thread
            // must call markForRead / markForWrite before it modifies the world to enable these checks.
            physicsWorld->markForWrite();


            // Register all collision agents, even though only box - box will be used in this particular example.
            // It's important to register collision agents before adding any entities to the world.
            hkpAgentRegisterUtil::registerAllAgents( physicsWorld->getCollisionDispatcher() );

            // We need to register all modules we will be running multi-threaded with the job queue
            physicsWorld->registerWithJobQueue( jobQueue );

            // Create all the physics rigid bodies
            setupPhysics( physicsWorld );
        }


        //
        // Initialize the VDB
        //
        hkArray<hkProcessContext*> contexts;


        // <PHYSICS-ONLY>: Register physics specific visual debugger processes
        // By default the VDB will show debug points and lines, however some products such as physics and cloth have additional viewers
        // that can show geometries etc and can be enabled and disabled by the VDB app.
        hkpPhysicsContext* context;
        {
            // The visual debugger so we can connect remotely to the simulation
            // The context must exist beyond the use of the VDB instance, and you can make
            // whatever contexts you like for your own viewer types.
            context = new hkpPhysicsContext();
            hkpPhysicsContext::registerAllPhysicsProcesses(); // all the physics viewers
            context->addWorld(physicsWorld); // add the physics world so the viewers can see it
            contexts.pushBack(context);

            // Now we have finished modifying the world, release our write marker.
            physicsWorld->unmarkForWrite();
        }

        hkVisualDebugger* vdb = new hkVisualDebugger(contexts);
        vdb->serve();


        //
        // Simulate the world for 1 minute.
        //


        // Take fixed time steps of 1/60th of a second.
        // This works well if your game runs solidly at 60Hz. If your game runs at 30Hz
        // you can take either 2 60Hz steps or 1 30Hz step. Note that at lower frequencies (i.e. 30 Hz)
        // more bullet through paper issues appear, and constraints will not be as stiff.
        // If you run at variable frame rate, or are likely to drop frames, you can consider
        // running your physics for a variable number of steps based on the system clock (i.e. last frame time).
        // Please refer to the user guide section on time stepping for a full treatment of this issue.

        // A stopwatch for waiting until the real time has passed
        hkStopwatch stopWatch;
        stopWatch.start();
        hkReal lastTime = stopWatch.getElapsedSeconds();

        hkReal timestep = 1.f / 60.f;
        int numSteps = int(60.f / timestep);

        for ( int i = 0; i < numSteps; ++i )
        {
            // <PHYSICS-ONLY>:
            // Step the physics world. This single call steps using this thread and all threads
            // in the threadPool. For other products you add jobs, call process all jobs and wait for completion.
            // See the multithreading chapter in the user guide for details
            {
                physicsWorld->stepMultithreaded( jobQueue, threadPool, timestep );
            }

            // Step the visual debugger. We first synchronize the timer data
            context->syncTimers( threadPool );
            vdb->step();

            // Clear accumulated timer data in this thread and all slave threads
            hkMonitorStream::getInstance().reset();
            threadPool->clearTimerData();


            // <PHYSICS-ONLY>:  Display the sphereRigidBody position to the console every second
            if (i % 60 == 0)
            {
                hkVector4 pos = g_ball->getPosition();
                printf("[%f,%f,%f]\n", pos(0), pos(1), pos(2));
            }

            // Pause until the actual time has passed
            while (stopWatch.getElapsedSeconds() < lastTime + timestep);
            lastTime += timestep;

            // Step the graphics display (none in this demo).
        }



        //
        // Clean up physics and graphics
        //

        // <PHYSICS-ONLY>: cleanup physics
        {
            physicsWorld->markForWrite();
            physicsWorld->removeReference();
        }
        vdb->removeReference();

        // Contexts are not reference counted at the base class level by the VDB as
        // they are just interfaces really. So only delete the context after you have
        // finished using the VDB.
        context->removeReference();

        delete jobQueue;

        //
        // Clean up the thread pool
        //

        threadPool->removeReference();


#if defined HK_PLATFORM_PS3_PPU
        extern void quitSpurs( CellSpurs* spurs );
        quitSpurs( spurs );
#endif
    }

    // Deallocate stack area
    threadMemory->setStackArea(0, 0);
    hkDeallocate(stackBuffer);

    threadMemory->removeReference();

    // Quit base system
    hkBaseSystem::quit();

    return 0;
}
Example #8
0
void HavokUtilities::initHavok()
{	
	{//initialize Havok Memory
		// Allocate 0.5MB of physics solver buffer.
		//hkMemoryRouter* m_pMemoryRouter;
		m_pMemoryRouter = hkMemoryInitUtil::initDefault(hkMallocAllocator::m_defaultMallocAllocator, hkMemorySystem::FrameInfo(500000));
		hkBaseSystem::init( m_pMemoryRouter, errorReport );
	}
	{// Initialize the multi-threading classes, hkJobQueue, and hkJobThreadPool
		// Most of the comments are copied and pasted from ConsoleExampleMt.cpp of HavokDemos folder (2010 version)
		// They can be used for all Havok multithreading tasks. In this exmaple we only show how to use
		// them for physics, but you can reference other multithreading demos in the demo framework
		// to see how to multithread other products. The model of usage is the same as for physics.
		// The hkThreadpool has a specified number of threads that can run Havok jobs.  These can work
		// alongside the main thread to perform any Havok multi-threadable computations.
		// The model for running Havok tasks in Spus and in auxilary threads is identical.  It is encapsulated in the
		// class hkJobThreadPool.  On PlayStation(R)3 we initialize the SPU version of this class, which is simply a SPURS taskset.
		// On other multi-threaded platforms we initialize the CPU version of this class, hkCpuJobThreadPool, which creates a pool of threads
		// that run in exactly the same way.  On the PlayStation(R)3 we could also create a hkCpuJobThreadPool.  However, it is only
		// necessary (and advisable) to use one Havok PPU thread for maximum efficiency. In this case we simply use this main thread
		// for this purpose, and so do not create a hkCpuJobThreadPool.
		// Get the number of physical threads available on the system
		//hkHardwareInfo m_hardwareInfo;
		hkGetHardwareInfo(m_hardwareInfo);
		m_iTotalNumThreadsUsed = m_hardwareInfo.m_numThreads;

		// We use one less than this for our thread pool, because we must also use this thread for our simulation
		//hkCpuJobThreadPoolCinfo m_threadPoolCinfo;
		m_threadPoolCinfo.m_numThreads = m_iTotalNumThreadsUsed - 1;

		//RDS_PREVDEFINITIONS this line is from previous HavokWrapper
		//m_threadPoolCinfo.m_allocateRuntimeMemoryBlocks = true;
		// This line enables timers collection, by allocating 200 Kb per thread.  If you leave this at its default (0),
		// timer collection will not be enabled.
		m_threadPoolCinfo.m_timerBufferPerThreadAllocation = 200000;
		m_pThreadPool = new hkCpuJobThreadPool( m_threadPoolCinfo );

		// We also need to create a Job queue. This job queue will be used by all Havok modules to run multithreaded work.
		// Here we only use it for physics.
		m_jobQueuInfo.m_jobQueueHwSetup.m_numCpuThreads = m_iTotalNumThreadsUsed;
		m_pJobQueue = new hkJobQueue(m_jobQueuInfo);

		//
		// Enable monitors for this thread.
		//

		// Monitors have been enabled for thread pool threads already (see above comment).
		hkMonitorStream::getInstance().resize(200000);
	}

	{// <PHYSICS-ONLY>: Create the physics world.			
		// At this point you would initialize any other Havok modules you are using.
		// The world cinfo contains global simulation parameters, including gravity, solver settings etc.

		// Set the simulation type of the world to multi-threaded.
		m_worldInfo.m_simulationType = hkpWorldCinfo::SIMULATION_TYPE_MULTITHREADED;

		// Flag objects that fall "out of the world" to be automatically removed - just necessary for this physics scene
		// In other words, objects that fall "out of the world" will be automatically removed
		m_worldInfo.m_broadPhaseBorderBehaviour = hkpWorldCinfo::BROADPHASE_BORDER_REMOVE_ENTITY;
	
		//RDS_HARDCODED values here --> just for me to see if I can make this part better
		//standard gravity settings, collision tolerance and world size 
		m_worldInfo.m_gravity.set(0,-9.8f,0);
		//I do not know what the next line does. For this demo it doesnt change anything if/if not having this line enabled
		//m_worldInfo.setupSolverInfo(hkpWorldCinfo::SOLVER_TYPE_8ITERS_MEDIUM);
		m_worldInfo.m_collisionTolerance = 0.1f;
		//This will effect the removal of objects when they fall out of the world.
		//If you have BROADPHASE_BORDER_REMOVE_ENTITY then your entities will be removed from Havok according to this number you set
		m_worldInfo.setBroadPhaseWorldSize(5000.0f);

		//initialize world with created info
		m_pPhysicsWorld = new hkpWorld(m_worldInfo);

		// RDS_PREVDEFINITIONS this line is from another HavokWrapper. Helps when using VisualDebugger
		// Disable deactivation, so that you can view timers in the VDB. This should not be done in your game.
		m_pPhysicsWorld->m_wantDeactivation = false;


		// When the simulation type is SIMULATION_TYPE_MULTITHREADED, in the debug build, the sdk performs checks
		// to make sure only one thread is modifying the world at once to prevent multithreaded bugs. Each thread
		// must call markForRead / markForWrite before it modifies the world to enable these checks.
		m_pPhysicsWorld->markForWrite();

		// Register all collision agents, even though only box - box will be used in this particular example.
		// It's important to register collision agents before adding any entities to the world.
		hkpAgentRegisterUtil::registerAllAgents( m_pPhysicsWorld->getCollisionDispatcher() );

		// We need to register all modules we will be running multi-threaded with the job queue
		m_pPhysicsWorld->registerWithJobQueue( m_pJobQueue );

		// Now we have finished modifying the world, release our write marker.
		m_pPhysicsWorld->unmarkForWrite();
	}

	{//RDS Begin --> you can use such a way to enable VisualDebugger
	 //so that you  do not need commenting out some lines all the time you change it
		#ifdef HAVOK_VISUAL_DEBUGGER_ENABLED
			registerVisualDebugger();
		#endif	
	}//RDS End
}