NxScene* plSimulationMgr::GetScene(plKey world)
{
    if (!world)
        world = GetKey();

    NxScene* scene = fScenes[world];

    if (!scene)
    {
        NxSceneDesc sceneDesc;
        sceneDesc.gravity.set(0, 0, -32.174049f);
        sceneDesc.userTriggerReport = &gSensorReport;
        sceneDesc.userContactReport = &gContactReport;
        scene = fSDK->createScene(sceneDesc);

        // See "Advancing The Simulation State" in the PhysX SDK Documentation
        // This will cause PhysX to only update for our step size. If we call simulate
        // faster than that, PhysX will return immediately. If we call it slower than that,
        // PhysX will do some extra steps for us (isn't that nice?).
        // Anyway, this should be a good way to make us independent of the framerate.
        // If not, I blame the usual suspects (Tye, eap, etc...)
        scene->setTiming(kDefaultStepSize);

        // Most physicals use the default friction and restitution values, so we
        // make them the default.
        NxMaterial* mat = scene->getMaterialFromIndex(0);
        float rest = mat->getRestitution();
        float sfriction = mat->getStaticFriction();
        float dfriction = mat->getDynamicFriction();
        mat->setRestitution(0.5);
        mat->setStaticFriction(0.5);
        mat->setDynamicFriction(0.5);

        // By default we just leave all the collision groups enabled, since
        // PhysX already makes sure that things like statics and statics don't
        // collide.  However, we do make it so the avatar and dynamic blockers
        // only block avatars and dynamics.
        for (int i = 0; i < plSimDefs::kGroupMax; i++)
        {
            scene->setGroupCollisionFlag(i, plSimDefs::kGroupAvatarBlocker, false);
            scene->setGroupCollisionFlag(i, plSimDefs::kGroupDynamicBlocker, false);
            scene->setGroupCollisionFlag(i, plSimDefs::kGroupLOSOnly, false);
            scene->setGroupCollisionFlag(plSimDefs::kGroupLOSOnly, i, false);
        }
        scene->setGroupCollisionFlag(plSimDefs::kGroupAvatar, plSimDefs::kGroupAvatar, false);
        scene->setGroupCollisionFlag(plSimDefs::kGroupAvatar, plSimDefs::kGroupAvatarBlocker, true);
        scene->setGroupCollisionFlag(plSimDefs::kGroupDynamic, plSimDefs::kGroupDynamicBlocker, true);
        scene->setGroupCollisionFlag(plSimDefs::kGroupAvatar, plSimDefs::kGroupStatic, true);
        scene->setGroupCollisionFlag( plSimDefs::kGroupStatic, plSimDefs::kGroupAvatar, true);
        scene->setGroupCollisionFlag(plSimDefs::kGroupAvatar, plSimDefs::kGroupDynamic, true);
        
        // The dynamics are in actor group 1, everything else is in 0.  Request
        // a callback for whenever a dynamic touches something.
        scene->setActorGroupPairFlags(0, 1, NX_NOTIFY_ON_TOUCH);
        scene->setActorGroupPairFlags(1, 1, NX_NOTIFY_ON_TOUCH);

        fScenes[world] = scene;
    }

    return scene;
}
Beispiel #2
0
	Data(bool useHardware, bool useHardwareOnly, bool useMultithreading, PhysicsParams *params)
	:	sdk(0),
		scene(0),
		crashed(false),

		statsNumActors(0),
		statsNumDynamicActors(0),
		statsNumDynamicActorsInAwakeGroups(0),
		statsMaxDynamicActorsInAwakeGroups(0),
		statsSimulationTime(0),
		statsSimulationWaitTime(0),
		statsSimulationStartWaitTime(0),
		startSimulationTime(0),

		statsContacts(0),
		ccd(false),
		ccdMaxThickness(0.5f),

		runningInHardware(false),
		physicslib_fluid_containment_actor(0),
		physicslib_fluid_containment_shape(0),
		physicslib_fluid_containment_sphere_actor(0),
		physicslib_fluid_containment_sphere_shape(0)
	{
		if (params == NULL)
		{
			params = &physics_defaultParams;
			::Logger::getInstance()->debug("PhysicsLib - No physics params given, using defaults.");
		}

		if (params->scriptRunner == NULL)
		{
			::Logger::getInstance()->warning("PhysicsLib - No script runner given, collision groups, etc. will be initialized to default values.");
		}

		NxPhysicsSDKDesc sdkDesc;
		if(!useHardware)
			sdkDesc.flags |= NX_SDKF_NO_HARDWARE;

		sdk = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION, 0, getLogger(), sdkDesc);
		//sdk = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION);

		// HACK: ...
		physxSDK = sdk;

		if(sdk)
		{
			if(sdk->getHWVersion() == NX_HW_VERSION_NONE)
				useHardware = false;

			if (params->ccd)
			{
				sdk->setParameter(NX_CONTINUOUS_CD, true);
				sdk->setParameter(NX_CCD_EPSILON, 0.001f);
			}
			this->ccd = params->ccd;
			this->ccdMaxThickness = params->ccdMaxThickness;

			NxSceneDesc sceneDesc;
			sceneDesc.gravity = NxVec3(params->gravity.x, params->gravity.y, params->gravity.z);	
			sceneDesc.userContactReport = &contactReport;
			//sceneDesc.userNotify = &userNotify;

			if(useHardware)
			{
				sceneDesc.simType = NX_SIMULATION_HW;
				if (useHardwareOnly)
				{
					sceneDesc.flags |= NX_SF_RESTRICTED_SCENE;
				}
			}
			else
			{
				sceneDesc.simType = NX_SIMULATION_SW;
			}

			if (!useMultithreading)
			{
				// Disable threading
				sceneDesc.flags = 0;
			}

			runningInHardware = useHardware;

			sceneDesc.flags |= NX_SF_ENABLE_ACTIVETRANSFORMS;
			scene = sdk->createScene(sceneDesc);
			if(scene)
			{
				NxMaterial *defaultMaterial = scene->getMaterialFromIndex(0);
				defaultMaterial->setStaticFriction(params->defaultStaticFriction);
				defaultMaterial->setDynamicFriction(params->defaultDynamicFriction);
				defaultMaterial->setRestitution(params->defaultRestitution);

#ifdef PROJECT_CLAW_PROTO
				// Create material for cops (larger friction, no restitution)
				NxMaterialDesc materialDesc;
				materialDesc.restitution = 0.0f;   
				materialDesc.restitutionCombineMode = NX_CM_MIN;
				materialDesc.staticFriction = 10.0f;
				materialDesc.dynamicFriction = 10.0f;
				unitMaterial = scene->createMaterial(materialDesc);
#endif

				sdk->setParameter(NX_VISUALIZATION_SCALE, 1.f);

#ifndef PROJECT_SHADOWGROUNDS
				sdk->setParameter(NX_SKIN_WIDTH, 0.01f);
#endif

				// NEW: the new scriptable collision/contact group initialization
				int contactFlags1 = NX_NOTIFY_ON_START_TOUCH | NX_NOTIFY_ON_TOUCH | NX_NOTIFY_FORCES;
#ifdef PHYSICS_FEEDBACK
				int contactFlags2 = NX_NOTIFY_ON_START_TOUCH | NX_NOTIFY_ON_TOUCH | NX_NOTIFY_FORCES;
#else
				int contactFlags2 = NX_NOTIFY_ON_START_TOUCH | NX_NOTIFY_FORCES;
#endif
				if (params->scriptRunner != NULL)
				{
					bool ok = params->scriptRunner->runPhysicsLibScript("physics_init", "set_contacts");
					if (!ok)
						::Logger::getInstance()->error("PhysicsLib - Failed to run physics_init:set_contacts script (script/sub may not be loaded or did not return expected value).");
				}

				for (int i = 0; i < PHYSICS_MAX_COLLISIONGROUPS; i++)
				{
					for (int j = 0; j < PHYSICS_MAX_COLLISIONGROUPS; j++)
					{
						if (physicslib_group_cont[i][j] != physicslib_group_cont[j][i])
						{
							::Logger::getInstance()->error("PhysicsLib - Improperly mirrored physics contacts data (group1 -> group2 does not have same flag as group2 -> group1).");
							::Logger::getInstance()->debug("contacts data group numbers follow:");
							::Logger::getInstance()->debug(int2str(i));
							::Logger::getInstance()->debug(int2str(j));
						}
						if (physicslib_group_cont[i][j] == PHYSICSLIB_GROUP_CONTACT_FLAGS1)
							scene->setActorGroupPairFlags(i, j, contactFlags1);
						else if (physicslib_group_cont[i][j] == PHYSICSLIB_GROUP_CONTACT_FLAGS2)
							scene->setActorGroupPairFlags(i, j, contactFlags2);
					}
				}

				if (params->scriptRunner != NULL)
				{
					bool ok = params->scriptRunner->runPhysicsLibScript("physics_init", "set_collisions");
					if (!ok)
						::Logger::getInstance()->error("PhysicsLib - Failed to run physics_init:set_collision script (script/sub may not be loaded or did not return expected value).");
				}

				for (int i = 0; i < PHYSICS_MAX_COLLISIONGROUPS; i++)
				{
					for (int j = 0; j < PHYSICS_MAX_COLLISIONGROUPS; j++)
					{
						if (physicslib_group_coll[i][j] != physicslib_group_coll[j][i])
						{
							::Logger::getInstance()->error("PhysicsLib - Improperly mirrored physics collision data (group1 -> group2 does not have same flag as group2 -> group1).");
							::Logger::getInstance()->debug("collision data group numbers follow:");
							::Logger::getInstance()->debug(int2str(i));
							::Logger::getInstance()->debug(int2str(j));
						}
						scene->setGroupCollisionFlag(i, j, physicslib_group_coll[i][j]);
					}
				}

// OLD SCHEISSE...
/*
				// Contact groups
				{
					int contactFlags1 = NX_NOTIFY_ON_START_TOUCH | NX_NOTIFY_ON_TOUCH | NX_NOTIFY_FORCES;
#ifdef PHYSICS_FEEDBACK
					int contactFlags2 = NX_NOTIFY_ON_START_TOUCH | NX_NOTIFY_ON_TOUCH | NX_NOTIFY_FORCES;
#else
					int contactFlags2 = NX_NOTIFY_ON_START_TOUCH | NX_NOTIFY_FORCES;
#endif
					//int contactFlags3 = NX_NOTIFY_ON_START_TOUCH | NX_NOTIFY_FORCES;

					scene->setActorGroupPairFlags(PHYSICS_COLLISIONGROUP_STATIC, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, contactFlags2);
					scene->setActorGroupPairFlags(PHYSICS_COLLISIONGROUP_STATIC, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES, contactFlags2);
					scene->setActorGroupPairFlags(PHYSICS_COLLISIONGROUP_STATIC, PHYSICS_COLLISIONGROUP_DYNAMIC_TERRAINOBJECTS, contactFlags1);
					scene->setActorGroupPairFlags(PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, PHYSICS_COLLISIONGROUP_DYNAMIC_TERRAINOBJECTS, contactFlags2);
					scene->setActorGroupPairFlags(PHYSICS_COLLISIONGROUP_MODEL_PARTICLES, PHYSICS_COLLISIONGROUP_DYNAMIC_TERRAINOBJECTS, contactFlags2);
					//scene->setActorGroupPairFlags(PHYSICS_COLLISIONGROUP_DYNAMIC_TERRAINOBJECTS, PHYSICS_COLLISIONGROUP_DYNAMIC_TERRAINOBJECTS, contactFlags2);
scene->setActorGroupPairFlags(PHYSICS_COLLISIONGROUP_DYNAMIC_TERRAINOBJECTS, PHYSICS_COLLISIONGROUP_DYNAMIC_TERRAINOBJECTS, contactFlags1);
					scene->setActorGroupPairFlags(PHYSICS_COLLISIONGROUP_DYNAMIC_TERRAINOBJECTS, PHYSICS_COLLISIONGROUP_UNITS, contactFlags2);
scene->setActorGroupPairFlags(PHYSICS_COLLISIONGROUP_STATIC, PHYSICS_COLLISIONGROUP_UNITS, contactFlags2);
scene->setActorGroupPairFlags(PHYSICS_COLLISIONGROUP_CLAW, PHYSICS_COLLISIONGROUP_STATIC, contactFlags1);
					//scene->setActorGroupPairFlags(PHYSICS_COLLISIONGROUP_DYNAMIC_TERRAINOBJECTS, PHYSICS_COLLISIONGROUP_UNITS, contactFlags3);
				}

				// Collision groups
				{
					// claw
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_CLAW, PHYSICS_COLLISIONGROUP_CLAW, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_CLAW, PHYSICS_COLLISIONGROUP_NOCOLLISION, false);
scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_NOCOLLISION, PHYSICS_COLLISIONGROUP_CLAW, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_CLAW, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_CLAW, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_CLAW, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL_NO_SOUND, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_CLAW, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_NO_SOUND, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_CLAW, PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, false);

					// Model particles
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL_NO_SOUND, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_NO_SOUND, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_MODEL_PARTICLES, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_MODEL_PARTICLES, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL_NO_SOUND, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_MODEL_PARTICLES, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_NO_SOUND, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL_NO_SOUND, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL_NO_SOUND, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL_NO_SOUND, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_NO_SOUND, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_NO_SOUND, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_NO_SOUND, false);

					// Doors
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_DOORS, PHYSICS_COLLISIONGROUP_DOORS, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_DOORS, PHYSICS_COLLISIONGROUP_STATIC, false);

					// Units and model particles
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_UNITS, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL_NO_SOUND, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_UNITS, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, false);

					// Fluids
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUIDS, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUIDS, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUIDS, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL_NO_SOUND, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUIDS, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_NO_SOUND, false);

					// Fluids w/ detailed collision
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUIDS_DETAILED, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUIDS_DETAILED, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUIDS_DETAILED, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL_NO_SOUND, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUIDS_DETAILED, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_NO_SOUND, false);

					// Fluid containment
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, PHYSICS_COLLISIONGROUP_STATIC, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL_NO_SOUND, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_NO_SOUND, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, PHYSICS_COLLISIONGROUP_UNITS, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, PHYSICS_COLLISIONGROUP_DOORS, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, PHYSICS_COLLISIONGROUP_DYNAMIC_TERRAINOBJECTS, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, PHYSICS_COLLISIONGROUP_FLUIDS_DETAILED, false);

					// No collision
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_NOCOLLISION, PHYSICS_COLLISIONGROUP_STATIC, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_NOCOLLISION, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_NOCOLLISION, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_NOCOLLISION, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL_NO_SOUND, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_NOCOLLISION, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_NO_SOUND, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_NOCOLLISION, PHYSICS_COLLISIONGROUP_UNITS, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_NOCOLLISION, PHYSICS_COLLISIONGROUP_DOORS, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_NOCOLLISION, PHYSICS_COLLISIONGROUP_DYNAMIC_TERRAINOBJECTS, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_NOCOLLISION, PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, false);
					scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_NOCOLLISION, PHYSICS_COLLISIONGROUP_NOCOLLISION, false);
				}
*/
			}
		}
	}