void CEditShape::Attach(CEditShape* from) { ApplyScale (); // transfer data from->ApplyScale (); Fmatrix M = from->_Transform(); M.mulA_43 (_ITransform()); for (ShapeIt it=from->shapes.begin(); it!=from->shapes.end(); it++){ switch (it->type){ case cfSphere:{ Fsphere& T = it->data.sphere; M.transform_tiny(T.P); add_sphere (T); }break; case cfBox:{ Fmatrix B = it->data.box; B.mulA_43 (M); add_box (B); }break; default: THROW; } } // common Scene->RemoveObject (from,true,true); xr_delete (from); ComputeBounds (); }
void calc_cam_diff_rot(Fmatrix item_transform, Fvector diff, Fvector& res) { Fmatrix cam_m; cam_m.i.set (Device.vCameraRight); cam_m.j.set (Device.vCameraTop); cam_m.k.set (Device.vCameraDirection); cam_m.c.set (Device.vCameraPosition); Fmatrix R; R.identity (); if(!fis_zero(diff.x)) { R.rotation(cam_m.i,diff.x); }else if(!fis_zero(diff.y)) { R.rotation(cam_m.j,diff.y); }else if(!fis_zero(diff.z)) { R.rotation(cam_m.k,diff.z); }; Fmatrix item_transform_i; item_transform_i.invert (item_transform); R.mulB_43(item_transform); R.mulA_43(item_transform_i); R.getHPB (res); res.mul (180.0f/PI); }
void CEditShape::Render(int priority, bool strictB2F) { inherited::Render(priority, strictB2F); if (1==priority){ if (strictB2F){ Device.SetShader (Device.m_WireShader); Device.SetRS (D3DRS_CULLMODE,D3DCULL_NONE); u32 clr = Selected()?subst_alpha(m_DrawTranspColor, color_get_A(m_DrawTranspColor)*2):m_DrawTranspColor; Fvector zero ={0.f,0.f,0.f}; for (ShapeIt it=shapes.begin(); it!=shapes.end(); ++it) { switch(it->type) { case cfSphere: { Fsphere& S = it->data.sphere; Fmatrix B; B.scale (S.R,S.R,S.R); B.translate_over (S.P); B.mulA_43 (_Transform()); RCache.set_xform_world(B); Device.SetShader (Device.m_WireShader); DU_impl.DrawCross (zero,1.f,m_DrawEdgeColor,false); DU_impl.DrawIdentSphere (true,true,clr,m_DrawEdgeColor); }break; case cfBox: { Fmatrix B = it->data.box; B.mulA_43 (_Transform()); RCache.set_xform_world(B); DU_impl.DrawIdentBox(true,true,clr,m_DrawEdgeColor); }break; } } Device.SetRS(D3DRS_CULLMODE,D3DCULL_CCW); }else{ if( Selected()&&m_Box.is_valid() ){ Device.SetShader (Device.m_SelectionShader); RCache.set_xform_world (_Transform()); u32 clr = 0xFFFFFFFF; Device.SetShader (Device.m_WireShader); DU_impl.DrawSelectionBox(m_Box,&clr); } } } }
void CCustomZone::Hit (SHit* pHDS) { Fmatrix M; M.identity(); M.translate_over (pHDS->p_in_bone_space); M.mulA_43 (XFORM()); PlayBulletParticles (M.c); }
void CDrawUtilities::DrawSphere(const Fmatrix& parent, const Fvector& center, float radius, u32 clr_s, u32 clr_w, BOOL bSolid, BOOL bWire) { Fmatrix B; B.scale (radius,radius,radius); B.translate_over (center); B.mulA_43 (parent); RCache.set_xform_world(B); DrawIdentSphere (bSolid, bWire, clr_s,clr_w); }
void CInventoryItem::UpdateXForm () { if (0==object().H_Parent()) return; // Get access to entity and its visual CEntityAlive* E = smart_cast<CEntityAlive*>(object().H_Parent()); if (!E) return; if (E->cast_base_monster()) return; const CInventoryOwner *parent = smart_cast<const CInventoryOwner*>(E); if (parent && parent->use_simplified_visual()) return; if (parent->attached(this)) return; R_ASSERT (E); IKinematics* V = smart_cast<IKinematics*> (E->Visual()); VERIFY (V); // Get matrices int boneL = -1, boneR = -1, boneR2 = -1; E->g_WeaponBones(boneL,boneR,boneR2); if (boneR == -1) return; // if ((HandDependence() == hd1Hand) || (STATE == eReload) || (!E->g_Alive())) // boneL = boneR2; #pragma todo("TO ALL: serious performance problem") 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); D.normalize_safe(); 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); object().Position().set(mRes.c); }
void BuildMatrix (Fmatrix &mView, float invsz, const Fvector norm, const Fvector& from) { // build projection Fmatrix mScale; Fvector at,up,right,y; at.sub (from,norm); y.set (0,1,0); if (_abs(norm.y)>.99f) y.set(1,0,0); right.crossproduct (y,norm); up.crossproduct (norm,right); mView.build_camera (from,at,up); mScale.scale (invsz,invsz,invsz); mView.mulA_43 (mScale); }
void CWallmarksEngine::BuildMatrix (Fmatrix &mView, float invsz, const Fvector& from) { // build projection Fmatrix mScale; Fvector at,up,right,y; at.sub (from,sml_normal); y.set (0,1,0); if (_abs(sml_normal.y)>.99f) y.set(1,0,0); right.crossproduct (y,sml_normal); up.crossproduct (sml_normal,right); mView.build_camera (from,at,up); mScale.scale (invsz,invsz,invsz); mView.mulA_43 (mScale); }
void CPHShell::Activate(const Fmatrix &m0,float dt01,const Fmatrix &m2,bool disable){ if(isActive())return; activate(disable); // ELEMENT_I i; mXFORM.set(m0); //for(i=elements.begin();elements.end() != i;++i){ // (*i)->Activate(m0,dt01, m2, disable); //} { ELEMENT_I i=elements.begin(),e=elements.end(); for(;i!=e;++i)(*i)->Activate(mXFORM,disable); } { JOINT_I i=joints.begin(),e=joints.end(); for(;i!=e;++i) (*i)->Activate(); } Fmatrix m; { Fmatrix old_m = mXFORM;//+GetGlobalTransformDynamic update mXFORM; GetGlobalTransformDynamic (&m); mXFORM = old_m; } m.invert();m.mulA_43 (mXFORM); TransformPosition(m); if(PKinematics()) { SetCallbacks( ); } //bActive=true; //bActivating=true; m_flags.set(flActive,TRUE); m_flags.set(flActivating,TRUE); spatial_register(); /////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// //mXFORM.set(m0); //Activate(disable); Fvector lin_vel; lin_vel.sub(m2.c,m0.c); set_LinearVel(lin_vel); }
void CArtefact::UpdateXForm() { if (Device.dwFrame!=dwXF_Frame) { dwXF_Frame = Device.dwFrame; if (0==H_Parent()) return; // Get access to entity and its visual CEntityAlive* E = smart_cast<CEntityAlive*>(H_Parent()); if(!E) return ; const CInventoryOwner *parent = smart_cast<const CInventoryOwner*>(E); if (parent && parent->use_simplified_visual()) return; VERIFY (E); IKinematics* V = smart_cast<IKinematics*> (E->Visual()); VERIFY (V); if(CAttachableItem::enabled()) return; // Get matrices int boneL = -1, boneR = -1, boneR2 = -1; E->g_WeaponBones (boneL,boneR,boneR2); if (boneR == -1) return; 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); D.normalize_safe(); R.crossproduct (mR.j,D); R.normalize_safe(); N.crossproduct (D,R); N.normalize_safe(); mRes.set (R,N,D,mR.c); mRes.mulA_43 (E->XFORM()); // UpdatePosition (mRes); XFORM().mul (mRes,offset()); } }
void PHDynamicData::InterpolateTransformVsParent(Fmatrix &transform){ Fmatrix parent_transform; //DMXPStoFMX(dBodyGetRotation(parent),dBodyGetPosition(parent),parent_transform); //DMXPStoFMX(dBodyGetRotation(body),dBodyGetPosition(body),BoneTransform); p_parent_body_interpolation->InterpolateRotation(parent_transform); p_parent_body_interpolation->InterpolatePosition(parent_transform.c); body_interpolation.InterpolateRotation(transform); body_interpolation.InterpolatePosition(transform.c); parent_transform.mulB_43 (ZeroTransform); parent_transform.invert(); //BoneTransform.mulA(parent_transform); transform.mulA_43 (parent_transform); }
void CEditShape::Detach() { if (shapes.size()>1){ Select (true); ApplyScale (); // create scene shapes const Fmatrix& M = _Transform(); ShapeIt it=shapes.begin(); it++; for (; it!=shapes.end(); it++){ string256 namebuffer; Scene->GenObjectName (OBJCLASS_SHAPE, namebuffer, Name); CEditShape* shape = (CEditShape*)Scene->GetOTool(ClassID)->CreateObject(0, namebuffer); switch (it->type){ case cfSphere:{ Fsphere T = it->data.sphere; M.transform_tiny(T.P); shape->PPosition= T.P; T.P.set (0,0,0); shape->add_sphere(T); }break; case cfBox:{ Fmatrix B = it->data.box; B.mulA_43 (M); shape->PPosition= B.c; B.c.set (0,0,0); shape->add_box (B); }break; default: THROW; } Scene->AppendObject (shape,false); shape->Select (true); } // erase shapes in base object it=shapes.begin(); it++; shapes.erase(it,shapes.end()); ComputeBounds(); Scene->UndoSave(); } }
bool CEditShape::FrustumPick(const CFrustum& frustum) { const Fmatrix& M = _Transform(); for (ShapeIt it=shapes.begin(); it!=shapes.end(); it++){ switch (it->type){ case cfSphere:{ Fvector C; Fsphere& T = it->data.sphere; M.transform_tiny(C,T.P); if (frustum.testSphere_dirty(C,T.R*FScale.x)) return true; }break; case cfBox:{ Fbox box; box.identity (); Fmatrix B = it->data.box; B.mulA_43 (_Transform()); box.xform (B); u32 mask = 0xff; if (frustum.testAABB(box.data(),mask)) return true; }break; } } return false; }
void CDrawUtilities::DrawCone (const Fmatrix& parent, const Fvector& apex, const Fvector& dir, float height, float radius, u32 clr_s, u32 clr_w, BOOL bSolid, BOOL bWire) { Fmatrix mScale; mScale.scale (2.f*radius,2.f*radius,height); // build final rotation / translation Fvector L_dir,L_up,L_right; L_dir.set (dir); L_dir.normalize (); L_up.set (0,1,0); if (_abs(L_up.dotproduct(L_dir))>.99f) L_up.set(0,0,1); L_right.crossproduct(L_up,L_dir); L_right.normalize (); L_up.crossproduct (L_dir,L_right); L_up.normalize (); Fmatrix mR; mR.i = L_right; mR._14 = 0; mR.j = L_up; mR._24 = 0; mR.k = L_dir; mR._34 = 0; mR.c = apex; mR._44 = 1; // final xform Fmatrix xf; xf.mul (mR,mScale); xf.mulA_43 (parent); RCache.set_xform_world(xf); DrawIdentCone (bSolid,bWire,clr_s,clr_w); }
ik_goal_matrix::e_collide_state CIKFoot::rotate( Fmatrix &xm, const Fplane& p, const Fvector &foot_normal, const Fvector &global_point, bool collide) const { Fvector ax; ax.crossproduct( p.n, foot_normal ); float s=ax.magnitude( ); clamp( s, 0.f, 1.f ); float angle = asinf( -s ); VERIFY( _valid( angle ) ); clamp( angle, -M_PI/6, M_PI/6 ); ik_goal_matrix::e_collide_state cl_state = ik_goal_matrix::cl_undefined; if( !fis_zero( s ) ) { cl_state = ik_goal_matrix::cl_aligned; ax.mul( 1.f/s ); ref_bone_to_foot( xm ); if( collide ) cl_state = CollideFoot( angle, angle, global_point, foot_normal, xm.c, p, ax); //if( cld.m_pick_dir ) Fvector c = xm.c; xm.mulA_43( Fmatrix( ).rotation( ax, angle ) ); xm.c = c; foot_to_ref_bone( xm ); } return cl_state; }
void CEditableObject::RenderBones(const Fmatrix& parent) { if (IsSkeleton()){ // render BoneVec& lst = m_Bones; for(BoneIt b_it=lst.begin(); b_it!=lst.end(); b_it++){ Device.SetShader(Device.m_WireShader); RCache.set_xform_world(parent); Fmatrix& M = (*b_it)->_LTransform(); Fvector p1 = M.c; u32 c_joint = (*b_it)->flags.is(CBone::flSelected)?color_bone_sel_color:color_bone_norm_color; if (EPrefs->object_flags.is(epoDrawJoints)) DU_impl.DrawJoint (p1,joint_size,c_joint); // center of mass if ((*b_it)->shape.type!=SBoneShape::stNone){ Fvector cm; M.transform_tiny(cm,(*b_it)->center_of_mass); if ((*b_it)->flags.is(CBone::flSelected)){ float sz = joint_size*2.f; DU_impl.DrawCross (cm, sz,sz,sz, sz,sz,sz, 0xFFFFFFFF, false); DU_impl.DrawRomboid (cm,joint_size*0.7f,color_bone_sel_cm); }else{ DU_impl.DrawRomboid (cm,joint_size*0.7f,color_bone_norm_cm); } } /* if (0){ M.transform_dir (d); p2.mad (p1,d,(*b_it)->_Length()); DU.DrawLine (p1,p2,c_joint); } */ if ((*b_it)->Parent()){ Device.SetShader(Device.m_SelectionShader); Fvector& p2 = (*b_it)->Parent()->_LTransform().c; DU_impl.DrawLine (p1,p2,color_bone_link_color); } if (EPrefs->object_flags.is(epoDrawBoneAxis)){ Fmatrix mat; mat.mul(parent,M); DU_impl.DrawObjectAxis(mat,0.03f,(*b_it)->flags.is(CBone::flSelected)); } if (EPrefs->object_flags.is(epoDrawBoneNames)){ parent.transform_tiny(p1); u32 c = (*b_it)->flags.is(CBone::flSelected)?0xFFFFFFFF:0xFF000000; u32 s = (*b_it)->flags.is(CBone::flSelected)?0xFF000000:0xFF909090; DU_impl.OutText(p1,(*b_it)->Name().c_str(),c,s); } if (EPrefs->object_flags.is(epoDrawBoneShapes)){ Device.SetShader(Device.m_SelectionShader); Fmatrix mat = M; mat.mulA_43 (parent); u32 c = (*b_it)->flags.is(CBone::flSelected)?0x80ffffff:0x300000ff; if ((*b_it)->shape.Valid()){ switch ((*b_it)->shape.type){ case SBoneShape::stBox: DU_impl.DrawOBB (mat,(*b_it)->shape.box,c,c); break; case SBoneShape::stSphere: DU_impl.DrawSphere (mat,(*b_it)->shape.sphere,c,c,TRUE,TRUE);break; case SBoneShape::stCylinder:DU_impl.DrawCylinder (mat,(*b_it)->shape.cylinder.m_center,(*b_it)->shape.cylinder.m_direction,(*b_it)->shape.cylinder.m_height,(*b_it)->shape.cylinder.m_radius,c,c,TRUE,TRUE);break; } } } } } }
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 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 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 CParticleEffect::Render(float ) { u32 dwOffset,dwCount; // Get a pointer to the particles in gp memory PAPI::Particle* particles; u32 p_cnt; ParticleManager()->GetParticles(m_HandleEffect,particles,p_cnt); if(p_cnt>0){ if (m_Def&&m_Def->m_Flags.is(CPEDef::dfSprite)){ FVF::LIT* pv_start = (FVF::LIT*)RCache.Vertex.Lock(p_cnt*4*4,geom->vb_stride,dwOffset); FVF::LIT* pv = pv_start; for(u32 i = 0; i < p_cnt; i++){ PAPI::Particle &m = particles[i]; Fvector2 lt,rb; lt.set (0.f,0.f); rb.set (1.f,1.f); if (m_Def->m_Flags.is(CPEDef::dfFramed)) m_Def->m_Frame.CalculateTC(iFloor(float(m.frame)/255.f),lt,rb); float r_x = m.size.x*0.5f; float r_y = m.size.y*0.5f; if (m_Def->m_Flags.is(CPEDef::dfVelocityScale)){ float speed = m.vel.magnitude(); r_x += speed*m_Def->m_VelocityScale.x; r_y += speed*m_Def->m_VelocityScale.y; } if (m_Def->m_Flags.is(CPEDef::dfAlignToPath)){ float speed = m.vel.magnitude(); if ((speed<EPS_S)&&m_Def->m_Flags.is(CPEDef::dfWorldAlign)){ Fmatrix M; M.setXYZ (m_Def->m_APDefaultRotation); if (m_RT_Flags.is(flRT_XFORM)){ Fvector p; m_XFORM.transform_tiny(p,m.pos); M.mulA_43 (m_XFORM); FillSprite (pv,M.k,M.i,p,lt,rb,r_x,r_y,m.color,m.rot.x); }else{ FillSprite (pv,M.k,M.i,m.pos,lt,rb,r_x,r_y,m.color,m.rot.x); } }else if ((speed>=EPS_S)&&m_Def->m_Flags.is(CPEDef::dfFaceAlign)){ Fmatrix M; M.identity(); M.k.div (m.vel,speed); M.j.set (0,1,0); if (_abs(M.j.dotproduct(M.k))>.99f) M.j.set(0,0,1); M.i.crossproduct (M.j,M.k); M.i.normalize (); M.j.crossproduct (M.k,M.i); M.j.normalize (); if (m_RT_Flags.is(flRT_XFORM)){ Fvector p; m_XFORM.transform_tiny(p,m.pos); M.mulA_43 (m_XFORM); FillSprite (pv,M.j,M.i,p,lt,rb,r_x,r_y,m.color,m.rot.x); }else{ FillSprite (pv,M.j,M.i,m.pos,lt,rb,r_x,r_y,m.color,m.rot.x); } }else{ Fvector dir; if (speed>=EPS_S) dir.div (m.vel,speed); else dir.setHP(-m_Def->m_APDefaultRotation.y,-m_Def->m_APDefaultRotation.x); if (m_RT_Flags.is(flRT_XFORM)){ Fvector p,d; m_XFORM.transform_tiny (p,m.pos); m_XFORM.transform_dir (d,dir); FillSprite (pv,p,d,lt,rb,r_x,r_y,m.color,m.rot.x); }else{ FillSprite (pv,m.pos,dir,lt,rb,r_x,r_y,m.color,m.rot.x); } } }else{ if (m_RT_Flags.is(flRT_XFORM)){ Fvector p; m_XFORM.transform_tiny (p,m.pos); FillSprite (pv,Device.vCameraTop,Device.vCameraRight,p,lt,rb,r_x,r_y,m.color,m.rot.x); }else{ FillSprite (pv,Device.vCameraTop,Device.vCameraRight,m.pos,lt,rb,r_x,r_y,m.color,m.rot.x); } } } dwCount = u32(pv-pv_start); RCache.Vertex.Unlock(dwCount,geom->vb_stride); if (dwCount) { RCache.set_xform_world (Fidentity); RCache.set_Geometry (geom); // u32 cm = RCache.get_CullMode(); RCache.set_CullMode (m_Def->m_Flags.is(CPEDef::dfCulling)?(m_Def->m_Flags.is(CPEDef::dfCullCCW)?CULL_CCW:CULL_CW):CULL_NONE); RCache.Render (D3DPT_TRIANGLELIST,dwOffset,0,dwCount,0,dwCount/2); RCache.set_CullMode (CULL_CCW ); } } } }