void CTeleWhirlwindObject:: keep () { CPhysicsShell* p = get_object() ->PPhysicsShell(); if(!p||!p->isActive()) return; else { p->SetAirResistance(0.f,0.f); p->set_ApplyByGravity(FALSE); } u16 element_number = p ->get_ElementsNumber(); Fvector center = m_telekinesis ->Center(); CPhysicsElement* maxE=p->get_ElementByStoreOrder(0); for(u16 element=0;element<element_number;++element) { CPhysicsElement* E= p->get_ElementByStoreOrder(element); if(maxE->getMass()<E->getMass())maxE=E; Fvector dir;dir.sub(center,E->mass_Center()); dir.normalize_safe(); Fvector vel; E->get_LinearVel(vel); float force=dir.dotproduct(vel)*E->getMass()/2.f; if(force<0.f) { dir.mul(force); } } maxE->setTorque(Fvector().set(0,500.f,0)); Fvector dist;dist.sub(center,maxE->mass_Center()); if(dist.magnitude()>m_telekinesis->keep_radius()*1.5f) { p->setTorque(Fvector().set(0,0,0)); p->setForce(Fvector().set(0,0,0)); p->set_LinearVel(Fvector().set(0,0,0)); p->set_AngularVel(Fvector().set(0,0,0)); p->set_ApplyByGravity(TRUE); switch_state(TS_Raise); } }
void reset_root_bone_start_pose( CPhysicsShell& shell ) { VERIFY( &shell ); CPhysicsElement * physics_root_element = shell.get_ElementByStoreOrder( 0 ); VERIFY( physics_root_element ); IKinematics * K = shell.PKinematics(); VERIFY( K ); u16 animation_root_bone_id = K->LL_GetBoneRoot(); CODEGeom *physics_root_bone_geom = physics_root_element->geometry( 0 ); VERIFY( physics_root_bone_geom ); u16 physics_root_bone_id = physics_root_bone_geom->bone_id(); VERIFY( physics_root_bone_id != BI_NONE ); if( animation_root_bone_id == physics_root_bone_id ) return ; //u16 anim_bones_number = K->LL_BoneCount(); //buffer_vector<u32> anim_bones_bind_positions( _alloca(anim_bones_number*sizeof(u32)), // anim_bones_number // ); #pragma todo("LL_GetBindTransform shoud use buffer_vector") xr_vector<Fmatrix> anim_bones_bind_positions; K->LL_GetBindTransform( anim_bones_bind_positions ); const Fmatrix physics_root_to_anim_root_bind_transformation = Fmatrix().mul_43( Fmatrix().invert( anim_bones_bind_positions[ physics_root_bone_id ] ), anim_bones_bind_positions[ animation_root_bone_id ] ); const Fmatrix &physics_root_bone_anim_transform = K->LL_GetTransform( physics_root_bone_id ); const Fmatrix physics_root_bone_corrected_pos = Fmatrix().mul_43( physics_root_bone_anim_transform , physics_root_to_anim_root_bind_transformation ); physics_root_element->SetTransform( Fmatrix().mul_43( shell.mXFORM, physics_root_bone_corrected_pos ) ); //physics_root_element->TransformPosition( Fmatrix().mul_43( Fmatrix().invert( K->LL_GetTransform( animation_root_bone_id ) ), physics_root_bone_corrected_pos ) ); }
void CTeleWhirlwindObject:: raise (float step) { CPhysicsShell* p = get_object() ->PPhysicsShell(); if(!p||!p->isActive()) return; else { p->SetAirResistance(0.f,0.f); p->set_ApplyByGravity(TRUE); } u16 element_number = p ->get_ElementsNumber(); Fvector center = m_telekinesis ->Center(); CPhysicsElement* maxE=p->get_ElementByStoreOrder(0); for(u16 element=0;element<element_number;++element) { float k=strength;//600.f; float predict_v_eps=0.1f; float mag_eps =.01f; CPhysicsElement* E= p->get_ElementByStoreOrder(element); if(maxE->getMass()<E->getMass()) maxE=E; if (!E->isActive()) continue; Fvector pos=E->mass_Center(); Fvector diff; diff.sub(center,pos); float mag=_sqrt(diff.x*diff.x+diff.z*diff.z); Fvector lc;lc.set(center); if(mag>1.f) { lc.y/=mag; } diff.sub(lc,pos); mag=diff.magnitude(); float accel=k/mag/mag/mag;//*E->getMass() Fvector dir; if(mag<mag_eps) { accel=0.f; //Fvector zer;zer.set(0,0,0); //E->set_LinearVel(zer); dir.random_dir(); } else { dir.set(diff);dir.mul(1.f/mag); } Fvector vel; E->get_LinearVel(vel); float delta_v=accel*fixed_step; Fvector delta_vel; delta_vel.set(dir);delta_vel.mul(delta_v); Fvector predict_vel;predict_vel.add(vel,delta_vel); Fvector delta_pos;delta_pos.set(predict_vel);delta_pos.mul(fixed_step); Fvector predict_pos;predict_pos.add(pos,delta_pos); Fvector predict_diff;predict_diff.sub(lc,predict_pos); float predict_mag=predict_diff.magnitude(); float predict_v=predict_vel.magnitude(); Fvector force;force.set(dir); if(predict_mag>mag && predict_vel.dotproduct(dir)>0.f && predict_v>predict_v_eps) { Fvector motion_dir;motion_dir.set(predict_vel);motion_dir.mul(1.f/predict_v); float needed_d=diff.dotproduct(motion_dir); Fvector needed_diff;needed_diff.set(motion_dir);needed_diff.mul(needed_d); Fvector nearest_p;nearest_p.add(pos,needed_diff);// Fvector needed_vel;needed_vel.set(needed_diff);needed_vel.mul(1.f/fixed_step); force.sub(needed_vel,vel); force.mul(E->getMass()/fixed_step); } else { force.mul(accel*E->getMass()); } E->applyForce(force.x,force.y+get_object()->EffectiveGravity()*E->getMass(),force.z); } Fvector dist;dist.sub(center,maxE->mass_Center()); if(dist.magnitude()<m_telekinesis->keep_radius()&&b_destroyable) { p->setTorque(Fvector().set(0,0,0)); p->setForce(Fvector().set(0,0,0)); p->set_LinearVel(Fvector().set(0,0,0)); p->set_AngularVel(Fvector().set(0,0,0)); switch_state(TS_Keep); } }