void CBoidObject::Physicalize( SBoidContext &bc ) { pe_params_particle ppart; //ppart.gravity = Vec3(0,0,0); ppart.flags = particle_traceable | particle_no_roll | pef_never_affect_triggers | pef_log_collisions; ppart.mass = 0; ppart.size = max(bc.fBoidRadius,0.01f); ppart.thickness = max(bc.fBoidThickness,0.01f); ppart.gravity = Vec3(0,0,0); ppart.kAirResistance = 0.0f; if(m_object) { IMaterial* pMat = m_object->GetIMaterial(); if(pMat->GetSubMtlCount() > 0) { ppart.surface_idx = pMat->GetSubMtl(0)->GetSurfaceTypeId(); } else { ppart.surface_idx = pMat->GetSurfaceTypeId(); } } else { // just like in GetGeometrySurfaceType() ppart.surface_idx = 0; IEntity *pEntity = gEnv->pEntitySystem->GetEntity(m_entity); if (pEntity) { IStatObj *pStatObj = pEntity->GetStatObj(0|ENTITY_SLOT_ACTUAL); if (pStatObj) { ISurfaceType *pSurfaceType = gEnv->pEntitySystem->GetBreakableManager()->GetFirstSurfaceType(pStatObj); if (pSurfaceType) ppart.surface_idx = pSurfaceType->GetId(); } } } IEntity *pEntity = gEnv->pEntitySystem->GetEntity(m_entity); if (pEntity) { SEntityPhysicalizeParams params; params.pParticle = &ppart; params.type = PE_PARTICLE; pEntity->Physicalize(params); m_pPhysics = pEntity->GetPhysics(); } }
void CBodyDestrutibilityInstance::Update( float frameTime ) { if (m_mikeAttachmentEntityId && m_mikeExplodeAlphaTestFadeOutTimer > 0.0f) { m_mikeExplodeAlphaTestFadeOutTimer -= min(frameTime, m_mikeExplodeAlphaTestFadeOutTimer); float alphaTestValue = max(min(m_mikeExplodeAlphaTestFadeOutTimer*m_mikeExplodeAlphaTestFadeOutScale+1.0f, 1.0f), 0.0f) * m_mikeExplodeAlphaTestMax; IEntity* pJellyEntity = gEnv->pEntitySystem->GetEntity(m_mikeAttachmentEntityId); ICharacterInstance* pJellyCharacter = pJellyEntity ? pJellyEntity->GetCharacter(0) : 0; IMaterial* pJellyMaterial = pJellyCharacter ? pJellyCharacter->GetIMaterial() : 0; if (pJellyMaterial) { int numSubMaterials = pJellyMaterial->GetSubMtlCount(); for (int i = 0; i < numSubMaterials; ++i) { IMaterial* pSubJellyMaterial = pJellyMaterial->GetSubMtl(i); pSubJellyMaterial->SetGetMaterialParamFloat("alpha", alphaTestValue, false); } } } }
//------------------------------------------------------------------------ bool CVehiclePartTread::Init(IVehicle* pVehicle, const CVehicleParams& table, IVehiclePart* parent, CVehicle::SPartInitInfo& initInfo, int partType) { if (!CVehiclePartBase::Init(pVehicle, table, parent, initInfo, eVPT_Tread)) return false; CVehicleParams subTable = table.findChild("Tread"); // Tread subtable if (!subTable) return false; string filename = subTable.getAttr("filename"); if (filename.empty()) return false; subTable.getAttr("uvSpeedMultiplier", m_uvSpeedMultiplier); if (table.haveAttr("component")) { if (CVehicleComponent* pComponent = static_cast<CVehicleComponent*>(m_pVehicle->GetComponent(table.getAttr("component")))) pComponent->AddPart(this); } m_slot = GetEntity()->LoadCharacter(m_slot, filename); m_pCharInstance = GetEntity()->GetCharacter(m_slot); if (!m_pCharInstance) return false; if (subTable.haveAttr("materialName")) { string materialName = subTable.getAttr("materialName"); materialName.MakeLower(); IMaterial* pMaterial = 0; const char* subMtlName = 0; int subMtlSlot = -1; // find tread material IEntityRenderProxy *pRenderProxy = (IEntityRenderProxy*)GetEntity()->GetProxy(ENTITY_PROXY_RENDER); if (pRenderProxy) { pMaterial = pRenderProxy->GetRenderMaterial(m_slot); if (pMaterial) { // if matname doesn't fit, look in submaterials if (string(pMaterial->GetName()).MakeLower().find(materialName) == string::npos) { for (int i=0; i < pMaterial->GetSubMtlCount(); ++i) { if (string(pMaterial->GetSubMtl(i)->GetName()).MakeLower().find(materialName) != string::npos) { subMtlName = pMaterial->GetSubMtl(i)->GetName(); subMtlSlot = i; break; } } } } } if (pMaterial) { // clone IMaterial *pCloned = pMaterial->GetMaterialManager()->CloneMultiMaterial(pMaterial, subMtlName); if (pCloned) { pRenderProxy->SetSlotMaterial(m_slot, pCloned); pMaterial = pCloned; m_pMaterial = pMaterial; } if (subMtlSlot > -1) m_pShaderResources = pMaterial->GetShaderItem(subMtlSlot).m_pShaderResources; else m_pShaderResources = pMaterial->GetShaderItem().m_pShaderResources; } if (m_pShaderResources) { for (int i = 0; i < EFTT_MAX; ++i) { if (!m_pShaderResources->GetTexture(i)) continue; SEfTexModificator& modif = *m_pShaderResources->GetTexture(i)->AddModificator(); modif.SetMember("m_eMoveType[0]", 1.0f); // ETMM_Fixed: u = m_OscRate[0] + sourceU modif.SetMember("m_OscRate[0]", 0.0f); } } } char wheelName[256]; IDefaultSkeleton& rIDefaultSkeleton = m_pCharInstance->GetIDefaultSkeleton(); for (int i=0; i<rIDefaultSkeleton.GetJointCount(); ++i) { const char* boneName = rIDefaultSkeleton.GetJointNameByID(i); if (0 != boneName) { // extract wheel name const size_t len = strcspn(boneName, "_"); if (len < strlen(boneName) && len < sizeof(wheelName)) { cry_strcpy(wheelName, boneName, len); CVehiclePartSubPartWheel* pWheel = (CVehiclePartSubPartWheel*)m_pVehicle->GetPart(wheelName); if (pWheel) { SWheelInfo wheelInfo; wheelInfo.slot = pWheel->m_slot; wheelInfo.jointId = i; wheelInfo.pWheel = pWheel; m_wheels.push_back(wheelInfo); m_lastWheelIndex = pWheel->GetWheelIndex(); } } } } m_pVehicle->SetObjectUpdate(this, IVehicle::eVOU_AlwaysUpdate); m_state = eVGS_Default; return true; }
//-------------------------------------------------------------------------------------------------- // 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; }//-------------------------------------------------------------------------------------------------