void CCar::CreateSkeleton(CSE_Abstract *po) { if (!Visual()) return; IRenderVisual *pVis = Visual(); IKinematics* pK = smart_cast<IKinematics*>(pVis); IKinematicsAnimated* pKA = smart_cast<IKinematicsAnimated*>(pVis); if(pKA) { pKA->PlayCycle ("idle"); pK->CalculateBones (TRUE); } phys_shell_verify_object_model ( *this ); #pragma todo(" replace below by P_build_Shell or call inherited") m_pPhysicsShell = P_create_Shell(); m_pPhysicsShell->build_FromKinematics(pK,&bone_map); m_pPhysicsShell->set_PhysicsRefObject(this); m_pPhysicsShell->mXFORM.set(XFORM()); m_pPhysicsShell->Activate(true); m_pPhysicsShell->SetAirResistance(0.f,0.f); m_pPhysicsShell->SetPrefereExactIntegration(); ApplySpawnIniToPhysicShell(&po->spawn_ini(),m_pPhysicsShell,false); ApplySpawnIniToPhysicShell(pK->LL_UserData(),m_pPhysicsShell,false); }
void CPhysicObject::create_collision_model ( ) { xr_delete( collidable.model ); VERIFY( Visual() ); IKinematics *K = Visual()->dcast_PKinematics (); VERIFY( K ); CInifile* ini = K->LL_UserData(); if( ini && ini->section_exist( "collide" ) && ini->line_exist("collide", "mesh" ) && ini->r_bool("collide", "mesh" ) ) { collidable.model = xr_new<CCF_DynamicMesh>( this ); return; } collidable.model = xr_new<CCF_Skeleton>(this); /* switch(m_type) { case epotBox: case epotFixedChain: case epotFreeChain : case epotSkeleton : collidable.model = xr_new<CCF_Skeleton>(this); break; default: NODEFAULT; } */ }
bool CCar::attach_Actor(CGameObject* actor) { if(Owner()||CPHDestroyable::Destroyed()) return false; CHolderCustom::attach_Actor(actor); IKinematics* K = smart_cast<IKinematics*>(Visual()); CInifile* ini = K->LL_UserData(); int id; if(ini->line_exist("car_definition","driver_place")) id=K->LL_BoneID(ini->r_string("car_definition","driver_place")); else { Owner()->setVisible(0); id=K->LL_GetBoneRoot(); } CBoneInstance& instance=K->LL_GetBoneInstance (u16(id)); m_sits_transforms.push_back(instance.mTransform); OnCameraChange(ectFirst); PPhysicsShell()->Enable(); PPhysicsShell()->add_ObjectContactCallback(ActorObstacleCallback); // VisualUpdate(); processing_activate(); ReleaseHandBreak(); // CurrentGameUI()->UIMainIngameWnd->CarPanel().Show(true); // CurrentGameUI()->UIMainIngameWnd->CarPanel().SetCarHealth(fEntityHealth/100.f); //CurrentGameUI()->UIMainIngameWnd.ShowBattery(true); //CBoneData& bone_data=K->LL_GetData(id); //Fmatrix driver_pos_tranform; //driver_pos_tranform.setHPB(bone_data.bind_hpb.x,bone_data.bind_hpb.y,bone_data.bind_hpb.z); //driver_pos_tranform.c.set(bone_data.bind_translate); //m_sits_transforms.push_back(driver_pos_tranform); //H_SetParent(actor); return true; }
void imotion_position::rootbone_callback ( CBoneInstance *BI ) { imotion_position *im = ( imotion_position* )BI->callback_param(); VERIFY( im ); if( !im->update_callback.update ) return; VERIFY( im->shell ); IKinematics *K = im->shell->PKinematics( ); VERIFY( K ); IKinematicsAnimated *KA = smart_cast<IKinematicsAnimated *>( K ); VERIFY( KA ); SKeyTable keys; KA->LL_BuldBoneMatrixDequatize( &K->LL_GetData( 0 ), u8(-1), keys ); CKey *key = 0; for( int i = 0; i < keys.chanel_blend_conts[0]; ++i ) { if ( keys.blends[0][i] == im->blend) key = &keys.keys[0][i]; } if( key ) { key->Q.rotation( Fvector().set( 0, 1, 0 ), im->angle ); } KA->LL_BoneMatrixBuild( *BI, &Fidentity, keys ); R_ASSERT2( _valid(BI->mTransform), "imotion_position::rootbone_callback" ); }
template <class T> IC void CCar::fill_wheel_vector(LPCSTR S,xr_vector<T>& type_wheels) { IKinematics* pKinematics =smart_cast<IKinematics*>(Visual()); string64 S1; int count = _GetItemCount(S); for (int i=0 ;i<count; ++i) { _GetItem (S,i,S1); u16 bone_id = pKinematics->LL_BoneID(S1); type_wheels.push_back (T()); T& twheel = type_wheels.back(); BONE_P_PAIR_IT J = bone_map.find(bone_id); if (J == bone_map.end()) { bone_map.insert(mk_pair(bone_id,physicsBone())); SWheel& wheel = (m_wheels_map.insert(mk_pair(bone_id,SWheel(this)))).first->second; wheel.bone_id = bone_id; twheel.pwheel = &wheel; wheel .Load(S1); twheel .Load(S1); } else { twheel.pwheel = &(m_wheels_map.find(bone_id))->second; twheel .Load(S1); } } }
void CWeaponStatMgun::UpdateBarrelDir() { IKinematics* K = smart_cast<IKinematics*>(Visual()); m_fire_bone_xform = K->LL_GetTransform(m_fire_bone); m_fire_bone_xform.mulA_43 (XFORM()); m_fire_pos.set (0,0,0); m_fire_bone_xform.transform_tiny(m_fire_pos); m_fire_dir.set (0,0,1); m_fire_bone_xform.transform_dir (m_fire_dir); m_allow_fire = true; Fmatrix XFi; XFi.invert (XFORM()); Fvector dep; XFi.transform_dir (dep,m_destEnemyDir); {// x angle m_i_bind_x_xform.transform_dir(dep); dep.normalize(); m_tgt_x_rot = angle_normalize_signed(m_bind_x_rot-dep.getP()); float sv_x = m_tgt_x_rot; clamp (m_tgt_x_rot,-m_lim_x_rot.y,-m_lim_x_rot.x); if (!fsimilar(sv_x,m_tgt_x_rot,EPS_L)) m_allow_fire=FALSE; } {// y angle m_i_bind_y_xform.transform_dir(dep); dep.normalize(); m_tgt_y_rot = angle_normalize_signed(m_bind_y_rot-dep.getH()); float sv_y = m_tgt_y_rot; clamp (m_tgt_y_rot,-m_lim_y_rot.y,-m_lim_y_rot.x); if (!fsimilar(sv_y,m_tgt_y_rot,EPS_L)) m_allow_fire=FALSE; } m_cur_x_rot = angle_inertion_var(m_cur_x_rot,m_tgt_x_rot,0.5f,3.5f,PI_DIV_6,Device.fTimeDelta); m_cur_y_rot = angle_inertion_var(m_cur_y_rot,m_tgt_y_rot,0.5f,3.5f,PI_DIV_6,Device.fTimeDelta); }
void CExplosiveRocket::PH_A_CrPr () { if (m_just_after_spawn) { CPhysicsShellHolder& obj = CInventoryItem::object(); VERIFY(obj.Visual()); IKinematics *K = obj.Visual()->dcast_PKinematics(); VERIFY( K ); if (!obj.PPhysicsShell()) { Msg("! ERROR: PhysicsShell is NULL, object [%s][%d]", obj.cName().c_str(), obj.ID()); return; } if(!obj.PPhysicsShell()->isFullActive()) { K->CalculateBones_Invalidate(); K->CalculateBones(TRUE); } obj.PPhysicsShell()->GetGlobalTransformDynamic(&obj.XFORM()); K->CalculateBones_Invalidate(); K->CalculateBones(TRUE); obj.spatial_move(); m_just_after_spawn = false; } }
void SArtefactDetectorsSupport::SetVisible(bool b) { m_switchVisTime = Device.dwTimeGlobal; if(b == !!m_parent->getVisible()) return; if(b) m_parent->StartLights (); else m_parent->StopLights (); if(b) { LPCSTR curr = pSettings->r_string(m_parent->cNameSect().c_str(), (b)?"det_show_particles":"det_hide_particles"); IKinematics* K = smart_cast<IKinematics*>(m_parent->Visual()); R_ASSERT2 (K, m_parent->cNameSect().c_str()); LPCSTR bone = pSettings->r_string(m_parent->cNameSect().c_str(), "particles_bone"); u16 bone_id = K->LL_BoneID(bone); R_ASSERT2 (bone_id!=BI_NONE, bone); m_parent->CParticlesPlayer::StartParticles(curr,bone_id,Fvector().set(0,1,0),m_parent->ID()); curr = pSettings->r_string(m_parent->cNameSect().c_str(), (b)?"det_show_snd":"det_hide_snd"); m_sound.create (curr, st_Effect, sg_SourceType); m_sound.play_at_pos (0, m_parent->Position(), 0); } m_parent->setVisible (b); m_parent->SwitchAfParticles(b); }
//проверка на попадание "осколком" по объекту ICF static BOOL grenade_hit_callback(collide::rq_result& result, LPVOID params) { SExpQParams& ep = *(SExpQParams*)params; u16 mtl_idx = GAMEMTL_NONE_IDX; if(result.O){ IKinematics* V = 0; if (0!=(V=smart_cast<IKinematics*>(result.O->Visual()))){ CBoneData& B= V->LL_GetData((u16)result.element); mtl_idx = B.game_mtl_idx; } }else{ //получить треугольник и узнать его материал CDB::TRI* T = Level().ObjectSpace.GetStaticTris()+result.element; mtl_idx = T->material; } SGameMtl* mtl = GMLib.GetMaterialByIdx(mtl_idx); float shoot_factor = 1.f - mtl->fShootFactor; ep.shoot_factor *=shoot_factor; #ifdef DEBUG if(ph_dbg_draw_mask.test(phDbgDrawExplosions)) { Fvector p;p.set(ep.l_dir);p.mul(result.range);p.add(ep.source_p); u8 c =u8(shoot_factor*255.f); DBG_DrawPoint(p,0.1f,D3DCOLOR_XRGB(255-c,0,c)); } #endif return (ep.shoot_factor>0.01f); }
void CPhysicsShellHolder::PHSaveState(NET_Packet &P) { //CPhysicsShell* pPhysicsShell=PPhysicsShell(); IKinematics* K =smart_cast<IKinematics*>(Visual()); //Flags8 lflags; //if(pPhysicsShell&&pPhysicsShell->isActive()) lflags.set(CSE_PHSkeleton::flActive,pPhysicsShell->isEnabled()); // P.w_u8 (lflags.get()); if(K) { P.w_u64(K->LL_GetBonesVisible()); P.w_u16(K->LL_GetBoneRoot()); } else { P.w_u64(u64(-1)); P.w_u16(0); } ///////////////////////////// Fvector min,max; min.set(flt_max,flt_max,flt_max); max.set(-flt_max,-flt_max,-flt_max); ///////////////////////////////////// u16 bones_number=PHGetSyncItemsNumber(); for(u16 i=0;i<bones_number;i++) { SPHNetState state; PHGetSyncItem(i)->get_State(state); Fvector& p=state.position; 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; } min.sub(2.f*EPS_L); max.add(2.f*EPS_L); VERIFY(!min.similar(max)); P.w_vec3(min); P.w_vec3(max); P.w_u16(bones_number); for(u16 i=0;i<bones_number;i++) { SPHNetState state; PHGetSyncItem(i)->get_State(state); state.net_Save(P,min,max); } }
Fvector& global_hit_position( Fvector &gp, CEntityAlive& ea, const SHit& H ) { VERIFY( ea.Visual() ); IKinematics *K = ea.Visual( )->dcast_PKinematics( ); VERIFY( K ); K->LL_GetTransform( H.bone() ).transform_tiny( gp, H.bone_space_position( ) ); ea.XFORM().transform_tiny( gp ); return gp; }
void CPHSkeleton::SaveNetState(NET_Packet& P) { CPhysicsShellHolder* obj=PPhysicsShellHolder(); CPhysicsShell* pPhysicsShell=obj->PPhysicsShell(); IKinematics* K =smart_cast<IKinematics*>(obj->Visual()); if(pPhysicsShell&&pPhysicsShell->isActive()) m_flags.set(CSE_PHSkeleton::flActive,pPhysicsShell->isEnabled()); P.w_u8 (m_flags.get()); if(K) { P.w_u64(K->LL_GetBonesVisible()); P.w_u16(K->LL_GetBoneRoot()); } else { P.w_u64(u64(-1)); P.w_u16(0); } ///////////////////////////// Fvector min,max; min.set(F_MAX,F_MAX,F_MAX); max.set(-F_MAX,-F_MAX,-F_MAX); ///////////////////////////////////// u16 bones_number=obj->PHGetSyncItemsNumber(); for(u16 i=0;i<bones_number;i++) { SPHNetState state; obj->PHGetSyncItem(i)->get_State(state); Fvector& p=state.position; 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; } min.sub(2.f*EPS_L); max.add(2.f*EPS_L); P.w_vec3(min); P.w_vec3(max); P.w_u16(bones_number); for(u16 i=0;i<bones_number;i++) { SPHNetState state; obj->PHGetSyncItem(i)->get_State(state); state.net_Save(P,min,max); } }
void CInventoryItem::UpdateXForm () { if (0==object().H_Parent()) return; // Get access to entity and its visual CEntityAlive* E = smart_cast<CEntityAlive*>(object().H_Parent()); if (!E) return; if (E->cast_base_monster()) return; const CInventoryOwner *parent = smart_cast<const CInventoryOwner*>(E); if (parent && parent->use_simplified_visual()) return; if (parent->attached(this)) return; R_ASSERT (E); IKinematics* V = smart_cast<IKinematics*> (E->Visual()); VERIFY (V); // Get matrices int boneL = -1, boneR = -1, boneR2 = -1; E->g_WeaponBones(boneL,boneR,boneR2); if (boneR == -1) return; // if ((HandDependence() == hd1Hand) || (STATE == eReload) || (!E->g_Alive())) // boneL = boneR2; #pragma todo("TO ALL: serious performance problem") V->CalculateBones (); Fmatrix& mL = V->LL_GetTransform(u16(boneL)); Fmatrix& mR = V->LL_GetTransform(u16(boneR)); // Calculate Fmatrix mRes; Fvector R,D,N; D.sub (mL.c,mR.c); D.normalize_safe(); if(fis_zero(D.magnitude())) { mRes.set(E->XFORM()); mRes.c.set(mR.c); } else { D.normalize(); R.crossproduct (mR.j,D); N.crossproduct (D,R); N.normalize(); mRes.set (R,N,D,mR.c); mRes.mulA_43 (E->XFORM()); } // UpdatePosition (mRes); object().Position().set(mRes.c); }
void imotion_position::set_root_callback () { VERIFY( shell ); IKinematics *K = shell->PKinematics( ); VERIFY( K ); CBoneInstance &bi = K->LL_GetBoneInstance( 0 ); VERIFY(!bi.callback()); bi.set_callback( bctCustom, rootbone_callback, this, true );//root may be not "0" ! }
void imotion_position::remove_root_callback() { VERIFY( shell ); IKinematics *K = shell->PKinematics( ); VERIFY( K ); CBoneInstance &bi = K->LL_GetBoneInstance( 0 ); VERIFY( bi.callback() == rootbone_callback ); VERIFY( bi.callback_param() == (void*) this ); bi.reset_callback(); }
void CHelicopter::UpdateCL() { inherited::UpdateCL (); CExplosive::UpdateCL(); if(PPhysicsShell() && (state() == CHelicopter::eDead) ) { PPhysicsShell()->InterpolateGlobalTransform(&XFORM()); IKinematics* K = smart_cast<IKinematics*>(Visual()); K->CalculateBones (); //smoke UpdateHeliParticles(); if(m_brokenSound._feedback()) m_brokenSound.set_position(XFORM().c); return; } else PPhysicsShell()->SetTransform(XFORM(), mh_unspecified ); m_movement.Update(); m_stepRemains+=Device.fTimeDelta; while(m_stepRemains>STEP) { MoveStep(); m_stepRemains-=STEP; } #ifdef DEBUG if(bDebug) { CGameFont* F = UI().Font().pFontDI; F->SetAligment (CGameFont::alCenter); // F->SetSizeI (0.02f); F->OutSetI (0.f,-0.8f); F->SetColor (0xffffffff); F->OutNext ("Heli: speed=%4.4f acc=%4.4f dist=%4.4f",m_movement.curLinearSpeed, m_movement.curLinearAcc, m_movement.GetDistanceToDestPosition()); } #endif if(m_engineSound._feedback()) m_engineSound.set_position(XFORM().c); m_enemy.Update(); //weapon UpdateWeapons(); UpdateHeliParticles(); IKinematics* K = smart_cast<IKinematics*>(Visual()); K->CalculateBones (); }
void SArtefactDetectorsSupport::Blink() { LPCSTR curr = pSettings->r_string(m_parent->cNameSect().c_str(), "det_show_particles"); IKinematics* K = smart_cast<IKinematics*>(m_parent->Visual()); R_ASSERT2 (K, m_parent->cNameSect().c_str()); LPCSTR bone = pSettings->r_string(m_parent->cNameSect().c_str(), "particles_bone"); u16 bone_id = K->LL_BoneID(bone); R_ASSERT2 (bone_id!=BI_NONE, bone); m_parent->CParticlesPlayer::StartParticles(curr,bone_id,Fvector().set(0,1,0),m_parent->ID(), 1000, true); }
void CCharacterPhysicsSupport::in_NetSpawn( CSE_Abstract* e ) { m_sv_hit = SHit(); if( m_EntityAlife.use_simplified_visual ( ) ) { m_flags.set( fl_death_anim_on, TRUE ); IKinematics* ka = smart_cast<IKinematics*>( m_EntityAlife.Visual( ) ); VERIFY( ka ); ka->CalculateBones_Invalidate( ); ka->CalculateBones( TRUE ); CollisionCorrectObjPos( m_EntityAlife.Position( ) ); m_pPhysicsShell = P_build_Shell( &m_EntityAlife, false ); ka->CalculateBones_Invalidate( ); ka->CalculateBones( TRUE ); return; } CPHDestroyable::Init();//this zerows colbacks !!; IRenderVisual *pVisual = m_EntityAlife.Visual(); IKinematicsAnimated*ka= smart_cast<IKinematicsAnimated*>( pVisual ); IKinematics*pK= smart_cast<IKinematics*>( pVisual ); VERIFY( &e->spawn_ini() ); m_death_anims.setup( ka, *e->s_name , pSettings ); if( !m_EntityAlife.g_Alive() ) { if( m_eType == etStalker ) ka->PlayCycle( "waunded_1_idle_0" ); else ka->PlayCycle( "death_init" ); }else if( !m_EntityAlife.animation_movement_controlled( ) ) ka->PlayCycle( "death_init" );///непонятно зачем это вообще надо запускать ///этот хак нужен, потому что некоторым монстрам ///анимация после спона, может быть вообще не назначена pK->CalculateBones_Invalidate( ); pK->CalculateBones( TRUE ); CPHSkeleton::Spawn( e ); movement( )->EnableCharacter(); movement( )->SetPosition(m_EntityAlife.Position( ) ); movement( )->SetVelocity ( 0, 0, 0 ); if(m_eType!=etActor) { m_flags.set( fl_specific_bonce_demager, TRUE ); m_BonceDamageFactor = 1.f; } if( Type( ) == etStalker ) { m_hit_animations.SetupHitMotions( *smart_cast<IKinematicsAnimated*>( m_EntityAlife.Visual( ) ) ); } anim_mov_state.init( ); anim_mov_state.active = m_EntityAlife.animation_movement_controlled( ); }
void imotion_position::move_update( ) { VERIFY( shell ); IKinematics *K = shell->PKinematics(); VERIFY( K ); disable_update( false ); K->CalculateBones_Invalidate( ); K->CalculateBones( ); disable_update( true ); VERIFY( shell ); }
void CPHSkeleton::RespawnInit() { IKinematics* K = smart_cast<IKinematics*>(PPhysicsShellHolder()->Visual()); if(K) { K->LL_SetBoneRoot(0); K->LL_SetBonesVisible(0xffffffffffffffffL); K->CalculateBones_Invalidate(); K->CalculateBones(TRUE); } Init(); ClearUnsplited(); }
void CCar::SWheelBreak::Load(LPCSTR section) { IKinematics *K =PKinematics(pwheel->car->Visual()) ; CInifile *ini =K->LL_UserData() ; VERIFY (ini) ; break_torque = ini->r_float("car_definition","break_torque") ; hand_break_torque = READ_IF_EXISTS(ini,r_float,"car_definition","hand_break_torque",break_torque) ; if(ini->section_exist(section)) { break_torque =READ_IF_EXISTS(ini,r_float,section,"break_torque",break_torque); hand_break_torque =READ_IF_EXISTS(ini,r_float,section,"hand_break_torque",hand_break_torque); } }
void CCar::SpawnInitPhysics (CSE_Abstract *D) { CSE_PHSkeleton *so = smart_cast<CSE_PHSkeleton*>(D); R_ASSERT (so); ParseDefinitions ();//parse ini filling in m_driving_wheels,m_steering_wheels,m_breaking_wheels CreateSkeleton (D);//creates m_pPhysicsShell & fill in bone_map IKinematics *K =smart_cast<IKinematics*>(Visual()); K->CalculateBones_Invalidate();//this need to call callbacks K->CalculateBones (TRUE); Init ();//inits m_driving_wheels,m_steering_wheels,m_breaking_wheels values using recieved in ParceDefinitions & from bone_map //PPhysicsShell()->add_ObjectContactCallback(ActorObstacleCallback); SetDefaultNetState (so); CPHUpdateObject::Activate (); }
void CWeaponRPG7::UpdateMissileVisibility() { bool vis_hud,vis_weap; vis_hud = (!!iAmmoElapsed || GetState()==eReload); vis_weap = !!iAmmoElapsed; if(GetHUDmode()) { HudItemData()->set_bone_visible("grenade",vis_hud,TRUE); } IKinematics* pWeaponVisual = smart_cast<IKinematics*>(Visual()); VERIFY (pWeaponVisual); pWeaponVisual->LL_SetBoneVisible(pWeaponVisual->LL_BoneID("grenade"), vis_weap, TRUE); }
CPhysicsShell* P_build_Shell (CGameObject* obj,bool not_active_state,LPCSTR fixed_bones) { U16Vec f_bones; if(fixed_bones){ IKinematics* K = smart_cast<IKinematics*>(obj->Visual()); int count = _GetItemCount(fixed_bones); for (int i=0 ;i<count; ++i){ string64 fixed_bone; _GetItem (fixed_bones,i,fixed_bone); f_bones.push_back(K->LL_BoneID(fixed_bone)); R_ASSERT2(BI_NONE!=f_bones.back(),"wrong fixed bone") ; } } return P_build_Shell (obj,not_active_state,f_bones); }
void CScriptGameObject::start_particles(LPCSTR pname, LPCSTR bone) { CParticlesPlayer* PP = smart_cast<CParticlesPlayer*>(&object()); if (!PP) return; IKinematics* K = smart_cast<IKinematics*>(object().Visual()); R_ASSERT(K); u16 play_bone = K->LL_BoneID(bone); R_ASSERT(play_bone != BI_NONE); if (K->LL_GetBoneVisible(play_bone)) PP->StartParticles(pname, play_bone, Fvector().set(0, 1, 0), 9999); else ai().script_engine().script_log(ScriptStorage::eLuaMessageTypeError, "Cant start particles, bone [%s] is not visible now", bone); }
void disable_bone_calculation(IKinematics &K, bool v ) { u16 bn = K.LL_BoneCount(); for(u16 i = 1; i< bn; ++i )//ommit real root { CBoneInstance &bi = K.LL_GetBoneInstance( i ); if( bi.callback_param()!=0 ) continue; #ifdef DEBUG if( v && bi.callback_overwrite() == BOOL(v) ) Msg( "! bone callback_overwrite may have different states" ); #endif bi.set_callback_overwrite( v ); } }
void CHelicopter::UpdateMGunDir() { IKinematics* K = smart_cast<IKinematics*>(Visual()); m_fire_bone_xform = K->LL_GetTransform(m_fire_bone); m_fire_bone_xform.mulA_43 (XFORM()); m_fire_pos.set (0,0,0); m_fire_bone_xform.transform_tiny(m_fire_pos); m_fire_dir.set (0,0,1); m_fire_bone_xform.transform_dir(m_fire_dir); m_fire_dir.sub (m_enemy.destEnemyPos,m_fire_pos).normalize_safe(); m_left_rocket_bone_xform = K->LL_GetTransform(m_left_rocket_bone); m_left_rocket_bone_xform.mulA_43 (XFORM()); m_left_rocket_bone_xform.c.y += 1.0f; //.fake m_right_rocket_bone_xform = K->LL_GetTransform(m_right_rocket_bone); m_right_rocket_bone_xform.mulA_43 (XFORM()); m_right_rocket_bone_xform.c.y += 1.0f; //.fake m_allow_fire = TRUE; Fmatrix XFi; XFi.invert (XFORM()); Fvector dep; XFi.transform_tiny (dep,m_enemy.destEnemyPos); {// x angle Fvector A_; A_.sub(dep,m_bind_x); m_i_bind_x_xform.transform_dir(A_); A_.normalize(); m_tgt_rot.x = angle_normalize_signed(m_bind_rot.x-A_.getP()); float sv_x = m_tgt_rot.x; clamp (m_tgt_rot.x,-m_lim_x_rot.y,-m_lim_x_rot.x); if (!fsimilar(sv_x,m_tgt_rot.x,EPS_L)) m_allow_fire=FALSE; } {// y angle Fvector A_; A_.sub(dep,m_bind_y); m_i_bind_y_xform.transform_dir(A_); A_.normalize(); m_tgt_rot.y = angle_normalize_signed(m_bind_rot.y-A_.getH()); float sv_y = m_tgt_rot.y; clamp (m_tgt_rot.y,-m_lim_y_rot.y,-m_lim_y_rot.x); if (!fsimilar(sv_y,m_tgt_rot.y,EPS_L)) m_allow_fire=FALSE; } if ((angle_difference(m_cur_rot.x,m_tgt_rot.x)>deg2rad(m_barrel_dir_tolerance))|| (angle_difference(m_cur_rot.y,m_tgt_rot.y)>deg2rad(m_barrel_dir_tolerance))) m_allow_fire=FALSE; }
void CArtefact::UpdateXForm() { if (Device.dwFrame!=dwXF_Frame) { dwXF_Frame = Device.dwFrame; if (0==H_Parent()) return; // Get access to entity and its visual CEntityAlive* E = smart_cast<CEntityAlive*>(H_Parent()); if(!E) return ; const CInventoryOwner *parent = smart_cast<const CInventoryOwner*>(E); if (parent && parent->use_simplified_visual()) return; VERIFY (E); IKinematics* V = smart_cast<IKinematics*> (E->Visual()); VERIFY (V); if(CAttachableItem::enabled()) return; // Get matrices int boneL = -1, boneR = -1, boneR2 = -1; E->g_WeaponBones (boneL,boneR,boneR2); if (boneR == -1) return; boneL = boneR2; V->CalculateBones (); Fmatrix& mL = V->LL_GetTransform(u16(boneL)); Fmatrix& mR = V->LL_GetTransform(u16(boneR)); // Calculate Fmatrix mRes; Fvector R,D,N; D.sub (mL.c,mR.c); D.normalize_safe(); R.crossproduct (mR.j,D); R.normalize_safe(); N.crossproduct (D,R); N.normalize_safe(); mRes.set (R,N,D,mR.c); mRes.mulA_43 (E->XFORM()); // UpdatePosition (mRes); XFORM().mul (mRes,offset()); } }
void CPhysicObject:: anim_time_set ( float time ) { if( !check_blend( m_anim_blend, cName().c_str(), cNameSect().c_str(), cNameVisual().c_str() ) ) return ; if( time < 0.f || time > m_anim_blend->timeTotal ) { #ifdef DEBUG Msg( " ! can not set blend time %f - it must be in range 0 - %f(timeTotal) obj: %s, model: %s, anim: %s", time, m_anim_blend->timeTotal, cName().c_str(), cNameVisual().c_str(), smart_cast<IKinematicsAnimated*>( PPhysicsShell()->PKinematics() )->LL_MotionDefName_dbg( m_anim_blend->motionID ).first ); #endif return; } m_anim_blend->timeCurrent = time; IKinematics *K = smart_cast<IKinematics*>(Visual()); VERIFY( K ); K->CalculateBones_Invalidate(); K->CalculateBones(TRUE); }
static void save_fixes( IKinematics *K ) { VERIFY( K ); saved_fixes.clear(); u16 nbb = K->LL_BoneCount(); for(u16 i = 0; i < nbb; ++i ) { CBoneInstance &bi = K->LL_GetBoneInstance( i ); if( bi.callback() == anim_bone_fix::callback ) { VERIFY( bi.callback_param()); anim_bone_fix* fix = (anim_bone_fix*) bi.callback_param(); VERIFY( fix->bone == &bi ); saved_fixes.push_back( fix ); } } }