bool has_physics_collision_shapes( IKinematics& K ) { u16 nbb = K.LL_BoneCount(); for(u16 i = 0; i < nbb; ++i ) if( bone_has_pysics( K, i ) ) return true; return false; }
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 ); } }
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 ); } } }
void character_hit_animation_controller::PlayHitMotion( const Fvector &dir, const Fvector &bone_pos, u16 bi, CEntityAlive &ea )const { IRenderVisual *pV = ea.Visual( ); IKinematicsAnimated* CA = smart_cast<IKinematicsAnimated*>( pV ); IKinematics* K = smart_cast<IKinematics*>( pV ); //play_cycle(CA,all_shift_down,1,block_times[6],1) ; if( !( K->LL_BoneCount( ) > bi ) ) return; Fvector dr = dir; Fmatrix m; GetBaseMatrix( m, ea ); #ifdef DEBUG if( ph_dbg_draw_mask1.test( phDbgHitAnims ) ) { DBG_OpenCashedDraw(); DBG_DrawLine( m.c, Fvector( ).sub( m.c, Fvector( ).mul( dir, 1.5 ) ), D3DCOLOR_XRGB( 255, 0, 255 ) ); DBG_ClosedCashedDraw( 1000 ); } #endif m.invert( ); m.transform_dir( dr ); // Fvector hit_point; K->LL_GetTransform( bi ).transform_tiny( hit_point, bone_pos ); ea.XFORM( ).transform_tiny( hit_point ); m.transform_tiny( hit_point ); Fvector torqu; torqu.crossproduct( dr, hit_point ); hit_point.x = 0; float rotational_ammount = hit_point.magnitude( ) * g_params.power_factor * g_params.rotational_power_factor;//_abs(torqu.x) if( torqu.x < 0 ) play_cycle( CA, hit_downr, 3, block_blends[7], 1 ) ; else play_cycle( CA, hit_downl, 3, block_blends[6], 1 ) ; if( !IsEffected( bi, *K ) ) return; if( torqu.x<0 ) play_cycle( CA, turn_right, 2, block_blends[4], rotational_ammount ) ; else play_cycle( CA, turn_left, 2, block_blends[5], rotational_ammount ) ; //CA->LL_SetChannelFactor(3,rotational_ammount); dr.x = 0; dr.normalize_safe(); dr.mul(g_params.power_factor); if( dr.y > g_params.side_sensitivity_threshold ) play_cycle( CA, rthit_motion, 2, block_blends[0], _abs( dr.y ) ) ; else if( dr.y < -g_params.side_sensitivity_threshold ) play_cycle( CA, lthit_motion, 2, block_blends[1], _abs( dr.y ) ) ; if( dr.z<0.f ) play_cycle( CA, fvhit_motion, 2, block_blends[2], _abs(dr.z) ) ; else play_cycle( CA, bkhit_motion, 2, block_blends[3], _abs( dr.z ) ) ; CA->LL_SetChannelFactor( 2, g_params.anim_channel_factor ); }
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); }
void CAI_Stalker::Hit(SHit* pHDS) { //хит может меняться в зависимости от ранга (новички получают больше хита, чем ветераны) SHit HDS = *pHDS; HDS.add_wound = true; float hit_power = HDS.power * m_fRankImmunity; if(m_boneHitProtection && HDS.hit_type == ALife::eHitTypeFireWound) { float BoneArmor = m_boneHitProtection->getBoneArmor(HDS.bone()); float ap = HDS.armor_piercing; if(!fis_zero(BoneArmor, EPS)) { if(ap > BoneArmor) { float d_hit_power = (ap - BoneArmor) / ap; if(d_hit_power < m_boneHitProtection->m_fHitFracNpc) d_hit_power = m_boneHitProtection->m_fHitFracNpc; hit_power *= d_hit_power; VERIFY(hit_power>=0.0f); } else { hit_power *= m_boneHitProtection->m_fHitFracNpc; HDS.add_wound = false; } } if ( wounded() ) //уже лежит => добивание { hit_power = 1000.f; } } HDS.power = hit_power; if (g_Alive()) { bool already_critically_wounded = critically_wounded(); if (!already_critically_wounded) { const CCoverPoint *cover = agent_manager().member().member(this).cover(); if ( !invulnerable() && cover && HDS.initiator() && ( HDS.initiator()->ID() != ID() ) && !fis_zero( HDS.damage() ) && brain().affect_cover() ) { agent_manager().location().add( xr_new<CDangerCoverLocation>(cover,Device.dwTimeGlobal,DANGER_INTERVAL,DANGER_DISTANCE) ); } } const CEntityAlive *entity_alive = smart_cast<const CEntityAlive*>(HDS.initiator()); if (entity_alive && !wounded()) { if (is_relation_enemy(entity_alive)) sound().play (eStalkerSoundInjuring); // else // sound().play (eStalkerSoundInjuringByFriend); } int weapon_type = -1; if (best_weapon()) weapon_type = best_weapon()->object().ef_weapon_type(); if ( !wounded() && !already_critically_wounded) { bool became_critically_wounded = update_critical_wounded(HDS.boneID,HDS.power); if ( !became_critically_wounded && animation().script_animations().empty() && (HDS.bone() != BI_NONE) ) { Fvector D; float yaw, pitch; D.getHP (yaw,pitch); #pragma todo("Dima to Dima : forward-back bone impulse direction has been determined incorrectly!") float power_factor = m_power_fx_factor * HDS.damage() / 100.f; clamp (power_factor,0.f,1.f); //IKinematicsAnimated *tpKinematics = smart_cast<IKinematicsAnimated*>(Visual()); IKinematics *tpKinematics = smart_cast<IKinematics*>(Visual()); #ifdef DEBUG tpKinematics->LL_GetBoneInstance (HDS.bone()); if (HDS.bone() >= tpKinematics->LL_BoneCount()) { Msg ("tpKinematics has no bone_id %d",HDS.bone()); HDS._dump (); } #endif // int fx_index = iFloor(tpKinematics->LL_GetBoneInstance(HDS.bone()).get_param(1) + (angle_difference(movement().m_body.current.yaw,-yaw) <= PI_DIV_2 ? 0 : 1)); // if (fx_index != -1) // animation().play_fx (power_factor,fx_index); } else { if (!already_critically_wounded && became_critically_wounded) { if (HDS.who) { CAI_Stalker *stalker = smart_cast<CAI_Stalker*>(HDS.who); if ( stalker && stalker->g_Alive() ) stalker->on_critical_wound_initiator (this); } } } } } if ( g_Alive() && ( !m_hit_callback || m_hit_callback( &HDS ) ) ) { float const damage_factor = invulnerable() ? 0.f : 100.f; memory().hit().add ( damage_factor*HDS.damage(), HDS.direction(), HDS.who, HDS.boneID ); } //conditions().health() = 1.f; inherited::Hit ( &HDS ); }