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" ); }
//проверка на попадание "осколком" по объекту 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); }
BOOL CWeaponStatMgun::net_Spawn(CSE_Abstract* DC) { if(!inheritedPH::net_Spawn (DC)) return FALSE; IKinematics* K = smart_cast<IKinematics*>(Visual()); CInifile* pUserData = K->LL_UserData(); R_ASSERT2 (pUserData,"Empty WeaponStatMgun user data!"); m_rotate_x_bone = K->LL_BoneID (pUserData->r_string("mounted_weapon_definition","rotate_x_bone")); m_rotate_y_bone = K->LL_BoneID (pUserData->r_string("mounted_weapon_definition","rotate_y_bone")); m_fire_bone = K->LL_BoneID (pUserData->r_string("mounted_weapon_definition","fire_bone")); m_camera_bone = K->LL_BoneID (pUserData->r_string("mounted_weapon_definition","camera_bone")); U16Vec fixed_bones; fixed_bones.push_back (K->LL_GetBoneRoot()); PPhysicsShell() = P_build_Shell(this,false,fixed_bones); CBoneData& bdX = K->LL_GetData(m_rotate_x_bone); VERIFY(bdX.IK_data.type==jtJoint); m_lim_x_rot.set (bdX.IK_data.limits[0].limit.x,bdX.IK_data.limits[0].limit.y); CBoneData& bdY = K->LL_GetData(m_rotate_y_bone); VERIFY(bdY.IK_data.type==jtJoint); m_lim_y_rot.set (bdY.IK_data.limits[1].limit.x,bdY.IK_data.limits[1].limit.y); xr_vector<Fmatrix> matrices; K->LL_GetBindTransform (matrices); m_i_bind_x_xform.invert (matrices[m_rotate_x_bone]); m_i_bind_y_xform.invert (matrices[m_rotate_y_bone]); m_bind_x_rot = matrices[m_rotate_x_bone].k.getP(); m_bind_y_rot = matrices[m_rotate_y_bone].k.getH(); m_bind_x.set (matrices[m_rotate_x_bone].c); m_bind_y.set (matrices[m_rotate_y_bone].c); m_cur_x_rot = m_bind_x_rot; m_cur_y_rot = m_bind_y_rot; m_destEnemyDir.setHP (m_bind_y_rot,m_bind_x_rot); XFORM().transform_dir (m_destEnemyDir); inheritedShooting::Light_Create(); processing_activate (); setVisible (TRUE); setEnabled (TRUE); return TRUE; }
void imotion_position::force_calculate_bones( IKinematicsAnimated& KA ) { IKinematics *K = shell->PKinematics(); VERIFY( K ); VERIFY( K == smart_cast<IKinematics *>( &KA ) ); disable_bone_calculation( *K, false ); K->Bone_Calculate( &K->LL_GetData(0), &Fidentity ); if( saved_visual_callback ) { u16 sv_root = K->LL_GetBoneRoot(); K->LL_SetBoneRoot( 0 ); saved_visual_callback( K ); K->LL_SetBoneRoot( sv_root ); } disable_bone_calculation( *K, true ); }
void CPHSkeleton::RecursiveBonesCheck(u16 id) { if(!removable) return; CPhysicsShellHolder* obj=PPhysicsShellHolder(); IKinematics* K = smart_cast<IKinematics*>(obj->Visual()); CBoneData& BD = K->LL_GetData(u16(id)); ////////////////////////////////////////// Flags64 mask; mask.assign(K->LL_GetBonesVisible()); /////////////////////////////////////////// if( mask.is(1ui64<<(u64)id)&& !(BD.shape.flags.is(SBoneShape::sfRemoveAfterBreak)) ) { removable = false; return; } /////////////////////////////////////////////// for (vecBonesIt it=BD.children.begin(); BD.children.end() != it; ++it){ RecursiveBonesCheck ((*it)->GetSelfID()); } }
void CCharacterPhysicsSupport::bone_chain_disable(u16 bone, u16 r_bone, IKinematics &K) { VERIFY(&K); u16 bid = bone; //K.LL_GetBoneInstance( bid ).set_callback( bctCustom, 0, 0, TRUE ); while( bid!=r_bone && bid != K.LL_GetBoneRoot() ) { CBoneData &bd = K.LL_GetData( bid ); if( K.LL_GetBoneInstance( bid ).callback() != anim_bone_fix::callback ) { m_weapon_bone_fixes.push_back( new anim_bone_fix() ); m_weapon_bone_fixes.back()->fix( bid, K ); } bid = bd.GetParentID(); //K.LL_GetBoneInstance( bid ).set_callback( bctCustom, 0, 0, TRUE ); } }
void CPhysicObject::AddElement(CPhysicsElement* root_e, int id) { IKinematics* K = smart_cast<IKinematics*>(Visual()); CPhysicsElement* E = P_create_Element(); CBoneInstance& B = K->LL_GetBoneInstance(u16(id)); E->mXFORM.set (K->LL_GetTransform(u16(id))); Fobb bb = K->LL_GetBox(u16(id)); if(bb.m_halfsize.magnitude()<0.05f) { bb.m_halfsize.add(0.05f); } E->add_Box (bb); E->setMass (10.f); E->set_ParentElement(root_e); B.set_callback (bctPhysics,m_pPhysicsShell->GetBonesCallback(),E); m_pPhysicsShell->add_Element (E); if( !(m_type==epotFreeChain && root_e==0) ) { CPhysicsJoint* J= P_create_Joint(CPhysicsJoint::full_control,root_e,E); J->SetAnchorVsSecondElement (0,0,0); J->SetAxisDirVsSecondElement (1,0,0,0); J->SetAxisDirVsSecondElement (0,1,0,2); J->SetLimits (-M_PI/2,M_PI/2,0); J->SetLimits (-M_PI/2,M_PI/2,1); J->SetLimits (-M_PI/2,M_PI/2,2); m_pPhysicsShell->add_Joint (J); } CBoneData& BD = K->LL_GetData(u16(id)); for (vecBonesIt it=BD.children.begin(); BD.children.end() != it; ++it){ AddElement (E,(*it)->GetSelfID()); } }
void type_motion_diagnostic( LPCSTR message, type_motion::edirection dr, const CEntityAlive& ea, const SHit& H, const MotionID &m ) { #ifdef DEBUG if(! death_anim_debug ) return; IKinematicsAnimated *KA = smart_cast<IKinematicsAnimated*>( ea.Visual() ); VERIFY( KA ); IKinematics *K = smart_cast<IKinematics*>( ea.Visual() ); LPCSTR bone_name = "not_definite"; if( H.bone() != BI_NONE ) { CBoneData& bd = K->LL_GetData( H.bone() ); bone_name = bd.name.c_str(); } LPCSTR motion_name = "not_set"; if( m.valid() ) motion_name = KA->LL_MotionDefName_dbg( m ).first; Msg( "death anims: %s, dir: %s, motion: %s, obj: %s, model: %s, bone: %s " ,message ,motion_dirs[ dr ].name, motion_name, ea.cName().c_str(), ea.cNameVisual().c_str(), bone_name ); #endif }
bool CPhysicObject::get_door_vectors ( Fvector& closed, Fvector& open ) const { VERIFY(Visual()); IKinematics *K = Visual()->dcast_PKinematics(); VERIFY(K); u16 door_bone = K->LL_BoneID("door"); if( door_bone==BI_NONE ) return false; const CBoneData &bd = K->LL_GetData( door_bone ); const SBoneShape &shape = bd.shape; if( shape.type != SBoneShape::stBox ) return false; if( shape.flags.test( SBoneShape::sfNoPhysics ) ) return false; Fmatrix start_bone_pos; K->Bone_GetAnimPos( start_bone_pos, door_bone, u8(-1), true ); Fmatrix start_pos = Fmatrix().mul_43( XFORM(), start_bone_pos ); const Fobb &box = shape.box; Fvector center_pos; start_pos.transform_tiny( center_pos, box.m_translate ); Fvector door_dir; start_pos.transform_dir(door_dir, box.m_rotate.i ); Fvector door_dir_local = box.m_rotate.i ; //Fvector door_dir_bone; start_bone_pos.transform_dir(door_dir_bone, box.m_rotate.i ); const Fvector det_vector = Fvector().sub( center_pos, start_pos.c ); if( door_dir.dotproduct( det_vector ) < 0.f ) { door_dir.invert(); door_dir_local.invert(); //door_dir_bone.invert(); } const SJointIKData &joint = bd.IK_data; if( joint.type != jtJoint ) return false; const Fvector2& limits = joint.limits[1].limit; //if( limits.y < EPS ) //limits.y - limits.x < EPS // return false; if( M_PI - limits.y < EPS && M_PI + limits.x < EPS ) return false; Fmatrix to_hi = Fmatrix().rotateY( -limits.x ); to_hi.transform_dir( open, door_dir_local ); Fmatrix to_lo = Fmatrix().rotateY( -limits.y ); to_lo.transform_dir( closed, door_dir_local ); start_pos.transform_dir(open); start_pos.transform_dir(closed); //DBG_OpenCashedDraw( ); #ifdef DEBUG if(dbg_draw_doors) { DBG_DrawMatrix( Fidentity, 10.0f ); DBG_DrawMatrix( XFORM(), .5f, 100 ); DBG_DrawMatrix( start_pos, 0.2f,100 ); const Fvector pos = start_pos.c.add( Fvector().set(0,0.2f,0) ); const Fvector pos1 = start_pos.c.add( Fvector().set(0,0.3f,0) ); DBG_DrawLine( pos, Fvector( ).add( pos, open ), D3DCOLOR_XRGB( 0, 255, 0 ) ); DBG_DrawLine( pos, Fvector( ).add( pos, closed ), D3DCOLOR_XRGB( 255, 0, 0 ) ); DBG_DrawLine( pos1, Fvector( ).add( pos1, det_vector ), D3DCOLOR_XRGB( 255, 255, 0 ) ); } #endif //DBG_ClosedCashedDraw( 50000000 ); return true; }
void render_box (IRenderVisual *visual, const Fmatrix &xform, const Fvector &additional, bool draw_child_boxes, const u32 &color) { CDebugRenderer &renderer = Level().debug_renderer(); IKinematics *kinematics = smart_cast<IKinematics*>(visual); VERIFY (kinematics); u16 bone_count = kinematics->LL_BoneCount(); VERIFY (bone_count); u16 visible_bone_count = kinematics->LL_VisibleBoneCount(); if (!visible_bone_count) return; Fmatrix matrix; Fvector *points = (Fvector*)_alloca(visible_bone_count*8*sizeof(Fvector)); Fvector *I = points; for (u16 i=0; i<bone_count; ++i) { if (!kinematics->LL_GetBoneVisible(i)) continue; const Fobb &obb = kinematics->LL_GetData(i).obb; if (fis_zero(obb.m_halfsize.square_magnitude())) { VERIFY (visible_bone_count > 1); --visible_bone_count; continue; } Fmatrix Mbox; obb.xform_get (Mbox); const Fmatrix &Mbone = kinematics->LL_GetBoneInstance(i).mTransform; Fmatrix X; matrix.mul_43 (xform,X.mul_43(Mbone,Mbox)); Fvector half_size = Fvector().add(obb.m_halfsize,additional); matrix.mulB_43 (Fmatrix().scale(half_size)); if (draw_child_boxes) renderer.draw_obb (matrix,color); static const Fvector local_points[8] = { Fvector().set(-1.f,-1.f,-1.f), Fvector().set(-1.f,-1.f,+1.f), Fvector().set(-1.f,+1.f,+1.f), Fvector().set(-1.f,+1.f,-1.f), Fvector().set(+1.f,+1.f,+1.f), Fvector().set(+1.f,+1.f,-1.f), Fvector().set(+1.f,-1.f,+1.f), Fvector().set(+1.f,-1.f,-1.f) }; for (u32 i=0; i<8; ++i, ++I) matrix.transform_tiny (*I,local_points[i]); } VERIFY (visible_bone_count); if (visible_bone_count == 1) { renderer.draw_obb (matrix,color); return; } VERIFY ((I - points) == (visible_bone_count*8)); MagicBox3 box = MagicMinBox(visible_bone_count*8,points); box.ComputeVertices (points); Fmatrix result; result.identity (); result.c = box.Center(); result.i.sub(points[3],points[2]).normalize(); result.j.sub(points[2],points[1]).normalize(); result.k.sub(points[2],points[6]).normalize(); Fvector scale; scale.x = points[3].distance_to(points[2])*.5f; scale.y = points[2].distance_to(points[1])*.5f; scale.z = points[2].distance_to(points[6])*.5f; result.mulB_43 (Fmatrix().scale(scale)); renderer.draw_obb (result,color); }
BOOL CHelicopter::net_Spawn(CSE_Abstract* DC) { SetfHealth(100.0f); setState(CHelicopter::eAlive); m_flame_started =false; m_light_started =false; m_exploded =false; m_ready_explode =false; m_dead =false; if (!inherited::net_Spawn(DC)) return (FALSE); CPHSkeleton::Spawn((CSE_Abstract*)(DC)); for(u32 i=0; i<4; ++i) CRocketLauncher::SpawnRocket(*m_sRocketSection, smart_cast<CGameObject*>(this)); // assigning m_animator here CSE_Abstract *abstract =(CSE_Abstract*)(DC); CSE_ALifeHelicopter *heli = smart_cast<CSE_ALifeHelicopter*>(abstract); VERIFY (heli); R_ASSERT (Visual()&&smart_cast<IKinematics*>(Visual())); IKinematics* K = smart_cast<IKinematics*>(Visual()); CInifile* pUserData = K->LL_UserData(); m_rotate_x_bone = K->LL_BoneID (pUserData->r_string("helicopter_definition","wpn_rotate_x_bone")); m_rotate_y_bone = K->LL_BoneID (pUserData->r_string("helicopter_definition","wpn_rotate_y_bone")); m_fire_bone = K->LL_BoneID (pUserData->r_string("helicopter_definition","wpn_fire_bone")); m_death_bones_to_hide = pUserData->r_string("on_death_mode","scale_bone"); m_left_rocket_bone = K->LL_BoneID (pUserData->r_string("helicopter_definition","left_rocket_bone")); m_right_rocket_bone = K->LL_BoneID (pUserData->r_string("helicopter_definition","right_rocket_bone")); m_smoke_bone = K->LL_BoneID (pUserData->r_string("helicopter_definition","smoke_bone")); m_light_bone = K->LL_BoneID (pUserData->r_string("helicopter_definition","light_bone")); CExplosive::Load (pUserData,"explosion"); CExplosive::SetInitiator(ID()); LPCSTR s = pUserData->r_string("helicopter_definition","hit_section"); if( pUserData->section_exist(s) ) { int lc = pUserData->line_count(s); LPCSTR name; LPCSTR value; s16 boneID; for (int i=0 ; i<lc; ++i) { pUserData->r_line( s, i, &name, &value); boneID =K->LL_BoneID(name); m_hitBones.insert( std::make_pair(boneID, (float)atof(value)) ); } } CBoneInstance& biX = smart_cast<IKinematics*>(Visual())->LL_GetBoneInstance(m_rotate_x_bone); biX.set_callback (bctCustom,BoneMGunCallbackX,this); CBoneInstance& biY = smart_cast<IKinematics*>(Visual())->LL_GetBoneInstance(m_rotate_y_bone); biY.set_callback (bctCustom,BoneMGunCallbackY,this); CBoneData& bdX = K->LL_GetData(m_rotate_x_bone); VERIFY(bdX.IK_data.type==jtJoint); m_lim_x_rot.set (bdX.IK_data.limits[0].limit.x,bdX.IK_data.limits[0].limit.y); CBoneData& bdY = K->LL_GetData(m_rotate_y_bone); VERIFY(bdY.IK_data.type==jtJoint); m_lim_y_rot.set (bdY.IK_data.limits[1].limit.x,bdY.IK_data.limits[1].limit.y); xr_vector<Fmatrix> matrices; K->LL_GetBindTransform (matrices); m_i_bind_x_xform.invert (matrices[m_rotate_x_bone]); m_i_bind_y_xform.invert (matrices[m_rotate_y_bone]); m_bind_rot.x = matrices[m_rotate_x_bone].k.getP(); m_bind_rot.y = matrices[m_rotate_y_bone].k.getH(); m_bind_x.set (matrices[m_rotate_x_bone].c); m_bind_y.set (matrices[m_rotate_y_bone].c); IKinematicsAnimated *A = smart_cast<IKinematicsAnimated*>(Visual()); if (A) { A->PlayCycle (*heli->startup_animation); K->CalculateBones (TRUE); } m_engineSound.create (*heli->engine_sound,st_Effect,sg_SourceType); m_engineSound.play_at_pos (0,XFORM().c,sm_Looped); CShootingObject::Light_Create (); setVisible (TRUE); setEnabled (TRUE); m_stepRemains = 0.0f; //lighting m_light_render = ::Render->light_create(); m_light_render->set_shadow (false); m_light_render->set_type (IRender_Light::POINT); m_light_render->set_range (m_light_range); m_light_render->set_color (m_light_color); if(g_Alive())processing_activate (); TurnEngineSound(false); if(pUserData->section_exist("destroyed")) CPHDestroyable::Load(pUserData,"destroyed"); #ifdef DEBUG Device.seqRender.Add(this,REG_PRIORITY_LOW-1); #endif return TRUE; }
bool bone_has_pysics( IKinematics& K, u16 bone_id ) { return K.LL_GetBoneVisible( bone_id ) && shape_is_physic(K.LL_GetData( bone_id ).shape); }