//void createRaycastThreads() void createRaycastThreads() { //// Create and start threads that will perform raycasts. //// Create a sync for each thread so that a signal may be sent //// from the main thread to the raycast thread that it can start //// performing raycasts. //for (PxU32 i=0; i < gNumThreads; ++i) for (uint i = 0; i < gNumThreads; ++i) { gThreads[i] = new RaycastThread(); ////Create a sync. //gThreads[i].mWorkReadySyncHandle = SnippetUtils::syncCreate(); gThreads[i].mWorkReadySyncHandle = new EventWaitHandle(false, EventResetMode.ManualReset); ////Create and start a thread. //gThreads[i].mThreadHandle = SnippetUtils::threadCreate(threadExecute, &gThreads[i]); gThreads[i].mThreadHandle = new Thread(threadExecute); gThreads[i].mThreadHandle.Start(gThreads[i]); } //// Create another sync so that the raycast threads can signal to the main //// thread that they have finished performing their raycasts. //gWorkDoneSyncHandle = SnippetUtils::syncCreate(); gWorkDoneSyncHandle = new EventWaitHandle(false, EventResetMode.ManualReset); }
//static void threadExecute(void* data) static unsafe void threadExecute(object data) { //RaycastThread* raycastThread = static_cast<RaycastThread*>(data); RaycastThread raycastThread = (RaycastThread)data; //// Perform random raycasts against the scene until stop. //for(;;) for (;;) { //// Wait here for the sync to be set then reset the sync //// to ensure that we only perform raycast work after the //// sync has been set again. //SnippetUtils::syncWait(raycastThread->mWorkReadySyncHandle); //SnippetUtils::syncReset(raycastThread->mWorkReadySyncHandle); raycastThread.mWorkReadySyncHandle.WaitOne(); raycastThread.mWorkReadySyncHandle.Reset(); //// If the thread has been signaled to quit then exit this function. //if (SnippetUtils::threadQuitIsSignalled(raycastThread->mThreadHandle)) // break; if (raycastThread.quit) { break; } //// Perform a fixed number of random raycasts against the scene //// and share the work between multiple threads. //while (SnippetUtils::atomicDecrement(&gRaysAvailable) >= 0) while (Interlocked.Decrement(ref gRaysAvailable) >= 0) { //PxVec3 dir = randVec3(); PxVec3 dir = randVec3(); //PxRaycastBuffer buf; //gScene->raycast(PxVec3(0.0f), dir.getNormalized(), 1000.0f, buf, PxHitFlag::eDEFAULT); PxRaycastBufferPtr buf = PxRaycastBufferPtr.New(); gScene.raycast(new PxVec3(0.0f), dir.getNormalized(), 1000f, buf, PxHitFlags.eDEFAULT); if (render_) { var rayNor = dir.getNormalized() * 1000; DebugRenderer.Current.AddLine(new Vector3(0), new Vector3(rayNor.x, rayNor.y, rayNor.z), 0xff00ffff); } buf.Free(); //// If this is the last raycast then signal this to the main thread. //if (SnippetUtils::atomicIncrement(&gRaysCompleted) == gRayCount) if (Interlocked.Increment(ref gRaysCompleted) == gRayCount) { // SnippetUtils::syncSet(gWorkDoneSyncHandle); gWorkDoneSyncHandle.Set(); } } } //// Quit the current thread. //SnippetUtils::threadQuit(raycastThread->mThreadHandle); }