int CScriptBind_Physics::RegisterExplosionCrack(IFunctionHandler *pH,const char *sGeometryFile,int nIdMaterial ) { IStatObj *pObj = gEnv->p3DEngine->LoadStatObj( sGeometryFile,"#ForceBreakable",NULL,false); if (!pObj || pObj->IsDefaultObject()) { ScriptWarning( "<RegisterExplosionCrack> Object file %s not found",sGeometryFile ); return pH->EndFunction(); } pObj->AddRef(); Vec3 vtx[3] = { pObj->GetHelperPos("1"),pObj->GetHelperPos("2"),pObj->GetHelperPos("3") }; //@TODO: restore it. m_pPhysicalWorld->GetGeomManager()->RegisterCrack( pObj->GetPhysGeom()->pGeom,vtx,0 ); return pH->EndFunction(); }
int CScriptBind_Physics::RegisterExplosionShape(IFunctionHandler *pH,const char *sGeometryFile,float fSize,int nIdMaterial,float fProbability, const char *sSplintersFile, float fSplintersOffset, const char *sSplintersCloudEffect) { ////////////////////////////////////////////////////////////////////////// // Remove all this. ////////////////////////////////////////////////////////////////////////// IStatObj *pObj = gEnv->p3DEngine->LoadStatObj( sGeometryFile,"#ForceBreakable",NULL,false ); if (!pObj || pObj->IsDefaultObject()) { ScriptWarning( "<RegisterExplosionShape> Object file %s not found",sGeometryFile ); return pH->EndFunction(); } pObj->AddRef(); pObj->GetIndexedMesh(true); // prepare idxMesh now if(sSplintersFile && *sSplintersFile!=0) // if sSplintersFile was specified { IStatObj *pSplinters = gEnv->p3DEngine->LoadStatObj(sSplintersFile,NULL,NULL,false); if (pSplinters) { pObj->SetSubObjectCount(pObj->GetSubObjectCount()+1); IStatObj::SSubObject *pSubObj = pObj->GetSubObject(pObj->GetSubObjectCount()-1); pSubObj->nType = STATIC_SUB_OBJECT_MESH; pSubObj->bHidden = true; pSubObj->name = "splinters"; (pSubObj->pStatObj = pSplinters)->AddRef(); pSubObj->helperSize.x = fSplintersOffset; nIdMaterial |= 1<<16; if (*sSplintersCloudEffect) { pSplinters->SetSubObjectCount(pSplinters->GetSubObjectCount()+1); pSplinters->SetFlags(pSplinters->GetFlags() & ~STATIC_OBJECT_COMPOUND); pSubObj = pSplinters->GetSubObject(pSplinters->GetSubObjectCount()-1); pSubObj->nType = STATIC_SUB_OBJECT_DUMMY; pSubObj->bHidden = true; pSubObj->name = "splinters_cloud"; pSubObj->properties = sSplintersCloudEffect; } } } phys_geometry *pPhysGeom = pObj->GetPhysGeom(); if (pPhysGeom) { m_pPhysicalWorld->AddExplosionShape( pPhysGeom->pGeom,fSize,nIdMaterial,fProbability ); } return pH->EndFunction(); }
//-------------------------------------------------------------------------------------------------- // 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; }//-------------------------------------------------------------------------------------------------