/Core/Dependencies/Engine/GameObjectManager.cpp
C++ | 1048 lines | 674 code | 162 blank | 212 comment | 97 complexity | 60a27d2cac4c7c93457df17e6bca82bf MD5 | raw file
- #include "StdAfx.h"
- #include "GameObjectManager.h"
- #include "GameObject.h"
- #ifdef HAVOK
- #include "HavokObject.h"
- #endif
- #ifdef PHYSX
- #include "PhysXObject.h"
- #include "PxTask.h"
- #ifdef PHYSX_APEX
- #include "NxApex.h"
- #include "GGEApexRenderResourceManager.h"
- #include "destructible/public/NxModuleDestructible.h"
- #include "clothing/public/NxModuleClothing.h"
- #include "clothing/public/NxClothingActor.h"
- #include <NxParamUtils.h>
- #endif
- #endif
- #include "AnimationManager.h"
- ///AI Agent Manager
- #include "..\AI\AIAgentManager.h"
- #include "AIWorldManager.h"
- using namespace std;
- ///This function is needed for memory initialization
- ///If you do not have it you can not initialize the Havok Memory system
- ///This function is called whenever an HK_ASSERT2() function finds a problem
- ///Look at GameObjectManager constructor for detailed information
- static void HK_CALL errorReport(const char* msg, void* userArgGivenToInit){
- GGETRACELOG("Havok Assertion Info = %s\n",msg);
- }
- /**********************************************GameObjectManagerDefinitionsSTART*********************************************/
- ///Destructor of the GameObjectManager
- GameObjectManager::~GameObjectManager()
- {
- //RDS_LOOK our game engine creates a game object manager even if it doesnt have havok in it
- //so this one is not called by the first screen but when we switch to different scene in the game
- //this function is called by the programmer in the GameScreen's Destroy() function
- //clear the memory y calling all the destructors of the gameObjects created
- int f_iActiveGameObjectCount = m_pGameObjectList.size();
- if (f_iActiveGameObjectCount>0) {//this check needs to be done
- for (list<GameObject*>::iterator i = m_pGameObjectList.begin(); i != m_pGameObjectList.end();i++)
- {
- GameObject* f_pTempGameObject = *i;
- delete(f_pTempGameObject);
- }
- }
- #ifdef HAVOK
- if (m_pPhysicsWorld) {
- m_pPhysicsWorld->markForWrite();
- m_pPhysicsWorld->removeReference();
- }
- if (m_bVisualDebuggerActive) {
- if (m_pVisualDebugger)
- m_pVisualDebugger->removeReference();
- if (m_pPhysicsContext)
- m_pPhysicsContext->removeReference();
- }
- if (m_pJobQueue)
- m_pJobQueue->~hkJobQueue();
- if (m_pThreadPool)
- m_pThreadPool->removeReference();
- m_pThreadPool = NULL;
- m_pJobQueue = NULL;
- m_pPhysicsWorld = NULL;
- m_pVisualDebugger = NULL;
- m_pPhysicsContext = NULL;
- #endif
- }
- ///GameObjectManager constructor.
- ///This function only initializes the memory needed by HavokPhysicsEngine
- GameObjectManager::GameObjectManager(){
- #ifdef PHYSX
- m_PhysXSDK = NULL;
- m_PhysXCooking = NULL;
- m_CpuDispatcher = NULL;
- recordMemoryAllocations = true;
- m_NbThreads = 1;
- #ifdef PHYSX_APEX
- m_GGEApexRender = new GGEApexRenderer();
- m_rewriteBuffers = false;
- #endif
- //this->CreateWorld(false);
- #endif
- #ifdef HAVOK
- //RDS_LOOK --> how much memory to allocate is needed to be asked to Havok Prof guys
- m_pMemoryRouter = hkMemoryInitUtil::initDefault(hkMallocAllocator::m_defaultMallocAllocator, hkMemorySystem::FrameInfo(500000));// Allocates 0.5MB of physics solver buffer.
- hkBaseSystem::init( m_pMemoryRouter, errorReport );//HAVOK_MEMORY_INITIALIZATION_LINE
- //Now set every member of the GameObjectManager instance to NULL. So that we can see if they have been initialized or not by checking "==NULL"
- m_pThreadPool = NULL;
- m_pJobQueue = NULL;
- m_pPhysicsWorld = NULL;
- m_pVisualDebugger = NULL;
- m_pPhysicsContext = NULL;
- m_bVisualDebuggerActive = false;
- this->CreateWorld(false);
- #endif
- m_bInitializationPeriod = true;
- m_aiAgentManager = new GamePipe::AIAgentManager();
- m_aiAgentManager->initialize();
- m_recastManager = new AIWorldManager();
- m_recastManager->initialize();
- }
- #ifdef PHYSX
- /*void ContactCallback::onContact(physx::PxContactPair & pair, physx::PxU32 events) {
- printf("COLLISSSSSSSSSSSSSSSSSSSSS");
- //if(events & physx::PxPairFlag::eNOTIFY_TOUCH_FOUND == 0) {
- // return;
- //}
- if(pair.actors[0]->userData == (void*)4 || pair.actors[1]->userData == (void*)4) {
- std::cout << "Hit with hoop detected" << std::endl;
- }
- if(pair.actors[0]->userData == (void*)6 || pair.actors[1]->userData == (void*)6) {
- std::cout << "Hit with ground detected" << std::endl;
- }
- }*/
- physx::PxFilterFlags PhysXFilterShader(
- physx::PxFilterObjectAttributes attributes0, physx::PxFilterData filterData0,
- physx::PxFilterObjectAttributes attributes1, physx::PxFilterData filterData1,
- physx::PxPairFlags& pairFlags, const void* constantBlock, physx::PxU32 constantBlockSize)
- {
- //printf("COLLISIONNNN");
- // let triggers through
- if(physx::PxFilterObjectIsTrigger(attributes0) || physx::PxFilterObjectIsTrigger(attributes1))
- {
- //printf("12345");
- pairFlags = physx::PxPairFlag::eTRIGGER_DEFAULT | physx::PxPairFlag::eNOTIFY_TOUCH_PERSISTS;
- return physx::PxFilterFlag::eDEFAULT;
- }
- // generate contacts for all that were not filtered above
- pairFlags = physx::PxPairFlag::eSWEPT_INTEGRATION_LINEAR;
- pairFlags |= physx::PxPairFlag::eCONTACT_DEFAULT | physx::PxPairFlag::eNOTIFY_TOUCH_FOUND;
- // trigger the contact callback for pairs (A,B) where
- // the filtermask of A contains the ID of B and vice versa.
- //if((filterData0.word0 & filterData1.word1) && (filterData1.word0 & filterData0.word1))
- // pairFlags |= physx::PxPairFlag::eNOTIFY_TOUCH_FOUND;
-
- return physx::PxFilterFlag::eDEFAULT;
- }
- void GameObjectManager::onConstraintBreak(physx::PxConstraintInfo* constraints, physx::PxU32 count){
- }
- void GameObjectManager::onWake(physx::PxActor** actors, physx::PxU32 count){
- }
- void GameObjectManager::onSleep(physx::PxActor** actors, physx::PxU32 count){
- }
- void GameObjectManager::onContact(const physx::PxContactPairHeader& pairHeader, const physx::PxContactPair* pairs, physx::PxU32 nbPairs)
- {
- }
- void GameObjectManager::onTrigger(physx::PxTriggerPair* pairs, physx::PxU32 count)
- {
- printf("onTrigger");
- bTrigger = true;
- for(physx::PxU32 i=0; i < count; i++)
- {
- if((&pairs[i].otherShape->getActor() == 0) && (&pairs[i].triggerShape->getActor() == 0))
- {
- //gTreasureFound = true;
-
- }
- }
- }
- void GameObjectManager::setTrigger(bool bt)
- {
- bTrigger = bt;
- }
- bool GameObjectManager::getTrigger()
- {
- return bTrigger;
- }
- void GameObjectManager::CreateWorld(bool f_bVisualDebuggerActive) {
- if(EnginePtr->GetPVDConnection() != NULL && EnginePtr->GetPVDConnection()->isConnected()){
- EnginePtr->GetPVDConnection()->disconnect();
- EnginePtr->GetPVDConnection()->release();
- }
-
- m_PhysXZoneManager = &physx::PxProfileZoneManager::createProfileZoneManager(EnginePtr->GetPhysXFoundation());
- if(!m_PhysXZoneManager){
- printf("createProfileZoneManager failed!");
- }
- m_PhysXSDK = PxCreatePhysics(PX_PHYSICS_VERSION, *EnginePtr->GetPhysXFoundation(), physx::PxTolerancesScale(), recordMemoryAllocations, m_PhysXZoneManager );
- //PxCreatePhysics(PX_PHYSICS_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback, physx::PxTolerancesScale(), recordMemoryAllocations);
-
- if(!m_PhysXSDK) {
- printf("PxCreatePhysics failed!");
- }
- if (!PxInitExtensions(*m_PhysXSDK)) {
- printf("PxInitExtensions failed!");
- }
- physx::PxCooking* m_PhysXCooking = PxCreateCooking(PX_PHYSICS_VERSION, *(EnginePtr->GetPhysXFoundation()), physx::PxCookingParams());
- if(!m_PhysXCooking) {
- printf("PxCreateCooking failed!");
- }
- physx::PxSimulationFilterShader gDefaultFilterShader = physx::PxDefaultSimulationFilterShader;
- physx::PxSceneDesc sceneDescC = m_PhysXSDK->getTolerancesScale();
- sceneDesc = &sceneDescC;
- sceneDesc->gravity = physx::PxVec3(0.0f, -9.81f, 0.0f);
- if(!sceneDesc->cpuDispatcher) {
- m_CpuDispatcher = physx::PxDefaultCpuDispatcherCreate(m_NbThreads);
- if(!m_CpuDispatcher)
- printf("PxDefaultCpuDispatcherCreate failed!");
- sceneDesc->cpuDispatcher = m_CpuDispatcher;
- }
- /*physx::pxtask::CudaContextManager *mCudaContextManager;
- physx::pxtask::CudaContextManagerDesc cudaContextManagerDesc;
- mCudaContextManager = physx::pxtask::createCudaContextManager(cudaContextManagerDesc, &m_PhysXSDK->getProfileZoneManager());
- if(!sceneDesc->gpuDispatcher && mCudaContextManager)
- {
- sceneDesc->gpuDispatcher = mCudaContextManager->getGpuDispatcher();
- }*/
- //ContactCallback contactCallback;
- //if(!sceneDesc.filterShader)
- //sceneDesc.filterShader = *gDefaultFilterShader;
- sceneDesc->filterShader = PhysXFilterShader;
- //sceneDesc->flags = physx::PxSceneFlag::eENABLE_SWEPT_INTEGRATION;
- //sceneDesc->sweepEpsilonDistance = 0.00001f;
- sceneDesc->simulationEventCallback = this;
- m_PhysXMaterial = m_PhysXSDK->createMaterial(0.5f, 0.5f, 0.4f); //static friction, dynamic friction, restitution
- if(!m_PhysXMaterial) {
- printf("createMaterial failed!");
- }
- m_PhysXScene = m_PhysXSDK->createScene(*sceneDesc);
- if (!m_PhysXScene)
- printf("createScene failed!");
- if (m_PhysXSDK->getPvdConnectionManager()) {
- physx::PxVisualDebuggerConnectionFlags connectionFlags = physx::PxVisualDebuggerExt::getAllConnectionFlags();
- EnginePtr->SetPVDConnection(m_PhysXSDK,connectionFlags);
- }
- #ifdef PHYSX_APEX
- static physx::PxDefaultErrorCallback gDefaultErrorCallback;
- m_ApexSDKDesc = new physx::apex::NxApexSDKDesc();
- m_ApexSDKDesc->physXSDK = m_PhysXSDK;
- m_ApexSDKDesc->cooking = m_PhysXCooking;
- m_ApexSDKDesc->outputStream = &gDefaultErrorCallback;
- //m_ApexSDKDesc->allocator = 0;
- //physx::apex::NxResourceCallback
- m_ApexSDKDesc->renderResourceManager = new GGEApexResourceManager();
- PX_ASSERT(m_ApexSDKDesc);
- m_ApexSDK = NxCreateApexSDK(*m_ApexSDKDesc);
- PX_ASSERT(m_ApexSDK);
- physx::apex::NxApexRenderDebug* apex_RenderDebug = m_ApexSDK->createApexRenderDebug(false,true);
- /*physx::PxMat44 pose;
- pose = physx::PxMat44::createIdentity();
- if(apex_RenderDebug){
- apex_RenderDebug->beginDrawGroup(pose);
- apex_RenderDebug->drawGrid(false,40);
- apex_RenderDebug->endDrawGroup();
- }*/
-
- m_ApexSceneDesc = new physx::apex::NxApexSceneDesc();
- m_ApexSceneDesc->scene = m_PhysXScene;
- m_ApexScene = m_ApexSDK->createScene(*m_ApexSceneDesc);
-
- //create destruction module
- m_apexDestructibleModule = static_cast<physx::apex::NxModuleDestructible*>(m_ApexSDK->createModule("Destructible"));
- NxParameterized::Interface* params = m_apexDestructibleModule->getDefaultModuleDesc();
- m_apexDestructibleModule->init(*params);
- //create cloth module
- m_apexClothModule = static_cast<physx::apex::NxModuleClothing*>(m_ApexSDK->createModule("Clothing"));
- if(m_apexClothModule != NULL){
- NxParameterized::Interface* clothDesc = m_apexClothModule->getDefaultModuleDesc();
- NxParameterized::setParamU32(*clothDesc,"maxNumCompartments",3);
- NxParameterized::setParamU32(*clothDesc,"maxUnusedPhysXResources",5);
- m_apexClothModule->init(*clothDesc);
- }
- //set up view and proj matricies
- Ogre::Camera* oCamera = EnginePtr->GetForemostGameScreen()->GetActiveCamera();
- physx::PxMat44 projMatrix;
- physx::PxMat44 viewMat;
- Ogre::Matrix4 ogProj = oCamera->getProjectionMatrix();
- Ogre::Matrix4 ogView = oCamera->getViewMatrix();
- for(int i = 0; i < 4; i++){
- for(int j = 0; j < 4; j++){
- projMatrix[i][j] = ogProj[i][j];
- viewMat[i][j] = ogView[i][j];
- }
- }
- int numproj = m_ApexScene->getNumProjMatrices();
- const physx::PxU32 viewIDlookAtRightHand = m_ApexScene->allocViewMatrix(physx::apex::ViewMatrixType::LOOK_AT_RH);
- const physx::PxU32 projIDperspectiveCubicRightHand = m_ApexScene->allocProjMatrix(physx::apex::ProjMatrixType::USER_CUSTOMIZED);
- m_ApexScene->setProjMatrix(projMatrix,projIDperspectiveCubicRightHand);
- m_ApexScene->setProjParams(0.1f, 10000.0f, 45.0f,EnginePtr->GetRenderWindow()->getWidth(),EnginePtr->GetRenderWindow()->getHeight(),projIDperspectiveCubicRightHand);
- m_ApexScene->setViewMatrix(viewMat,viewIDlookAtRightHand);
- m_ApexScene->setUseViewProjMatrix(viewIDlookAtRightHand,projIDperspectiveCubicRightHand);
- //Get APEX framework debug rendering parameters
- NxParameterized::Interface &dbgRenderParams = *m_ApexScene->getDebugRenderParams();
- //Get clothing debug rendering parameters
- NxParameterized::Interface &dbgRenderParamsClothing = *m_ApexScene->getModuleDebugRenderParams("Clothing");
- //Get Destruction debug rendering parameters
- NxParameterized::Interface &dbgRenderParamsDestruction = *m_ApexScene->getModuleDebugRenderParams("Destructible");
- /*NxParameterized::setParamBool(dbgRenderParams, "VISUALIZATION_ENABLE", true);
- NxParameterized::setParamF32(dbgRenderParams, "VISUALIZATION_SCALE", 1.0f);
- NxParameterized::setParamBool(dbgRenderParamsClothing,"VISUALIZE_CLOTHING_ACTOR",true);
- NxParameterized::setParamF32(dbgRenderParamsClothing, "VISUALIZE_CLOTHING_PHYSICS_MESH_WIRE", 0.9f);
- NxParameterized::setParamBool(dbgRenderParamsDestruction,"VISUALIZE_DESTRUCTIBLE_ACTOR",true);*/
- m_ApexActors = new m_apexActorStruct[25];
- m_ApexActorCount = 0;
- #endif
- }
- #endif
- void GameObjectManager::DeleteGameObjects()
- {
- int f_iActiveGameObjectCount = m_pGameObjectList.size();
- if (f_iActiveGameObjectCount>0) {//this check needs to be done
- for (list<GameObject*>::iterator i = m_pGameObjectList.begin(); i != m_pGameObjectList.end();i++)
- {
- GameObject* f_pTempGameObject = *i;
- /*GraphicsObject* graphicsObject = f_pTempGameObject->m_pGraphicsObject;
- if (graphicsObject)
- {
- Ogre::SceneNode* sceneNode = graphicsObject->m_pOgreSceneNode;
- Ogre::String entityNodeName = sceneNode->getName();;
- //sceneNode = sceneNode->getParentSceneNode();
- //sceneNode->detachObject(entityNodeName);
- //EnginePtr->GetForemostGameScreen()->GetDefaultSceneManager()->destroySceneNode(sceneNode);
- }*/
- delete(f_pTempGameObject);
- }
- }
- }
- #ifdef HAVOK
- ///This creates the Physics world for the user according to the values in the hkpWorldinfo
- ///The boolean parameter(f_bVisualDebuggerActive) is set to false as default
- void GameObjectManager::CreateWorld(bool f_bVisualDebuggerActive)
- {
- // Most of the comments are copied and pasted from ConsoleExampleMt.cpp of HavokDemos folder (2010 version)
- //RDS_HARDCODED
- ///This variable is set for being able to change the game running speed.
- m_fWorldStep = 1/60.0f;
- //a sanity check.if the world is already created do not create it again and again
- if (m_pPhysicsWorld==NULL)
- {// 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
- hkGetHardwareInfo(m_hardwareInfo);
- m_iTotalNumThreadsUsed = m_hardwareInfo.m_numThreads;
- m_threadPoolCinfo.m_numThreads = m_iTotalNumThreadsUsed - 1;// We use one less than this for our thread pool, because we must also use this thread for our simulation
- m_threadPoolCinfo.m_timerBufferPerThreadAllocation = 200000;// 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_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.-->I am not really sure what this means now RDS_LOOK
- hkMonitorStream::getInstance().resize(200000);// Monitors have been enabled for thread pool threads already (see above comment).
- // <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.
- m_worldInfo.m_simulationType = hkpWorldCinfo::SIMULATION_TYPE_MULTITHREADED;// Set the simulation type of the world to multi-threaded.
- // 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);
- m_pPhysicsWorld = new hkpWorld(m_worldInfo);//initialize world with created info
- // 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() );
- m_pPhysicsWorld->registerWithJobQueue( m_pJobQueue );// We need to register all modules we will be running multi-threaded with the job queue
- m_pPhysicsWorld->unmarkForWrite();// Now we have finished modifying the world, release our write marker.
- }
- if ((m_bVisualDebuggerActive==false)&&(f_bVisualDebuggerActive==true)&&(m_pVisualDebugger==NULL))
- {// Initialize the VDB
- m_bVisualDebuggerActive = true;
- // <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.
- {
- // 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.
- m_pPhysicsContext = new hkpPhysicsContext();// Create context for Visual Debugger
- hkpPhysicsContext::registerAllPhysicsProcesses(); //Reigster all the physics viewers
- m_pPhysicsWorld->markForWrite();//RDS for the following line to be able to have effect on m_pPhysicsWorld
- m_pPhysicsContext->addWorld(m_pPhysicsWorld); // add the physics world so the viewers can see it
- m_arrayPhysicsContext.pushBack(m_pPhysicsContext);
- m_pPhysicsWorld->unmarkForWrite();// Now we have finished modifying the world, release our write marker.
- }
- m_pVisualDebugger = new hkVisualDebugger(m_arrayPhysicsContext);//Create VDB instance
- m_pVisualDebugger->serve();
- }
- }
- #endif
- #ifdef PHYSX
- void GameObjectManager::SetVisualDebugger(bool f_bVisualDebuggerActive) {
- }
- #endif
- #ifdef HAVOK
- void GameObjectManager::SetVisualDebugger(bool f_bVisualDebuggerActive)
- {
- //if the VisualDebugger has not been initialized first initialise it
- if ((m_bVisualDebuggerActive==false)&&(f_bVisualDebuggerActive==true)&&(m_pVisualDebugger==NULL))
- {// Initialize the VDB
- m_bVisualDebuggerActive = true;
- // <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.
- {
- // 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.
- m_pPhysicsContext = new hkpPhysicsContext();// Create context for Visual Debugger
- hkpPhysicsContext::registerAllPhysicsProcesses(); //Reigster all the physics viewers
- m_pPhysicsWorld->markForWrite();//RDS for the following line to be able to have effect on m_pPhysicsWorld
- m_pPhysicsContext->addWorld(m_pPhysicsWorld); // add the physics world so the viewers can see it
- m_arrayPhysicsContext.pushBack(m_pPhysicsContext);
- m_pPhysicsWorld->unmarkForWrite();// Now we have finished modifying the world, release our write marker.
- }
- m_pVisualDebugger = new hkVisualDebugger(m_arrayPhysicsContext);//Create VDB instance
- m_pVisualDebugger->serve();
- }
- //if the visual debugger was already running and user wanted to just close the connection for some time
- //instead of clearing the content and deleting pointers just shutdown the connection
- if ((m_bVisualDebuggerActive)&&(f_bVisualDebuggerActive==false)) {
- if (m_pVisualDebugger)//just a sanity check
- m_pVisualDebugger->shutdown();
- }
- //if the user initialized the visualdebugger before and wants to reactivate the visual debugger for some purpose
- //this will be enough
- if ((m_bVisualDebuggerActive==false)&&(m_pVisualDebugger!=NULL)&&(f_bVisualDebuggerActive==true))
- {// Initialize the VDB back again if it was set to true
- m_bVisualDebuggerActive=true;
- m_pVisualDebugger->serve();
- }
- }
- #endif
- void GameObjectManager::RefreshGameObjectsList(bool fromGameEngine)
- {
- //delete the ones to be deleted
- int f_iToBeDeletedGameObjectCount = m_pGameObjectsToDeleteList.size();
- if (f_iToBeDeletedGameObjectCount>0)
- {
- if (m_bReachDeleteList || !fromGameEngine)
- {
- m_bReachDeleteList = false;
- for (list<GameObject*>::iterator i = m_pGameObjectsToDeleteList.begin(); i != m_pGameObjectsToDeleteList.end();i++)
- {
- GameObject* f_pTempGameObject = *i;
- m_pGameObjectList.remove(f_pTempGameObject);
- delete(f_pTempGameObject);
- }
- m_pGameObjectsToDeleteList.clear();
- m_bReachDeleteList = true;
- }
- }
- //add the ones to be added
- int f_iToBeAddedGameObjectCount = m_pGameObjectsToAddList.size();
- if (f_iToBeAddedGameObjectCount>0)
- {
- if (m_bReachAddList || !fromGameEngine)
- {
- m_bReachAddList=false;
- for (list<GameObject*>::iterator i = m_pGameObjectsToAddList.begin(); i != m_pGameObjectsToAddList.end();i++)
- {
- GameObject* f_pTempGameObject = *i;
- m_pGameObjectList.push_back(f_pTempGameObject);
- }
- m_pGameObjectsToAddList.clear();
- m_bReachAddList=true;
- }
- }
- }
- #ifdef PHYSX
- void GameObjectManager::UpdateWorld() {
- if (m_pPhysicsWorld==NULL)//if physics world is not created just return
- return;
- RefreshGameObjectsList();
- #ifdef PHYSX_APEX
-
- m_ApexScene->simulate(EnginePtr->GetDeltaTime());
-
- #else
- m_PhysXScene->simulate(EnginePtr->GetDeltaTime());
- m_PhysXScene->fetchResults(true);
- #endif
- if (m_pGameObjectList.begin() != m_pGameObjectList.end())
- {
- //update all the gameobjects
- for (list<GameObject*>::iterator i = m_pGameObjectList.begin(); i != m_pGameObjectList.end();i++)
- {
- GameObject* f_pTempGameObject = *i;
- if (!f_pTempGameObject->update()||!f_pTempGameObject->isActive())
- {
- if (m_bReachDeleteList)
- {
- m_pGameObjectsToDeleteList.push_back(f_pTempGameObject);
- }
- }
- }
- }
- #ifdef PHYSX_APEX
-
- //update the projection and view matricies this frame
- Ogre::Camera* oCamera = EnginePtr->GetForemostGameScreen()->GetActiveCamera();
- physx::PxMat44 projMatrix;
- physx::PxMat44 viewMat;
- Ogre::Matrix4 ogProj = oCamera->getProjectionMatrix();
- Ogre::Matrix4 ogView = oCamera->getViewMatrix();
- for(int i = 0; i < 4; i++){
- for(int j = 0; j < 4; j++){
- projMatrix[i][j] = ogProj[i][j];
- viewMat[i][j] = ogView[i][j];
- }
- }
- //static const physx::PxU32 viewIDlookAtRightHand = m_ApexScene->allocViewMatrix(physx::apex::ViewMatrixType::LOOK_AT_RH);
- //static const physx::PxU32 projIDperspectiveCubicRightHand = m_ApexScene->allocProjMatrix(physx::apex::ProjMatrixType::USER_CUSTOMIZED);
- m_ApexScene->setProjMatrix(projMatrix,0);
- m_ApexScene->setProjParams(0.1f, 10000.0f, 45.0f,EnginePtr->GetRenderWindow()->getWidth(),EnginePtr->GetRenderWindow()->getHeight(),0);
- m_ApexScene->setViewMatrix(viewMat,0);
- m_ApexScene->setUseViewProjMatrix(0,0);
- /*physx::apex::NxApexRenderableIterator* iter = m_ApexScene->createRenderableIterator();
- for( physx::apex::NxApexRenderable *r = iter->getFirst() ; r ; r = iter->getNext() ){
- GGEApexRenderer apexRenderer;
- apexRenderer.m_materialName = "lambert2";
- r->lockRenderResources();
- r->updateRenderResources(m_rewriteBuffers);
- r->dispatchRenderResources(apexRenderer);
- r->unlockRenderResources();
-
- }
- iter->release();*/
- //update all the apex actors in the array
- for(int i = 0; i < m_ApexActorCount; i++){
- GGEApexRenderer apexRenderer;
- apexRenderer.m_materialName = m_ApexActors[i].m_matName;
- switch(m_ApexActors[i].m_actortype)
- {
- //destructible object
- case(0):
- {
- physx::apex::NxDestructibleActor* destrcActor = (physx::apex::NxDestructibleActor*)(m_ApexActors[i].m_apexActor);
- destrcActor->lockRenderResources();
- destrcActor->updateRenderResources();
- destrcActor->dispatchRenderResources(apexRenderer);
- destrcActor->unlockRenderResources();
- break;
- }
- //cloth object
- case (1):
- {
- physx::apex::NxClothingActor* clothActor = (physx::apex::NxClothingActor*)(m_ApexActors[i].m_apexActor);
- clothActor->lockRenderResources();
- clothActor->updateRenderResources();
- clothActor->dispatchRenderResources(apexRenderer);
- clothActor->unlockRenderResources();
- break;
- }
- default:
- break;
- }
- }
- //update the apex scene
- GGEApexRenderer apexRenderer;
- apexRenderer.m_materialName = "lambert2";
- m_ApexScene->prepareRenderResourceContexts();
- m_ApexScene->lockRenderResources();
- m_ApexScene->updateRenderResources();
- m_ApexScene->dispatchRenderResources(apexRenderer);
- m_ApexScene->unlockRenderResources();
-
- physx::PxU32 errorState = 0;
- //call fetch results to finish the simulation for this frame
- m_ApexScene->fetchResults(true,&errorState);
-
- #endif
- }
- #endif
- #ifdef HAVOK
- ///This function should be called in the update loop of the gameScreen to update every object in the GameObjectList
- ///This function takes action according to the GameObjectType specified in each GameObject instance
- void GameObjectManager::UpdateWorld()
- {
- if (m_pPhysicsWorld==NULL)//if physics world is not created just return
- return;
- if (m_bInitializationPeriod)
- m_bInitializationPeriod=false;
- #ifdef GGE_PROFILER2
- float starttime;
- starttime= (float)GGE_Profiler2Ptr->m_pTimer2->getMicroseconds();
- GGE_Profiler2Ptr->SetPhysicsStartTime(starttime);
- #endif
- RefreshGameObjectsList();
- //if the frame per second gets less than 5 fps just iterate the havok world as if it is 5fps
- //this helps a lot in the initialization of the screen
- //EnginePtr->GetDeltaTime() can reach up to 18 which will iterate havok world 18 seconds for 1 frame
- m_fWorldStep = EnginePtr->GetDeltaTime();
- if (m_fWorldStep>1.0f/5.0f)
- m_fWorldStep=1.0f/5.0f;
- //unsigned long long f_iActiveGameObjectCount = m_pGameObjectList.size();
- if (m_pGameObjectList.begin() != m_pGameObjectList.end())
- {
- //update all the gameobjects
- for (list<GameObject*>::iterator i = m_pGameObjectList.begin(); i != m_pGameObjectList.end();i++)
- {
- GameObject* f_pTempGameObject = *i;
- if (!f_pTempGameObject->isActive()||!f_pTempGameObject->update())
- {
- if (m_bReachDeleteList)
- {
- m_pGameObjectsToDeleteList.push_back(f_pTempGameObject);
- }
- }
- }
- //RDS_LOOK I do not know why these are here for any question dogasiyli@hotmail.com
- // Updating visual debugger should happen after all the updates in the world have occured
- if (m_bVisualDebuggerActive) {
- if (m_pPhysicsContext!=NULL)//NULL check is just a sanity check
- m_pPhysicsContext->syncTimers(m_pThreadPool);
- if (m_pVisualDebugger!=NULL)//NULL check is just a sanity check
- m_pVisualDebugger->step();
- }
- hkMonitorStream::getInstance().reset();
- m_pThreadPool->clearTimerData();
- }
- m_aiAgentManager->update(EnginePtr->GetDeltaTime());
- #ifdef GGE_PROFILER2
- float endtime;
- endtime = (float)GGE_Profiler2Ptr->m_pTimer2->getMicroseconds();
- GGE_Profiler2Ptr->SetPhysicsEndTime(endtime);
- #endif
- // XXX UPDATE THE PHYSICS WORLD LAST!
- // Random crashes can occur if you are dealing with many many havok objects otherwise.
- // Crashes still occur if too many TOI events happen between havok objects
- // YOU HAVE BEEN WARNED
- if (m_pPhysicsWorld!=NULL)
- m_pPhysicsWorld->stepMultithreaded(m_pJobQueue,m_pThreadPool,m_fWorldStep);
- }
- #endif
- #ifdef PHYSX
- void GameObjectManager::PushBackManager()
- {
- return;
- }
- void GameObjectManager::PopBackManager()
- {
- return;
- }
- #endif
- #ifdef HAVOK
- void GameObjectManager::PushBackManager()
- {
- if (m_bVisualDebuggerActive) {
- if (m_pVisualDebugger)
- m_pVisualDebugger->shutdown();
- }
- }
- void GameObjectManager::PopBackManager()
- {
- if ((m_bVisualDebuggerActive)&&(m_pVisualDebugger!=NULL))//NULL check is just a sanity check
- {// Initialize the VDB back again if it was set to true
- m_pVisualDebugger->serve();
- }
- }
- #endif
- ///Adds a GameObject to GameObjectManager list
- void GameObjectManager::AddGameObject(GameObject* f_pNewGameObject)
- {
- if (f_pNewGameObject==NULL)
- return;
- if (m_bInitializationPeriod)
- {
- m_pGameObjectList.push_back(f_pNewGameObject);
- if(f_pNewGameObject->m_eObjectType)
- {
- GGETRACELOG("Added ObjectType"); //1st check if Object type exists cuz of compatibility with old .scene file
- char str[10];
- _itoa_s(f_pNewGameObject->m_eObjectType,str,10);
- GGETRACELOG(str);
- }
- else
- {
- GGETRACELOG("Added Old Object");
- }
- if(f_pNewGameObject->m_eCollisionShapeType)
- {
- GGETRACELOG("Added CollisionShapeType");
- char str2[10];
- _itoa_s(f_pNewGameObject->m_eCollisionShapeType,str2,10);
- GGETRACELOG(str2);
- }
- else
- {
- GGETRACELOG("Added Old Object without collision shape type");
- }
- }
- else
- {
- //while (!m_bReachAddList);
- GGETRACELOG("Initialization Period false block");
- m_bReachAddList = false;
- m_pGameObjectsToAddList.push_back(f_pNewGameObject);
- m_bReachAddList = true;
- }
- }
- ///Deletes a GameObject from GameObjectManager list
- void GameObjectManager::RemoveGameObject(GameObject* f_pNewGameObject)
- {
- if ((m_pGameObjectList.size()<1)&&(f_pNewGameObject==NULL))
- return;
- if (this->HasGameObject(f_pNewGameObject->m_pGraphicsObject->m_sOgreUniqueName))
- {
- //while (!m_bReachDeleteList);
- m_bReachDeleteList = false;
- m_pGameObjectsToDeleteList.push_back(f_pNewGameObject);
- m_bReachDeleteList = true;
- }
- }
- int GameObjectManager::GetNumOfGameObjects()
- {
- if (m_pGameObjectList.size()<1)
- return 0;
- return m_pGameObjectList.size();
- }
- ///This function returns true if there is a GameObject with an entity that has the given name
- bool GameObjectManager::HasGameObject(Ogre::String f_sOgreUniqueName)
- {
- //RDS_IMPROVE Needs checking if it is doing sth incorrect
- //I think we should pass the OgreSceneManager and make sth like
- //return OgreSceneManager->hasEntity(f_sTempUniqueName);
- for (list<GameObject*>::iterator i = m_pGameObjectList.begin(); i != m_pGameObjectList.end(); i++)
- {
- GameObject* f_pTempGameObject = *i;
- if(f_pTempGameObject->m_pGraphicsObject != NULL)
- {
- if (f_pTempGameObject->m_pGraphicsObject->m_sOgreUniqueName.compare(f_sOgreUniqueName)==0)
- {
- return true;
- }
- }
- }
- return false;
- }
- ///This function returns the GameObject with an entity that has the given name, if no such GameObject exist it returns NULL
- GameObject* GameObjectManager::GetGameObject(Ogre::String f_sOgreUniqueName)
- {
- //RDS_IMPROVE Needs checking if it is doing sth incorrect
- //I think we should pass the OgreSceneManager and make sth like
- //if (OgreSceneManager->hasEntity(f_sTempUniqueName))
- // return OgreSceneManager->getEntity(f_sTempUniqueName);
- //return NULL;
- for (list<GameObject*>::iterator i = m_pGameObjectList.begin(); i != m_pGameObjectList.end(); i++)
- {
- GameObject* f_pTempGameObject = *i;
- if(f_pTempGameObject->m_pGraphicsObject != NULL)
- {
- if (f_pTempGameObject->m_pGraphicsObject->m_sOgreUniqueName.compare(f_sOgreUniqueName)==0)
- {
- return f_pTempGameObject;
- }
- }
- }
- return NULL;
- }
- #ifdef HAVOK
- ///This Function returns the created hkpWorld
- hkpWorld* GameObjectManager::GetWorld(){return m_pPhysicsWorld;}
- #endif
- #ifdef PHYSX
- physx::PxPhysics* GameObjectManager::GetPhysXWorld(){
- return m_PhysXSDK;
- }
- physx::PxScene* GameObjectManager::GetPhysXScene() {
- return m_PhysXScene;
- }
- physx::PxCooking* GameObjectManager::GetPhysXCooking() {
- return m_PhysXCooking;
- }
- physx::PxSceneDesc* GameObjectManager::GetPhysXDesc()
- {
- return sceneDesc;
- }
- physx::PxProfileZoneManager* GameObjectManager::GetPhysXZoneManager(){
- return m_PhysXZoneManager;
- }
- #ifdef PHYSX_APEX
- physx::apex::NxApexSDK* GameObjectManager::GetApexSDK(){
- return m_ApexSDK;
- }
- physx::apex::NxApexSDKDesc* GameObjectManager::GetApexSDKDesc(){
- return m_ApexSDKDesc;
- }
- physx::apex::NxApexScene* GameObjectManager::GetApexScene(){
- return m_ApexScene;
- }
- physx::apex::NxApexSceneDesc* GameObjectManager::GetApexSceneDesc(){
- return m_ApexSceneDesc;
- }
- physx::apex::NxModuleDestructible* GameObjectManager::GetDestructibleModule(){
- return m_apexDestructibleModule;
- }
- GGEApexRenderer* GameObjectManager::GetApexRender(){
- return m_GGEApexRender;
- }
- void GameObjectManager::AddApexActor(physx::apex::NxApexActor* actor,std::string mat,int actortype){
- if(m_ApexActorCount < 25){
- m_ApexActors[m_ApexActorCount].m_apexActor = actor;
- m_ApexActors[m_ApexActorCount].m_matName = mat;
- m_ApexActors[m_ApexActorCount].m_actortype = actortype;
- m_ApexActorCount++;
- }
- }
- #endif
- #endif
- GamePipe::AIAgentManager* GameObjectManager::getAIAgentManager()
- {
- return m_aiAgentManager;
- };
- AIWorldManager* GameObjectManager::getAIWorldManager()
- {
- return m_recastManager;
- };
- #ifdef HAVOK
- ///This function casts a ray from a point to the other and sets the pointer variables according to the closest hit
- bool GameObjectManager::castRay( Ogre::Vector3 f_vCastFrom,
- Ogre::Vector3 f_vCastTo,
- hkpRigidBody** f_pFirstCollidedRigidBody,
- GameObject** f_pCollidedGameObject,
- Ogre::Vector3* f_vReturnCollisionPoint
- )
- {
- hkpWorldRayCastInput input;
- input.m_from.set(f_vCastFrom.x, f_vCastFrom.y, f_vCastFrom.z);
- input.m_to.set( f_vCastTo.x, f_vCastTo.y, f_vCastTo.z);
- hkpClosestRayHitCollector output;
- m_pPhysicsWorld->castRay(input, output );
- // These comments are from HavokDemos_2010
- // To visualise the raycast we make use of a macro defined in "hkDebugDisplay.h" called HK_DISPLAY_LINE.
- // The macro takes three parameters: a start point, an end point and the line color.
- // If a hit is found we display a RED line from the raycast start point to the point of intersection and mark that
- // point with a small RED cross. The intersection point is calculated using: startWorld + (result.m_mindist * endWorld).
- //
- // If no hit is found we simply display a GREY line between the raycast start and end points.
- if( output.hasHit() )
- {
- hkVector4 intersectionPointWorld;
- intersectionPointWorld.setInterpolate4( input.m_from, input.m_to, output.getHit().m_hitFraction );
- //now lets store the collision point to send back to who ever called the function
- hkReal f_fIntersectionPoint[3];
- intersectionPointWorld.store3(f_fIntersectionPoint);
- *f_vReturnCollisionPoint = Ogre::Vector3(f_fIntersectionPoint[0],f_fIntersectionPoint[1],f_fIntersectionPoint[2]);
- //some helper lines for visual debugger
- HK_DISPLAY_LINE( input.m_from, intersectionPointWorld, hkColor::RED);
- HK_DISPLAY_ARROW( intersectionPointWorld, output.getHit().m_normal, hkColor::CYAN);
- //get the rigidBody pointer of the collidable (in other words owner of the root collidable)
- //by this line we will also send the collided rigidBody pointer to the function caller
- (*f_pFirstCollidedRigidBody) = (hkpRigidBody *)(output.getHit().m_rootCollidable->getOwner());
- //Now check if the rigidBody has a collision listener.
- //If it has a collisionlistener we can also send the GameObject pointer back to the function caller too
- if ((*f_pFirstCollidedRigidBody)->getContactListeners().getSize()>0)
- {
- //if we are here it means the rigidbody has a collision listener
- //so we are gonna grab it, but we will just grab the first one because normally 1 gameObject should have 1 collision listener
- //this assumption should be correct because I create collision listeners for gameObjects and I only have 1 to 1 attachment
- CollisionListener* f_pOtherGameObjectListener = (CollisionListener*)((*f_pFirstCollidedRigidBody)->getContactListeners()[0]);
- //Now get the pointer and set it to the passed parameter so that we are sending back the pointer of the collided gameObject
- *f_pCollidedGameObject = f_pOtherGameObjectListener->m_pGameObject;
- }
- return true;
- }
- else
- {
- // Otherwise draw as GREY
- HK_DISPLAY_LINE(input.m_from, input.m_to, hkColor::rgbFromChars(200, 200, 200));
- }
- return false;
- };
- #endif
- /***********************************************GameObjectManagerDefinitionsEND**********************************************/