bool PhysXCookingWrapper::CreateCooking(physx::PxU32 PXVersion, physx::PxFoundation& foundation, physx::PxCookingParams& parameters) { if(!CookingValid()) { cooking = PxCreateCooking(PXVersion, foundation, parameters); } return CookingValid(); }
//============================================================================= // PRIVATE FUNCTIONS //============================================================================= static physx::unique_ptr<PxConvexMesh> GenerateConvexFromDXMesh(PxPhysics &iPhysics, ID3DXMesh *iMesh) { //Used to retrieve information from X file struct Mesh_FVF { D3DXVECTOR3 VertexPos; D3DXVECTOR3 Normal; D3DXVECTOR2 TexCoord; }; int aNumVerticies = iMesh->GetNumVertices(); DWORD FVFSize = D3DXGetFVFVertexSize(iMesh->GetFVF()); //Create pointer for vertices PxVec3* verts = new PxVec3[aNumVerticies]; char *DXMeshPtr; iMesh->LockVertexBuffer(D3DLOCK_READONLY, (void**)&DXMeshPtr); for(int i = 0; i < aNumVerticies; i++) { Mesh_FVF *DXMeshFVF = (Mesh_FVF*)DXMeshPtr; verts[i] = PxVec3(DXMeshFVF->VertexPos.x, DXMeshFVF->VertexPos.y, DXMeshFVF->VertexPos.z); DXMeshPtr += FVFSize; } iMesh->UnlockVertexBuffer(); // Create descriptor for convex mesh PxConvexMeshDesc convexDesc; convexDesc.points.count = aNumVerticies; convexDesc.points.stride = sizeof(PxVec3); convexDesc.points.data = verts; convexDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX; PxTolerancesScale toleranceScale; toleranceScale.length = 1.0f; toleranceScale.mass = 1000.0f; toleranceScale.speed = 9.8f; assert(toleranceScale.isValid()); physx::unique_ptr<PxCooking> cooker = physx::unique_ptr<PxCooking>( PxCreateCooking(PX_PHYSICS_VERSION, iPhysics.getFoundation(), PxCookingParams(toleranceScale)) ); // Cooking from memory MemoryStream buf; physx::unique_ptr<PxConvexMesh> convexMesh; if(cooker->cookConvexMesh(convexDesc, buf)) { convexMesh = physx::unique_ptr<PxConvexMesh>(iPhysics.createConvexMesh(buf)); } delete[] verts; return convexMesh; }
PxCooking* getDefaultCooking( PxFoundation* foundation ) { PxTolerancesScale scale = PxTolerancesScale(); PxCookingParams params( scale ); // disable mesh cleaning - perform mesh validation on development configurations params.meshPreprocessParams |= PxMeshPreprocessingFlag::eDISABLE_CLEAN_MESH; // disable edge precompute, edges are set for each triangle, slows contact generation //params.meshPreprocessParams |= PxMeshPreprocessingFlag::eDISABLE_ACTIVE_EDGES_PRECOMPUTE; // lower hierarchy for internal mesh params.meshCookingHint = PxMeshCookingHint::eCOOKING_PERFORMANCE; return PxCreateCooking( PX_PHYSICS_VERSION, *foundation, params ); }
/** * Method is used to initialize physics manager, init PhysX extensions and cooking objects. */ void PhysicsManager::initializePhysicsManager() { if(!PxInitExtensions(*physicsSDK)) Logger::getInstance()->saveLog(Log<string>("Physics Extensions initialization error occurred!")); PxFoundation& foundation = physicsSDK->getFoundation(); cooking = PxCreateCooking(PX_PHYSICS_VERSION, &foundation, PxCookingParams()); if(!cooking) Logger::getInstance()->saveLog(Log<string>("Physics Cooking creation error occurred!")); defaultFilterShader = filterShader; initializeScene(); addPhysicsMaterial("Default",Vector3D(0.5,0.5,0.0)); //PxExtensionVisualDebugger::connect(physicsSDK->getPvdConnectionManager(),"localhost",5425, 10000, true); }
void phx::app::base::init() { neb::app::base::init(); // Physx // Foundation px_foundation_ = PxCreateFoundation( PX_PHYSICS_VERSION, px_default_allocator_callback_, px_default_error_callback_); assert(px_foundation_); bool recordMemoryAllocations = true; // Profile Zone Manager px_profile_zone_manager_ = &::physx::PxProfileZoneManager::createProfileZoneManager( px_foundation_ ); assert( px_profile_zone_manager_ ); // Physics px_physics_ = PxCreatePhysics( PX_PHYSICS_VERSION, *px_foundation_, physx::PxTolerancesScale(), recordMemoryAllocations, px_profile_zone_manager_ ); assert( px_physics_ ); // cooking /** @todo fix cooking signature */ auto scales = physx::PxTolerancesScale(); px_cooking_ = PxCreateCooking( PX_PHYSICS_VERSION, *px_foundation_, ::physx::PxCookingParams(scales) ); assert( px_cooking_ ); // Extensions assert( PxInitExtensions( *px_physics_ ) ); // character controller manager /** @todo fix cooking signature */ /* px_character_controller_manager_ = ::PxCreateControllerManager( *px_foundation_ ); assert( px_character_controller_manager_ );*/ // vehicle assert( PxInitVehicleSDK(*px_physics_) ); PxVehicleSetBasisVectors(physx::PxVec3(0,1,0), physx::PxVec3(0,0,-1)); PxVehicleSetUpdateMode(physx::PxVehicleUpdateMode::Enum::eACCELERATION); }
bool PhysicsSystemImpl::create() { m_physx_allocator = LUMIX_NEW(m_allocator, AssertNullAllocator); m_error_callback = LUMIX_NEW(m_allocator, CustomErrorCallback); m_foundation = PxCreateFoundation( PX_PHYSICS_VERSION, *m_physx_allocator, *m_error_callback ); m_physics = PxCreatePhysics( PX_PHYSICS_VERSION, *m_foundation, physx::PxTolerancesScale() ); physx::PxTolerancesScale scale; m_cooking = PxCreateCooking(PX_PHYSICS_VERSION, *m_foundation, physx::PxCookingParams(scale)); connect2VisualDebugger(); return true; }
bool PhysicsSystemImpl::create() { m_physx_allocator = m_allocator.newObject<AssertNullAllocator>(); m_error_callback = m_allocator.newObject<CustomErrorCallback>(); m_foundation = PxCreateFoundation( PX_PHYSICS_VERSION, *m_physx_allocator, *m_error_callback ); m_physics = PxCreatePhysics( PX_PHYSICS_VERSION, *m_foundation, physx::PxTolerancesScale() ); m_controller_manager = PxCreateControllerManager(*m_foundation); m_cooking = PxCreateCooking(PX_PHYSICS_VERSION, *m_foundation, physx::PxCookingParams()); connect2VisualDebugger(); return true; }
bool Apex::InitPhysX() { static PxDefaultErrorCallback gDefaultErrorCallback; static PxDefaultAllocator gDefaultAllocatorCallback; mFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback); if(!mFoundation) return false; bool recordMemoryAllocations = true; mPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *mFoundation, PxTolerancesScale(), recordMemoryAllocations); if(!mPhysics) return false; mCooking = PxCreateCooking(PX_PHYSICS_VERSION, *mFoundation, PxCookingParams()); if (!mCooking) return false; if (!PxInitExtensions(*mPhysics)) return false; //PxSceneDesc sceneDesc(mPhysics->getTolerancesScale()); //sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f); //if(!sceneDesc.cpuDispatcher) //{ // mCpuDispatcher = PxDefaultCpuDispatcherCreate(mNbThreads); // if(!mCpuDispatcher) // return false; // sceneDesc.cpuDispatcher = mCpuDispatcher; //} //if(!sceneDesc.filterShader) //{ // sceneDesc.filterShader = PxDefaultSimulationFilterShader; //} // ///*#ifdef PX_WINDOWS //if(!sceneDesc.gpuDispatcher && mCudaContextManager) //{ // sceneDesc.gpuDispatcher = mCudaContextManager->getGpuDispatcher(); //} //#*/ //mProfileZoneManager = &PxProfileZoneManager::createProfileZoneManager(mFoundation); //pxtask::CudaContextManagerDesc cudaContextManagerDesc; //mCudaContextManager = pxtask::createCudaContextManager(*mFoundation,cudaContextManagerDesc, mProfileZoneManager); //sceneDesc.gpuDispatcher = mCudaContextManager->getGpuDispatcher(); //mScene[mCurrentScene] = mPhysics->createScene(sceneDesc); //if (!mScene[mCurrentScene]) // return false; defaultMaterial = mPhysics->createMaterial(0.5f, 0.5f, 0.1f); //static friction, dynamic friction, restitution if(!defaultMaterial) return false; // Create a plane PxRigidStatic* plane = PxCreatePlane(*mPhysics, PxPlane(PxVec3(0,1,0), 700), *defaultMaterial); if (!plane) return false; //mScene[mCurrentScene]->addActor(*plane); // Create a heightfield PhysXHeightfield* heightfield = new PhysXHeightfield(); //heightfield->InitHeightfield(mPhysics, mScene[mCurrentScene], "terrain5.raw"); // check if PvdConnection manager is available on this platform if(mPhysics->getPvdConnectionManager() == NULL) { return true; } // setup connection parameters const char* pvd_host_ip = "127.0.0.1"; // IP of the PC which is running PVD int port = 5425; // TCP port to connect to, where PVD is listening unsigned int timeout = 100; // timeout in milliseconds to wait for PVD to respond, // consoles and remote PCs need a higher timeout. PxVisualDebuggerConnectionFlags connectionFlags = PxVisualDebuggerExt::getAllConnectionFlags(); // and now try to connect pvdConnection = PxVisualDebuggerExt::createConnection(mPhysics->getPvdConnectionManager(), pvd_host_ip, port, timeout, connectionFlags); mPhysics->getVisualDebugger()->setVisualDebuggerFlag(PxVisualDebuggerFlags::eTRANSMIT_CONTACTS, true); return true; }
void GameWorld::init() { gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback); if (!gFoundation) { printf("PxCreateFoundation failed!"); } gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(), true); if (!PxInitExtensions(*gPhysics)) { printf("init error pxinit\n"); } gCooking = PxCreateCooking(PX_PHYSICS_VERSION, *gFoundation, PxCookingParams(gPhysics->getTolerancesScale())); if (!gCooking) { printf("PxCreateCooking failed!\n"); } PxSceneDesc sceneDesc(gPhysics->getTolerancesScale()); sceneDesc.gravity = PxVec3(0.0f, -98.0f, 0.0f); gDispatcher = PxDefaultCpuDispatcherCreate(2); sceneDesc.cpuDispatcher = gDispatcher; sceneDesc.filterShader = PxDefaultSimulationFilterShader; gScene = gPhysics->createScene(sceneDesc); gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f); PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0, 0, 1, 400), *gMaterial); gScene->addActor(*groundPlane); groundPlane = PxCreatePlane(*gPhysics, PxPlane(0, 0, -1, 400), *gMaterial); gScene->addActor(*groundPlane); groundPlane = PxCreatePlane(*gPhysics, PxPlane(1, 0, 0, 280), *gMaterial); gScene->addActor(*groundPlane); groundPlane = PxCreatePlane(*gPhysics, PxPlane(-1, 0, 0, 280), *gMaterial); gScene->addActor(*groundPlane); groundPlane = PxCreatePlane(*gPhysics, PxPlane(0, -1, 0, 600), *gMaterial); gScene->addActor(*groundPlane); groundPlane = PxCreatePlane(*gPhysics, PxPlane(0, 1, 0, -1), *gMaterial); gScene->addActor(*groundPlane); gGround.loadFromObj(GROUND_FILE); gGround.cookingMesh(*gPhysics, *gCooking); gGround.createActor(*gMaterial, *gPhysics); gScene->addActor(*(gGround.actor)); //包围盒 box.loadFromObj(BOX_FILE); //初始化飞球 pxFlyBall = new PxFlyBall(Color4f(1.0, 200 / 255.0, 0), 5.0); Material mtl; PerlinImage perlinYellow = createPerlinLightYelloImage(40, 40, 6, 1.8); PerlinTexture(perlinYellow, mtl.kd_texid); mtl.ka = Color4f(1, 1, 1, 1); mtl.kd = Color4f(1, 1, 1, 1); mtl.ks = Color4f(1, 1, 1, 1); pxFlyBall->mtl = mtl; pxFlyBall->createPxBall(*gPhysics, PxTransform(PxVec3(rand() % 500 - 250, 100, rand() % 700 - 350)), *gMaterial); pxFlyBall->pxActor->setAngularDamping(0.5); perlinYellow.clear(); gScene->addActor(*(pxFlyBall->pxActor)); //初始化白球 pxControlBall = new PxControlBall(Color4f(1.0, 1.0, 1.0), 5.0); PerlinImage perlinGray = createPerlinGrayImage(40, 40, 6, 1.8); PerlinTexture(perlinGray, mtl.kd_texid); mtl.ka = Color4f(1, 1, 1, 1); mtl.kd = Color4f(1, 1, 1, 1); mtl.ks = Color4f(0, 0, 0, 0); pxControlBall->mtl = mtl; pxControlBall->createPxBall(*gPhysics, PxTransform(PxVec3(0, 50, 0)), *gMaterial); pxControlBall->pxActor->setAngularDamping(0.5); perlinGray.clear(); gScene->addActor(*(pxControlBall->pxActor)); GLfloat light1PosType[] = { -5.0,1.0,5.0,0.0 }; GLfloat whiteColor[] = { 1.0,1.0,1.0,1.0 }; GLfloat darkColor[] = { 0.4,0.4,0.4,1 }; GLfloat specColor[] = { 1,1,1,1 }; GLfloat lightColor[] = { 1,1,1,1 }; GLfloat globalAmbient[] = { 0.2,0.2,0.2,1.0 }; glLightModelfv(GL_LIGHT_MODEL_AMBIENT, globalAmbient); glLightfv(GL_LIGHT1, GL_AMBIENT, darkColor); glLightfv(GL_LIGHT1, GL_DIFFUSE, lightColor); glLightfv(GL_LIGHT1, GL_SPECULAR, specColor); glLightfv(GL_LIGHT1, GL_POSITION, light1PosType); }
//////// GAME-LEVEL RIGID BODY PHYSICS STUFF /////// void InitGamePhys() { #if WITH_BOX2D FPhysicsIntegration2D::InitializePhysics(); #endif #if WITH_PHYSX // Do nothing if SDK already exists if(GPhysXFoundation != NULL) { return; } // Make sure LoadPhysXModules(); // Create Foundation GPhysXAllocator = new FPhysXAllocator(); FPhysXErrorCallback* ErrorCallback = new FPhysXErrorCallback(); GPhysXFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, *GPhysXAllocator, *ErrorCallback); check(GPhysXFoundation); #if PHYSX_MEMORY_STATS // Want names of PhysX allocations GPhysXFoundation->setReportAllocationNames(true); #endif // Create profile manager GPhysXProfileZoneManager = &PxProfileZoneManager::createProfileZoneManager(GPhysXFoundation); check(GPhysXProfileZoneManager); // Create Physics PxTolerancesScale PScale; PScale.length = CVarToleranceScaleLength.GetValueOnGameThread(); PScale.mass = CVarTolerenceScaleMass.GetValueOnGameThread(); PScale.speed = CVarToleranceScaleSpeed.GetValueOnGameThread(); GPhysXSDK = PxCreatePhysics(PX_PHYSICS_VERSION, *GPhysXFoundation, PScale, false, GPhysXProfileZoneManager); check(GPhysXSDK); GPhysCommandHandler = new FPhysCommandHandler(); FCoreUObjectDelegates::PreGarbageCollect.AddRaw(GPhysCommandHandler, &FPhysCommandHandler::Flush); // Init Extensions PxInitExtensions(*GPhysXSDK); #if WITH_VEHICLE PxInitVehicleSDK(*GPhysXSDK); #endif //Turn on PhysX 3.3 unified height field collision detection. //This approach shares the collision detection code between meshes and height fields such that height fields behave identically to the equivalent terrain created as a mesh. //This approach facilitates mixing the use of height fields and meshes in the application with no tangible difference in collision behavior between the two approaches PxRegisterUnifiedHeightFields(*GPhysXSDK); #if WITH_PHYSICS_COOKING || WITH_RUNTIME_PHYSICS_COOKING // Create Cooking PxCookingParams PCookingParams(PScale); PCookingParams.meshWeldTolerance = 0.1f; // Weld to 1mm precision PCookingParams.meshPreprocessParams = PxMeshPreprocessingFlags(PxMeshPreprocessingFlag::eWELD_VERTICES | PxMeshPreprocessingFlag::eREMOVE_UNREFERENCED_VERTICES | PxMeshPreprocessingFlag::eREMOVE_DUPLICATED_TRIANGLES); PCookingParams.targetPlatform = PxPlatform::ePC; //PCookingParams.meshCookingHint = PxMeshCookingHint::eCOOKING_PERFORMANCE; //PCookingParams.meshSizePerformanceTradeOff = 0.0f; GPhysXCooking = PxCreateCooking(PX_PHYSICS_VERSION, *GPhysXFoundation, PCookingParams); check(GPhysXCooking); #endif #if WITH_APEX // Build the descriptor for the APEX SDK NxApexSDKDesc ApexDesc; ApexDesc.physXSDK = GPhysXSDK; // Pointer to the PhysXSDK ApexDesc.cooking = GPhysXCooking; // Pointer to the cooking library ApexDesc.renderResourceManager = &GApexNullRenderResourceManager; // We will not be using the APEX rendering API, so just use a dummy render resource manager ApexDesc.resourceCallback = &GApexResourceCallback; // The resource callback is how APEX asks the application to find assets when it needs them // Create the APEX SDK NxApexCreateError ErrorCode; GApexSDK = NxCreateApexSDK(ApexDesc, &ErrorCode); check(ErrorCode == APEX_CE_NO_ERROR); check(GApexSDK); #if APEX_STATICALLY_LINKED // We need to instantiate the module if we have statically linked them // Otherwise all createModule functions will fail instantiateModuleDestructible(); #if WITH_APEX_CLOTHING instantiateModuleClothing(); #endif #if WITH_APEX_LEGACY instantiateModuleLegacy(); #endif #endif // 1 legacy module for all in APEX 1.3 // Load the only 1 legacy module #if WITH_APEX_LEGACY GApexModuleLegacy = GApexSDK->createModule("Legacy"); check(GApexModuleLegacy); #endif // WITH_APEX_LEGACY // Load APEX Destruction module GApexModuleDestructible = static_cast<NxModuleDestructible*>(GApexSDK->createModule("Destructible")); check(GApexModuleDestructible); // Set Destructible module parameters NxParameterized::Interface* ModuleParams = GApexModuleDestructible->getDefaultModuleDesc(); // ModuleParams contains the default module descriptor, which may be modified here before calling the module init function GApexModuleDestructible->init(*ModuleParams); // Disabling dynamic LOD GApexModuleDestructible->setLODEnabled(false); // Set chunk report for fracture effect callbacks GApexModuleDestructible->setChunkReport(&GApexChunkReport); GApexModuleDestructible->setMaxDynamicChunkIslandCount((physx::PxU32)FMath::Max(CVarAPEXMaxDestructibleDynamicChunkIslandCount.GetValueOnGameThread(), 0)); GApexModuleDestructible->setMaxChunkCount((physx::PxU32)FMath::Max(CVarAPEXMaxDestructibleDynamicChunkCount.GetValueOnGameThread(), 0)); GApexModuleDestructible->setSortByBenefit(CVarAPEXSortDynamicChunksByBenefit.GetValueOnGameThread() != 0); GApexModuleDestructible->setChunkReportSendChunkStateEvents(true); // APEX 1.3 to preserve 1.2 behavior GApexModuleDestructible->setUseLegacyDamageRadiusSpread(true); GApexModuleDestructible->setUseLegacyChunkBoundsTesting(true); #if WITH_APEX_CLOTHING // Load APEX Clothing module GApexModuleClothing = static_cast<NxModuleClothing*>(GApexSDK->createModule("Clothing")); check(GApexModuleClothing); // Set Clothing module parameters ModuleParams = GApexModuleClothing->getDefaultModuleDesc(); // Can be tuned for switching between more memory and more spikes. NxParameterized::setParamU32(*ModuleParams, "maxUnusedPhysXResources", 5); // If true, let fetch results tasks run longer than the fetchResults call. // Setting to true could not ensure same finish timing with Physx simulation phase NxParameterized::setParamBool(*ModuleParams, "asyncFetchResults", false); // ModuleParams contains the default module descriptor, which may be modified here before calling the module init function GApexModuleClothing->init(*ModuleParams); #endif //WITH_APEX_CLOTHING #endif // #if WITH_APEX #endif // WITH_PHYSX }
void Gameplay::entityInit(Object * p) { // load config _config = new TiXmlDocument( "./cfg/config.xml" ); _config->LoadFile(); // read pitch shift option TiXmlElement* xmlSound = Gameplay::iGameplay->getConfigElement( "sound" ); assert( xmlSound ); int pitchShift; xmlSound->Attribute( "pitchShift", &pitchShift ); _pitchShiftIsEnabled = ( pitchShift != 0 ); // read cheats option TiXmlElement* details = Gameplay::iGameplay->getConfigElement( "details" ); assert( details ); int cheats; details->Attribute( "cheats", &cheats ); _cheatsEnabled = ( cheats != 0 ); // read free jumping mode int freemode; details->Attribute( "freemode", &freemode ); _freeModeIsEnabled = ( freemode != 0 ); // read meters / feet mode int units; details->Attribute( "units", &units ); _feetModeIsEnabled = ( units != 0 ); // setup random number generation getCore()->getRandToolkit()->setSeed( GetTickCount() ); // retrieve interfaces queryInterface( "Engine", &iEngine ); assert( iEngine ); queryInterface( "Gui", &iGui ); assert( iGui ); queryInterface( "Language", &iLanguage ); assert( iLanguage ); queryInterface( "Input", &iInput ); assert( iInput ); queryInterface( "Audio", &iAudio ); assert( iAudio ); if( !iAudio || !iInput || !iLanguage || !iGui || !iEngine ) { throw Exception( "One or more core modules are not found, so gameplay will Crash Right Now!" ); } // check language module if( wcscmp( iLanguage->getVersionString(), ::version.getVersionString() ) != 0 ) { // incompatible module? - show no localization data iLanguage->reset(); } getCore()->logMessage("Version: %ls (Clean)", ::version.getVersionString()); // create input device _inputDevice = iInput->createInputDevice(); createActionMap(); // create physics resources foundation = PxCreateFoundation(PX_PHYSICS_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback); gPhysicsSDK = PxCreatePhysics(PX_PHYSICS_VERSION, *foundation, PxTolerancesScale() ); pxCooking = PxCreateCooking(PX_PHYSICS_VERSION, *foundation, PxCookingParams(PxTolerancesScale())); PxInitExtensions(*gPhysicsSDK); //PHYSX3 //NxGetPhysicsSDK()->setParameter( NX_VISUALIZATION_SCALE, 100.0f ); //NxGetPhysicsSDK()->setParameter( NX_VISUALIZE_ACTOR_AXES, 1 ); //NxGetPhysicsSDK()->setParameter( NX_VISUALIZE_COLLISION_SHAPES, 1 ); //NxGetPhysicsSDK()->setParameter( NX_VISUALIZE_COLLISION_STATIC, 1 ); //NxGetPhysicsSDK()->setParameter( NX_VISUALIZE_COLLISION_DYNAMIC,1 ); // generate user community events from XML documents generateUserCommunityEvents(); // open index TiXmlDocument* index = new TiXmlDocument( "./usr/index.xml" ); index->LoadFile(); // enumerate career nodes TiXmlNode* child = index->FirstChild(); if( child ) do { if( child->Type() == TiXmlNode::ELEMENT && strcmp( child->Value(), "career" ) == 0 ) { _careers.push_back( new Career( static_cast<TiXmlElement*>( child ) ) ); } child = child->NextSibling(); } while( child != NULL ); // close index document delete index; // create career for LICENSED_CHAR #ifdef GAMEPLAY_EDITION_ATARI createLicensedCareer(); #endif // determine afterfx configuration TiXmlElement* video = getConfigElement( "video" ); assert( video ); int afterfx = 0; video->Attribute( "afterfx", &afterfx ); // create render target if( afterfx && iEngine->isPfxSupported( engine::pfxBloom ) && iEngine->isPfxSupported( engine::pfxMotionBlur ) ) { _renderTarget = new AfterFxRT(); } else { _renderTarget = new SimpleRT(); } // play menu music playSoundtrack( "./res/sounds/music/dirty_moleculas_execution.ogg" ); // evaluation protection #ifdef GAMEPLAY_EVALUATION_TIME SYSTEMTIME evaluationTime = GAMEPLAY_EVALUATION_TIME; SYSTEMTIME latestFileTime; if( getLatestFileTimeB( &latestFileTime ) ) { if( isGreaterTime( &latestFileTime, &evaluationTime ) ) { pushActivity( new Messagebox( Gameplay::iLanguage->getUnicodeString( 765 ) ) ); } else { // startup _preloaded = new Preloaded(); pushActivity( _preloaded ); } } #else // determine if licence is required to play game bool licenceIsRequired = false; #ifndef GAMEPLAY_EDITION_ND #ifndef GAMEPLAY_EDITION_ATARI #ifndef GAMEPLAY_EDITION_POLISH licenceIsRequired = false; #endif #endif #endif // startup _preloaded = new Preloaded(); pushActivity( _preloaded ); #endif }
bool Px3World::restartSDK( bool destroyOnly, Px3World *clientWorld, Px3World *serverWorld) { // If either the client or the server still exist // then we cannot reset the SDK. if ( clientWorld || serverWorld ) return false; if(smPvdConnection) smPvdConnection->release(); if(smCooking) smCooking->release(); if(smCpuDispatcher) smCpuDispatcher->release(); // Destroy the existing SDK. if ( gPhysics3SDK ) { PxCloseExtensions(); gPhysics3SDK->release(); } if(smErrorCallback) { SAFE_DELETE(smErrorCallback); } if(smFoundation) { smFoundation->release(); SAFE_DELETE(smErrorCallback); } // If we're not supposed to restart... return. if ( destroyOnly ) return true; bool memTrack = false; #ifdef TORQUE_DEBUG memTrack = true; #endif smErrorCallback = new Px3ConsoleStream; smFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, smMemoryAlloc, *smErrorCallback); smProfileZoneManager = &physx::PxProfileZoneManager::createProfileZoneManager(smFoundation); gPhysics3SDK = PxCreatePhysics(PX_PHYSICS_VERSION, *smFoundation, physx::PxTolerancesScale(),memTrack,smProfileZoneManager); if ( !gPhysics3SDK ) { Con::errorf( "PhysX3 failed to initialize!" ); Platform::messageBox( Con::getVariable( "$appName" ), avar("PhysX3 could not be started!\r\n"), MBOk, MIStop ); Platform::forceShutdown( -1 ); // We shouldn't get here, but this shuts up // source diagnostic tools. return false; } if(!PxInitExtensions(*gPhysics3SDK)) { Con::errorf( "PhysX3 failed to initialize extensions!" ); Platform::messageBox( Con::getVariable( "$appName" ), avar("PhysX3 could not be started!\r\n"), MBOk, MIStop ); Platform::forceShutdown( -1 ); return false; } smCooking = PxCreateCooking(PX_PHYSICS_VERSION, *smFoundation, physx::PxCookingParams(physx::PxTolerancesScale())); if(!smCooking) { Con::errorf( "PhysX3 failed to initialize cooking!" ); Platform::messageBox( Con::getVariable( "$appName" ), avar("PhysX3 could not be started!\r\n"), MBOk, MIStop ); Platform::forceShutdown( -1 ); return false; } #ifdef TORQUE_DEBUG physx::PxVisualDebuggerConnectionFlags connectionFlags(physx::PxVisualDebuggerExt::getAllConnectionFlags()); smPvdConnection = physx::PxVisualDebuggerExt::createConnection(gPhysics3SDK->getPvdConnectionManager(), "localhost", 5425, 100, connectionFlags); #endif return true; }
bool Optimizer:: dumpPhysXCookMesh(IGameNode* gameNode, const std::string& nodeName, int flag) { // 受缩放影响 GMatrix worldTM = gameNode->GetWorldTM(); Point3 scale = worldTM.Scaling(); // 世界矩阵的逆矩阵 GMatrix nodeInvWorldTM = gameNode->GetWorldTM().Inverse(); IGameObject* gameObject = gameNode->GetIGameObject(); IGameMesh* gameMesh = static_cast<IGameMesh*>(gameObject); gameMesh->InitializeData(); int numFaces = gameMesh->GetNumberOfFaces(); int numVertex = numFaces * 3; std::vector<physx::PxVec3> pxVertices; pxVertices.reserve(numVertex); oiram::IndexBuffer indexBuffer; indexBuffer.use32BitIndices = numVertex > 65535; indexBuffer.use32BitIndices ? indexBuffer.uiIndexBuffer.reserve(numVertex) : indexBuffer.usIndexBuffer.reserve(numVertex); for (int i = 0; i < numFaces; ++i) { FaceEx* face = gameMesh->GetFace(i); for (int v = 0; v < 3; ++v) { Point3 position = gameMesh->GetVertex(face->vert[v], false); position = position * nodeInvWorldTM; pxVertices.push_back(physx::PxVec3(position.x * scale.x, position.y * scale.y, position.z * scale.z)); if (indexBuffer.use32BitIndices) indexBuffer.uiIndexBuffer.push_back(static_cast<unsigned int>(indexBuffer.uiIndexBuffer.size())); else indexBuffer.usIndexBuffer.push_back(static_cast<unsigned short>(indexBuffer.usIndexBuffer.size())); } } gameNode->ReleaseIGameObject(); // 初始化physx对象 physx::PxDefaultAllocator s_defAlloc; PxOiramErrorCallback s_defErrCb; physx::PxFoundation* pFound = PxCreateFoundation(PX_PHYSICS_VERSION, s_defAlloc, s_defErrCb); physx::PxCooking* pCooking = PxCreateCooking(PX_PHYSICS_VERSION, *pFound, physx::PxCookingParams()); // 优化物理模型顶点 optimizePhysXMesh(flag, mD3DDevice, mEpsilon, pxVertices, indexBuffer); bool success = false; PxCookMesh cookMesh; switch (flag) { // cookConvexMesh case 1: default: { physx::PxConvexMeshDesc meshDesc; meshDesc.points.data = pxVertices.data(); meshDesc.points.count = static_cast<physx::PxU32>(pxVertices.size()); meshDesc.points.stride = sizeof(physx::PxVec3); meshDesc.flags = physx::PxConvexFlag::eCOMPUTE_CONVEX; // 先尝试导出 success = meshDesc.isValid() && pCooking->cookConvexMesh(meshDesc, cookMesh); if (!success) { // polygon数量大于255的时候需要加上eINFLATE_CONVEX meshDesc.flags |= physx::PxConvexFlag::eINFLATE_CONVEX; success = meshDesc.isValid() && pCooking->cookConvexMesh(meshDesc, cookMesh); } } break; // cookTriangleMesh case 2: { physx::PxTriangleMeshDesc meshDesc; meshDesc.points.data = pxVertices.data(); meshDesc.points.count = static_cast<physx::PxU32>(pxVertices.size()); meshDesc.points.stride = sizeof(physx::PxVec3); if (indexBuffer.use32BitIndices) { meshDesc.triangles.data = indexBuffer.uiIndexBuffer.data(); meshDesc.triangles.count = static_cast<physx::PxU32>(indexBuffer.uiIndexBuffer.size()) / 3; meshDesc.triangles.stride = sizeof(physx::PxU32) * 3; } else { meshDesc.triangles.data = indexBuffer.usIndexBuffer.data(); meshDesc.triangles.count = static_cast<physx::PxU16>(indexBuffer.usIndexBuffer.size()) / 3; meshDesc.triangles.stride = sizeof(physx::PxU16) * 3; meshDesc.flags = physx::PxMeshFlag::e16_BIT_INDICES; } success = meshDesc.isValid(); success = success && pCooking->cookTriangleMesh(meshDesc, cookMesh); } break; } if (success) { std::string pxName = nodeName + ".px"; LogManager::getSingleton().logMessage(false, "Exporting: %s", pxName.c_str()); pxName = config.exportPath + pxName; FILE* fp = fopen(pxName.c_str(), "wb"); if (fp) { fwrite(cookMesh.getData(), cookMesh.getSize(), 1, fp); fclose(fp); } } pCooking->release(); pFound->release(); return success; }
//////// GAME-LEVEL RIGID BODY PHYSICS STUFF /////// void InitGamePhys() { #if WITH_BOX2D FPhysicsIntegration2D::InitializePhysics(); #endif #if WITH_PHYSX // Do nothing if SDK already exists if(GPhysXFoundation != NULL) { return; } // Make sure LoadPhysXModules(); // Create Foundation GPhysXAllocator = new FPhysXAllocator(); FPhysXErrorCallback* ErrorCallback = new FPhysXErrorCallback(); GPhysXFoundation = PxCreateFoundation(PX_FOUNDATION_VERSION, *GPhysXAllocator, *ErrorCallback); check(GPhysXFoundation); #if PHYSX_MEMORY_STATS // Want names of PhysX allocations GPhysXFoundation->setReportAllocationNames(true); #endif // Create profile manager GPhysXVisualDebugger = PxCreatePvd(*GPhysXFoundation); check(GPhysXVisualDebugger); // Create Physics PxTolerancesScale PScale; PScale.length = CVarToleranceScaleLength.GetValueOnGameThread(); PScale.speed = CVarToleranceScaleSpeed.GetValueOnGameThread(); GPhysXSDK = PxCreatePhysics(PX_PHYSICS_VERSION, *GPhysXFoundation, PScale, false, GPhysXVisualDebugger); check(GPhysXSDK); FPhysxSharedData::Initialize(); GPhysCommandHandler = new FPhysCommandHandler(); GPreGarbageCollectDelegateHandle = FCoreUObjectDelegates::PreGarbageCollect.AddRaw(GPhysCommandHandler, &FPhysCommandHandler::Flush); // Init Extensions PxInitExtensions(*GPhysXSDK, GPhysXVisualDebugger); #if WITH_VEHICLE PxInitVehicleSDK(*GPhysXSDK); #endif if (CVarUseUnifiedHeightfield.GetValueOnGameThread()) { //Turn on PhysX 3.3 unified height field collision detection. //This approach shares the collision detection code between meshes and height fields such that height fields behave identically to the equivalent terrain created as a mesh. //This approach facilitates mixing the use of height fields and meshes in the application with no tangible difference in collision behavior between the two approaches except that //heightfield thickness is not supported for unified heightfields. PxRegisterUnifiedHeightFields(*GPhysXSDK); } else { PxRegisterHeightFields(*GPhysXSDK); } if( FParse::Param( FCommandLine::Get(), TEXT( "PVD" ) ) ) { PvdConnect(TEXT("localhost"), true); } #if WITH_PHYSICS_COOKING || WITH_RUNTIME_PHYSICS_COOKING // Create Cooking PxCookingParams PCookingParams(PScale); PCookingParams.meshWeldTolerance = 0.1f; // Weld to 1mm precision PCookingParams.meshPreprocessParams = PxMeshPreprocessingFlags(PxMeshPreprocessingFlag::eWELD_VERTICES); // Force any cooking in PhysX or APEX to use older incremental hull method // This is because the new 'quick hull' method can generate degenerate geometry in some cases (very thin meshes etc.) //PCookingParams.convexMeshCookingType = PxConvexMeshCookingType::eINFLATION_INCREMENTAL_HULL; PCookingParams.targetPlatform = PxPlatform::ePC; //PCookingParams.meshCookingHint = PxMeshCookingHint::eCOOKING_PERFORMANCE; //PCookingParams.meshSizePerformanceTradeOff = 0.0f; GPhysXCooking = PxCreateCooking(PX_PHYSICS_VERSION, *GPhysXFoundation, PCookingParams); check(GPhysXCooking); #endif #if WITH_APEX // Build the descriptor for the APEX SDK apex::ApexSDKDesc ApexDesc; ApexDesc.foundation = GPhysXFoundation; // Pointer to the PxFoundation ApexDesc.physXSDK = GPhysXSDK; // Pointer to the PhysXSDK ApexDesc.cooking = GPhysXCooking; // Pointer to the cooking library ApexDesc.renderResourceManager = &GApexNullRenderResourceManager; // We will not be using the APEX rendering API, so just use a dummy render resource manager ApexDesc.resourceCallback = &GApexResourceCallback; // The resource callback is how APEX asks the application to find assets when it needs them #if PLATFORM_MAC FString DylibFolder = FPaths::EngineDir() / TEXT("Binaries/ThirdParty/PhysX/"); ANSICHAR* DLLLoadPath = (ANSICHAR*)FMemory::Malloc(DylibFolder.Len() + 1); FCStringAnsi::Strcpy(DLLLoadPath, DylibFolder.Len() + 1, TCHAR_TO_UTF8(*DylibFolder)); ApexDesc.dllLoadPath = DLLLoadPath; #endif // Create the APEX SDK apex::ApexCreateError ErrorCode; GApexSDK = apex::CreateApexSDK(ApexDesc, &ErrorCode); check(ErrorCode == APEX_CE_NO_ERROR); check(GApexSDK); #if PLATFORM_MAC FMemory::Free(DLLLoadPath); #endif #if UE_BUILD_SHIPPING GApexSDK->setEnableApexStats(false); #endif #if APEX_STATICALLY_LINKED // We need to instantiate the module if we have statically linked them // Otherwise all createModule functions will fail instantiateModuleDestructible(); #if WITH_APEX_CLOTHING instantiateModuleClothing(); #endif #if WITH_APEX_LEGACY instantiateModuleLegacy(); #endif #endif // 1 legacy module for all in APEX 1.3 // Load the only 1 legacy module #if WITH_APEX_LEGACY GApexModuleLegacy = GApexSDK->createModule("Legacy"); check(GApexModuleLegacy); #endif // WITH_APEX_LEGACY // Load APEX Destruction module GApexModuleDestructible = static_cast<apex::ModuleDestructible*>(GApexSDK->createModule("Destructible")); check(GApexModuleDestructible); // Set Destructible module parameters NvParameterized::Interface* ModuleParams = GApexModuleDestructible->getDefaultModuleDesc(); // ModuleParams contains the default module descriptor, which may be modified here before calling the module init function GApexModuleDestructible->init(*ModuleParams); // Set chunk report for fracture effect callbacks GApexModuleDestructible->setChunkReport(&GApexChunkReport); GApexModuleDestructible->setMaxDynamicChunkIslandCount((physx::PxU32)FMath::Max(CVarAPEXMaxDestructibleDynamicChunkIslandCount.GetValueOnGameThread(), 0)); GApexModuleDestructible->setMaxChunkCount((physx::PxU32)FMath::Max(CVarAPEXMaxDestructibleDynamicChunkCount.GetValueOnGameThread(), 0)); GApexModuleDestructible->setSortByBenefit(CVarAPEXSortDynamicChunksByBenefit.GetValueOnGameThread() != 0); GApexModuleDestructible->scheduleChunkStateEventCallback(apex::DestructibleCallbackSchedule::FetchResults); // APEX 1.3 to preserve 1.2 behavior GApexModuleDestructible->setUseLegacyDamageRadiusSpread(true); GApexModuleDestructible->setUseLegacyChunkBoundsTesting(true); #if WITH_APEX_CLOTHING // Load APEX Clothing module GApexModuleClothing = static_cast<apex::ModuleClothing*>(GApexSDK->createModule("Clothing")); check(GApexModuleClothing); // Set Clothing module parameters ModuleParams = GApexModuleClothing->getDefaultModuleDesc(); // Can be tuned for switching between more memory and more spikes. NvParameterized::setParamU32(*ModuleParams, "maxUnusedPhysXResources", 5); // If true, let fetch results tasks run longer than the fetchResults call. // Setting to true could not ensure same finish timing with Physx simulation phase NvParameterized::setParamBool(*ModuleParams, "asyncFetchResults", false); // ModuleParams contains the default module descriptor, which may be modified here before calling the module init function GApexModuleClothing->init(*ModuleParams); #endif //WITH_APEX_CLOTHING #endif // #if WITH_APEX #endif // WITH_PHYSX }