door::door ( CPhysicObject* object ) : m_object ( *object ), m_state ( door_state_open ), m_previous_state ( door_state_open ), m_target_state ( door_state_open ), m_registered_position ( object->Position() ), m_locked ( false ) { VERIFY ( valid(m_state) ); VERIFY ( valid(m_target_state) ); VERIFY ( valid(m_previous_state) ); R_ASSERT ( m_object.get_door_vectors( m_closed_vector, m_open_vector ) ); Fmatrix invert; invert.invert ( m_object.XFORM() ); invert.transform_dir ( m_open_vector ); invert.transform_dir ( m_closed_vector ); float const length = 1.1f; m_open_vector.mul ( length ); m_closed_vector.mul ( length ); m_object.spatial.type |= STYPE_VISIBLEFORAI; }
//---------------------------------------------------- IC bool build_mesh(const Fmatrix& parent, CEditableMesh* mesh, CGeomPartExtractor* extractor, u32 game_mtl_mask, BOOL ignore_shader) { bool bResult = true; mesh->GenerateVNormals (&parent); // fill faces for (SurfFaces::const_iterator sp_it=mesh->GetSurfFaces().begin(); sp_it!=mesh->GetSurfFaces().end(); sp_it++){ const IntVec& face_lst = sp_it->second; CSurface* surf = sp_it->first; int gm_id = surf->_GameMtl(); if (gm_id==GAMEMTL_NONE_ID){ ELog.DlgMsg (mtError,"Object '%s', surface '%s' contain invalid game material.",mesh->Parent()->m_LibName.c_str(),surf->_Name()); bResult = FALSE; break; } SGameMtl* M = GMLib.GetMaterialByID(gm_id); if (0==M){ ELog.DlgMsg (mtError,"Object '%s', surface '%s' contain undefined game material.",mesh->Parent()->m_LibName.c_str(),surf->_Name()); bResult = FALSE; break; } if (!M->Flags.is(game_mtl_mask)) continue; // check engine shader compatibility if (!ignore_shader){ IBlender* B = EDevice.Resources->_FindBlender(surf->_ShaderName()); if (FALSE==B){ ELog.Msg (mtError,"Can't find engine shader '%s'. Object '%s', surface '%s'. Export interrupted.",surf->_ShaderName(),mesh->Parent()->m_LibName.c_str(),surf->_Name()); bResult = FALSE; break; } if (TRUE==B->canBeLMAPped()){ ELog.Msg (mtError,"Object '%s', surface '%s' contain static engine shader - '%s'. Export interrupted.",mesh->Parent()->m_LibName.c_str(),surf->_Name(),surf->_ShaderName()); bResult = FALSE; break; } } const st_Face* faces = mesh->GetFaces(); VERIFY(faces); const Fvector* vn = mesh->GetVNormals(); VERIFY(vn); const Fvector* pts = mesh->GetVertices(); VERIFY(pts); for (IntVec::const_iterator f_it=face_lst.begin(); f_it!=face_lst.end(); f_it++){ const st_Face& face = faces[*f_it]; Fvector v[3],n[3]; parent.transform_tiny (v[0],pts[face.pv[0].pindex]); parent.transform_tiny (v[1],pts[face.pv[1].pindex]); parent.transform_tiny (v[2],pts[face.pv[2].pindex]); parent.transform_dir (n[0],vn[*f_it*3+0]); n[0].normalize(); parent.transform_dir (n[1],vn[*f_it*3+1]); n[1].normalize(); parent.transform_dir (n[2],vn[*f_it*3+2]); n[2].normalize(); const Fvector2* uv[3]; mesh->GetFaceTC (*f_it,uv); extractor->AppendFace (surf,v,n,uv); } if (!bResult) break; } mesh->UnloadVNormals (); return bResult; }
void pDomain::transform(const pDomain& domain, const Fmatrix& m) { switch (type) { case PDBox:{ Fbox* bb_dest=(Fbox*)&p1; Fbox* bb_from=(Fbox*)&domain.p1; bb_dest->xform(*bb_from,m); }break; case PDPlane: m.transform_tiny(p1,domain.p1); m.transform_dir(p2,domain.p2); // radius1 stores the d of the plane eqn. radius1 = -(p1 * p2); break; case PDSphere: m.transform_tiny(p1,domain.p1); break; case PDCylinder: case PDCone: m.transform_tiny(p1,domain.p1); m.transform_dir(p2,domain.p2); m.transform_dir(u,domain.u); m.transform_dir(v,domain.v); break; case PDBlob: m.transform_tiny(p1,domain.p1); break; case PDPoint: m.transform_tiny(p1,domain.p1); break; case PDLine: m.transform_tiny(p1,domain.p1); m.transform_dir(p2,domain.p2); break; case PDRectangle: m.transform_tiny(p1,domain.p1); m.transform_dir(p2,domain.p2); m.transform_dir(u,domain.u); m.transform_dir(v,domain.v); break; case PDTriangle: m.transform_tiny(p1,domain.p1); m.transform_dir(p2,domain.p2); m.transform_dir(u,domain.u); m.transform_dir(v,domain.v); break; case PDDisc: m.transform_tiny(p1,domain.p1); m.transform_dir(p2,domain.p2); m.transform_dir(u,domain.u); m.transform_dir(v,domain.v); break; default: NODEFAULT; } }
bool CKinematics:: PickBone (const Fmatrix &parent_xform, Fvector& normal, float& dist, const Fvector& start, const Fvector& dir, u16 bone_id) { Fvector S,D;//normal = {0,0,0} // transform ray from world to model Fmatrix P; P.invert (parent_xform); P.transform_tiny (S,start); P.transform_dir (D,dir); for (u32 i=0; i<children.size(); i++) if (LL_GetChild(i)->PickBone(normal,dist,S,D,bone_id)) { parent_xform.transform_dir (normal); return true; } return false; }
void CDrawUtilities::DrawCross(const Fvector& p, float szx1, float szy1, float szz1, float szx2, float szy2, float szz2, u32 clr, BOOL bRot45) { _VertexStream* Stream = &RCache.Vertex; // actual rendering u32 vBase; FVF::L* pv = (FVF::L*)Stream->Lock(bRot45?12:6,vs_L->vb_stride,vBase); pv->set(p.x+szx2,p.y,p.z,clr); pv++; pv->set(p.x-szx1,p.y,p.z,clr); pv++; pv->set(p.x,p.y+szy2,p.z,clr); pv++; pv->set(p.x,p.y-szy1,p.z,clr); pv++; pv->set(p.x,p.y,p.z+szz2,clr); pv++; pv->set(p.x,p.y,p.z-szz1,clr); pv++; if (bRot45){ Fmatrix M; M.setHPB(PI_DIV_4,PI_DIV_4,PI_DIV_4); for(int i=0;i<6;i++,pv++){ pv->p.sub((pv-6)->p,p); M.transform_dir(pv->p); pv->p.add(p); pv->color = clr; } } // unlock VB and Render it as triangle list Stream->Unlock(bRot45?12:6,vs_L->vb_stride); DU_DRAW_DP (D3DPT_LINELIST,vs_L,vBase,bRot45?6:3); }
//void CEntity::Hit (float perc, Fvector &dir, CObject* who, s16 element,Fvector position_in_object_space, float impulse, ALife::EHitType hit_type) void CEntity::Hit (SHit* pHDS) { // if (bDebug) Log("Process HIT: ", *cName()); // *** process hit calculations // Calc impulse Fvector vLocalDir; float m = pHDS->dir.magnitude(); VERIFY (m>EPS); // convert impulse into local coordinate system Fmatrix mInvXForm; mInvXForm.invert (XFORM()); mInvXForm.transform_dir (vLocalDir,pHDS->dir); vLocalDir.invert (); // hit impulse if(pHDS->impulse) HitImpulse (pHDS->impulse,pHDS->dir,vLocalDir); // @@@: WT // Calc amount (correct only on local player) float lost_health = CalcCondition(pHDS->damage()); // Signal hit if(BI_NONE!=pHDS->bone()) HitSignal(lost_health,vLocalDir,pHDS->who,pHDS->boneID); // If Local() - perform some logic if (Local() && !g_Alive() && !AlreadyDie() && (m_killer_id == ALife::_OBJECT_ID(-1))) { KillEntity (pHDS->whoID); } //must be last!!! @slipch inherited::Hit(pHDS); }
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); }
bool CEditShape::RayPick(float& distance, const Fvector& start, const Fvector& direction, SRayPickInfo* pinf) { float dist = distance; for (ShapeIt it=shapes.begin(); it!=shapes.end(); it++){ switch (it->type){ case cfSphere:{ Fvector S,D; Fmatrix M; M.invert (FTransformR); M.transform_dir (D,direction); FITransform.transform_tiny(S,start); Fsphere& T = it->data.sphere; float bk_r = T.R; // T.R = FScale.x; T.intersect (S,D,dist); if (dist<=0.f) dist = distance; T.R = bk_r; }break; case cfBox:{ Fbox box; box.identity (); Fmatrix BI; BI.invert (it->data.box); Fvector S,D,S1,D1,P; FITransform.transform_tiny (S,start); FITransform.transform_dir (D,direction); BI.transform_tiny (S1,S); BI.transform_dir (D1,D); Fbox::ERP_Result rp_res = box.Pick2(S1,D1,P); if (rp_res==Fbox::rpOriginOutside){ it->data.box.transform_tiny (P); FTransform.transform_tiny (P); P.sub (start); dist = P.magnitude(); } }break; } } if (dist<distance){ distance = dist; return true; } return false; }
void occRasterizer::on_dbg_render() { #if DEBUG if( !ps_r2_ls_flags_ext.is(R_FLAGEXT_HOM_DEPTH_DRAW) ) { dbg_HOM_draw_initialized = false; return; } for ( int i = 0; i< occ_dim_0; ++i) { for ( int j = 0; j< occ_dim_0; ++j) { if( bDebug ) { Fvector quad,left_top,right_bottom,box_center,box_r; quad.set( (float)j-occ_dim_0/2.f, -((float)i-occ_dim_0/2.f), (float)bufDepth_0[i][j]/occQ_s32); Device.mProject; float z = -Device.mProject._43/(float)(Device.mProject._33-quad.z); left_top.set ( quad.x*z/Device.mProject._11/(occ_dim_0/2.f), quad.y*z/Device.mProject._22/(occ_dim_0/2.f), z); right_bottom.set ( (quad.x+1)*z/Device.mProject._11/(occ_dim_0/2.f), (quad.y+1)*z/Device.mProject._22/(occ_dim_0/2.f), z); box_center.set ((right_bottom.x + left_top.x)/2, (right_bottom.y + left_top.y)/2, z); box_r = right_bottom; box_r.sub(box_center); Fmatrix inv; inv.invert(Device.mView); inv.transform( box_center ); inv.transform_dir( box_r ); pixel_box& tmp = dbg_pixel_boxes[ i*occ_dim_0+j]; tmp.center = box_center; tmp.radius = box_r; tmp.z = quad.z; dbg_HOM_draw_initialized = true; } if( !dbg_HOM_draw_initialized ) return; pixel_box& tmp = dbg_pixel_boxes[ i*occ_dim_0+j]; Fmatrix Transform; Transform.identity(); Transform.translate(tmp.center); // draw wire Device.SetNearer(TRUE); RCache.set_Shader (dxRenderDeviceRender::Instance().m_SelectionShader); RCache.dbg_DrawOBB( Transform, tmp.radius, D3DCOLOR_XRGB(u32(255*pow(tmp.z,20.f)),u32(255*(1-pow(tmp.z,20.f))),0) ); Device.SetNearer(FALSE); } } #endif }
void CParticleGroup::SItem::StartRelatedChild(CParticleEffect* emitter, LPCSTR eff_name, PAPI::Particle& m) { CParticleEffect*C = static_cast<CParticleEffect*>(RImplementation.model_CreatePE(eff_name)); Fmatrix M; M.identity(); Fvector vel; vel.sub(m.pos,m.posB); vel.div(fDT_STEP); if (emitter->m_RT_Flags.is(CParticleEffect::flRT_XFORM)){ M.set (emitter->m_XFORM); M.transform_dir (vel); }; Fvector p; M.transform_tiny (p,m.pos); M.c.set (p); C->Play (); C->UpdateParent (M,vel,FALSE); _children_related.push_back(C); }
bool CBone::Pick(float& dist, const Fvector& S, const Fvector& D, const Fmatrix& parent) { Fvector start, dir; Fmatrix M; M.mul_43(parent,_LTransform()); M.invert(); M.transform_tiny(start,S); M.transform_dir(dir,D); switch (shape.type){ case SBoneShape::stBox: return shape.box.intersect (start,dir,dist); case SBoneShape::stSphere: return shape.sphere.intersect (start,dir,dist); case SBoneShape::stCylinder:return shape.cylinder.intersect (start,dir,dist); default: Fsphere S; S.P.set(0,0,0); S.R=0.025f; return S.intersect(start,dir,dist); } }
void CCarWeapon::UpdateBarrelDir() { CKinematics* K = smart_cast<CKinematics*>(m_object->Visual()); m_fire_bone_xform = K->LL_GetTransform(m_fire_bone); m_fire_bone_xform.mulA_43(m_object->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_norm.set(0,1,0); m_fire_bone_xform.transform_dir(m_fire_norm); m_allow_fire = true; Fmatrix XFi; XFi.invert (m_object->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()); clamp (m_tgt_x_rot,-m_lim_x_rot.y,-m_lim_x_rot.x); } {// 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()); clamp (m_tgt_y_rot,-m_lim_y_rot.y,-m_lim_y_rot.x); } m_cur_x_rot = angle_inertion_var(m_cur_x_rot,m_tgt_x_rot,m_min_gun_speed,m_max_gun_speed,PI,Device.fTimeDelta); m_cur_y_rot = angle_inertion_var(m_cur_y_rot,m_tgt_y_rot,m_min_gun_speed,m_max_gun_speed,PI,Device.fTimeDelta); static float dir_eps = deg2rad(5.0f); if( !fsimilar(m_cur_x_rot,m_tgt_x_rot,dir_eps)|| !fsimilar(m_cur_y_rot,m_tgt_y_rot,dir_eps)) m_allow_fire=FALSE; #if (0) if(Device.dwFrame%200==0){ Msg("m_cur_x_rot=[%f]",m_cur_x_rot); Msg("m_cur_y_rot=[%f]",m_cur_y_rot); } #endif }
void CBone::ShapeRotate(const Fvector& _amount) { Fvector amount=_amount; Fmatrix _IT;_IT.invert(_LTransform()); if (Tools->GetSettings(etfCSParent)) _IT.transform_dir(amount); switch (shape.type){ case SBoneShape::stBox:{ Fmatrix R; R.setXYZi(amount.x,amount.y,amount.z); shape.box.transform(shape.box,R); }break; case SBoneShape::stSphere: break; case SBoneShape::stCylinder:{ Fmatrix R; R.setXYZi(amount.x,amount.y,amount.z); R.transform_dir(shape.cylinder.m_direction); }break; } }
void CPHGeometryOwner::add_Shape(const SBoneShape& shape,const Fmatrix& offset) { switch(shape.type) { case SBoneShape::stBox : { Fobb box=shape.box; Fmatrix m; m.set(offset); //Fmatrix position; //position.set(box.m_rotate); //position.c.set(box.m_translate); //position.mulA(offset); //box.m_rotate.set(position); //box.m_translate.set(position.c); box.transform(box,m); add_Box(box); break; } case SBoneShape::stSphere : { Fsphere sphere=shape.sphere; offset.transform_tiny(sphere.P); add_Sphere(sphere); break; } case SBoneShape::stCylinder : { Fcylinder C=shape.cylinder; offset.transform_tiny(C.m_center); offset.transform_dir(C.m_direction); add_Cylinder(C); break; } case SBoneShape::stNone : break; default: NODEFAULT; } }
void __fastcall TUI_ControlAIMapNodeRotate::Move(TShiftState _Shift) { if (_Shift.Contains(ssLeft)){ float amount = -UI->m_DeltaCpH.x * UI->m_MouseSR; if( Tools->GetSettings(etfASnap) ) CHECK_SNAP(m_fRotateSnapAngle,amount,Tools->m_RotateSnapAngle); Fmatrix R; if (fis_zero(m_RotateVector.x)) R.rotateZ(amount); else R.rotateX(amount); AINodeVec& lst = ((ESceneAIMapTool*)parent_tool)->Nodes(); for(AINodeIt _F = lst.begin();_F!=lst.end();_F++) if((*_F)->flags.is(SAINode::flSelected)){ Fvector new_n; R.transform_dir(new_n,(*_F)->Plane.n); if (Fvector().set(0,1,0).dotproduct(new_n)>0.02f){ (*_F)->Plane.build((*_F)->Pos,new_n); } } } }
void CParticleGroup::SItem::StartFreeChild(CParticleEffect* emitter, LPCSTR nm, PAPI::Particle& m) { CParticleEffect*C = static_cast<CParticleEffect*>(RImplementation.model_CreatePE(nm)); if(!C->IsLooped()){ Fmatrix M; M.identity(); Fvector vel; vel.sub(m.pos,m.posB); vel.div(fDT_STEP); if (emitter->m_RT_Flags.is(CParticleEffect::flRT_XFORM)){ M.set (emitter->m_XFORM); M.transform_dir (vel); }; Fvector p; M.transform_tiny (p,m.pos); M.c.set (p); C->Play (); C->UpdateParent (M,vel,FALSE); _children_free.push_back(C); }else{ #ifdef _EDITOR Msg ("!Can't use looped effect '%s' as 'On Birth' child for group.",nm); #else Debug.fatal (DEBUG_INFO,"Can't use looped effect '%s' as 'On Birth' child for group.",nm); #endif } }
void CIKLimb::GoalMatrix(Matrix &M,SCalculateData* cd) { VERIFY(cd->m_tri&&cd->m_tri_hight!=-dInfinity); const Fmatrix &obj=*cd->m_obj; CDB::TRI *tri=cd->m_tri; CKinematics *K=cd->m_K; Fvector* pVerts = Level().ObjectSpace.GetStaticVerts(); Fvector normal; normal.mknormal (pVerts[tri->verts[0]],pVerts[tri->verts[1]],pVerts[tri->verts[2]]); VERIFY(!fis_zero(normal.magnitude())); Fmatrix iobj;iobj.invert(obj);iobj.transform_dir(normal); Fmatrix xm;xm.set(K->LL_GetTransform(m_bones[2])); //Fvector dbg; //dbg.set(Fvector().mul(normal,normal.y*tri_hight // -normal.dotproduct(xm.i)*m_toe_position.x // -normal.dotproduct(xm.j)*m_toe_position.y // -normal.dotproduct(xm.k)*m_toe_position.z-m_toe_position.x // )); normal.invert(); Fvector ax;ax.crossproduct(normal,xm.i); float s=ax.magnitude(); if(!fis_zero(s)) { ax.mul(1.f/s); xm.mulA_43(Fmatrix().rotation(ax,asinf(-s))); } Fvector otri;iobj.transform_tiny(otri,pVerts[tri->verts[0]]); float tp=normal.dotproduct(otri); Fvector add; add.set(Fvector().mul(normal,-m_toe_position.x+tp-xm.c.dotproduct(normal))); xm.c.add(add); Fmatrix H; CBoneData& bd=K->LL_GetData(m_bones[0]); H.set(bd.bind_transform); H.mulA_43(K->LL_GetTransform(bd.GetParentID())); H.c.set(K->LL_GetTransform(m_bones[0]).c); #ifdef DEBUG if(ph_dbg_draw_mask.test(phDbgIKAnimGoalOnly)) xm.set(K->LL_GetTransform(m_bones[2])); if(ph_dbg_draw_mask.test(phDbgDrawIKGoal)) { Fmatrix DBGG; DBGG.mul_43(obj,xm); DBG_DrawMatrix(DBGG,0.2f); DBGG.mul_43(obj,H); DBG_DrawMatrix(DBGG,0.2f); } #endif H.invert(); Fmatrix G; G.mul_43(H,xm); XM2IM(G,M); }
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; } }
bool ESceneObjectTool::ExportBreakableObjects(SExportStreams* F) { bool bResult = true; CGeomPartExtractor* extractor=0; Fbox bb; if (!GetBox(bb)) return false; extractor = xr_new<CGeomPartExtractor>(); extractor->Initialize(bb,EPS_L,2); UI->SetStatus ("Export breakable objects..."); // collect verts&&faces { SPBItem* pb = UI->ProgressStart(m_Objects.size(),"Prepare geometry..."); for (ObjectIt it=m_Objects.begin(); it!=m_Objects.end(); it++){ pb->Inc(); CSceneObject* obj = dynamic_cast<CSceneObject*>(*it); VERIFY(obj); if (obj->IsStatic()){ CEditableObject *O = obj->GetReference(); const Fmatrix& T = obj->_Transform(); for(EditMeshIt M=O->FirstMesh();M!=O->LastMesh();M++) if (!build_mesh (T,*M,extractor,SGameMtl::flBreakable,FALSE)){bResult=false;break;} } } UI->ProgressEnd(pb); } if (!extractor->Process()) bResult = false; // export parts if (bResult){ SBPartVec& parts = extractor->GetParts(); SPBItem* pb = UI->ProgressStart(parts.size(),"Export Parts..."); for (SBPartVecIt p_it=parts.begin(); p_it!=parts.end(); p_it++){ pb->Inc(); SBPart* P = *p_it; if (P->Valid()){ // export visual AnsiString sn = AnsiString().sprintf("meshes\\brkbl#%d.ogf",(p_it-parts.begin())); xr_string fn = Scene->LevelPath()+sn.c_str(); IWriter* W = FS.w_open(fn.c_str()); R_ASSERT(W); if (!P->Export(*W,1)){ ELog.DlgMsg (mtError,"Invalid breakable object."); bResult = false; break; } FS.w_close (W); // export spawn object { AnsiString entity_ref = "breakable_object"; ISE_Abstract* m_Data = create_entity(entity_ref.c_str()); VERIFY(m_Data); CSE_Visual* m_Visual = m_Data->visual(); VERIFY(m_Visual); // set params m_Data->set_name (entity_ref.c_str()); m_Data->set_name_replace (sn.c_str()); m_Data->position().set (P->m_RefOffset); m_Data->angle().set (P->m_RefRotate); m_Visual->set_visual (sn.c_str(),false); if (s_draw_dbg){ Fmatrix MX; MX.setXYZi (P->m_RefRotate); MX.translate_over (P->m_RefOffset); Fvector DR = {0,0,1}; MX.transform_dir (DR); Tools->m_DebugDraw.AppendLine(P->m_RefOffset,Fvector().mad(P->m_RefOffset,MX.k,1.f),0xFF0000FF,false,false); } NET_Packet Packet; m_Data->Spawn_Write (Packet,TRUE); F->spawn.stream.open_chunk (F->spawn.chunk++); F->spawn.stream.w (Packet.B.data,Packet.B.count); F->spawn.stream.close_chunk (); destroy_entity (m_Data); } }else{ ELog.Msg(mtError,"Can't export invalid part #%d",p_it-parts.begin()); } } UI->ProgressEnd(pb); } // clean up xr_delete(extractor); return bResult; }
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 CLensFlare::OnFrame(int id) { if (dwFrame==Device.dwFrame)return; #ifndef _EDITOR if (!g_pGameLevel) return; #endif dwFrame = Device.dwFrame; vSunDir.mul (g_pGamePersistent->Environment().CurrentEnv.sun_dir,-1); // color float tf = g_pGamePersistent->Environment().fTimeFactor; Fvector& c = g_pGamePersistent->Environment().CurrentEnv.sun_color; LightColor.set (c.x,c.y,c.z,1.f); CLensFlareDescriptor* desc = (id==-1)?0:&m_Palette[id]; switch(m_State){ case lfsNone: m_State=lfsShow; m_Current=desc; break; case lfsIdle: if (desc!=m_Current) m_State=lfsHide; break; case lfsShow: m_StateBlend = m_Current?(m_StateBlend + m_Current->m_StateBlendUpSpeed * Device.fTimeDelta * tf):1.f+EPS; if (m_StateBlend>=1.f) m_State=lfsIdle; break; case lfsHide: m_StateBlend = m_Current?(m_StateBlend - m_Current->m_StateBlendDnSpeed * Device.fTimeDelta * tf):0.f-EPS; if (m_StateBlend<=0.f){ m_State = lfsShow; m_Current = desc; m_StateBlend= m_Current?m_Current->m_StateBlendUpSpeed * Device.fTimeDelta * tf:0; } break; } clamp(m_StateBlend,0.f,1.f); if ((m_Current==0)||(LightColor.magnitude_rgb()==0.f)){bRender=false; return;} // // Compute center and axis of flares // float fDot; Fvector vecPos; Fmatrix matEffCamPos; matEffCamPos.identity(); // Calculate our position and direction matEffCamPos.i.set(Device.vCameraRight); matEffCamPos.j.set(Device.vCameraTop); matEffCamPos.k.set(Device.vCameraDirection); vecPos.set(Device.vCameraPosition); vecDir.set(0.0f, 0.0f, 1.0f); matEffCamPos.transform_dir(vecDir); vecDir.normalize(); // Figure out of light (or flare) might be visible vecLight.set(vSunDir); vecLight.normalize(); fDot = vecLight.dotproduct(vecDir); if(fDot <= 0.01f){ bRender = false; return;} else bRender = true; // Calculate the point directly in front of us, on the far clip plane float fDistance = FAR_DIST*0.75f; vecCenter.mul(vecDir, fDistance); vecCenter.add(vecPos); // Calculate position of light on the far clip plane vecLight.mul(fDistance / fDot); vecLight.add(vecPos); // Compute axis which goes from light through the center of the screen vecAxis.sub(vecLight, vecCenter); // // Figure out if light is behind something else vecX.set(1.0f, 0.0f, 0.0f); matEffCamPos.transform_dir(vecX); vecX.normalize(); vecY.crossproduct(vecX, vecDir); #ifdef _EDITOR float dist = UI->ZFar(); if (Tools->RayPick(Device.m_Camera.GetPosition(),vSunDir,dist)) fBlend = fBlend - BLEND_DEC_SPEED * Device.fTimeDelta; else fBlend = fBlend + BLEND_INC_SPEED * Device.fTimeDelta; #else CObject* o_main = g_pGameLevel->CurrentViewEntity(); STranspParam TP (this,Device.vCameraPosition,vSunDir,1000.f,EPS_L); collide::ray_defs RD (TP.P,TP.D,TP.f,CDB::OPT_CULL,collide::rqtBoth); if (m_ray_cache.result&&m_ray_cache.similar(TP.P,TP.D,TP.f)){ // similar with previous query == 0 TP.vis = 0.f; }else{ float _u,_v,_range; if (CDB::TestRayTri(TP.P,TP.D,m_ray_cache.verts,_u,_v,_range,false)&&(_range>0 && _range<TP.f)){ TP.vis = 0.f; }else{ // cache outdated. real query. r_dest.r_clear (); if (g_pGameLevel->ObjectSpace.RayQuery (r_dest,RD,material_callback,&TP,NULL,o_main)) m_ray_cache.result = FALSE ; } } blend_lerp(fBlend,TP.vis,BLEND_DEC_SPEED,Device.fTimeDelta); #endif clamp( fBlend, 0.0f, 1.0f ); // gradient if (m_Current->m_Flags.is(CLensFlareDescriptor::flGradient)) { Fvector scr_pos; Device.mFullTransform.transform ( scr_pos, vecLight ); float kx = 1, ky = 1; float sun_blend = 0.5f; float sun_max = 2.5f; scr_pos.y *= -1; if (_abs(scr_pos.x) > sun_blend) kx = ((sun_max - (float)_abs(scr_pos.x))) / (sun_max - sun_blend); if (_abs(scr_pos.y) > sun_blend) ky = ((sun_max - (float)_abs(scr_pos.y))) / (sun_max - sun_blend); if (!((_abs(scr_pos.x) > sun_max) || (_abs(scr_pos.y) > sun_max))){ float op = m_StateBlend*m_Current->m_Gradient.fOpacity; fGradientValue = kx * ky * op * fBlend; }else fGradientValue = 0; } }
void CActor::g_cl_CheckControls(u32 mstate_wf, Fvector &vControlAccel, float &Jump, float dt) { mstate_old = mstate_real; vControlAccel.set (0,0,0); if (!(mstate_real&mcFall) && (character_physics_support()->movement()->Environment()==CPHMovementControl::peInAir)) { m_fFallTime -= dt; if (m_fFallTime<=0.f){ m_fFallTime = s_fFallTime; mstate_real |= mcFall; mstate_real &=~ mcJump; } } if(!CanMove()) { if(mstate_wf&mcAnyMove) { StopAnyMove(); mstate_wf &= ~mcAnyMove; mstate_wf &= ~mcJump; } //character_physics_support()->movement()->EnableCharacter(); //return; } // update player accel if (mstate_wf&mcFwd) vControlAccel.z += 1; if (mstate_wf&mcBack) vControlAccel.z += -1; if (mstate_wf&mcLStrafe) vControlAccel.x += -1; if (mstate_wf&mcRStrafe) vControlAccel.x += 1; if (character_physics_support()->movement()->Environment()==CPHMovementControl::peOnGround || character_physics_support()->movement()->Environment()==CPHMovementControl::peAtWall ) { // crouch if ((0==(mstate_real&mcCrouch))&&(mstate_wf&mcCrouch)) { if(mstate_real&mcClimb) { mstate_wf&=~mcCrouch; } else { character_physics_support()->movement()->EnableCharacter(); bool Crouched = false; if (isActorAccelerated(mstate_wf, IsZoomAimingMode())) Crouched = character_physics_support()->movement()->ActivateBoxDynamic(1); else Crouched = character_physics_support()->movement()->ActivateBoxDynamic(2); if (Crouched) mstate_real |= mcCrouch; } } // jump m_fJumpTime -= dt; if ( CanJump() && (mstate_wf&mcJump) ) { mstate_real |= mcJump; m_bJumpKeyPressed = TRUE; Jump = m_fJumpSpeed; m_fJumpTime = s_fJumpTime; //уменьшить силу игрока из-за выполненого прыжка if (!GodMode()) conditions().ConditionJump(inventory().TotalWeight() / MaxCarryWeight()); } /* if(m_bJumpKeyPressed) Jump = m_fJumpSpeed; */ // mask input into "real" state u32 move = mcAnyMove|mcAccel; if (((mstate_real&mcCrouch))) { if (!isActorAccelerated(mstate_real, IsZoomAimingMode()) && isActorAccelerated(mstate_wf, IsZoomAimingMode())) { character_physics_support()->movement()->EnableCharacter(); if(!character_physics_support()->movement()->ActivateBoxDynamic(1))move &=~mcAccel; } if (isActorAccelerated(mstate_real, IsZoomAimingMode()) && !isActorAccelerated(mstate_wf, IsZoomAimingMode())) { character_physics_support()->movement()->EnableCharacter(); if(character_physics_support()->movement()->ActivateBoxDynamic(2))mstate_real &=~mcAccel; } } if ((mstate_wf&mcSprint) && !CanSprint()) { mstate_wf &= ~mcSprint; } mstate_real &= (~move); mstate_real |= (mstate_wf & move); if(mstate_wf&mcSprint) mstate_real|=mcSprint; else mstate_real&=~mcSprint; if(!(mstate_real&(mcFwd|mcLStrafe|mcRStrafe))||mstate_real&(mcCrouch|mcClimb)|| !isActorAccelerated(mstate_wf, IsZoomAimingMode())) { mstate_real&=~mcSprint; mstate_wishful&=~mcSprint; } // check player move state if (mstate_real&mcAnyMove) { BOOL bAccelerated = isActorAccelerated(mstate_real, IsZoomAimingMode())&&CanAccelerate(); // correct "mstate_real" if opposite keys pressed if (_abs(vControlAccel.z)<EPS) mstate_real &= ~(mcFwd+mcBack ); if (_abs(vControlAccel.x)<EPS) mstate_real &= ~(mcLStrafe+mcRStrafe); // normalize and analyze crouch and run float scale = vControlAccel.magnitude(); if (scale>EPS) { scale = m_fWalkAccel/scale; if (bAccelerated) if (mstate_real&mcBack) scale *= m_fRunBackFactor; else scale *= m_fRunFactor; else if (mstate_real&mcBack) scale *= m_fWalkBackFactor; if (mstate_real&mcCrouch) scale *= m_fCrouchFactor; if (mstate_real&mcClimb) scale *= m_fClimbFactor; if (mstate_real&mcSprint) scale *= m_fSprintFactor; if (mstate_real&(mcLStrafe|mcRStrafe) && !(mstate_real&mcCrouch)) { if (bAccelerated) scale *= m_fRun_StrafeFactor; else scale *= m_fWalk_StrafeFactor; } vControlAccel.mul (scale); }else{ // mstate_real &= ~mcAnyMove; } } }else{ // mstate_real &=~ mcAnyMove; } //------------------------------------------------------------------------------- //transform local dir to world dir Fmatrix mOrient; mOrient.rotateY (-r_model_yaw); mOrient.transform_dir(vControlAccel); //XFORM().transform_dir(vControlAccel); /* if(mstate_real&mcClimb&&mstate_real&mcAnyMove&& inventory().ActiveItem()&&inventory().ActiveItem()->HandDependence()==hd2Hand) { //inventory().ActiveItem()->Deactivate(); inventory().Activate(NO_ACTIVE_SLOT); } */ }
void CKinematics::AddWallmark(const Fmatrix* parent_xform, const Fvector3& start, const Fvector3& dir, ref_shader shader, float size) { Fvector S,D,normal = {0,0,0}; // transform ray from world to model Fmatrix P; P.invert (*parent_xform); P.transform_tiny (S,start); P.transform_dir (D,dir); // find pick point float dist = flt_max; BOOL picked = FALSE; DEFINE_VECTOR (Fobb,OBBVec,OBBVecIt); OBBVec cache_obb; cache_obb.resize (LL_BoneCount()); for (u16 k=0; k<LL_BoneCount(); k++){ CBoneData& BD = LL_GetData(k); if (LL_GetBoneVisible(k)&&!BD.shape.flags.is(SBoneShape::sfNoPickable)){ Fobb& obb = cache_obb[k]; obb.transform (BD.obb,LL_GetBoneInstance(k).mTransform); if (CDB::TestRayOBB(S,D, obb)) for (u32 i=0; i<children.size(); i++) if (LL_GetChild(i)->PickBone(normal,dist,S,D,k)) picked=TRUE; } } if (!picked) return; // calculate contact point Fvector cp; cp.mad (S,D,dist); // collect collide boxes Fsphere test_sphere; test_sphere.set (cp,size); U16Vec test_bones; test_bones.reserve (LL_BoneCount()); for (k=0; k<LL_BoneCount(); k++){ CBoneData& BD = LL_GetData(k); if (LL_GetBoneVisible(k)&&!BD.shape.flags.is(SBoneShape::sfNoPickable)){ Fobb& obb = cache_obb[k]; if (CDB::TestSphereOBB(test_sphere, obb)) test_bones.push_back(k); } } // find similar wm for (u32 wm_idx=0; wm_idx<wallmarks.size(); wm_idx++){ intrusive_ptr<CSkeletonWallmark>& wm = wallmarks[wm_idx]; if (wm->Similar(shader,cp,0.02f)){ if (wm_idx<wallmarks.size()-1) wm = wallmarks.back(); wallmarks.pop_back(); break; } } // ok. allocate wallmark intrusive_ptr<CSkeletonWallmark> wm = xr_new<CSkeletonWallmark>(this,parent_xform,shader,cp,Device.fTimeGlobal); wm->m_LocalBounds.set (cp,size*2.f); wm->XFORM()->transform_tiny (wm->m_Bounds.P,cp); wm->m_Bounds.R = wm->m_Bounds.R; Fvector tmp; tmp.invert (D); normal.add(tmp).normalize (); // build UV projection matrix Fmatrix mView,mRot; BuildMatrix (mView,1/(0.9f*size),normal,cp); mRot.rotateZ (::Random.randF(deg2rad(-20.f),deg2rad(20.f))); mView.mulA_43 (mRot); // fill vertices for (u32 i=0; i<children.size(); i++){ CSkeletonX* S = LL_GetChild(i); for (U16It b_it=test_bones.begin(); b_it!=test_bones.end(); b_it++) S->FillVertices (mView,*wm,normal,size,*b_it); } wallmarks.push_back (wm); }
void CActor::g_cl_CheckControls(u32 mstate_wf, Fvector &vControlAccel, float &Jump, float dt) { float cam_eff_factor = 0.0f; mstate_old = mstate_real; vControlAccel.set (0,0,0); if (!(mstate_real&mcFall) && (character_physics_support()->movement()->Environment()==CPHMovementControl::peInAir)) { m_fFallTime -= dt; if (m_fFallTime<=0.f) { m_fFallTime = s_fFallTime; mstate_real |= mcFall; mstate_real &=~ mcJump; } } if(!CanMove()) { if(mstate_wf&mcAnyMove) { StopAnyMove(); mstate_wf &= ~mcAnyMove; mstate_wf &= ~mcJump; } } // update player accel if (mstate_wf&mcFwd) vControlAccel.z += 1; if (mstate_wf&mcBack) vControlAccel.z += -1; if (mstate_wf&mcLStrafe) vControlAccel.x += -1; if (mstate_wf&mcRStrafe) vControlAccel.x += 1; CPHMovementControl::EEnvironment curr_env = character_physics_support()->movement()->Environment(); if(curr_env==CPHMovementControl::peOnGround || curr_env==CPHMovementControl::peAtWall) { // crouch if ((0==(mstate_real&mcCrouch))&&(mstate_wf&mcCrouch)) { if(mstate_real&mcClimb) { mstate_wf&=~mcCrouch; } else { character_physics_support()->movement()->EnableCharacter(); bool Crouched = false; if(isActorAccelerated(mstate_wf, IsZoomAimingMode())) Crouched = character_physics_support()->movement()->ActivateBoxDynamic(1); else Crouched = character_physics_support()->movement()->ActivateBoxDynamic(2); if(Crouched) mstate_real |= mcCrouch; } } // jump m_fJumpTime -= dt; if( CanJump() && (mstate_wf&mcJump) ) { mstate_real |= mcJump; m_bJumpKeyPressed = TRUE; Jump = m_fJumpSpeed; m_fJumpTime = s_fJumpTime; //уменьшить силу игрока из-за выполненого прыжка if (!GodMode()) conditions().ConditionJump(inventory().TotalWeight() / MaxCarryWeight()); } // mask input into "real" state u32 move = mcAnyMove|mcAccel; if(mstate_real&mcCrouch) { if (!isActorAccelerated(mstate_real, IsZoomAimingMode()) && isActorAccelerated(mstate_wf, IsZoomAimingMode())) { character_physics_support()->movement()->EnableCharacter(); if(!character_physics_support()->movement()->ActivateBoxDynamic(1))move &=~mcAccel; } if (isActorAccelerated(mstate_real, IsZoomAimingMode()) && !isActorAccelerated(mstate_wf, IsZoomAimingMode())) { character_physics_support()->movement()->EnableCharacter(); if(character_physics_support()->movement()->ActivateBoxDynamic(2))mstate_real &=~mcAccel; } } if ((mstate_wf&mcSprint) && !CanSprint()) mstate_wf &= ~mcSprint; mstate_real &= (~move); mstate_real |= (mstate_wf & move); if(mstate_wf&mcSprint) mstate_real|=mcSprint; else mstate_real&=~mcSprint; if(!(mstate_real&(mcFwd|mcLStrafe|mcRStrafe))||mstate_real&(mcCrouch|mcClimb)|| !isActorAccelerated(mstate_wf, IsZoomAimingMode())) { mstate_real&=~mcSprint; mstate_wishful&=~mcSprint; } // check player move state if(mstate_real&mcAnyMove) { BOOL bAccelerated = isActorAccelerated(mstate_real, IsZoomAimingMode())&&CanAccelerate(); // correct "mstate_real" if opposite keys pressed if (_abs(vControlAccel.z)<EPS) mstate_real &= ~(mcFwd+mcBack ); if (_abs(vControlAccel.x)<EPS) mstate_real &= ~(mcLStrafe+mcRStrafe); // normalize and analyze crouch and run float scale = vControlAccel.magnitude(); if(scale>EPS) { scale = m_fWalkAccel/scale; if (bAccelerated) if (mstate_real&mcBack) scale *= m_fRunBackFactor; else scale *= m_fRunFactor; else if (mstate_real&mcBack) scale *= m_fWalkBackFactor; if (mstate_real&mcCrouch) scale *= m_fCrouchFactor; if (mstate_real&mcClimb) scale *= m_fClimbFactor; if (mstate_real&mcSprint) scale *= m_fSprintFactor; if (mstate_real&(mcLStrafe|mcRStrafe) && !(mstate_real&mcCrouch)) { if (bAccelerated) scale *= m_fRun_StrafeFactor; else scale *= m_fWalk_StrafeFactor; } vControlAccel.mul (scale); cam_eff_factor = scale; }//scale>EPS }//(mstate_real&mcAnyMove) }//peOnGround || peAtWall if(IsGameTypeSingle() && cam_eff_factor>EPS) { LPCSTR state_anm = NULL; if(mstate_real&mcSprint && !(mstate_old&mcSprint) ) state_anm = "sprint"; else if(mstate_real&mcLStrafe && !(mstate_old&mcLStrafe) ) state_anm = "strafe_left"; else if(mstate_real&mcRStrafe && !(mstate_old&mcRStrafe) ) state_anm = "strafe_right"; else if(mstate_real&mcFwd && !(mstate_old&mcFwd) ) state_anm = "move_fwd"; else if(mstate_real&mcBack && !(mstate_old&mcBack) ) state_anm = "move_back"; if(state_anm) { //play moving cam effect CActor* control_entity = static_cast_checked<CActor*>(Level().CurrentControlEntity()); R_ASSERT2 (control_entity, "current control entity is NULL"); CEffectorCam* ec = control_entity->Cameras().GetCamEffector(eCEActorMoving); if(NULL==ec) { string_path eff_name; xr_sprintf (eff_name, sizeof(eff_name), "%s.anm", state_anm); string_path ce_path; string_path anm_name; strconcat (sizeof(anm_name), anm_name, "camera_effects\\actor_move\\", eff_name); if (FS.exist( ce_path, "$game_anims$", anm_name)) { CAnimatorCamLerpEffectorConst* e = xr_new<CAnimatorCamLerpEffectorConst>(); float max_scale = 70.0f; float factor = cam_eff_factor/max_scale; e->SetFactor (factor); e->SetType (eCEActorMoving); e->SetHudAffect (false); e->SetCyclic (false); e->Start (anm_name); control_entity->Cameras().AddCamEffector(e); } } } } //transform local dir to world dir Fmatrix mOrient; mOrient.rotateY (-r_model_yaw); mOrient.transform_dir(vControlAccel); }
void XV2IV(const Fvector &XV,IVektor &IV) { xm2im.transform_dir(cast_fv(IV),XV); }
void IV2XV(const IVektor &IV,Fvector &XV) { xm2im.transform_dir(XV),cast_fv(IV); }
bool ESceneObjectTool::ExportClimableObjects(SExportStreams* F) { bool bResult = true; CGeomPartExtractor* extractor = 0; Fbox bb; if (!GetBox(bb)) return false; extractor = xr_new<CGeomPartExtractor>(); extractor->Initialize (bb,EPS_L,int_max); UI->SetStatus ("Export climable objects..."); // collect verts&&faces { SPBItem* pb = UI->ProgressStart(m_Objects.size(), "Prepare geometry..."); for (ObjectIt it=m_Objects.begin(); it!=m_Objects.end(); it++) { pb->Inc(); CSceneObject* obj = dynamic_cast<CSceneObject*>(*it); VERIFY (obj); if (obj->IsStatic()) { CEditableObject *O = obj->GetReference(); const Fmatrix& T = obj->_Transform(); for(EditMeshIt M =O->FirstMesh(); M!=O->LastMesh(); M++) if (!build_mesh (T, *M, extractor, SGameMtl::flClimable, TRUE)) { bResult = false; break; } } } UI->ProgressEnd(pb); } if (!extractor->Process()) bResult = false; // export parts if (bResult) { SBPartVec& parts = extractor->GetParts(); SPBItem* pb = UI->ProgressStart(parts.size(),"Export Parts..."); for (SBPartVecIt p_it=parts.begin(); p_it!=parts.end(); p_it++) { pb->Inc (); SBPart* P = *p_it; if (P->Valid()) { // export visual AnsiString sn = AnsiString().sprintf("clmbl#%d",(p_it-parts.begin())); Fvector local_normal = {0,0,0}; LPCSTR mat_name = NULL; for (SBFaceVecIt it=P->m_Faces.begin(); it!=P->m_Faces.end(); it++) { for (u32 k=0; k<3; k++) local_normal.add ((*it)->n[k]); mat_name = (*it)->surf->_GameMtlName(); } local_normal.normalize_safe (); // export spawn object { AnsiString entity_ref = "climable_object"; ISE_Abstract* m_Data = create_entity(entity_ref.c_str()); VERIFY(m_Data); ISE_Shape* m_Shape = m_Data->shape(); VERIFY(m_Shape); // CSE_Visual* m_Visual = m_Data->visual(); VERIFY(m_Visual); // set params m_Data->set_name (entity_ref.c_str()); m_Data->set_name_replace (sn.c_str()); // set shape CShapeData::shape_def shape; shape.type = CShapeData::cfBox; shape.data.box.scale ((P->m_BBox.max.x-P->m_BBox.min.x)*0.5f, (P->m_BBox.max.y-P->m_BBox.min.y)*0.5f, (P->m_BBox.max.z-P->m_BBox.min.z)*0.5f); m_Shape->assign_shapes (&shape,1); // orientate object if (!OrientToNorm(local_normal,P->m_OBB.m_rotate,P->m_OBB.m_halfsize)) { ELog.Msg(mtError,"Invalid climable object found. [%3.2f, %3.2f, %3.2f]",VPUSH(P->m_RefOffset)); } else { Fmatrix M; M.set (P->m_OBB.m_rotate.i,P->m_OBB.m_rotate.j,P->m_OBB.m_rotate.k,P->m_OBB.m_translate); M.getXYZ (P->m_RefRotate); // не i потому что в движке так m_Data->position().set (P->m_RefOffset); m_Data->angle().set (P->m_RefRotate); m_Data->set_additional_info((void*)mat_name); NET_Packet Packet; m_Data->Spawn_Write (Packet,TRUE); F->spawn.stream.open_chunk (F->spawn.chunk++); F->spawn.stream.w (Packet.B.data,Packet.B.count); F->spawn.stream.close_chunk (); if (s_draw_dbg) { Tools->m_DebugDraw.AppendOBB(P->m_OBB); M.transform_dir (local_normal); Tools->m_DebugDraw.AppendLine(P->m_RefOffset,Fvector().mad(P->m_RefOffset,local_normal,1.f)); } } destroy_entity (m_Data); } }else { ELog.Msg(mtError,"Can't export invalid part #%d",p_it-parts.begin()); } } UI->ProgressEnd (pb); } // clean up xr_delete (extractor); return bResult; }
void CActor::NoClipFly(int cmd) { Fvector cur_pos;// = Position(); cur_pos.set(0,0,0); float scale = 1.0f; if(pInput->iGetAsyncKeyState(DIK_LSHIFT)) scale = 0.25f; else if(pInput->iGetAsyncKeyState(DIK_LMENU)) scale = 4.0f; switch(cmd) { case kJUMP: cur_pos.y += 0.1f; break; case kCROUCH: cur_pos.y -= 0.1f; break; case kFWD: cur_pos.z += 0.1f; break; case kBACK: cur_pos.z -= 0.1f; break; case kL_STRAFE: cur_pos.x -= 0.1f; break; case kR_STRAFE: cur_pos.x += 0.1f; break; case kCAM_1: cam_Set(eacFirstEye); break; case kCAM_2: cam_Set(eacLookAt); break; case kCAM_3: cam_Set(eacFreeLook); break; case kNIGHT_VISION: SwitchNightVision(); break; case kTORCH: SwitchTorch(); break; case kDETECTOR: { PIItem det_active = inventory().ItemFromSlot(DETECTOR_SLOT); if(det_active) { CCustomDetector* det = smart_cast<CCustomDetector*>(det_active); det->ToggleDetector(g_player_hud->attached_item(0)!=NULL); return; } } break; case kUSE: ActorUse(); break; } cur_pos.mul(scale); Fmatrix mOrient; mOrient.rotateY(-(cam_Active()->GetWorldYaw())); mOrient.transform_dir(cur_pos); Position().add(cur_pos); character_physics_support()->movement()->SetPosition(Position()); }
bool CIKFoot::GetFootStepMatrix( ik_goal_matrix &m, const Fmatrix &g_anim, const SIKCollideData &cld, bool collide, bool rotation, bool b_make_shift/*=true*/ )const { const Fmatrix global_anim = g_anim; Fvector local_point; ToePosition( local_point ); //toe position in bone[2] space Fvector global_point; global_anim.transform_tiny( global_point, local_point ); //non collided toe in global space Fvector foot_normal; FootNormal( foot_normal ); global_anim.transform_dir( foot_normal ); #ifdef DEBUG //if( ph_dbg_draw_mask.test( phDbgDrawIKGoal ) ) //{ // DBG_DrawLine( global_point, Fvector().add( global_point, foot_normal ), D3DCOLOR_XRGB( 0, 255, 255) ); //} #endif if( cld.m_collide_point == ik_foot_geom::heel || cld.m_collide_point == ik_foot_geom::side ) { Fmatrix foot;ref_bone_to_foot( foot, g_anim ); Fvector heel; HeelPosition( heel ); foot.transform_tiny(global_point, heel ); #ifdef DEBUG if( ph_dbg_draw_mask.test( phDbgDrawIKGoal ) ) DBG_DrawPoint( global_point, 0.01, D3DCOLOR_XRGB( 0, 255, 255)); #endif Fmatrix foot_to_ref; ref_bone_to_foot_transform(foot_to_ref).transform_tiny(local_point, heel ); } float dtoe_tri =-cld.m_plane.d - cld.m_plane.n.dotproduct( global_point ); if( !cld.collided || _abs( dtoe_tri ) > collide_dist ) { m.set( global_anim, ik_goal_matrix::cl_free ); return false; } Fplane p = cld.m_plane; Fmatrix xm; xm.set( global_anim ); ik_goal_matrix::e_collide_state cl_state = ik_goal_matrix::cl_undefined; if( rotation )//!collide || ik_allign_free_foot cl_state = rotate( xm, p, foot_normal, global_point, collide ); if( b_make_shift && make_shift( xm, local_point, collide, p, cld.m_pick_dir ) ) switch( cl_state ) { case ik_goal_matrix::cl_aligned : break; case ik_goal_matrix::cl_undefined : case ik_goal_matrix::cl_free : cl_state = ik_goal_matrix::cl_translational; break; case ik_goal_matrix::cl_rotational: cl_state = ik_goal_matrix::cl_mixed; break; default: NODEFAULT; } else if( cl_state == ik_goal_matrix::cl_undefined ) cl_state = ik_goal_matrix::cl_free; VERIFY( _valid( xm ) ); m.set( xm, cl_state ); #ifdef DEBUG if(ph_dbg_draw_mask.test( phDbgDrawIKGoal )) { DBG_DrawPoint( global_point, 0.03f, D3DCOLOR_RGBA( 255, 0, 0, 255 ) ); } if(!fsimilar( _abs( DET( g_anim ) - 1.f ), _abs( DET( m.get() ) - 1.f ), 0.001f ) ) Msg("scale g_anim: %f scale m: %f ", DET( g_anim ) , DET( m.get() ) ); #endif return true; }