bool CIKFoot::make_shift( Fmatrix &xm,const Fvector &cl_point, bool collide, const Fplane &p, const Fvector &pick_dir )const { Fvector shift = pick_dir; //Fvector toe; ToePosition( toe ); xm.transform_tiny( toe ); Fvector point; xm.transform_tiny( point, cl_point ); float dot = p.n.dotproduct( shift ); if( _abs( dot ) < min_dot ) { shift.add( Fvector( ).mul( p.n, min_dot - _abs( dot ) ) ); dot = p.n.dotproduct( shift ); } VERIFY( !fis_zero( dot ) ); float shift_m = ( -p.d - p.n.dotproduct( point ) )/dot; if(collide && shift_m > 0.f ) return false; clamp( shift_m, -collide_dist, collide_dist ); shift.mul( shift_m ); xm.c.add( shift ); #if 0 if(shift_m > 0.f) { DBG_OpenCashedDraw(); DBG_DrawLine( toe, Fvector().add( toe, shift ), D3DCOLOR_XRGB( 255, 255, 255 ) ); DBG_ClosedCashedDraw( 1000 ); } #endif return true; }
void collide_anim_dbg_draw( CPhysicsShell *shell, float dt ) { VERIFY( shell ); if( dbg_imotion_draw_velocity ) { shell->AnimToVelocityState( dt, default_l_limit * 10, default_w_limit * 10 ); DBG_OpenCashedDraw(); shell->dbg_draw_velocity( dbg_imotion_draw_velocity_scale, D3DCOLOR_XRGB( 0, 255, 0 ) ); DBG_ClosedCashedDraw( 50000 ); } if( dbg_imotion_draw_skeleton ) { DBG_OpenCashedDraw(); CPhysicsShellHolder * sh = static_cast<CPhysicsShellHolder*>( shell->get_ElementByStoreOrder( 0 )->PhysicsRefObject() ); DBG_PhysBones( *sh ); DBG_ClosedCashedDraw( 50000 ); } }
static void dbg_draw_state_end( CPhysicsShell *shell ) { VERIFY( shell ); if( dbg_imotion_draw_velocity ) { DBG_OpenCashedDraw(); shell->dbg_draw_velocity( dbg_imotion_draw_velocity_scale, D3DCOLOR_ARGB( 100 ,255, 0, 0 ) ); //shell->dbg_draw_force( 0.01, D3DCOLOR_XRGB( 0, 0, 255 ) ); DBG_ClosedCashedDraw( 50000 ); } if(dbg_imotion_collide_debug) { #ifdef DEBUG DBG_OpenCashedDraw(); shell->dbg_draw_geometry( 0.02, D3DCOLOR_ARGB( 255, 255, 255, 255 ) ); DBG_ClosedCashedDraw( 50000 ); #endif } }
BOOL CPhysicObject::net_Spawn(CSE_Abstract* DC) { CSE_Abstract *e = (CSE_Abstract*)(DC); CSE_ALifeObjectPhysic *po = smart_cast<CSE_ALifeObjectPhysic*>(e); R_ASSERT (po); m_type = EPOType(po->type); m_mass = po->mass; m_collision_hit_callback= NULL; m_anim_blend = 0; inherited::net_Spawn ( DC ); create_collision_model ( ); CPHSkeleton::Spawn(e); setVisible(TRUE); setEnabled(TRUE); if (!PPhysicsShell()->isBreakable()&&!CScriptBinder::object()&&!CPHSkeleton::IsRemoving()) SheduleUnregister(); //if (PPhysicsShell()->Animated()) //{ // processing_activate(); //} bones_snd_player = create_moving_bones_snd_player( *this ); if( bones_snd_player ) play_bones_sound(); m_just_after_spawn = true; m_activated = false; if (DC->s_flags.is(M_SPAWN_UPDATE)) { NET_Packet temp; temp.B.count = 0; DC->UPDATE_Write (temp); if (temp.B.count > 0) { temp.r_seek (0); net_Import (temp); } } //processing_activate(); #ifdef DEBUG if(dbg_draw_doors) { DBG_OpenCashedDraw( ); Fvector closed, open; get_door_vectors( closed, open ); DBG_ClosedCashedDraw( 50000000 ); } #endif return TRUE; }
float imotion_position::move( float dt, IKinematicsAnimated& KA ) { VERIFY( shell ); //float ret = 0; float advance_time = 0.f; float collide_dt = dt; u32 iterations = 1; if( dt > max_collide_timedelta ) { float f_iterations = ceil( dt / max_collide_timedelta ) ; VERIFY( f_iterations > 0.f ); collide_dt = dt/f_iterations; iterations = u32( f_iterations ); } for( u32 i = 0; i < iterations; ++i ) { float ad = 0.f; u32 sv_blends_num = blends_num( KA ); buffer_vector<sblend_save> saved_blends( _alloca( sv_blends_num*sizeof( sblend_save ) ), sv_blends_num ); if( !flags.test( fl_switch_dm_toragdoll ) ) { save_blends( saved_blends, KA ); ad = motion_collide( collide_dt, KA ); } advance_time +=ad; if( !!flags.test( fl_switch_dm_toragdoll ) ) { restore_blends( saved_blends ); time_to_end -= ad; force_calculate_bones( KA ); //advance_time += advance_animation( -( end_delta ), KA );//+ ad shell->ToAnimBonesPositions( shell_motion_has_history ? mh_not_clear : mh_unspecified ); shell_motion_has_history = true; #ifdef DEBUG if( dbg_imotion_collide_debug ) { depth = 0; shell->CollideAll(); interactive_motion_diagnostic( make_string( " move (to ragdoll): deppth= %f", depth ).c_str() ); DBG_OpenCashedDraw(); shell->dbg_draw_geometry( 0.02, D3DCOLOR_ARGB( 255, 255, 0 ,255 ) ); DBG_ClosedCashedDraw( 50000 ); } #endif advance_time += advance_animation( end_delta, KA ); break; } } return advance_time; }
void CExplosive::ExplodeWaveProcessObject(collide::rq_results& storage, CPhysicsShellHolder*l_pGO) { Fvector l_goPos; if(l_pGO->Visual()) l_pGO->Center (l_goPos); else return; //мне непонятно зачем наносить хит от взрыва по объектам не имеющим вижуал - поэтому игнорируем #ifdef DEBUG if(ph_dbg_draw_mask.test(phDbgDrawExplosions)) { DBG_OpenCashedDraw(); } #endif float l_effect=ExplosionEffect(storage,this,l_pGO,m_vExplodePos,m_fBlastRadius); float l_impuls = m_fBlastHitImpulse * l_effect; float l_hit = m_fBlastHit * l_effect; if(l_impuls > .001f||l_hit> 0.001) { Fvector l_dir;l_dir.sub(l_goPos,m_vExplodePos); float rmag=_sqrt(m_fUpThrowFactor*m_fUpThrowFactor+1.f+2.f*m_fUpThrowFactor*l_dir.y); l_dir.y += m_fUpThrowFactor; //rmag -модуль l_dir после l_dir.y += m_fUpThrowFactor, модуль=_sqrt(l_dir^2+y^2+2.*(l_dir,y)),y=(0,m_fUpThrowFactor,0) (до этого модуль l_dir =1) l_dir.mul(1.f/rmag);//перенормировка NET_Packet P; SHit HS; HS.GenHeader(GE_HIT, l_pGO->ID()); // cast_game_object()->u_EventGen (P,GE_HIT,l_pGO->ID()); HS.whoID =Initiator(); // P.w_u16 (Initiator()); HS.weaponID = cast_game_object()->ID(); // P.w_u16 (cast_game_object()->ID()); HS.dir = l_dir; // P.w_dir (l_dir); HS.power = l_hit; // P.w_float (l_hit); HS.p_in_bone_space = l_goPos; // P.w_vec3 (l_goPos); HS.impulse = l_impuls; // P.w_float (l_impuls); HS.hit_type = (m_eHitTypeBlast); // P.w_u16 (u16(m_eHitTypeBlast)); HS.boneID = 0; // P.w_s16 (0); HS.Write_Packet(P); cast_game_object()->u_EventSend (P); } #ifdef DEBUG if(ph_dbg_draw_mask.test(phDbgDrawExplosions)) { DBG_ClosedCashedDraw(100000); } #endif }
void CPhysicObject::PH_A_CrPr () { if (m_just_after_spawn) { VERIFY(Visual()); IKinematics *K = Visual()->dcast_PKinematics(); VERIFY( K ); if (!PPhysicsShell()) { return; } if(!PPhysicsShell()->isFullActive()) { K->CalculateBones_Invalidate(); K->CalculateBones(TRUE); } PPhysicsShell()->GetGlobalTransformDynamic(&XFORM()); K->CalculateBones_Invalidate(); K->CalculateBones(TRUE); #if 0 Fbox bb= BoundingBox (); DBG_OpenCashedDraw (); Fvector c,r,p; bb.get_CD(c,r ); XFORM().transform_tiny(p,c); DBG_DrawAABB( p, r,D3DCOLOR_XRGB(255, 0, 0)); //PPhysicsShell()->XFORM().transform_tiny(c); Fmatrix mm; PPhysicsShell()->GetGlobalTransformDynamic(&mm); mm.transform_tiny(p,c); DBG_DrawAABB( p, r,D3DCOLOR_XRGB(0, 255, 0)); DBG_ClosedCashedDraw (50000); #endif spatial_move(); m_just_after_spawn = false; VERIFY(!OnServer()); PPhysicsShell()->get_ElementByStoreOrder(0)->Fix(); PPhysicsShell()->SetIgnoreStatic (); //PPhysicsShell()->SetIgnoreDynamic (); //PPhysicsShell()->DisableCollision(); } //CalculateInterpolationParams() };
void CCharacterPhysicsSupport::FlyTo(const Fvector &disp) { R_ASSERT(m_pPhysicsShell); float ammount=disp.magnitude(); if(fis_zero(ammount,EPS_L)) return; ph_world->Freeze(); bool g=m_pPhysicsShell->get_ApplyByGravity(); m_pPhysicsShell->set_ApplyByGravity(false); m_pPhysicsShell->add_ObjectContactCallback(StaticEnvironmentCB); void* cd=m_pPhysicsShell->get_CallbackData(); m_pPhysicsShell->set_CallbackData(m_pPhysicsShell->PIsland()); m_pPhysicsShell->UnFreeze(); Fvector vel;vel.set(disp); const u16 steps_num=10; const float fsteps_num=steps_num; vel.mul(1.f/fsteps_num/fixed_step); for(u16 i=0;steps_num>i;++i) { m_pPhysicsShell->set_LinearVel(vel); #if 0 DBG_OpenCashedDraw(); //m_pPhysicsShell->dbg_draw_geometry( 0.2f, D3DCOLOR_XRGB( 255, 100, 0 ) ); m_pPhysicsShell->dbg_draw_velocity( 0.01f, D3DCOLOR_XRGB( 0, 255, 0 ) ); m_pPhysicsShell->dbg_draw_force( 0.1f, D3DCOLOR_XRGB( 0, 0, 255 ) ); // DBG_ClosedCashedDraw( 50000 ); #endif ph_world->Step(); #if 0 // DBG_OpenCashedDraw(); //m_pPhysicsShell->dbg_draw_geometry( 0.2f, D3DCOLOR_XRGB( 255, 100, 0 ) ); m_pPhysicsShell->dbg_draw_velocity( 0.01f, D3DCOLOR_XRGB( 100, 255, 0 ) ); m_pPhysicsShell->dbg_draw_force( 0.1f, D3DCOLOR_XRGB( 100, 0, 255 ) ); DBG_ClosedCashedDraw( 50000 ); #endif } //u16 step_num=disp.magnitude()/fixed_step; m_pPhysicsShell->set_ApplyByGravity(g); m_pPhysicsShell->set_CallbackData(cd); m_pPhysicsShell->remove_ObjectContactCallback(StaticEnvironmentCB); ph_world->UnFreeze(); }
float imotion_position::collide_animation ( float dt, IKinematicsAnimated& k ) { advance_animation( dt, k ); #ifdef DEBUG collide_anim_dbg_draw ( shell, dt ); #endif shell->ToAnimBonesPositions( shell_motion_has_history ? mh_not_clear : mh_unspecified ); depth = 0; #ifdef DEBUG if( dbg_imotion_collide_debug ) DBG_OpenCashedDraw(); #endif shell->CollideAll( ); #ifdef DEBUG if( dbg_imotion_collide_debug ) DBG_ClosedCashedDraw(50000); #endif #ifdef DEBUG if( dbg_imotion_collide_debug ) interactive_motion_diagnostic( make_string( " collide_animation: deppth= %f", depth ).c_str() ); #endif return dt; }
void CCharacterPhysicsSupport::in_shedule_Update( u32 DT ) { ///VERIFY( 0 ); //CPHSkeleton::Update(DT); if(m_collision_activating_delay) UpdateCollisionActivatingDellay(); if( !m_EntityAlife.use_simplified_visual ( ) ) CPHDestroyable::SheduleUpdate( DT ); else if( m_pPhysicsShell&&m_pPhysicsShell->isFullActive( ) && !m_pPhysicsShell->isEnabled( ) ) m_EntityAlife.deactivate_physics_shell( ); movement( )->in_shedule_Update( DT ); #if 0 if( anim_mov_state.active ) { DBG_OpenCashedDraw( ); DBG_DrawMatrix( mXFORM, 0.5f ); DBG_ClosedCashedDraw( 5000 ); } #endif }
void imotion_position::state_end( ) { VERIFY( shell ); inherited::state_end( ); CPhysicsShellHolder *obj= static_cast<CPhysicsShellHolder*>( shell->get_ElementByStoreOrder( 0 )->PhysicsRefObject() ); VERIFY( obj ); obj->processing_deactivate(); shell->Enable(); shell->setForce( Fvector().set( 0.f, 0.f, 0.f ) ); shell->setTorque( Fvector().set( 0.f, 0.f, 0.f ) ); shell->AnimToVelocityState( end_delta, default_l_limit * 10, default_w_limit * 10 ); #ifdef DEBUG dbg_draw_state_end( shell ); #endif shell->remove_ObjectContactCallback( get_depth ); IKinematics *K = shell->PKinematics(); disable_update( false ); disable_bone_calculation( *K, false ); K->SetUpdateCallback( saved_visual_callback ); deinit_bones(); save_fixes( K ); shell->EnabledCallbacks( TRUE ); restore_fixes( ); VERIFY( K ); IKinematicsAnimated *KA = smart_cast<IKinematicsAnimated*>( shell->PKinematics() ); VERIFY( KA ); update_callback.motion = 0; KA->SetUpdateTracksCalback( 0 ); #if 0 DBG_OpenCashedDraw(); shell->dbg_draw_geometry( 0.02, D3DCOLOR_ARGB( 255, 0, 255, 0 ) ); DBG_DrawBones( *shell->get_ElementByStoreOrder( 0 )->PhysicsRefObject() ); DBG_ClosedCashedDraw( 50000 ); #endif u16 root = K->LL_GetBoneRoot(); if( root!=0 ) { K->LL_GetTransform( 0 ).set( Fidentity ); K->LL_SetBoneVisible( 0, FALSE, FALSE ); u16 bip01 = K->LL_BoneID( "bip01" ); if( bip01 != BI_NONE && bip01 != root ) { K->LL_GetTransform( bip01 ).set( Fidentity ); K->LL_SetBoneVisible( bip01, FALSE, FALSE ); } } K->CalculateBones_Invalidate(); K->CalculateBones( true ); #if 0 DBG_OpenCashedDraw(); shell->dbg_draw_geometry( 0.02, D3DCOLOR_ARGB( 255, 0, 0, 255 ) ); DBG_DrawBones( *shell->get_ElementByStoreOrder( 0 )->PhysicsRefObject() ); DBG_ClosedCashedDraw( 50000 ); #endif }
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 ); }
bool CPHActivationShape:: Activate (const Fvector need_size,u16 steps,float max_displacement,float max_rotation,bool un_freeze_later/* =false*/) { #ifdef DEBUG if(ph_dbg_draw_mask.test(phDbgDrawDeathActivationBox)) { DBG_OpenCashedDraw(); Fmatrix M; PHDynamicData::DMXPStoFMX(dBodyGetRotation(m_body),dBodyGetPosition(m_body),M); Fvector v;dGeomBoxGetLengths(m_geom,cast_fp(v));v.mul(0.5f); DBG_DrawOBB(M,v,D3DCOLOR_XRGB(0,255,0)); } #endif VERIFY(m_geom&&m_body); CPHObject::activate(); ph_world->Freeze(); UnFreeze(); max_depth=0.f; dGeomUserDataSetObjectContactCallback(m_geom,GetMaxDepthCallback) ; //ph_world->Step(); ph_world->StepTouch(); u16 num_it =15; float fnum_it=float(num_it); float fnum_steps=float(steps); float fnum_steps_r=1.f/fnum_steps; float resolve_depth=0.01f; float max_vel=max_depth/fnum_it*fnum_steps_r/fixed_step; float limit_l_vel=_max(_max(need_size.x,need_size.y),need_size.z)/fnum_it*fnum_steps_r/fixed_step; if(limit_l_vel>default_l_limit) limit_l_vel=default_l_limit; if(max_vel>limit_l_vel) max_vel=limit_l_vel; float max_a_vel=max_rotation/fnum_it*fnum_steps_r/fixed_step; if(max_a_vel>default_w_limit) max_a_vel=default_w_limit; //ph_world->CutVelocity(0.f,0.f); dGeomUserDataSetCallbackData(m_geom,this); dGeomUserDataSetObjectContactCallback( m_geom, ActivateTestDepthCallback ); if( m_flags.test( flStaticEnvironment ) ) dGeomUserDataAddObjectContactCallback(m_geom,StaticEnvironment); max_depth=0.f; Fvector from_size; Fvector step_size,size; dGeomBoxGetLengths(m_geom,cast_fp(from_size)); step_size.sub(need_size,from_size); step_size.mul(fnum_steps_r); size.set(from_size); bool ret=false; V_PH_WORLD_STATE temp_state; ph_world->GetState(temp_state); for(int m=0;steps>m;++m) { //float param =fnum_steps_r*(1+m); //InterpolateBox(id,param); size.add(step_size); dGeomBoxSetLengths(m_geom,size.x,size.y,size.z); u16 attempts=10; do{ ret=false; for(int i=0;num_it>i;++i) { max_depth=0.f; ph_world->Step(); CHECK_POS(Position(),"pos after ph_world->Step()",false); ph_world->CutVelocity(max_vel,max_a_vel); CHECK_POS(Position(),"pos after CutVelocity",true); //if(m==0&&i==0)ph_world->GetState(temp_state); if(max_depth < resolve_depth) { ret=true; break; } } attempts--; }while(!ret&&attempts>0); #ifdef DEBUG Msg("correction attempts %d",10-attempts); #endif } RestoreVelocityState(temp_state); CHECK_POS(Position(),"pos after RestoreVelocityState(temp_state);",true); if(!un_freeze_later)ph_world->UnFreeze(); #ifdef DEBUG if(ph_dbg_draw_mask.test(phDbgDrawDeathActivationBox)) { DBG_OpenCashedDraw(); Fmatrix M; PHDynamicData::DMXPStoFMX(dBodyGetRotation(m_body),dBodyGetPosition(m_body),M); Fvector v;v.set(need_size);v.mul(0.5f); DBG_DrawOBB(M,v,D3DCOLOR_XRGB(0,255,255)); DBG_ClosedCashedDraw(30000); } #endif return ret; }
void CCharacterPhysicsSupport:: EndActivateFreeShell ( CObject* who, const Fvector& inital_entity_position, const Fvector& dp, const Fvector & velocity ) { VERIFY ( m_pPhysicsShell ); VERIFY( m_eState==esDead ); #ifdef DEBUG if( dbg_draw_ragdoll_spawn ) { DBG_OpenCashedDraw(); m_pPhysicsShell->dbg_draw_geometry( 0.2f, D3DCOLOR_XRGB( 255, 100, 0 ) ); DBG_ClosedCashedDraw( 50000 ); } #endif CollisionCorrectObjPos( dp ); m_pPhysicsShell->SetGlTransformDynamic(mXFORM); #ifdef DEBUG if( dbg_draw_ragdoll_spawn ) { DBG_OpenCashedDraw(); m_pPhysicsShell->dbg_draw_geometry( 0.2f, D3DCOLOR_XRGB( 255, 0, 100 ) ); DBG_ClosedCashedDraw( 50000 ); } #endif //fly back after correction FlyTo(Fvector().sub(inital_entity_position,m_EntityAlife.Position())); #ifdef DEBUG if( dbg_draw_ragdoll_spawn ) { DBG_OpenCashedDraw(); m_pPhysicsShell->dbg_draw_geometry( 0.2f, D3DCOLOR_XRGB( 100, 255, 100 ) ); DBG_ClosedCashedDraw( 50000 ); } #endif Fvector v = velocity; m_character_shell_control.apply_start_velocity_factor( who, v ); #ifdef DEBUG if( death_anim_debug ) { Msg( "death anim: ragdoll velocity picked from char controller =(%f,%f,%f), velocity applied to ragdoll =(%f,%f,%f) ", velocity.x, velocity.y, velocity.z, v.x, v.y, v.z ); } #endif m_pPhysicsShell->set_LinearVel( v ); //actualize m_pPhysicsShell->GetGlobalTransformDynamic(&mXFORM); m_pPhysicsShell->mXFORM.set(mXFORM); //if( false && anim_mov_ctrl && anim_mov_blend && anim_mov_blend->blend != CBlend::eFREE_SLOT && anim_mov_blend->timeCurrent + Device.fTimeDelta*anim_mov_blend->speed < anim_mov_blend->timeTotal-SAMPLE_SPF-EPS)//. //{ // const Fmatrix sv_xform = mXFORM; // mXFORM.set( start_xform ); // //anim_mov_blend->blendPower = 1; // anim_mov_blend->timeCurrent += Device.fTimeDelta * anim_mov_blend->speed; // m_pPhysicsShell->AnimToVelocityState( Device.fTimeDelta, 2 * default_l_limit, 10.f * default_w_limit ); // mXFORM.set( sv_xform ); //} IKinematics* K=smart_cast<IKinematics*>( m_EntityAlife.Visual( ) ); K->CalculateBones_Invalidate(); K->CalculateBones (TRUE); }
void CExplosive::Explode() { VERIFY(0xffff != Initiator()); VERIFY(m_explosion_flags.test(flReadyToExplode));//m_bReadyToExplode VERIFY(!ph_world->Processing()); //m_bExploding = true; m_explosion_flags.set(flExploding,TRUE); cast_game_object()->processing_activate(); Fvector& pos = m_vExplodePos; Fvector& dir = m_vExplodeDir; #ifdef DEBUG if(ph_dbg_draw_mask.test(phDbgDrawExplosions)) { DBG_OpenCashedDraw(); DBG_DrawPoint(pos,0.3f,D3DCOLOR_XRGB(255,0,0)); } #endif // Msg("---------CExplosive Explode [%d] frame[%d]",cast_game_object()->ID(), Device.dwFrame); OnBeforeExplosion(); //играем звук взрыва Sound->play_at_pos(sndExplode, 0, pos, false); //показываем эффекты m_wallmark_manager.PlaceWallmarks (pos); Fvector vel; smart_cast<CPhysicsShellHolder*>(cast_game_object())->PHGetLinearVell(vel); Fmatrix explode_matrix; explode_matrix.identity(); explode_matrix.j.set(dir); Fvector::generate_orthonormal_basis(explode_matrix.j, explode_matrix.i, explode_matrix.k); explode_matrix.c.set(pos); CParticlesObject* pStaticPG; pStaticPG = CParticlesObject::Create(*m_sExplodeParticles,!m_bDynamicParticles); if (m_bDynamicParticles) m_pExpParticle = pStaticPG; pStaticPG->UpdateParent(explode_matrix,vel); pStaticPG->Play(); //включаем подсветку от взрыва StartLight(); //trace frags Fvector frag_dir; ////////////////////////////// //осколки ////////////////////////////// //------------------------------------- bool SendHits = false; if (OnServer()) SendHits = true; else SendHits = false; for(int i = 0; i < m_iFragsNum; ++i){ frag_dir.random_dir (); frag_dir.normalize (); CCartridge cartridge; cartridge.m_kDist = 1.f; cartridge.m_kHit = 1.f; cartridge.m_kImpulse = 1.f; cartridge.m_kPierce = 1.f; cartridge.fWallmarkSize = fWallmarkSize; cartridge.bullet_material_idx = GMLib.GetMaterialIdx(WEAPON_MATERIAL_NAME); cartridge.m_flags.set (CCartridge::cfTracer,FALSE); Level().BulletManager().AddBullet( pos, frag_dir, m_fFragmentSpeed, m_fFragHit, m_fFragHitImpulse, Initiator(), cast_game_object()->ID(), m_eHitTypeFrag, m_fFragsRadius, cartridge, SendHits ); } if (cast_game_object()->Remote()) return; ///////////////////////////////// //взрывная волна //////////////////////////////// //--------------------------------------------------------------------- xr_vector<ISpatial*> ISpatialResult; g_SpatialSpace->q_sphere(ISpatialResult,0,STYPE_COLLIDEABLE,pos,m_fBlastRadius); m_blasted_objects.clear (); for (u32 o_it=0; o_it<ISpatialResult.size(); o_it++) { ISpatial* spatial = ISpatialResult[o_it]; // feel_touch_new(spatial->dcast_CObject()); CPhysicsShellHolder *pGameObject = smart_cast<CPhysicsShellHolder*>(spatial->dcast_CObject()); if(pGameObject && cast_game_object()->ID() != pGameObject->ID()) m_blasted_objects.push_back(pGameObject); } GetExplosionBox(m_vExplodeSize); START_PROFILE("explosive/activate explosion box") ActivateExplosionBox(m_vExplodeSize,m_vExplodePos); STOP_PROFILE //--------------------------------------------------------------------- #ifdef DEBUG if(ph_dbg_draw_mask.test(phDbgDrawExplosions)) { DBG_ClosedCashedDraw(100000); } #endif ////////////////////////////////////////////////////////////////////////// // Explode Effector ////////////// CGameObject* GO = smart_cast<CGameObject*>(Level().CurrentEntity()); CActor* pActor = smart_cast<CActor*>(GO); if(pActor) { float dist_to_actor = pActor->Position().distance_to(pos); float max_dist = EFFECTOR_RADIUS; if (dist_to_actor < max_dist) AddEffector (pActor, effExplodeHit, effector.effect_sect_name, (max_dist - dist_to_actor) / max_dist ); } }
float imotion_position::motion_collide( float dt, IKinematicsAnimated& KA ) { VERIFY( shell ); float advance_time = collide_animation( dt, KA ); if( time_to_end < ( max_collide_timedelta + end_delta ) ) { interactive_motion_diagnostic( make_string( "motion_collide 0: stoped: time out, time delta %f", dt ).c_str() ); flags.set( fl_switch_dm_toragdoll, TRUE ); return advance_time; } if( depth > depth_resolve ) { #ifdef DEBUG if( dbg_imotion_collide_debug ) { //interactive_motion_diagnostic( make_string( " motion_collide collided0: deppth= %f", depth ).c_str() ); interactive_motion_diagnostic( make_string( "motion_collide 1: stoped: colide: %s, depth %f", collide_diag().c_str(), depth ).c_str() ); DBG_OpenCashedDraw(); shell->dbg_draw_geometry( 0.02, D3DCOLOR_ARGB( 255, 0, 255, 0 ) ); DBG_ClosedCashedDraw( 50000 ); } #endif u32 sv_blends_num = blends_num( KA ); buffer_vector<sblend_save> saved_blends( _alloca( sv_blends_num*sizeof( sblend_save ) ), sv_blends_num ); save_blends( saved_blends, KA ); // sv1 float depth0 = depth; advance_time += collide_animation( collide_adwance_delta, KA ); #ifdef DEBUG if( dbg_imotion_collide_debug ) { interactive_motion_diagnostic( make_string( " motion_collide collided1: deppth= %f", depth ).c_str() ); DBG_OpenCashedDraw(); shell->dbg_draw_geometry( 0.02, D3DCOLOR_ARGB( 255, 0, 255, 255 ) ); DBG_ClosedCashedDraw( 50000 ); } #endif if( depth > depth0 ) { interactive_motion_diagnostic( make_string( "motion_collide 1: stoped: colide: %s, depth %f", collide_diag().c_str(), depth ).c_str() ); flags.set( fl_switch_dm_toragdoll, TRUE ); } else { depth0= depth; advance_time += collide_animation( collide_adwance_delta, KA ); #ifdef DEBUG if( dbg_imotion_collide_debug ) { interactive_motion_diagnostic( make_string( " motion_collide collided2: deppth= %f", depth ).c_str() ); DBG_OpenCashedDraw(); shell->dbg_draw_geometry( 0.02, D3DCOLOR_ARGB( 255, 0, 255, 0 ) ); DBG_ClosedCashedDraw( 50000 ); } #endif if( depth > depth_resolve ) { interactive_motion_diagnostic( make_string( "motion_collide 2: stoped: colide: %s, depth %f", collide_diag().c_str(), depth ).c_str() ); flags.set( fl_switch_dm_toragdoll, TRUE ); } } restore_blends( saved_blends );// rs1 //advance_time += advance_animation( dt-advance_time, KA ); time_to_end += (dt-advance_time); advance_time += (dt-advance_time); force_calculate_bones( KA ); shell->ToAnimBonesPositions( shell_motion_has_history ? mh_clear : mh_unspecified ); #ifdef DEBUG if( dbg_imotion_collide_debug ) { depth = 0; shell->CollideAll(); interactive_motion_diagnostic( make_string( " motion_collide restore: %f ", depth ).c_str() ); DBG_OpenCashedDraw(); shell->dbg_draw_geometry( 0.02, D3DCOLOR_ARGB( 255, 255, 0, 0 ) ); DBG_ClosedCashedDraw( 50000 ); } #endif } return advance_time; }
void CActor::Hit (SHit* pHDS) { pHDS->aim_bullet = false; SHit HDS = *pHDS; if( HDS.hit_type<ALife::eHitTypeBurn || HDS.hit_type >= ALife::eHitTypeMax ) { string256 err; sprintf (err, "Unknown/unregistered hit type [%d]", HDS.hit_type); R_ASSERT2 (0, err ); } #ifdef DEBUG if(ph_dbg_draw_mask.test(phDbgCharacterControl)) { DBG_OpenCashedDraw(); Fvector to;to.add(Position(),Fvector().mul(HDS.dir,HDS.phys_impulse())); DBG_DrawLine(Position(),to,D3DCOLOR_XRGB(124,124,0)); DBG_ClosedCashedDraw(500); } #endif bool bPlaySound = true; if (!g_Alive()) bPlaySound = false; if (!IsGameTypeSingle() && !g_pGamePersistent->bDedicatedServer) { game_PlayerState* ps = Game().GetPlayerByGameID(ID()); if (ps && ps->testFlag(GAME_PLAYER_FLAG_INVINCIBLE)) { bPlaySound = false; if (Device.dwFrame != last_hit_frame && HDS.bone() != BI_NONE) { // вычислить позицию и направленность партикла Fmatrix pos; CParticlesPlayer::MakeXFORM(this,HDS.bone(),HDS.dir,HDS.p_in_bone_space,pos); // установить particles CParticlesObject* ps = NULL; if (eacFirstEye == cam_active && this == Level().CurrentEntity()) ps = CParticlesObject::Create(invincibility_fire_shield_1st,TRUE); else ps = CParticlesObject::Create(invincibility_fire_shield_3rd,TRUE); ps->UpdateParent(pos,Fvector().set(0.f,0.f,0.f)); GamePersistent().ps_needtoplay.push_back(ps); }; }; last_hit_frame = Device.dwFrame; }; if( !g_pGamePersistent->bDedicatedServer && !sndHit[HDS.hit_type].empty() && (ALife::eHitTypeTelepatic != HDS.hit_type)) { ref_sound& S = sndHit[HDS.hit_type][Random.randI(sndHit[HDS.hit_type].size())]; bool b_snd_hit_playing = sndHit[HDS.hit_type].end() != std::find_if(sndHit[HDS.hit_type].begin(), sndHit[HDS.hit_type].end(), playing_pred()); if(ALife::eHitTypeExplosion == HDS.hit_type) { if (this == Level().CurrentControlEntity()) { S.set_volume(10.0f); if(!m_sndShockEffector){ m_sndShockEffector = xr_new<SndShockEffector>(); m_sndShockEffector->Start(this, float(S._handle()->length_ms()), HDS.damage() ); } } else bPlaySound = false; } if (bPlaySound && !b_snd_hit_playing) { Fvector point = Position(); point.y += CameraHeight(); S.play_at_pos (this, point); }; } //slow actor, only when he gets hit if(HDS.hit_type == ALife::eHitTypeWound || HDS.hit_type == ALife::eHitTypeStrike) { hit_slowmo = HDS.damage(); clamp (hit_slowmo,0.0f,1.f); } else hit_slowmo = 0.f; //--------------------------------------------------------------- if (Level().CurrentViewEntity() == this && !g_pGamePersistent->bDedicatedServer && HDS.hit_type == ALife::eHitTypeFireWound) { CObject* pLastHitter = Level().Objects.net_Find(m_iLastHitterID); CObject* pLastHittingWeapon = Level().Objects.net_Find(m_iLastHittingWeaponID); HitSector(pLastHitter, pLastHittingWeapon); }; if ((mstate_real&mcSprint) && Level().CurrentControlEntity() == this && HDS.hit_type != ALife::eHitTypeTelepatic && HDS.hit_type != ALife::eHitTypeRadiation ) { // mstate_real &=~mcSprint; mstate_wishful &=~mcSprint; }; if(!g_pGamePersistent->bDedicatedServer) { HitMark (HDS.damage(), HDS.dir, HDS.who, HDS.bone(), HDS.p_in_bone_space, HDS.impulse, HDS.hit_type); } switch (GameID()) { case GAME_SINGLE: { float hit_power = HitArtefactsOnBelt(HDS.damage(), HDS.hit_type); if (GodMode())//psActorFlags.test(AF_GODMODE)) { HDS.power = 0.0f; // inherited::Hit(0.f,dir,who,element,position_in_bone_space,impulse, hit_type); inherited::Hit(&HDS); return; } else { //inherited::Hit (hit_power,dir,who,element,position_in_bone_space, impulse, hit_type); HDS.power = hit_power; inherited::Hit(&HDS); }; } break; default: { m_bWasBackStabbed = false; if (HDS.hit_type == ALife::eHitTypeWound_2 && Check_for_BackStab_Bone(HDS.bone())) { // convert impulse into local coordinate system Fmatrix mInvXForm; mInvXForm.invert (XFORM()); Fvector vLocalDir; mInvXForm.transform_dir (vLocalDir,HDS.dir); vLocalDir.invert (); Fvector a = {0,0,1}; float res = a.dotproduct(vLocalDir); if (res < -0.707) { game_PlayerState* ps = Game().GetPlayerByGameID(ID()); if (!ps || !ps->testFlag(GAME_PLAYER_FLAG_INVINCIBLE)) m_bWasBackStabbed = true; } }; float hit_power = 0; if (m_bWasBackStabbed) hit_power = 100000; else hit_power = HitArtefactsOnBelt(HDS.damage(), HDS.hit_type); HDS.power = hit_power; inherited::Hit (&HDS); //inherited::Hit (hit_power,dir,who,element,position_in_bone_space, impulse, hit_type, 0.0f); } break; } }
void CInventoryItem::PH_A_CrPr () { if (m_just_after_spawn) { VERIFY(object().Visual()); IKinematics *K = object().Visual()->dcast_PKinematics(); VERIFY( K ); if (!object().PPhysicsShell()) { Msg("! ERROR: PhysicsShell is NULL, object [%s][%d]", object().cName().c_str(), object().ID()); VERIFY2(0, "physical shell is NULL"); return; } if(!object().PPhysicsShell()->isFullActive()) { K->CalculateBones_Invalidate(); K->CalculateBones(TRUE); } object().PPhysicsShell()->GetGlobalTransformDynamic(&object().XFORM()); K->CalculateBones_Invalidate(); K->CalculateBones(TRUE); #if 0 Fbox bb= BoundingBox (); DBG_OpenCashedDraw (); Fvector c,r,p; bb.get_CD(c,r ); XFORM().transform_tiny(p,c); DBG_DrawAABB( p, r,D3DCOLOR_XRGB(255, 0, 0)); //PPhysicsShell()->XFORM().transform_tiny(c); Fmatrix mm; PPhysicsShell()->GetGlobalTransformDynamic(&mm); mm.transform_tiny(p,c); DBG_DrawAABB( p, r,D3DCOLOR_XRGB(0, 255, 0)); DBG_ClosedCashedDraw (50000); #endif object().spatial_move(); m_just_after_spawn = false; VERIFY(!OnServer()); object().PPhysicsShell()->get_ElementByStoreOrder(0)->Fix(); object().PPhysicsShell()->SetIgnoreStatic (); //object().PPhysicsShell()->SetIgnoreDynamic (); //PPhysicsShell()->DisableCollision(); } /*net_updateData* p = NetSync(); //restore recalculated data and get data for interpolation if (!object().CrPr_IsActivated()) return; //////////////////////////////////// CPHSynchronize* pSyncObj = NULL; pSyncObj = object().PHGetSyncItem (0); if (!pSyncObj) return; //////////////////////////////////// pSyncObj->get_State (p->PredictedState); //////////////////////////////////// pSyncObj->set_State (p->RecalculatedState); //////////////////////////////////// if (!m_flags.test(FInInterpolate)) return; //////////////////////////////////// Fmatrix xformX; pSyncObj->cv2obj_Xfrom(p->PredictedState.quaternion, p->PredictedState.position, xformX); VERIFY2 (_valid(xformX),*object().cName()); pSyncObj->cv2obj_Xfrom (p->PredictedState.quaternion, p->PredictedState.position, xformX); p->IEndRot.set (xformX); p->IEndPos.set (xformX.c); VERIFY2 (_valid(p->IEndPos),*object().cName()); ///////////////////////////////////////////////////////////////////////// CalculateInterpolationParams (); ///////////////////////////////////////////////////*/ };