void CSmokeManager::CreateSmokeObstructionObject( SSmokeInstance& smokeInstance ) { smokeInstance.RemoveObstructionObject(); pe_params_pos pos; pos.scale = 0.1f; pos.pos = smokeInstance.vPositon; smokeInstance.pObstructObject = gEnv->pPhysicalWorld->CreatePhysicalEntity(PE_STATIC, &pos); if (smokeInstance.pObstructObject) { primitives::sphere sphere; sphere.center = Vec3(0,0,0); sphere.r = kMaxSmokeRadius; int obstructID = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceTypeIdByName("mat_obstruct"); IGeometry *pGeom = gEnv->pPhysicalWorld->GetGeomManager()->CreatePrimitive(primitives::sphere::type, &sphere); phys_geometry *geometry = gEnv->pPhysicalWorld->GetGeomManager()->RegisterGeometry(pGeom, obstructID); pGeom->Release(); pe_geomparams params; params.flags = geom_colltype14; geometry->nRefCount = 0; // automatically delete geometry smokeInstance.pObstructObject->AddGeometry(geometry, ¶ms); } }
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); }
void CVehicleMovementAerodynamic::AddSphere(Vec3 *_pvPos,float _fRadius,float _fMass,int _iID) { IGeomManager *pGeomManager = gEnv->pPhysicalWorld->GetGeomManager(); primitives::sphere Sphere; Sphere.center.Set(0.0f,0.0f,0.0f); Sphere.r = _fRadius; IGeometry *pGeometry = pGeomManager->CreatePrimitive(primitives::sphere::type,&Sphere); phys_geometry *pPhysGeometry = pGeomManager->RegisterGeometry(pGeometry); pGeometry->Release(); pe_geomparams GeomParams; GeomParams.pos = *_pvPos; GeomParams.mass = _fMass; if (IPhysicalEntity* pPhysics = GetPhysics()) pPhysics->AddGeometry(pPhysGeometry,&GeomParams,_iID); pGeomManager->UnregisterGeometry(pPhysGeometry); }
int CParachute::AddCel(IPhysicalEntity* pPhysics, int _iID,SWing *_pCel) { IPhysicalWorld *pPhysicalWorld = gEnv->pPhysicalWorld; primitives::box geomBox; geomBox.Basis = Matrix33::CreateRotationXYZ(Ang3(DEG2RAD(_pCel->fAngleX),DEG2RAD(_pCel->fAngleY),0.0f)); geomBox.bOriented = 1; geomBox.center.Set(0.0f,0.0f,0.0f); geomBox.size = _pCel->vSize; IGeometry *pGeom = pPhysicalWorld->GetGeomManager()->CreatePrimitive(primitives::box::type,&geomBox); phys_geometry *physGeom = pPhysicalWorld->GetGeomManager()->RegisterGeometry(pGeom); pGeom->Release(); pe_geomparams partpos; partpos.pos = _pCel->vPos; partpos.mass = _pCel->fMass; int id = pPhysics->AddGeometry(physGeom,&partpos); pPhysicalWorld->GetGeomManager()->UnregisterGeometry(physGeom); return id; }
int CVehicleMovementAerodynamic::AddBox(Vec3 *_pvPos,Vec3 *_pvSize,float _fMass,int _iID/*=-1*/) { IPhysicalEntity* pPhysics = GetPhysics(); IGeomManager *pGeomManager = gEnv->pPhysicalWorld->GetGeomManager(); primitives::box Box; Box.Basis.SetIdentity(); Box.center.Set(0.0f,0.0f,0.0f); Box.size = (*_pvSize) / 2.0f; Box.bOriented = 0; IGeometry *pGeometry = pGeomManager->CreatePrimitive(primitives::box::type,&Box); phys_geometry *pPhysGeometry = pGeomManager->RegisterGeometry(pGeometry); pGeometry->Release(); pe_geomparams partpos; partpos.pos = *_pvPos; partpos.mass = _fMass; int id = pPhysics->AddGeometry(pPhysGeometry,&partpos,_iID); pGeomManager->UnregisterGeometry(pPhysGeometry); return id; }
void CBoidObject::CreateRigidBox(SBoidContext &bc,const Vec3 &boxSize,float mass,float density) { if(m_pPhysics) { m_pPhysics = 0; } Vec3 orgVelocity = m_speed*m_heading; if(m_pPhysics && m_pPhysics->GetType() == PE_PARTICLE) { pe_params_particle pparams; m_pPhysics->GetParams(&pparams); orgVelocity = pparams.velocity*pparams.heading; } Quat q(IDENTITY); CalcOrientation(q); pe_params_pos bodypos; bodypos.pos = m_pos; bodypos.q = q; bodypos.scale = m_scale; IEntity *pEntity = gEnv->pEntitySystem->GetEntity(m_entity); if(!pEntity) return; SEntityPhysicalizeParams entityPhysParams; entityPhysParams.type = PE_RIGID; pEntity->Physicalize(entityPhysParams); m_pPhysics = pEntity->GetPhysics(); if(!m_pPhysics) return; m_pPhysics->SetParams(&bodypos); pe_params_flags pf; pf.flagsOR = pef_never_affect_triggers|pef_never_break; m_pPhysics->SetParams(&pf); primitives::box geomBox; geomBox.Basis.SetIdentity(); geomBox.center.Set(0,0,0); geomBox.size = boxSize; geomBox.bOriented = 0; IGeometry *pGeom = bc.physics->GetGeomManager()->CreatePrimitive(primitives::box::type,&geomBox); phys_geometry *physGeom = bc.physics->GetGeomManager()->RegisterGeometry(pGeom); pGeom->Release(); pe_geomparams partpos; partpos.pos.Set(0,0,0); if(mass > 0) partpos.mass = mass; // some fish mass. if(density > 0) partpos.density = density; partpos.surface_idx = GetGeometrySurfaceType(); m_pPhysics->AddGeometry(physGeom,&partpos,0); bc.physics->GetGeomManager()->UnregisterGeometry(physGeom); pe_simulation_params symparams; symparams.damping = 0.3f; symparams.dampingFreefall = 0.2f; m_pPhysics->SetParams(&symparams); pe_params_buoyancy pb; pb.waterDensity = 1000.0f; pb.waterDamping = 1; pb.waterResistance = 1000; pb.waterPlane.n.Set(0,0,1); //pb.waterPlane.origin.set(0,0,gEnv->p3DEngine->GetWaterLevel(&m_center)); pb.waterPlane.origin.Set(0,0,bc.waterLevel); m_pPhysics->SetParams(&pb); // Set original velocity on physics. pe_action_set_velocity psetvel; psetvel.v = orgVelocity; m_pPhysics->Action(&psetvel); }
// ----------------------------------------------------------------- // Name : displayAt // ----------------------------------------------------------------- void Button::displayAt(int iXOffset, int iYOffset, Color cpntColor, Color docColor) { if (m_bVisible) { IGeometry * pGeoToDisplay = m_pGeometryBase; bool bNeedPop = false; bool bAddMode = false; if (m_bClickState) { switch (m_ClickedOption) { case None: break; case ReplaceTex: pGeoToDisplay = m_pGeometryClicked; break; case AddTex: pGeoToDisplay->display(iXOffset, iYOffset, cpntColor * docColor); pGeoToDisplay = m_pGeometryClicked; break; case Decal: iXOffset += 3; iYOffset += 3; break; case Scale: { float coef = 1.2f; Vertex fCenter = Jogy::interface->screenTransform( iXOffset + getXPos() + getWidth() / 2, iYOffset + getYPos() + getHeight() / 2); Jogy::interface->pushMatrix(); Jogy::interface->translate(fCenter.x * (1 - coef), fCenter.y * (1 - coef), 0.0f); Jogy::interface->scale(coef, coef, 1.0f); bNeedPop = true; break; } case Enlight: { cpntColor = (cpntColor + 1) / 2; bAddMode = true; break; } } } if (!m_bEnabled) { Color c(1,1,1,0.3f); cpntColor.multiply(&c); } else if (m_bMouseOver && !m_bClickState) { switch (m_HoverOption) { case None: break; case ReplaceTex: pGeoToDisplay = m_pGeometryHover; break; case AddTex: pGeoToDisplay->display(iXOffset, iYOffset, cpntColor * docColor); pGeoToDisplay = m_pGeometryHover; break; case Decal: iXOffset += 3; iYOffset += 3; break; case Scale: { float coef = 1.2f; Vertex fCenter = Jogy::interface->screenTransform( iXOffset + getXPos() + getWidth() / 2, iYOffset + getYPos() + getHeight() / 2); Jogy::interface->pushMatrix(); Jogy::interface->translate(fCenter.x * (1 - coef), fCenter.y * (1 - coef), 0.0f); Jogy::interface->scale(coef, coef, 1.0f); bNeedPop = true; break; } case Enlight: { cpntColor = (cpntColor + 1) / 2; bAddMode = true; break; } } } bool bPrevMode = false; if (bAddMode) { bPrevMode = Jogy::interface->setAdditiveMode(true); } pGeoToDisplay->display(iXOffset, iYOffset, cpntColor * docColor); m_pLabel->displayAt(iXOffset, iYOffset, cpntColor, docColor); if (m_pGeometryAttachedImage != NULL) { m_pGeometryAttachedImage->display(m_iXPxl + iXOffset, m_iYPxl + iYOffset, cpntColor * m_DiffuseColor); } if (bAddMode) { Jogy::interface->setAdditiveMode(bPrevMode); } if (bNeedPop) { Jogy::interface->popMatrix(); } } }
void CPickAndThrowProxy::Physicalize() { IEntity* pPlayerEntity = m_player.GetEntity(); IPhysicalEntity* pPlayerPhysics = pPlayerEntity->GetPhysics(); const bool bPhysicsChanged = (pPlayerPhysics != m_pLastPlayerPhysics); // Don't create it again if already exists and its associated physic entity is the same if ((m_pPickNThrowProxy && !bPhysicsChanged) || !g_pGameCVars->pl_pickAndThrow.useProxies) return; CRY_ASSERT(m_pParams != NULL); if (!m_pParams) return; if (bPhysicsChanged) Unphysicalize(); pe_params_pos pp; pp.pos = pPlayerEntity->GetWorldPos(); pp.iSimClass = SC_ACTIVE_RIGID; IPhysicalEntity* pPickNThrowProxy = gEnv->pPhysicalWorld->CreatePhysicalEntity(PE_ARTICULATED, &pp, pPlayerEntity, PHYS_FOREIGN_ID_ENTITY); phys_geometry *pGeom = NULL; switch(m_pParams->proxyShape) { case ePS_Capsule : { primitives::capsule prim; prim.axis.Set(0,0,1); prim.center.zero(); prim.r = m_pParams->fRadius; prim.hh = m_pParams->fHeight; IGeometry *pPrimGeom = gEnv->pPhysicalWorld->GetGeomManager()->CreatePrimitive(primitives::capsule::type, &prim); pGeom = gEnv->pPhysicalWorld->GetGeomManager()->RegisterGeometry(pPrimGeom, 0); pGeom->nRefCount = 0; pPrimGeom->Release(); } break; case ePS_Sphere : { primitives::sphere prim; prim.center.zero(); prim.r = m_pParams->fRadius; IGeometry *pPrimGeom = gEnv->pPhysicalWorld->GetGeomManager()->CreatePrimitive(primitives::sphere::type, &prim); pGeom = gEnv->pPhysicalWorld->GetGeomManager()->RegisterGeometry(pPrimGeom, 0); pGeom->nRefCount = 0; pPrimGeom->Release(); } break; case ePS_Cylinder : { primitives::cylinder prim; prim.axis.Set(0,0,1); prim.center.zero(); prim.r = m_pParams->fRadius; prim.hh = m_pParams->fHeight; IGeometry *pPrimGeom = gEnv->pPhysicalWorld->GetGeomManager()->CreatePrimitive(primitives::cylinder::type, &prim); pGeom = gEnv->pPhysicalWorld->GetGeomManager()->RegisterGeometry(pPrimGeom, 0); pGeom->nRefCount = 0; pPrimGeom->Release(); } break; default: CRY_ASSERT_MESSAGE(false, "Invalid proxy shape?"); } if (pGeom) { CRY_ASSERT(pPlayerEntity->GetPhysics() && (pPlayerEntity->GetPhysics()->GetType() == PE_LIVING)); pe_params_articulated_body pab; pab.pHost = pPlayerPhysics; m_pLastPlayerPhysics = pPlayerPhysics; pab.posHostPivot = m_pParams->vPosPivot; pab.bGrounded = 1; pab.nJointsAlloc = 1; pPickNThrowProxy->SetParams(&pab); pe_articgeomparams gp; gp.pos.zero(); gp.flags = CPickAndThrowProxy::geom_colltype_proxy; gp.flagsCollider = 0; gp.mass = 0.0f; pPickNThrowProxy->AddGeometry(pGeom, &gp); m_pPickNThrowProxy = pPickNThrowProxy; } }
//-------------------------------------------------------------------------------------------------- // Name: ExtractPhysDataFromEvent // Desc: Extracts collider's physical data from an event // Note 1: Ideally *ALL* of this should be calculated offline and the minimal data loaded // Note 2: We're currently duplicating some work done in CryAction, so should be reading that in //-------------------------------------------------------------------------------------------------- bool CBreakableGlassSystem::ExtractPhysDataFromEvent(const EventPhysCollision& physEvent, SBreakableGlassPhysData& data, SBreakableGlassInitParams& initParams) { if (IPhysicalEntity* pPhysEntity = physEvent.pEntity[PHYSEVENT_COLLIDEE]) { // Get collider entity data const int entType = pPhysEntity->GetiForeignData(); const int entPart = physEvent.partid[PHYSEVENT_COLLIDEE]; // Local output data IStatObj* pStatObj = NULL; IMaterial* pRenderMat = NULL; phys_geometry* pPhysGeom = NULL; uint renderFlags = 0; Matrix34A entityMat; entityMat.SetIdentity(); // Only handling simple objects at the moment const pe_type physType = pPhysEntity->GetType(); if (physType == PE_STATIC || physType == PE_RIGID) { // Entity or static object? if (entType == PHYS_FOREIGN_ID_ENTITY) { IEntity* pEntity = (IEntity*)pPhysEntity->GetForeignData(PHYS_FOREIGN_ID_ENTITY); pStatObj = pEntity->GetStatObj(entPart); entityMat = pEntity->GetSlotWorldTM(entPart); if (IEntityRenderProxy* pRenderProxy = (IEntityRenderProxy*)pEntity->GetProxy(ENTITY_PROXY_RENDER)) { pRenderMat = pRenderProxy->GetRenderMaterial(entPart); IRenderNode* pRenderNode = pRenderProxy->GetRenderNode(); renderFlags = pRenderNode ? pRenderNode->GetRndFlags() : 0; // Fall back to top level material if sub-object fails to find it if (!pRenderMat) { pRenderMat = pRenderProxy->GetRenderMaterial(); if (!pRenderMat && pStatObj) { pRenderMat = pStatObj->GetMaterial(); } } } } else if (entType == PHYS_FOREIGN_ID_STATIC) { if (IRenderNode* pBrush = (IRenderNode*)physEvent.pForeignData[PHYSEVENT_COLLIDEE]) { pStatObj = pBrush->GetEntityStatObj(0, 0, &entityMat); pRenderMat = pBrush->GetMaterial(); renderFlags = pBrush->GetRndFlags(); // May need to get sub-object and it's material if (pStatObj && pStatObj->GetFlags() & STATIC_OBJECT_COMPOUND) { if (IStatObj::SSubObject* pSubObj = pStatObj->GetSubObject(entPart)) { pStatObj = pSubObj->pStatObj; if (!pSubObj->bIdentityMatrix) { entityMat = entityMat * pSubObj->tm; } // Find the correct sub-material // Note: We loop as the slots don't always line up const int subMtlCount = pRenderMat->GetSubMtlCount(); for (int i = 0; i < subMtlCount; ++i) { if (IMaterial* pSubMat = pRenderMat->GetSubMtl(i)) { if (pSubMat->GetSurfaceTypeId() == initParams.surfaceTypeId) { pRenderMat = pSubMat; break; } } } } } } } } // Validate geometry of collided object pPhysGeom = pStatObj ? pStatObj->GetPhysGeom() : NULL; IGeometry* pGeom = pPhysGeom ? pPhysGeom->pGeom : NULL; bool validGeom = false; primitives::box bbox; int thinAxis; if (pGeom) { // Determine thin geometry axis for glass alignment pGeom->GetBBox(&bbox); thinAxis = idxmin3((float*)&bbox.size); // Handle geometry mesh type switch (pGeom->GetType()) { case GEOM_TRIMESH: // Perform full mesh analysis and extraction if (mesh_data* pPhysMeshData = (mesh_data*)pGeom->GetData()) { if (ValidatePhysMesh(pPhysMeshData, thinAxis) && ExtractPhysMesh(pPhysMeshData, thinAxis, bbox, data.defaultFrag)) { validGeom = true; } } break; case GEOM_BOX: // Simple box, so assume valid validGeom = true; break; default: // Only support boxes and tri-meshes break; } } // Invalid geometry, so can't continue if (!validGeom) { pPhysGeom = NULL; } // Attempt UV coord extraction from render mesh else { ExtractUVCoords(pStatObj, bbox, thinAxis, data); } // Copy final data data.pStatObj = pStatObj; data.pPhysGeom = pPhysGeom; data.renderFlags = renderFlags; data.entityMat = entityMat; initParams.pGlassMaterial = pRenderMat; } return data.pStatObj && data.pPhysGeom && initParams.pGlassMaterial; }//-------------------------------------------------------------------------------------------------