Exemplo n.º 1
0
moveContext *
initMove()
{
   moveContext *context = NULL;
   Spurs *spurs;
   gemAttribute gem_attr;
   int ret;
   int i;

   spurs = initSpurs ("gem_spurs");

   if (spurs == NULL)
     goto error;

   printf ("preparing GemAttribute structure with spurs\n");

   gem_attr.version = 2;
   gem_attr.max = 1;
   gem_attr.spurs = spurs;
   gem_attr.memory = NULL;
   gem_attr.spu_priorities[0] = 1;
   for (i = 1; i < 8; ++i)
     gem_attr.spu_priorities[i] = 0;

   printf ("calling GemInit with GemAttribute structure version=%d max_connect=%d spurs=%X\n",
           gem_attr.version, gem_attr.max, gem_attr.spurs);
   ret = gemInit (&gem_attr);
   printf ("return from GemInit %X \n", ret);
   if (ret)
     goto error;

   ret = gemPrepareCamera (128, 0.5);
   printf ("GemPrepareCamera return %d exposure set to 128 and quality to 0.5\n",
           ret);
   if (ret)
     goto error;
   ret = gemReset (0);
   printf ("GemReset return %X \n", ret);
   if (ret)
     goto error;

   context = (moveContext *)malloc (sizeof (moveContext));
   context->spurs = spurs;
   ret = initCamera (context);

   if (ret == 0)
     return context;

error:
   if (spurs)
     endSpurs (spurs);
   if (context)
     free (context);
   return NULL;
}
Exemplo n.º 2
0
int
initGem ()
{
  int ret;
  int i;

  initSpurs ();

  ret = gemGetMemorySize (1);
  printf
      ("return from GemGetMemorySize %X size in bytes needed for move device to init libgem\n",
      ret);
  gem_memory = malloc (ret);

  printf
      ("preparing GemAttribute structure with sprus and memory stuff is very important align correctly spurs structure \n");
  u8 gem_spu_priorities[8] = { 1, 1, 1, 1, 1, 0, 0, 0 };	// execute
								// libgem jobs
								// on 5 spu
  gemAttribute gem_attr;

  initAttributeGem (&gem_attr, 1, gem_memory, spurs, gem_spu_priorities);

  printf
      ("calling GemInit with GemAttribute structure version=%d max_connect=%d spurs=%X memory_ptr=%X  \n",
      gem_attr.version, gem_attr.max, gem_attr.spurs, gem_attr.memory);
  ret = gemInit (&gem_attr);
  printf ("return from GemInit %X \n", ret);
  ret= initGemVideoConvert();
  printf ("return from initGemVideoConvert %X \n", ret);
  ret = gemPrepareCamera (128, 0.5);
  printf ("GemPrepareCamera return %d exposure set to 128 and quality to 0.5\n",
      ret);
  ret = gemReset (0);
  printf ("GemReset return %X \n", ret);
  return ret;

}
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;
}