void CPHSkeleton::UnsplitSingle(CPHSkeleton* SO) { //Msg("%o,received has %d,",this,m_unsplited_shels.size()); if (0==m_unsplited_shels.size()) return; //. hack CPhysicsShellHolder* obj = PPhysicsShellHolder(); CPhysicsShellHolder* O =SO->PPhysicsShellHolder(); VERIFY2(m_unsplited_shels.size(),"NO_SHELLS !!"); VERIFY2(!O->m_pPhysicsShell,"this has shell already!!!"); CPhysicsShell* newPhysicsShell=m_unsplited_shels.front().first; O->m_pPhysicsShell=newPhysicsShell; VERIFY(_valid(newPhysicsShell->mXFORM)); IKinematics *newKinematics=smart_cast<IKinematics*>(O->Visual()); IKinematics *pKinematics =smart_cast<IKinematics*>(obj->Visual()); Flags64 mask0,mask1; u16 split_bone=m_unsplited_shels.front().second; mask1.assign(pKinematics->LL_GetBonesVisible());//source bones mask pKinematics->LL_SetBoneVisible(split_bone,FALSE,TRUE); pKinematics->CalculateBones_Invalidate (); pKinematics->CalculateBones (TRUE); mask0.assign(pKinematics->LL_GetBonesVisible());//first part mask VERIFY2(mask0.flags,"mask0 -Zero"); mask0.invert(); mask1.and(mask0.flags);//second part mask newKinematics->LL_SetBoneRoot (split_bone); VERIFY2(mask1.flags,"mask1 -Zero"); newKinematics->LL_SetBonesVisible (mask1.flags); newKinematics->CalculateBones_Invalidate (); newKinematics->CalculateBones (TRUE); newPhysicsShell->set_Kinematics(newKinematics); VERIFY(_valid(newPhysicsShell->mXFORM)); newPhysicsShell->ResetCallbacks(split_bone,mask1); VERIFY(_valid(newPhysicsShell->mXFORM)); newPhysicsShell->ObjectInRoot().identity(); if(!newPhysicsShell->isEnabled())O->processing_deactivate(); newPhysicsShell->set_PhysicsRefObject(O); m_unsplited_shels.erase(m_unsplited_shels.begin()); O->setVisible(TRUE); O->setEnabled(TRUE); SO->CopySpawnInit (); CopySpawnInit (); VERIFY3(CheckObjectSize(pKinematics),*(O->cNameVisual()),"Object unsplit whith no size"); VERIFY3(CheckObjectSize(newKinematics),*(O->cNameVisual()),"Object unsplit whith no size"); }
void CPHShellSimpleCreator::CreatePhysicsShell() { CPhysicsShellHolder* owner = smart_cast<CPhysicsShellHolder*>(this); VERIFY(owner); if (!owner->Visual()) return; CKinematics* pKinematics = smart_cast<CKinematics*>(owner->Visual()); VERIFY (pKinematics); if(owner->PPhysicsShell()) return; owner->PPhysicsShell() = P_create_Shell(); #ifdef DEBUG owner->PPhysicsShell()->dbg_obj=owner; #endif owner->m_pPhysicsShell->build_FromKinematics (pKinematics,0); owner->PPhysicsShell()->set_PhysicsRefObject (owner); //m_pPhysicsShell->SmoothElementsInertia(0.3f); owner->PPhysicsShell()->mXFORM.set (owner->XFORM()); owner->PPhysicsShell()->SetAirResistance (0.001f, 0.02f); }
void CPHCollisionDamageReceiver::Init() { CPhysicsShellHolder *sh =PPhysicsShellHolder (); IKinematics *K =smart_cast<IKinematics*>(sh->Visual()); CInifile *ini=K->LL_UserData(); if(ini->section_exist("collision_damage")) { CInifile::Sect& data = ini->r_section("collision_damage"); for (CInifile::SectCIt I=data.Data.begin(); I!=data.Data.end(); I++){ const CInifile::Item& item = *I; u16 index = K->LL_BoneID(*item.first); R_ASSERT3(index != BI_NONE, "Wrong bone name", *item.first); BoneInsert(index,float(atof(*item.second))); CODEGeom* og= sh->PPhysicsShell()->get_GeomByID(index); //R_ASSERT3(og, "collision damage bone has no physics collision", *item.first); if(og)og->add_obj_contact_cb(CollisionCallback); } } }
void CBlackGraviArtefact::GraviStrike() { xr_list<s16> elements_list; xr_list<Fvector> bone_position_list; Fvector object_pos ; Fvector strike_dir ; rq_storage.r_clear (); for(GAME_OBJECT_LIST_it it = m_GameObjectList.begin(); m_GameObjectList.end() != it; ++it) { CPhysicsShellHolder* pGameObject = *it; if(pGameObject->Visual()) pGameObject->Center(object_pos); else object_pos.set(pGameObject->Position()); strike_dir.sub(object_pos, Position()); float distance = strike_dir.magnitude(); float impulse = 100.f*m_fStrikeImpulse * (1.f - (distance/m_fRadius)* (distance/m_fRadius)); if(impulse > .001f) { //? BOOL enabled = getEnabled(); //? setEnabled (FALSE); impulse *= CExplosive::ExplosionEffect (rq_storage,NULL,pGameObject, Position(),m_fRadius); //? setEnabled (enabled); } float hit_power ; CEntityAlive* pEntityAlive = smart_cast<CEntityAlive*>(pGameObject); if(pGameObject->m_pPhysicsShell) hit_power = 0; else if(pEntityAlive && pEntityAlive->g_Alive() && pEntityAlive->character_physics_support()->movement()->CharacterExist()) hit_power = 0; else hit_power = impulse; if(impulse > .001f) { while(!elements_list.empty()) { s16 element = elements_list.front(); Fvector bone_pos = bone_position_list.front(); NET_Packet P; SHit HS; HS.GenHeader(GE_HIT, pGameObject->ID()); // u_EventGen (P,GE_HIT, pGameObject->ID()); HS.whoID =ID(); // P.w_u16 (ID()); HS.weaponID = ID(); // P.w_u16 (ID()); HS.dir = strike_dir; // P.w_dir (strike_dir); HS.power = hit_power; // P.w_float (hit_power); HS.boneID = element; // P.w_s16 (element); HS.p_in_bone_space = bone_pos; // P.w_vec3 (bone_pos); HS.impulse = impulse; // P.w_float (impulse); HS.hit_type = (ALife::eHitTypeWound); // P.w_u16 (u16(ALife::eHitTypeWound)); HS.Write_Packet(P); u_EventSend (P); elements_list.pop_front(); bone_position_list.pop_front(); } } } }
bool CPHSkeleton::Spawn(CSE_Abstract *D) { CSE_PHSkeleton *po = smart_cast<CSE_PHSkeleton*>(D); VERIFY (po); m_flags = po->_flags; CSE_Visual *visual = smart_cast<CSE_Visual*>(D); VERIFY (visual); m_startup_anim = visual->startup_animation; if(po->_flags.test(CSE_PHSkeleton::flSpawnCopy)) { CPHSkeleton* source=smart_cast<CPHSkeleton*>(Level().Objects.net_Find(po->source_id)); R_ASSERT2(source,"no source"); source->UnsplitSingle(this); m_flags.set (CSE_PHSkeleton::flSpawnCopy,FALSE); po->_flags.set (CSE_PHSkeleton::flSpawnCopy,FALSE); po->source_id =BI_NONE; return true; } else { CPhysicsShellHolder *obj = PPhysicsShellHolder(); IKinematics *K = NULL; if (obj->Visual()) { K= smart_cast<IKinematics*>(obj->Visual()); if(K) { K->LL_SetBoneRoot(po->saved_bones.root_bone); K->LL_SetBonesVisible(po->saved_bones.bones_mask); } } SpawnInitPhysics(D); RestoreNetState(po); if(obj->PPhysicsShell()&&obj->PPhysicsShell()->isFullActive()) obj->PPhysicsShell()->GetGlobalTransformDynamic(&obj->XFORM()); CPHDestroyableNotificate::spawn_notificate(D); if(K) { CInifile* ini=K->LL_UserData(); if(ini&&ini->section_exist("collide")) { if(ini->line_exist("collide","not_collide_parts")) { CGID gr= CPHCollideValidator::RegisterGroup(); obj->PPhysicsShell()->RegisterToCLGroup(gr); } } if(ini&&ini->section_exist("collide_parts")) { if(ini->line_exist("collide_parts","small_object")) { obj->PPhysicsShell()->SetSmall(); } if(ini->line_exist("collide_parts","ignore_small_objects")) { obj->PPhysicsShell()->SetIgnoreSmall(); } } } } return false; }