コード例 #1
0
ファイル: GHavok.cpp プロジェクト: Jerdak/OgreHavokTest
/*
void GHavok::Step(double dt){
	_dCurrentTime += dt;

	if(_dCurrentTime >= _dPhysicsTimeThresh){
		// This must be called single threaded here, prior to calling startStepWorld() below.
		physicsWorld->resetThreadTokens();

		// This will signal all threads which are in the wait state, to start processing stepDeltaTime() concurrently.
		multithreadingUtil->startStepWorld( _currentTime );

		// We can now do other things in this thread if we wish, while the physics runs in separate threads.
		// The call below will block until all physics processing the timestep is finished in all threads.
		multithreadingUtil->waitForStepWorldFinished();

		stepVisualDebugger( _hkVis, _multithreadingUtil, _context );

		//Get physics ball position
		hkVector4 pos = _hkSphere->getPosition();

		//Apply ball position to ogrenode
		_ogreScene->setPosition(pos(0),pos(1)+0.05f,pos(2));

		_dCurrentTime = 0.0f;
	}
}*/
void GHavok::DestroyHavok() {
    WriteToLog("Destroying havok environment...");

    _physicsWorld->markForWrite();
    _physicsWorld->removeReference();

    delete _multithreadingUtil;

    _hkVis->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();

    // Deallocate stack area
    _threadMemory->setStackArea(0, 0);
    hkDeallocate(_stackBuffer);
    WriteToLog("Complete\n");

    //Deallocate runtime blocks
    hkMemory::getInstance().freeRuntimeBlocks();

    _bCreated = false;
    _nThreads = 0;
    _bThreaded = false;
}
コード例 #2
0
hkDemoFileSystem::~hkDemoFileSystem()
{
	m_parent->removeReference();
	for( int i = 0; i < m_locations.getSize(); ++i )
	{
		hkDeallocate( m_locations[i] );
	}
}
コード例 #3
0
ObjectsOnLandscapeDemo::~ObjectsOnLandscapeDemo()
{
	// Delete the world before removing reference to the packfile data
	if(m_world)
	{
		m_world->markForWrite();
		m_world->removeReference();
		m_world = HK_NULL;
	}

	if (m_packfileData)
		m_packfileData->removeReference();

	hkDeallocate( m_stackBuffer );
	hkThreadMemory::getInstance().setStackArea( m_oldStack.m_current, m_oldStack.getFreeBytes() );
}
コード例 #4
0
RayTraceDemo::~RayTraceDemo()
{
	// Re-enable warnings:									
	hkError::getInstance().setEnabled(0x7dd65995, true); 

	hkReferencedObject::lockAll();
	hkAlignedDeallocate<unsigned char>(m_canvasData);
	m_world->markForWrite();
	m_world->removeReference();
	m_world = HK_NULL;
	m_shape->removeReference();
	m_context->lock();
	m_texture->free();
	m_texture->release();
	m_context->unlock();

	hkReferencedObject::unlockAll();
	hkDeallocate( m_stackBuffer );
	hkThreadMemory::getInstance().setStackArea( m_oldStack.m_current, m_oldStack.getFreeBytes() );
}
コード例 #5
0
void Havok::Close()
{
/*	if(0)
	{
		udword Size = mRigidBodies.size();
		for(udword i=0;i<Size;i++)
		{
			hkpRigidBody* rb = mRigidBodies[i];
			DELETESINGLE(rb);
		}
	}*/

	{
		mPhysicsWorld->lock();
		const udword Size = mPhantoms.GetNbEntries();
		for(udword i=0;i<Size;i++)
		{
			hkpAabbPhantom* phantom = (hkpAabbPhantom*)mPhantoms[i];
			phantom->removeReference();
		}
		mPhysicsWorld->unlock();
	}

	// <PHYSICS-ONLY>: cleanup physics
	{
		mPhysicsWorld->markForWrite();
		mPhysicsWorld->removeReference();
		mPhysicsWorld = null;
	}

	{
		if(mVdb)
		{
			mVdb->removeReference();
			mVdb = null;
		}

		// 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.
		if(mContext)
		{
			mContext->removeReference();
			mContext = null;
		}
	}

	{
		DELETESINGLE(mJobQueue);

		//
		// Clean up the thread pool
		//

		if(mThreadPool)
		{
			mThreadPool->removeReference();
			mThreadPool = null;
		}
	}

	// Deallocate stack area
//	mThreadMemory->setStackArea(0, 0);
	hkDeallocate(mStackBuffer);
	mStackBuffer = null;

//	mThreadMemory->removeReference();
//	mThreadMemory = null;
	mMemoryRouter = null;

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

//	DELETESINGLE(gMemoryManager);
//	gMemoryManager = null;
	hkMemoryInitUtil::quit();
}
コード例 #6
0
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;
}