//
	// 创建物理场景
	//
	BOOL CSceneManager::CreatePhysicsScene(VOID)
	{
		for (EntityMap::const_iterator itEntity = m_meshs.begin(); itEntity != m_meshs.end(); ++itEntity) {
			const CEntityMesh *pEntityMesh = (const CEntityMesh *)itEntity->second;
			ASSERT(pEntityMesh);

			const CSubMesh *pPhysicsMesh = pEntityMesh->GetPhysicsSubMesh();
			if (pPhysicsMesh == NULL) continue;
			if (pEntityMesh->IsEnablePhysicsQuery() == FALSE && pEntityMesh->IsEnablePhysicsSimulation() == FALSE) continue;

			const VEC3 *position = pEntityMesh->GetSceneNode()->GetWorldPosition();
			const QUAT *orientation = pEntityMesh->GetSceneNode()->GetWorldOrientation();
			const PxTransform pxLocalPose(PxVec3(0.0f, 0.0f, 0.0f));
			const PxTransform pxGlobalPose(PxVec3((*position)[0], (*position)[1], (*position)[2]), PxQuat((*orientation)[0], (*orientation)[1], (*orientation)[2], (*orientation)[3]));

			const PxMaterial &pxMaterial = GetPhysicsStandardMaterial((MATERIAL_TYPE)pEntityMesh->GetPhysicsMaterial()->GetPhysics()->GetType());
			const PxFilterData pxQueryFilterData = PxFilterData(QUERY_FLAGS_SCENE_MESH, 0, 0, 0);
			const PxFilterData pxSimulationFilterData = PxFilterData(SIMULATION_FLAGS_WORD0[pEntityMesh->GetPhysicsSimulationTypeIndex()], SIMULATION_FLAGS_WORD1[pEntityMesh->GetPhysicsSimulationTypeIndex()], 0, 0);

			PxRigidActor *pPxRigidActor = (PxRigidActor *)m_physics.CreateRigidActor(pEntityMesh->GetSceneNode()->GetName(), pxGlobalPose, FALSE, TRUE, TRUE);
			PxShape *pPxShape = PxCreateShapeMesh(pPxRigidActor, pPhysicsMesh->GetVertexBuffer(), pPhysicsMesh->GetVertexCount(), pPhysicsMesh->GetFaceBuffer(), pPhysicsMesh->GetFaceCount(), pxMaterial, pxLocalPose, pEntityMesh->IsEnablePhysicsQuery(), pEntityMesh->IsEnablePhysicsSimulation(), pxQueryFilterData, pxSimulationFilterData);
			pPxShape->userData = pEntityMesh->userData;
		}

		return TRUE;
	}
