int CScriptBind_Physics::SamplePhysEnvironment(IFunctionHandler *pH) { int nEnts,i,nHits=0,objtypes = ent_static|ent_rigid|ent_sleeping_rigid|ent_sort_by_mass; pe_status_nparts snp; pe_status_pos sp; IPhysicalEntity **pEnts; geom_world_data gwd; IGeometry *pSphere; primitives::sphere sph; intersection_params ip; geom_contact *pcontacts; IPhysicalWorld *pWorld = m_pSystem->GetIPhysicalWorld(); IEntity *pEntity; SmartScriptTable pObj(m_pSS); ip.bStopAtFirstTri=ip.bNoBorder=ip.bNoAreaContacts = true; ip.bThreadSafe = true; if (!pH->GetParams(sph.center,sph.r)) return pH->EndFunction(); if (pH->GetParamCount()>2) pH->GetParam(3,objtypes); pSphere = pWorld->GetGeomManager()->CreatePrimitive(primitives::sphere::type,&sph); nEnts = pWorld->GetEntitiesInBox(sph.center-Vec3(sph.r),sph.center+Vec3(sph.r),pEnts,objtypes); for(i=0;i<nEnts;i++) for(sp.ipart=pEnts[i]->GetStatus(&snp)-1;sp.ipart>=0;sp.ipart--) { sp.partid=-1; pEnts[i]->GetStatus(&sp); gwd.offset=sp.pos; gwd.R=Matrix33(sp.q); gwd.scale=sp.scale; WriteLockCond lock; if ((sp.flagsOR & (geom_colltype0|geom_no_coll_response))==geom_colltype0 && sp.pGeomProxy->IntersectLocked(pSphere,&gwd,0,&ip,pcontacts,lock)) { ++nHits; if (pEntity = (IEntity*)pEnts[i]->GetForeignData(PHYS_FOREIGN_ID_ENTITY)) pObj->SetAt(nHits*3-2, pEntity->GetScriptTable()); else pObj->SetNullAt(nHits*3-2); pObj->SetAt(nHits*3-1, sp.partid); pObj->SetAt(nHits*3, pWorld->GetPhysicalEntityId(pEnts[i])); if (pEnts[i]->GetType()!=PE_ARTICULATED) break; } } pSphere->Release(); return pH->EndFunction(*pObj); }
virtual void OnIterStart(SActivationInfo *pActInfo) { const int type = GetPortInt(pActInfo, EIP_Type); const Vec3& min(GetPortVec3(pActInfo, EIP_Min)); const Vec3& max(GetPortVec3(pActInfo, EIP_Max)); IPhysicalWorld *pWorld = gEnv->pPhysicalWorld; IPhysicalEntity **ppList = NULL; int numEnts = pWorld->GetEntitiesInBox(min,max,ppList,ent_all); for (int i = 0; i < numEnts; ++i) { const EntityId id = pWorld->GetPhysicalEntityId(ppList[i]); const EEntityType entityType = GetEntityType(id); if (IsValidType(type, entityType)) { AddEntity(id); } } }
virtual void OnIterStart(SActivationInfo *pActInfo) { const int type = GetPortInt(pActInfo, EIP_Type); const Vec3& center(GetPortVec3(pActInfo, EIP_Pos)); const float range = GetPortFloat(pActInfo, EIP_Range); const float rangeSq = range * range; const Vec3 min(center.x-range, center.y-range, center.z-range); const Vec3 max(center.x+range, center.y+range, center.z+range); IPhysicalWorld *pWorld = gEnv->pPhysicalWorld; IPhysicalEntity **ppList = NULL; int numEnts = pWorld->GetEntitiesInBox(min,max,ppList,ent_all); for (int i = 0; i < numEnts; ++i) { const EntityId id = pWorld->GetPhysicalEntityId(ppList[i]); const EEntityType entityType = GetEntityType(id); if (IsValidType(type, entityType)) { AddEntity(id); } } }
virtual void OnIterStart(SActivationInfo *pActInfo) { const int type = GetPortInt(pActInfo, EIP_Type); const char* area = GetPortString(pActInfo, EIP_Area); // Find the entity IEntitySystem *pEntitySystem = gEnv->pEntitySystem; if (pEntitySystem) { IEntity *pArea = pEntitySystem->FindEntityByName(area); if (pArea) { IEntityAreaProxy *pAreaProxy = (IEntityAreaProxy*)pArea->GetProxy(ENTITY_PROXY_AREA); if (pAreaProxy) { Vec3 min, max, worldPos(pArea->GetWorldPos()); min.Set(0.f,0.f,0.f); max.Set(0.f,0.f,0.f); EEntityAreaType areaType = pAreaProxy->GetAreaType(); // Construct bounding space around area switch (areaType) { case ENTITY_AREA_TYPE_BOX: { pAreaProxy->GetBox(min, max); min += worldPos; max += worldPos; } break; case ENTITY_AREA_TYPE_SPHERE: { Vec3 center; float radius = 0.f; pAreaProxy->GetSphere(center, radius); min.Set(center.x-radius, center.y-radius, center.z-radius); max.Set(center.x+radius, center.y+radius, center.z+radius); } break; case ENTITY_AREA_TYPE_SHAPE: { const Vec3 *points = pAreaProxy->GetPoints(); const int count = pAreaProxy->GetPointsCount(); if (count > 0) { Vec3 p = worldPos + points[0]; min = p; max = p; for (int i = 1; i < count; ++i) { p = worldPos + points[i]; if (p.x < min.x) min.x = p.x; if (p.y < min.y) min.y = p.y; if (p.z < min.z) min.z = p.z; if (p.x > max.x) max.x = p.x; if (p.y > max.y) max.y = p.y; if (p.z > max.z) max.z = p.z; } } } break; } IPhysicalWorld *pWorld = gEnv->pPhysicalWorld; IPhysicalEntity **ppList = NULL; int numEnts = pWorld->GetEntitiesInBox(min,max,ppList,ent_all); for (int i = 0; i < numEnts; ++i) { const EntityId id = pWorld->GetPhysicalEntityId(ppList[i]); const EEntityType entityType = GetEntityType(id); if (IsValidType(type, entityType)) { // Sanity check - Test entity's position IEntity *pEntity = pEntitySystem->GetEntity(id); if (pEntity && pAreaProxy->CalcPointWithin(id, pEntity->GetWorldPos(), pAreaProxy->GetHeight()==0)) { AddEntity(id); } } } } } } }
void CTornado::UpdateFlow() { IVehicleSystem* pVehicleSystem = g_pGame->GetIGameFramework()->GetIVehicleSystem(); assert(pVehicleSystem); float frameTime(gEnv->pTimer->GetFrameTime()); IPhysicalWorld *ppWorld = gEnv->pPhysicalWorld; Vec3 pos(GetEntity()->GetWorldPos()); //first, check the entities in range m_nextEntitiesCheck -= frameTime; if (m_nextEntitiesCheck<0.0f) { m_nextEntitiesCheck = 1.0f; Vec3 radiusVec(m_radius,m_radius,0); IPhysicalEntity **ppList = NULL; int numEnts = ppWorld->GetEntitiesInBox(pos-radiusVec,pos+radiusVec+Vec3(0,0,m_cloudHeight*0.5f),ppList,ent_sleeping_rigid|ent_rigid|ent_living); m_spinningEnts.clear(); for (int i=0;i<numEnts;++i) { // add check for spectating players... EntityId id = ppWorld->GetPhysicalEntityId(ppList[i]); CActor* pActor = static_cast<CActor*>(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(!pActor || !pActor->GetSpectatorMode()) { m_spinningEnts.push_back(id); } } //OutputDistance(); } //mess entities around for (size_t i=0;i<m_spinningEnts.size();++i) { IPhysicalEntity *ppEnt = ppWorld->GetPhysicalEntityById(m_spinningEnts[i]); if (ppEnt) { pe_status_pos spos; pe_status_dynamics sdyn; if (!ppEnt->GetStatus(&spos) || !ppEnt->GetStatus(&sdyn)) continue; //gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(spos.pos,2.0f,ColorB(255,0,255,255)); Vec3 delta(pos - spos.pos); delta.z = 0.0f; float dLen(delta.len()); float forceMult(max(0.0f,(m_radius-dLen)/m_radius)); if (dLen>0.001f) delta /= dLen; else delta.zero(); Vec3 upVector(0,0,1); float spinImpulse(m_spinImpulse); float attractionImpulse(m_attractionImpulse); float upImpulse(m_upImpulse); if (ppEnt->GetType() == PE_LIVING) { upImpulse *= 0.75f; attractionImpulse *= 0.35f; spinImpulse *= 1.5f; } if (IVehicle* pVehicle = pVehicleSystem->GetVehicle(m_spinningEnts[i])) { IVehicleMovement* pMovement = pVehicle->GetMovement(); if (pMovement && pMovement->GetMovementType() == IVehicleMovement::eVMT_Air) { SVehicleMovementEventParams params; params.fValue = forceMult; pMovement->OnEvent(IVehicleMovement::eVME_Turbulence, params); } } Vec3 spinForce( (delta % upVector) * spinImpulse ); Vec3 attractionForce(delta * attractionImpulse); Vec3 upForce(0,0,upImpulse); pe_action_impulse aimpulse; aimpulse.impulse = (spinForce + attractionForce + upForce) * (forceMult * sdyn.mass * frameTime); aimpulse.angImpulse = (upVector + (delta % upVector)) * (gf_PI * 0.33f * forceMult * sdyn.mass * frameTime); aimpulse.iApplyTime = 0; ppEnt->Action(&aimpulse); //gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(spos.pos,ColorB(255,0,255,255),spos.pos+aimpulse.impulse.GetNormalizedSafe(ZERO),ColorB(255,0,255,255)); } } }