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); }
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."); }
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; }
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 }