BOOL obj_ItemSpawnPoint::Update()
{
	static int delayCheckSpawnPointsInAir = 100;
	if(delayCheckSpawnPointsInAir)
		--delayCheckSpawnPointsInAir;
	if(g_bEditMode && m_bEditorCheckSpawnPointAtStart && delayCheckSpawnPointsInAir ==0)
	{
		m_bEditorCheckSpawnPointAtStart = false;
		for(ITEM_SPAWN_POINT_VECTOR::iterator it=m_SpawnPointsV.begin(); it!=m_SpawnPointsV.end(); ++it)
		{
			PxVec3 from(it->pos.x, it->pos.y+1.0f, it->pos.z);
			PxRaycastHit hit;
			PxSceneQueryFilterData filter(PxFilterData(COLLIDABLE_STATIC_MASK,0,0,0), PxSceneQueryFilterFlags(PxSceneQueryFilterFlag::eSTATIC));
			if(g_pPhysicsWorld->raycastSingle(from, PxVec3(0,-1,0), 10000, PxSceneQueryFlags(PxSceneQueryFlag::eIMPACT), hit, filter))
			{
				r3dPoint3D hitPos(hit.impact.x, hit.impact.y, hit.impact.z);
				if(R3D_ABS(it->pos.y - hitPos.y) > 2.0f)
				{
					r3dArtBug("Item CP Spawn at %.2f, %.2f, %.2f has spawn position(s) in the air. Please select it and use Check Locations button\n", 
						GetPosition().x, GetPosition().y, GetPosition().z);
					break;
				}
			}
		}
		r3dShowArtBugs();
	}

	return parent::Update();
}
Exemple #3
0
BOOL obj_Bullet::Update()
{
	parent::Update();
	const GameObject* owner = GameWorld().GetObject(ownerID);

	if( m_CreationTime+5.0f < r3dGetTime() ) // Bullets should only live for 5 seconds. 
	{
		// yeah your dead. 
		if(owner && owner->NetworkLocal)
		{
			PKT_C2C_PlayerHitNothing_s n;
			p2pSendToHost(owner, &n, sizeof(n), true);
		}
		return false;
	}

	r3dVector dir = (GetPosition() - oldstate.Position);
	if(dir.Length()==0)
		dir = m_FireDirection;
	// perform collision check
	m_AppliedVelocity += r3dVector(0, -9.81f, 0) * m_Weapon->m_AmmoMass * r3dGetFrameTime();
	r3dPoint3D motion = m_AppliedVelocity * r3dGetFrameTime();
	float motionLen = motion.Length();
	motion.Normalize();

	PxU32 collisionFlag = COLLIDABLE_STATIC_MASK;
	if(owner && owner->NetworkLocal)
		collisionFlag |= (1<<PHYSCOLL_NETWORKPLAYER);

	PxSphereGeometry sphere(0.0025f); // Make it tiny. 5 milimeter diameter
	PxTransform pose(PxVec3(GetPosition().x, GetPosition().y, GetPosition().z), PxQuat(0,0,0,1));

	PxSweepHit hit;
	PxSceneQueryFilterData filter(PxFilterData(collisionFlag, 0, 0, 0), PxSceneQueryFilterFlag::eSTATIC|PxSceneQueryFilterFlag::eDYNAMIC);
	
	
	if(g_pPhysicsWorld->PhysXScene->sweepSingle(sphere, pose, PxVec3(motion.x, motion.y, motion.z), motionLen, PxSceneQueryFlag::eINITIAL_OVERLAP|PxSceneQueryFlag::eIMPACT|PxSceneQueryFlag::eNORMAL, hit, filter))
	{

		// if the hit is the final stop. 
		if ( OnHit(hit) ) {
			return false;
		}
	}
	else 
	{
		// perform movement
		SetPosition(GetPosition() + m_AppliedVelocity * r3dGetFrameTime());
	}

	
	if(m_ParticleTracer)
		m_ParticleTracer->SetPosition(GetPosition());

	return true;
}
void obj_DroppedItem::UpdateObjectPositionAfterCreation()
{
	if(!PhysicsObject)
		return;

	PxActor* actor = PhysicsObject->getPhysicsActor();
	if(!actor)
		return;

	PxBounds3 pxBbox = actor->getWorldBounds();
	PxVec3 pxCenter = pxBbox.getCenter();

	// place object on the ground, to prevent excessive bouncing
	{
		PxRaycastHit hit;
		PxSceneQueryFilterData filter(PxFilterData(COLLIDABLE_STATIC_MASK, 0, 0, 0), PxSceneQueryFilterFlag::eSTATIC);
		if(g_pPhysicsWorld->raycastSingle(PxVec3(pxCenter.x, pxCenter.y, pxCenter.z), PxVec3(0, -1, 0), 50.0f, PxSceneQueryFlag::eIMPACT, hit, filter))
		{
			SetPosition(r3dPoint3D(hit.impact.x, hit.impact.y+0.1f, hit.impact.z));
		}
	}
}
float obj_ItemSpawnPoint::DrawPropertyEditor(float scrx, float scry, float scrw, float scrh, const AClass* startClass, const GameObjects& selected)
{
	float starty = scry;

	starty += parent::DrawPropertyEditor(scrx, scry, scrw,scrh, startClass, selected );

	if( IsParentOrEqual( &ClassData, startClass ) )
	{		
		starty += imgui_Static ( scrx, starty, "Item Spawn Point Parameters" );
		starty += imgui_Value_Slider(scrx, starty, "Tick Period (sec)", &m_TickPeriod, 1.0f, 50000.0f, "%.2f");
		starty += imgui_Value_Slider(scrx, starty, "Cooldown (sec)", &m_Cooldown, 1.0f, 50000.0f, "%.2f");
		starty += imgui_Value_Slider(scrx, starty, "De-spawn (sec)", &m_DestroyItemTimer, 0.0f, 50000.0f, "%.2f");
		int isOneItemSpawn = m_OneItemSpawn?1:0;
		starty += imgui_Checkbox(scrx, starty, "One Item Spawn", &isOneItemSpawn, 1);
		m_OneItemSpawn = isOneItemSpawn?true:false;
		
		if(!m_OneItemSpawn)
		{
			static stringlist_t lootBoxNames;
			static int* lootBoxIDs = NULL;
			static int numLootBoxes = 0;
			if(numLootBoxes == 0)
			{
				struct tempS
				{
					char* name;
					uint32_t id;
				};
				std::vector<tempS> lootBoxes;
				{
					tempS holder;
					holder.name = "EMPTY";
					holder.id = 0;
					lootBoxes.push_back(holder);		
				}

				g_pWeaponArmory->startItemSearch();
				while(g_pWeaponArmory->searchNextItem())
				{
					uint32_t itemID = g_pWeaponArmory->getCurrentSearchItemID();
					const BaseItemConfig* cfg = g_pWeaponArmory->getConfig(itemID);
					if( cfg->category == storecat_LootBox )
					{
						tempS holder;
						holder.name = cfg->m_StoreName;
						holder.id = cfg->m_itemID;
						lootBoxes.push_back(holder);						 
					}
				}
				numLootBoxes = (int)lootBoxes.size();
				lootBoxIDs = new int[numLootBoxes];
				for(int i=0; i<numLootBoxes; ++i)
				{
					lootBoxNames.push_back(lootBoxes[i].name);
					lootBoxIDs[i] = lootBoxes[i].id;
				}
			}

			int sel = 0;
			static float offset = 0;
			for(int i=0; i<numLootBoxes; ++i)
				if(m_LootBoxID == lootBoxIDs[i])
					sel = i;
			starty += imgui_Static ( scrx, starty, "Loot box:" );
			if(imgui_DrawList(scrx, starty, 360, 122, lootBoxNames, &offset, &sel))
			{
				m_LootBoxID = lootBoxIDs[sel];
				PropagateChange( m_LootBoxID, &obj_ItemSpawnPoint::m_LootBoxID, this, selected ) ;
			}
			starty += 122;
		}
		else
		{
			starty += imgui_Value_SliderI(scrx, starty, "ItemID", (int*)&m_LootBoxID, 0, 1000000, "%d", false);
			PropagateChange( m_LootBoxID, &obj_ItemSpawnPoint::m_LootBoxID, this, selected ) ;
		}
		
		// don't allow multi edit of this
		if( selected.Count() <= 1 )
		{
			{
				if(imgui_Button(scrx, starty, 200, 25, "Check locations"))
				{
					for(ITEM_SPAWN_POINT_VECTOR::iterator it=m_SpawnPointsV.begin(); it!=m_SpawnPointsV.end(); ++it)
					{
						PxVec3 from(it->pos.x, it->pos.y+1.0f, it->pos.z);
						PxRaycastHit hit;
						PxSceneQueryFilterData filter(PxFilterData(COLLIDABLE_STATIC_MASK,0,0,0), PxSceneQueryFilterFlags(PxSceneQueryFilterFlag::eSTATIC));
						if(g_pPhysicsWorld->raycastSingle(from, PxVec3(0,-1,0), 10000, PxSceneQueryFlags(PxSceneQueryFlag::eIMPACT), hit, filter))
						{
							r3dPoint3D hitPos(hit.impact.x, hit.impact.y, hit.impact.z);
							if(R3D_ABS(it->pos.y - hitPos.y) > 2.0f)
							{
								gCam = it->pos + r3dPoint3D(0,1,0);
								break;
							}
						}
					}
				}
				starty += 30;
			}

			if(imgui_Button(scrx+110, starty, 100, 25, "Add Location"))
			{
				ItemSpawn itemSpawn;
				itemSpawn.pos = GetPosition() + r3dPoint3D(2, 0, 2);
				m_SpawnPointsV.push_back(itemSpawn);
				m_SelectedSpawnPoint = m_SpawnPointsV.size()-1;
			}

			starty += 25;

			int i=0;
			for(ITEM_SPAWN_POINT_VECTOR::iterator it=m_SpawnPointsV.begin(); it!=m_SpawnPointsV.end(); )
			{
				// selection button
				char tempStr[32];
				sprintf(tempStr, "Location %d", i+1);
				if(imgui_Button(scrx, starty, 100, 25, tempStr, i==m_SelectedSpawnPoint))
				{
					// shift click on location will set camera to it
					if(Keyboard->IsPressed(kbsLeftShift))
					{
						extern BaseHUD* HudArray[6];
						extern int CurHUDID;
						HudArray[CurHUDID]->FPS_Position = m_SpawnPointsV[i].pos;
						HudArray[CurHUDID]->FPS_Position.y += 0.1f;
					}
					
					m_SelectedSpawnPoint = i;
				}

				// delete button
				if(m_SpawnPointsV.size() > 1)
				{
					if(imgui_Button(scrx + 110, starty, 100, 25, "DEL"))
					{
						it = m_SpawnPointsV.erase(it);
						continue;
					}
					m_SelectedSpawnPoint = R3D_CLAMP(m_SelectedSpawnPoint, 0, (int)m_SpawnPointsV.size()-1);
				}

				starty += 25;

				++it;
				++i;
			}

			extern r3dPoint3D UI_TargetPos;
			if((Mouse->IsPressed(r3dMouse::mLeftButton)) && Keyboard->IsPressed(kbsLeftControl))
				m_SpawnPointsV[m_SelectedSpawnPoint].pos = UI_TargetPos;

		}
	}

	return starty-scry;
}
Exemple #6
0
void obj_Grenade::onExplode()
{
	// if owner disappeared, do nothing.
	const GameObject* owner = GameWorld().GetObject(ownerID);
	if(!owner)
		return;

	bool closeToGround = false;

	PxRaycastHit hit;
	PxSceneQueryFilterData filter(PxFilterData(COLLIDABLE_STATIC_MASK, 0, 0, 0), PxSceneQueryFilterFlag::eSTATIC);
	if(g_pPhysicsWorld->raycastSingle(PxVec3(GetPosition().x, GetPosition().y+1, GetPosition().z), PxVec3(0, -1, 0), 50.0f, PxSceneQueryFlag::eDISTANCE, hit, filter))
	{
		if(hit.distance < 5.0f)
			closeToGround = true;
	}

	if(closeToGround)
	{
		// add decal
		DecalParams params;
		params.Dir		= lastCollisionNormal;
		params.Pos		= GetPosition();
		params.TypeID	= GetDecalID( r3dHash::MakeHash(""), r3dHash::MakeHash(m_Weapon->m_PrimaryAmmo->getDecalSource()) );
		if( params.TypeID != INVALID_DECAL_ID )
			g_pDecalChief->Add( params );
	}

	//check for underwater splash
	r3dPoint3D waterSplashPos;
	extern bool TraceWater(const r3dPoint3D& start, const r3dPoint3D& finish, r3dPoint3D& waterSplashPos);
	if( TraceWater( GetPosition() - r3dPoint3D(0.0f, m_Weapon->m_AmmoArea, 0.0f), GetPosition() + r3dPoint3D(0.0f, m_Weapon->m_AmmoArea, 0.0f), waterSplashPos))
	{
		SpawnImpactParticle(r3dHash::MakeHash("Water"), r3dHash::MakeHash(m_Weapon->m_PrimaryAmmo->getDecalSource()), waterSplashPos, r3dPoint3D(0,1,0));
		extern void WaterSplash(const r3dPoint3D& waterSplashPos, float height, float size, float amount, int texIdx);
		WaterSplash(GetPosition(), m_Weapon->m_AmmoArea, 10.0f/m_Weapon->m_AmmoArea, 0.04f, 1);
	}

	SpawnImpactParticle(r3dHash::MakeHash(""), r3dHash::MakeHash(m_Weapon->m_PrimaryAmmo->getDecalSource()), GetPosition(), r3dPoint3D(0,1,0));

	//	Start radial blur effect
	gExplosionVisualController.AddExplosion(GetPosition(), m_Weapon->m_AmmoArea);
	// for now hard coded for flash bang grenade
	if(m_Weapon->m_itemID == 101137)
	{
		// only apply flashbank for local player
		if(gClientLogic().localPlayer_ && !gClientLogic().localPlayer_->bDead)
		{
			// check that player can actually see explosion (need better test, for when explosion is behind wall)
			bool explosionVisible = r3dRenderer->IsSphereInsideFrustum(GetPosition(), 2.0f)>0;
			if(explosionVisible)
			{
				float radiusAdd = 0.0f;
				float durationAdd = 0.0f;
				float dist = (GetPosition()-gClientLogic().localPlayer_->GetPosition()).Length();
				float str = 1.0f - R3D_CLAMP(dist / (GPP->c_fFlashBangRadius+radiusAdd), 0.0f, 1.0f);
				if (str > 0.01f)
				{
					FlashBangEffectParams fbep;
					fbep.duration = (GPP->c_fFlashBangDuration+durationAdd) * str;
					fbep.pos = GetPosition();
					gFlashbangVisualController.StartEffect(fbep);
				}
			}
		}
	}

	// do damage only if owner is local player, otherwise we will broadcast damage multiple times
	r3d_assert(owner);
if(owner->NetworkLocal)
{
gClientLogic().ApplyExplosionDamage(GetPosition(), m_Weapon->m_AmmoArea, 0, r3dVector(0,0,0), 360.0f);
}
	setActiveFlag(0);

#if APEX_ENABLED
	//	Apply apex destructions
	g_pApexWorld->ApplyAreaDamage(m_Weapon->m_AmmoDamage * 0.01f, 1, GetPosition(), m_Weapon->m_AmmoArea, true);
#endif
}