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 CGroupObject::RotateLocal(Fvector& axis, float angle ) { inherited::RotateLocal(axis,angle); Fmatrix Ginv; Ginv.set (FITransformRP); UpdateTransform (true); for (ObjectIt it=m_Objects.begin(); it!=m_Objects.end(); it++){ Fmatrix O,On; O.mul (Ginv,(*it)->FTransformRP); On.mul (FTransform,O); Fvector xyz; On.getXYZ (xyz); (*it)->NumSetRotation(xyz); (*it)->NumSetPosition(On.c); // (*it)->PivotRotateParent(m_old,FTransform,axis,angle); } /* for (ObjectIt it=m_Objects.begin(); it!=m_Objects.end(); it++) (*it)->PivotRotateLocal(FTransformRP,FPosition,axis,angle); */ }
void CShootingObject::UpdateFlameParticles () { if(0==m_sFlameParticlesCurrent.size()) return; if(!m_pFlameParticles) return; Fmatrix pos; pos.set (get_ParticlesXFORM() ); pos.c.set (get_CurrentFirePoint() ); VERIFY(_valid(pos)); m_pFlameParticles->SetXFORM (pos); if(!m_pFlameParticles->IsLooped() && !m_pFlameParticles->IsPlaying() && !m_pFlameParticles->PSI_alive()) { m_pFlameParticles->Stop(); CParticlesObject::Destroy(m_pFlameParticles); } }
void CPoltergeist::Die(CObject* who) { if (m_tele) { if (state_invisible) { setVisible(true); if (PPhysicsShell()) { Fmatrix M; M.set (XFORM()); M.translate_over (m_current_position); PPhysicsShell()->SetTransform (M); } else Position() = m_current_position; } } inherited::Die (who); Energy::disable (); ability()->on_die (); }
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 CParticlesPlayer::StartParticles(const shared_str& ps_name, const Fmatrix& xform, u16 sender_id, int life_time, bool auto_stop) { CObject* object = m_self_object; VERIFY(object); for(BoneInfoVecIt it = m_Bones.begin(); it!=m_Bones.end(); it++) { SParticlesInfo &particles_info =*it->AppendParticles(object,ps_name); particles_info.sender_id = sender_id; particles_info.life_time=auto_stop ? life_time : u32(-1); xform.getHPB(particles_info.angles); //начать играть партиклы Fmatrix m; m.set(xform); GetBonePos(object,it->index,it->offset,m.c); particles_info.ps->UpdateParent(m,zero_vel); if(!particles_info.ps->IsPlaying()) particles_info.ps->Play (); } m_bActiveBones = true; }
void CWeapon::UpdateXForm () { if (Device.dwFrame == dwXF_Frame) return; dwXF_Frame = Device.dwFrame; if (!H_Parent()) return; // Get access to entity and its visual CEntityAlive* E = smart_cast<CEntityAlive*>(H_Parent()); if (!E) { if (!IsGameTypeSingle()) UpdatePosition (H_Parent()->XFORM()); return; } const CInventoryOwner *parent = smart_cast<const CInventoryOwner*>(E); if (parent && parent->use_simplified_visual()) return; if (parent->attached(this)) return; IKinematics* V = smart_cast<IKinematics*> (E->Visual()); VERIFY (V); // Get matrices int boneL = -1, boneR = -1, boneR2 = -1; // this ugly case is possible in case of a CustomMonster, not a Stalker, nor an Actor E->g_WeaponBones (boneL,boneR,boneR2); if (boneR == -1) return; if ((HandDependence() == hd1Hand) || (GetState() == eReload) || (!E->g_Alive())) boneL = boneR2; V->CalculateBones (); Fmatrix& mL = V->LL_GetTransform(u16(boneL)); Fmatrix& mR = V->LL_GetTransform(u16(boneR)); // Calculate Fmatrix mRes; Fvector R,D,N; D.sub (mL.c,mR.c); if(fis_zero(D.magnitude())) { mRes.set (E->XFORM()); mRes.c.set (mR.c); } else { D.normalize (); R.crossproduct (mR.j,D); N.crossproduct (D,R); N.normalize (); mRes.set (R,N,D,mR.c); mRes.mulA_43 (E->XFORM()); } UpdatePosition (mRes); }
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 CSceneObject::GetFullTransformToWorld( Fmatrix& m ) { m.set(_Transform()); }
void CKinematicsAnimated::Bone_GetAnimPos(Fmatrix& pos,u16 id,u8 mask_channel, bool ignore_callbacks) { CBoneInstance bi = LL_GetBoneInstance(id); BoneChain_Calculate(&LL_GetData(id),bi,mask_channel,ignore_callbacks); pos.set(bi.mTransform); }
void CRenderTarget::phase_combine () { bool _menu_pp = g_pGamePersistent?g_pGamePersistent->OnRenderPPUI_query():false; u32 Offset = 0; Fvector2 p0,p1; //*** exposure-pipeline u32 gpu_id = Device.dwFrame%2; { t_LUM_src->surface_set (rt_LUM_pool[gpu_id*2+0]->pSurface); t_LUM_dest->surface_set (rt_LUM_pool[gpu_id*2+1]->pSurface); } // low/hi RTs u_setrt ( rt_Generic_0,rt_Generic_1,0,HW.pBaseZB ); RCache.set_CullMode ( CULL_NONE ); RCache.set_Stencil ( FALSE ); BOOL split_the_scene_to_minimize_wait = FALSE; if (ps_r2_ls_flags.test(R2FLAG_EXP_SPLIT_SCENE)) split_the_scene_to_minimize_wait=TRUE; // draw skybox if (1) { RCache.set_ColorWriteEnable (); CHK_DX(HW.pDevice->SetRenderState ( D3DRS_ZENABLE, FALSE )); g_pGamePersistent->Environment().RenderSky (); CHK_DX(HW.pDevice->SetRenderState ( D3DRS_ZENABLE, TRUE )); } // //if (RImplementation.o.bug) { RCache.set_Stencil (TRUE,D3DCMP_LESSEQUAL,0x01,0xff,0x00); // stencil should be >= 1 if (RImplementation.o.nvstencil) { u_stencil_optimize (FALSE); RCache.set_ColorWriteEnable (); } //} // calc m-blur matrices Fmatrix m_previous, m_current; Fvector2 m_blur_scale; { static Fmatrix m_saved_viewproj; // (new-camera) -> (world) -> (old_viewproj) Fmatrix m_invview; m_invview.invert (Device.mView); m_previous.mul (m_saved_viewproj,m_invview); m_current.set (Device.mProject) ; m_saved_viewproj.set(Device.mFullTransform) ; float scale = ps_r2_mblur/2.f; m_blur_scale.set (scale,-scale).div(12.f); } // Draw full-screen quad textured with our scene image if (!_menu_pp) { // Compute params Fmatrix m_v2w; m_v2w.invert (Device.mView ); CEnvDescriptorMixer& envdesc= g_pGamePersistent->Environment().CurrentEnv ; const float minamb = 0.001f; Fvector4 ambclr = { _max(envdesc.ambient.x*2,minamb), _max(envdesc.ambient.y*2,minamb), _max(envdesc.ambient.z*2,minamb), 0 }; ambclr.mul (ps_r2_sun_lumscale_amb); Fvector4 envclr = { envdesc.sky_color.x*2+EPS, envdesc.sky_color.y*2+EPS, envdesc.sky_color.z*2+EPS, envdesc.weight }; Fvector4 fogclr = { envdesc.fog_color.x, envdesc.fog_color.y, envdesc.fog_color.z, 0 }; envclr.x *= 2*ps_r2_sun_lumscale_hemi; envclr.y *= 2*ps_r2_sun_lumscale_hemi; envclr.z *= 2*ps_r2_sun_lumscale_hemi; Fvector4 sunclr,sundir; // sun-params { light* fuckingsun = (light*)RImplementation.Lights.sun_adapted._get() ; Fvector L_dir,L_clr; float L_spec; L_clr.set (fuckingsun->color.r,fuckingsun->color.g,fuckingsun->color.b); L_spec = u_diffuse2s (L_clr); Device.mView.transform_dir (L_dir,fuckingsun->direction); L_dir.normalize (); sunclr.set (L_clr.x,L_clr.y,L_clr.z,L_spec); sundir.set (L_dir.x,L_dir.y,L_dir.z,0); } // Fill VB float _w = float(Device.dwWidth); float _h = float(Device.dwHeight); p0.set (.5f/_w, .5f/_h); p1.set ((_w+.5f)/_w, (_h+.5f)/_h ); // Fill vertex buffer Fvector4* pv = (Fvector4*) RCache.Vertex.Lock (4,g_combine_VP->vb_stride,Offset); pv->set (hclip(EPS, _w), hclip(_h+EPS, _h), p0.x, p1.y); pv++; pv->set (hclip(EPS, _w), hclip(EPS, _h), p0.x, p0.y); pv++; pv->set (hclip(_w+EPS, _w), hclip(_h+EPS, _h), p1.x, p1.y); pv++; pv->set (hclip(_w+EPS, _w), hclip(EPS, _h), p1.x, p0.y); pv++; RCache.Vertex.Unlock (4,g_combine_VP->vb_stride); // Setup textures IDirect3DBaseTexture9* e0 = _menu_pp?0:envdesc.sky_r_textures_env[0].second->surface_get(); IDirect3DBaseTexture9* e1 = _menu_pp?0:envdesc.sky_r_textures_env[1].second->surface_get(); t_envmap_0->surface_set (e0); _RELEASE(e0); t_envmap_1->surface_set (e1); _RELEASE(e1); // Draw RCache.set_Element (s_combine->E[0] ); RCache.set_Geometry (g_combine_VP ); RCache.set_c ("m_v2w", m_v2w ); RCache.set_c ("L_ambient", ambclr ); RCache.set_c ("Ldynamic_color", sunclr ); RCache.set_c ("Ldynamic_dir", sundir ); RCache.set_c ("env_color", envclr ); RCache.set_c ("fog_color", fogclr ); RCache.Render (D3DPT_TRIANGLELIST,Offset,0,4,0,2); } // Forward rendering { u_setrt (rt_Generic_0,0,0,HW.pBaseZB); // LDR RT RCache.set_CullMode (CULL_CCW); RCache.set_Stencil (FALSE); RCache.set_ColorWriteEnable (); g_pGamePersistent->Environment().RenderClouds (); RImplementation.render_forward (); if (g_pGamePersistent) g_pGamePersistent->OnRenderPPUI_main() ; // PP-UI } // Perform blooming filter and distortion if needed RCache.set_Stencil (FALSE); phase_bloom ( ); // HDR RT invalidated here // Distortion filter BOOL bDistort = RImplementation.o.distortion_enabled; // This can be modified { if ((0==RImplementation.mapDistort.size()) && !_menu_pp) bDistort= FALSE; if (bDistort) { u_setrt (rt_Generic_1,0,0,HW.pBaseZB); // Now RT is a distortion mask RCache.set_CullMode (CULL_CCW); RCache.set_Stencil (FALSE); RCache.set_ColorWriteEnable (); CHK_DX(HW.pDevice->Clear ( 0L, NULL, D3DCLEAR_TARGET, color_rgba(127,127,0,127), 1.0f, 0L)); RImplementation.r_dsgraph_render_distort (); if (g_pGamePersistent) g_pGamePersistent->OnRenderPPUI_PP() ; // PP-UI } } // PP enabled ? BOOL PP_Complex = u_need_PP (); if (_menu_pp) PP_Complex = FALSE; // Combine everything + perform AA if (PP_Complex) u_setrt ( rt_Color,0,0,HW.pBaseZB ); // LDR RT else u_setrt ( Device.dwWidth,Device.dwHeight,HW.pBaseRT,NULL,NULL,HW.pBaseZB); //. u_setrt ( Device.dwWidth,Device.dwHeight,HW.pBaseRT,NULL,NULL,HW.pBaseZB); RCache.set_CullMode ( CULL_NONE ) ; RCache.set_Stencil ( FALSE ) ; if (1) { // struct v_aa { Fvector4 p; Fvector2 uv0; Fvector2 uv1; Fvector2 uv2; Fvector2 uv3; Fvector2 uv4; Fvector4 uv5; Fvector4 uv6; }; float _w = float(Device.dwWidth); float _h = float(Device.dwHeight); float ddw = 1.f/_w; float ddh = 1.f/_h; p0.set (.5f/_w, .5f/_h); p1.set ((_w+.5f)/_w, (_h+.5f)/_h ); // Fill vertex buffer v_aa* pv = (v_aa*) RCache.Vertex.Lock (4,g_aa_AA->vb_stride,Offset); pv->p.set(EPS, float(_h+EPS), EPS,1.f); pv->uv0.set(p0.x, p1.y);pv->uv1.set(p0.x-ddw,p1.y-ddh);pv->uv2.set(p0.x+ddw,p1.y+ddh);pv->uv3.set(p0.x+ddw,p1.y-ddh);pv->uv4.set(p0.x-ddw,p1.y+ddh);pv->uv5.set(p0.x-ddw,p1.y,p1.y,p0.x+ddw);pv->uv6.set(p0.x,p1.y-ddh,p1.y+ddh,p0.x);pv++; pv->p.set(EPS, EPS, EPS,1.f); pv->uv0.set(p0.x, p0.y);pv->uv1.set(p0.x-ddw,p0.y-ddh);pv->uv2.set(p0.x+ddw,p0.y+ddh);pv->uv3.set(p0.x+ddw,p0.y-ddh);pv->uv4.set(p0.x-ddw,p0.y+ddh);pv->uv5.set(p0.x-ddw,p0.y,p0.y,p0.x+ddw);pv->uv6.set(p0.x,p0.y-ddh,p0.y+ddh,p0.x);pv++; pv->p.set(float(_w+EPS),float(_h+EPS), EPS,1.f); pv->uv0.set(p1.x, p1.y);pv->uv1.set(p1.x-ddw,p1.y-ddh);pv->uv2.set(p1.x+ddw,p1.y+ddh);pv->uv3.set(p1.x+ddw,p1.y-ddh);pv->uv4.set(p1.x-ddw,p1.y+ddh);pv->uv5.set(p1.x-ddw,p1.y,p1.y,p1.x+ddw);pv->uv6.set(p1.x,p1.y-ddh,p1.y+ddh,p1.x);pv++; pv->p.set(float(_w+EPS),EPS, EPS,1.f); pv->uv0.set(p1.x, p0.y);pv->uv1.set(p1.x-ddw,p0.y-ddh);pv->uv2.set(p1.x+ddw,p0.y+ddh);pv->uv3.set(p1.x+ddw,p0.y-ddh);pv->uv4.set(p1.x-ddw,p0.y+ddh);pv->uv5.set(p1.x-ddw,p0.y,p0.y,p1.x+ddw);pv->uv6.set(p1.x,p0.y-ddh,p0.y+ddh,p1.x);pv++; RCache.Vertex.Unlock (4,g_aa_AA->vb_stride); // Draw COLOR if (ps_r2_ls_flags.test(R2FLAG_AA)) RCache.set_Element (s_combine->E[bDistort?3:1]); // look at blender_combine.cpp else RCache.set_Element (s_combine->E[bDistort?4:2]); // look at blender_combine.cpp RCache.set_c ("e_barrier", ps_r2_aa_barier.x, ps_r2_aa_barier.y, ps_r2_aa_barier.z, 0); RCache.set_c ("e_weights", ps_r2_aa_weight.x, ps_r2_aa_weight.y, ps_r2_aa_weight.z, 0); RCache.set_c ("e_kernel", ps_r2_aa_kernel, ps_r2_aa_kernel, ps_r2_aa_kernel, 0); RCache.set_c ("m_current", m_current); RCache.set_c ("m_previous", m_previous); RCache.set_c ("m_blur", m_blur_scale.x,m_blur_scale.y, 0,0); RCache.set_Geometry (g_aa_AA); RCache.Render (D3DPT_TRIANGLELIST,Offset,0,4,0,2); } RCache.set_Stencil (FALSE); // if FP16-BLEND !not! supported - draw flares here, overwise they are already in the bloom target /* if (!RImplementation.o.fp16_blend)*/ g_pGamePersistent->Environment().RenderFlares (); // lens-flares // PP-if required if (PP_Complex) { phase_pp (); } // Re-adapt luminance RCache.set_Stencil (FALSE); //*** exposure-pipeline-clear { std::swap (rt_LUM_pool[gpu_id*2+0],rt_LUM_pool[gpu_id*2+1]); t_LUM_src->surface_set (NULL); t_LUM_dest->surface_set (NULL); } #ifdef DEBUG RCache.set_CullMode ( CULL_CCW ); static xr_vector<Fplane> saved_dbg_planes; if (bDebug) saved_dbg_planes= dbg_planes; else dbg_planes = saved_dbg_planes; if (1) for (u32 it=0; it<dbg_planes.size(); it++) { Fplane& P = dbg_planes[it]; Fvector zero ; zero.mul (P.n,P.d); Fvector L_dir,L_up=P.n,L_right; L_dir.set (0,0,1); if (_abs(L_up.dotproduct(L_dir))>.99f) L_dir.set(1,0,0); L_right.crossproduct(L_up,L_dir); L_right.normalize (); L_dir.crossproduct (L_right,L_up); L_dir.normalize (); Fvector p0,p1,p2,p3; float sz = 100.f; p0.mad (zero,L_right,sz).mad (L_dir,sz); p1.mad (zero,L_right,sz).mad (L_dir,-sz); p2.mad (zero,L_right,-sz).mad (L_dir,-sz); p3.mad (zero,L_right,-sz).mad (L_dir,+sz); RCache.dbg_DrawTRI (Fidentity,p0,p1,p2,0xffffffff); RCache.dbg_DrawTRI (Fidentity,p2,p3,p0,0xffffffff); } static xr_vector<dbg_line_t> saved_dbg_lines; if (bDebug) saved_dbg_lines = dbg_lines; else dbg_lines = saved_dbg_lines; if (1) for (u32 it=0; it<dbg_lines.size(); it++) { RCache.dbg_DrawLINE (Fidentity,dbg_lines[it].P0,dbg_lines[it].P1,dbg_lines[it].color); } #endif // ********************* Debug /* if (0) { u32 C = color_rgba (255,255,255,255); float _w = float(Device.dwWidth)/3; float _h = float(Device.dwHeight)/3; // draw light-spheres #ifdef DEBUG if (0) for (u32 it=0; it<dbg_spheres.size(); it++) { Fsphere S = dbg_spheres[it].first; Fmatrix M; u32 ccc = dbg_spheres[it].second.get(); M.scale (S.R,S.R,S.R); M.translate_over (S.P); RCache.dbg_DrawEllipse (M,ccc); RCache.dbg_DrawAABB (S.P,.05f,.05f,.05f,ccc); } #endif // Draw quater-screen quad textured with our direct-shadow-map-image if (1) { u32 IX=0,IY=1; p0.set (.5f/_w, .5f/_h); p1.set ((_w+.5f)/_w, (_h+.5f)/_h ); // Fill vertex buffer FVF::TL* pv = (FVF::TL*) RCache.Vertex.Lock (4,g_combine->vb_stride,Offset); pv->set ((IX+0)*_w+EPS, (IY+1)*_h+EPS, EPS, 1.f, C, p0.x, p1.y); pv++; pv->set ((IX+0)*_w+EPS, (IY+0)*_h+EPS, EPS, 1.f, C, p0.x, p0.y); pv++; pv->set ((IX+1)*_w+EPS, (IY+1)*_h+EPS, EPS, 1.f, C, p1.x, p1.y); pv++; pv->set ((IX+1)*_w+EPS, (IY+0)*_h+EPS, EPS, 1.f, C, p1.x, p0.y); pv++; RCache.Vertex.Unlock (4,g_combine->vb_stride); // Draw COLOR RCache.set_Shader (s_combine_dbg_0); RCache.set_Geometry (g_combine); RCache.Render (D3DPT_TRIANGLELIST,Offset,0,4,0,2); } // Draw quater-screen quad textured with our accumulator if (0) { u32 IX=1,IY=1; p0.set (.5f/_w, .5f/_h); p1.set ((_w+.5f)/_w, (_h+.5f)/_h ); // Fill vertex buffer FVF::TL* pv = (FVF::TL*) RCache.Vertex.Lock (4,g_combine->vb_stride,Offset); pv->set ((IX+0)*_w+EPS, (IY+1)*_h+EPS, EPS, 1.f, C, p0.x, p1.y); pv++; pv->set ((IX+0)*_w+EPS, (IY+0)*_h+EPS, EPS, 1.f, C, p0.x, p0.y); pv++; pv->set ((IX+1)*_w+EPS, (IY+1)*_h+EPS, EPS, 1.f, C, p1.x, p1.y); pv++; pv->set ((IX+1)*_w+EPS, (IY+0)*_h+EPS, EPS, 1.f, C, p1.x, p0.y); pv++; RCache.Vertex.Unlock (4,g_combine->vb_stride); // Draw COLOR RCache.set_Shader (s_combine_dbg_1); RCache.set_Geometry (g_combine); RCache.Render (D3DPT_TRIANGLELIST,Offset,0,4,0,2); } } */ #ifdef DEBUG dbg_spheres.clear (); dbg_lines.clear (); dbg_planes.clear (); #endif }
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 CPHDestroyable::NotificatePart(CPHDestroyableNotificate *dn) { CPhysicsShell *own_shell=PPhysicsShellHolder()->PPhysicsShell() ; CPhysicsShell *new_shell=dn->PPhysicsShellHolder()->PPhysicsShell() ; IKinematics *own_K =smart_cast<IKinematics*>(PPhysicsShellHolder()->Visual()); IKinematics *new_K =smart_cast<IKinematics*>(dn->PPhysicsShellHolder()->Visual()) ; VERIFY (own_K&&new_K&&own_shell&&new_shell) ; CInifile *own_ini =own_K->LL_UserData() ; CInifile *new_ini =new_K->LL_UserData() ; ////////////////////////////////////////////////////////////////////////////////// Fmatrix own_transform; own_shell ->GetGlobalTransformDynamic (&own_transform) ; new_shell ->SetGlTransformDynamic (own_transform) ; //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// float random_min =1.f ; float random_hit_imp =1.f ; //////////////////////////////////////////////////////////////////////////////////// u16 ref_bone =own_K->LL_GetBoneRoot(); float imp_transition_factor =1.f ; float lv_transition_factor =1.f ; float av_transition_factor =1.f ; //////////////////////////////////////////////////////////////////////////////////// if(own_ini&&own_ini->section_exist("impulse_transition_to_parts")) { random_min =own_ini->r_float("impulse_transition_to_parts","random_min"); random_hit_imp =own_ini->r_float("impulse_transition_to_parts","random_hit_imp"); //////////////////////////////////////////////////////// if(own_ini->line_exist("impulse_transition_to_parts","ref_bone")) ref_bone =own_K->LL_BoneID(own_ini->r_string("impulse_transition_to_parts","ref_bone")); imp_transition_factor =own_ini->r_float("impulse_transition_to_parts","imp_transition_factor"); lv_transition_factor =own_ini->r_float("impulse_transition_to_parts","lv_transition_factor"); av_transition_factor =own_ini->r_float("impulse_transition_to_parts","av_transition_factor"); if(own_ini->section_exist("collide_parts")) { if(own_ini->line_exist("collide_parts","small_object")) { new_shell->SetSmall(); } if(own_ini->line_exist("collide_parts","ignore_small_objects")) { new_shell->SetIgnoreSmall(); } } } if(new_ini&&new_ini->section_exist("impulse_transition_from_source_bone")) { //random_min =new_ini->r_float("impulse_transition_from_source_bone","random_min"); //random_hit_imp =new_ini->r_float("impulse_transition_from_source_bone","random_hit_imp"); //////////////////////////////////////////////////////// if(new_ini->line_exist("impulse_transition_from_source_bone","ref_bone")) ref_bone =own_K->LL_BoneID(new_ini->r_string("impulse_transition_from_source_bone","ref_bone")); imp_transition_factor =new_ini->r_float("impulse_transition_from_source_bone","imp_transition_factor"); lv_transition_factor =new_ini->r_float("impulse_transition_from_source_bone","lv_transition_factor"); av_transition_factor =new_ini->r_float("impulse_transition_from_source_bone","av_transition_factor"); } ////////////////////////////////////////////////////////////////////////////////////////////////////// dBodyID own_body=own_shell->get_Element(ref_bone)->get_body() ; u16 new_el_number = new_shell->get_ElementsNumber() ; for(u16 i=0;i<new_el_number;++i) { CPhysicsElement* e=new_shell->get_ElementByStoreOrder(i); float random_hit=random_min*e->getMass(); if(m_fatal_hit.is_valide() && m_fatal_hit.bone()!=BI_NONE ) { Fvector pos; Fmatrix m;m.set(own_K->LL_GetTransform(m_fatal_hit.bone())); m.mulA_43 (PPhysicsShellHolder()->XFORM()); m.transform_tiny(pos,m_fatal_hit.bone_space_position()); e->applyImpulseVsGF(pos,m_fatal_hit.direction(),m_fatal_hit.phys_impulse()*imp_transition_factor); random_hit+=random_hit_imp*m_fatal_hit.phys_impulse(); } Fvector rnd_dir;rnd_dir.random_dir(); e->applyImpulse(rnd_dir,random_hit); Fvector mc; mc.set(e->mass_Center()); dVector3 res_lvell; dBodyGetPointVel(own_body,mc.x,mc.y,mc.z,res_lvell); cast_fv(res_lvell).mul(lv_transition_factor); e->set_LinearVel(cast_fv(res_lvell)); Fvector res_avell;res_avell.set(cast_fv(dBodyGetAngularVel(own_body))); res_avell.mul(av_transition_factor); e->set_AngularVel(res_avell); } new_shell->Enable(); new_shell->EnableCollision(); dn->PPhysicsShellHolder()->setVisible(TRUE); dn->PPhysicsShellHolder()->setEnabled(TRUE); if(own_shell->IsGroupObject()) new_shell->RegisterToCLGroup(own_shell->GetCLGroup());//CollideBits CPHSkeleton* ps=dn->PPhysicsShellHolder()->PHSkeleton(); if(ps) { if(own_ini&&own_ini->section_exist("autoremove_parts")) { ps->SetAutoRemove(1000*(READ_IF_EXISTS(own_ini,r_u32,"autoremove_parts","time",ps->DefaultExitenceTime()))); } if(new_ini&&new_ini->section_exist("autoremove")) { ps->SetAutoRemove(1000*(READ_IF_EXISTS(new_ini,r_u32,"autoremove","time",ps->DefaultExitenceTime()))); } } }
void CSceneObject::GetFullTransformToLocal( Fmatrix& m ) { m.set(_ITransform()); }
void CIKFoot::set_toe( u16 bones[4] ) { VERIFY( Kinematics() ); m_foot_bone_id = bones[2]; m_toe_bone_id = bones[3]; xr_vector<Fmatrix> binds; Kinematics()->LL_GetBindTransform( binds ); const Fmatrix bind_ref = binds[ bones[m_ref_bone] ]; const Fmatrix ibind_ref = Fmatrix().invert( bind_ref ); const Fmatrix bind2 = binds[ bones[2] ] ; const Fmatrix ibind2 = Fmatrix().invert( bind2 ); //const Fmatrix ref_to_b2 = Fmatrix().mul_43( ibind2, bind_ref ); const Fmatrix b2to_ref = Fmatrix().mul_43( ibind_ref, bind2 ); const Fmatrix bind3 = binds[ bones[3] ] ; const Fmatrix ibind3 = Fmatrix().invert( bind3 ); m_bind_b2_to_b3.mul_43( ibind2, bind3 ); /////////////////////////////////////////////////////// Fvector ax ,foot_normal, foot_dir; get_local_vector( 2, foot_normal, m_foot_normal ); get_local_vector( 2, foot_dir, m_foot_direction ); //ref_to_b2.transform_tiny( foot_normal, m_foot_normal.v ); //ref_to_b2.transform_tiny( foot_dir, m_foot_direction.v ); ax.add( foot_normal, foot_dir ); ax.normalize(); /////////////////////////////////////////////////////// Fvector pos; pos.set( 0, 0, 0 ); Fmatrix ibind = ibind3; envc pred( ibind, ax, pos ); ///////////////////////////////////////////////////////// Kinematics()->EnumBoneVertices( pred, bones[3] ); bind3.transform_tiny( pos ); ibind2.transform_tiny( pos ); m_toe_position.v.set( pos ); ///////////////////////////////////////////////////////// ibind.set( ibind2 ); ax.set( foot_normal ); Kinematics()->EnumBoneVertices( pred, bones[2] ); m_toe_position.v.x = _max( pos.x, m_toe_position.v.x ); ///////////////////////////////////////////////////////// ax.sub( foot_normal, foot_dir ); ax.normalize(); pred.start_pos.set(0,0,0);pos.set( 0, 0, 0 ); Kinematics()->EnumBoneVertices( pred, bones[2] ); m_heel_position.v = pred.pos ; m_heel_position.v.add( Fvector().mul( foot_dir, Fvector().sub( m_toe_position.v, pos ).dotproduct( foot_dir ) * 0.2f ) ); m_heel_position.bone = 2; /////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////// bind2.transform_tiny( m_toe_position.v ); ibind_ref.transform_tiny( m_toe_position.v ); m_toe_position.bone = ref_bone(); ///////////////////////////////////////////////////////// get_local_vector( foot_normal, m_foot_normal ); m_foot_width = ( Fvector().sub( m_toe_position.v, b2to_ref.c ) ).dotproduct( foot_normal ); }
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; }
void CBastArtefact::UpdateCLChild() { //Log ("--- A - CBastArtefact",*cName()); //Log ("--- A - CBastArtefact",renderable.xform); //современем энергия по немногу тоже уменьшается if(m_fEnergy>0) m_fEnergy -= m_fEnergyDecreasePerTime*Device.fTimeDelta; if (getVisible() && m_pPhysicsShell) { if(m_bStrike) { //выбрать жертву, если она еще не выбрана if(!m_AliveList.empty() && m_AttakingEntity == NULL) { CEntityAlive* pEntityToHit = NULL; if(m_AliveList.size()>1) { do { int rnd = ::Random.randI(m_AliveList.size()); pEntityToHit = m_AliveList[rnd]; } while (pEntityToHit == m_pHitedEntity); } else { pEntityToHit = m_AliveList.front(); } m_AttakingEntity = pEntityToHit; } } if(m_AttakingEntity) { if(m_AttakingEntity->g_Alive() && m_fEnergy>m_fStrikeImpulse) { m_fEnergy -= m_fStrikeImpulse; //бросить артефакт на выбранную цель Fvector dir; m_AttakingEntity->Center(dir); dir.sub(this->Position()); dir.y += ::Random.randF(-0.05f, 0.5f); m_pPhysicsShell->applyImpulse(dir, m_fStrikeImpulse * Device.fTimeDelta * m_pPhysicsShell->getMass()); } else { m_AttakingEntity = NULL; m_bStrike = false; } } if(m_fEnergy>0 && ::Random.randF(0.f, 1.0f)<(m_fEnergy/(m_fStrikeImpulse*100.f))) { CParticlesObject* pStaticPG; pStaticPG = CParticlesObject::Create(*m_sParticleName,TRUE); Fmatrix pos; pos.set(XFORM()); Fvector vel; //vel.sub(Position(),ps_Element(0).vPosition); //vel.div((Level().timeServer()-ps_Element(0).dwTime)/1000.f); vel.set(0,0,0); pStaticPG->UpdateParent(pos, vel); pStaticPG->Play(); } } else if(H_Parent()) XFORM().set(H_Parent()->XFORM()); }