void CDrawUtilities::DrawDirectionalLight(const Fvector& p, const Fvector& d, float radius, float range, u32 c) { float r=radius*0.71f; Fvector R,N,D; D.normalize(d); Fmatrix rot; N.set (0,1,0); if (_abs(D.y)>0.99f) N.set(1,0,0); R.crossproduct(N,D); R.normalize(); N.crossproduct(D,R); N.normalize(); rot.set(R,N,D,p); float sz=radius+range; // fill VB _VertexStream* Stream = &RCache.Vertex; u32 vBase; FVF::L* pv = (FVF::L*)Stream->Lock(6,vs_L->vb_stride,vBase); pv->set (0,0,r, c); rot.transform_tiny(pv->p); pv++; pv->set (0,0,sz, c); rot.transform_tiny(pv->p); pv++; pv->set (-r,0,r, c); rot.transform_tiny(pv->p); pv++; pv->set (-r,0,sz, c); rot.transform_tiny(pv->p); pv++; pv->set (r,0,r, c); rot.transform_tiny(pv->p); pv++; pv->set (r,0,sz, c); rot.transform_tiny(pv->p); pv++; Stream->Unlock (6,vs_L->vb_stride); // and Render it as triangle list DU_DRAW_DP (D3DPT_LINELIST,vs_L,vBase,3); Fbox b; b.min.set(-r,-r,-r); b.max.set(r,r,r); DrawLineSphere ( p, radius, c, true ); }
void CDrawUtilities::DrawPlane (const Fvector& center, const Fvector2& scale, const Fvector& rotate, u32 clr_s, u32 clr_w, BOOL bCull, BOOL bSolid, BOOL bWire) { Fmatrix M; M.setHPB (rotate.y,rotate.x,rotate.z); M.translate_over(center); // fill VB _VertexStream* Stream = &RCache.Vertex; u32 vBase; if (bSolid){ DU_DRAW_SH(dxRenderDeviceRender::Instance().m_SelectionShader); FVF::L* pv = (FVF::L*)Stream->Lock(5,vs_L->vb_stride,vBase); pv->set (-scale.x, 0, -scale.y, clr_s); M.transform_tiny(pv->p); pv++; pv->set (-scale.x, 0, +scale.y, clr_s); M.transform_tiny(pv->p); pv++; pv->set (+scale.x, 0, +scale.y, clr_s); M.transform_tiny(pv->p); pv++; pv->set (+scale.x, 0, -scale.y, clr_s); M.transform_tiny(pv->p); pv++; pv->set (*(pv-4)); Stream->Unlock(5,vs_L->vb_stride); if (!bCull) DU_DRAW_RS(D3DRS_CULLMODE,D3DCULL_NONE); DU_DRAW_DP (D3DPT_TRIANGLEFAN,vs_L,vBase,2); if (!bCull) DU_DRAW_RS(D3DRS_CULLMODE,D3DCULL_CCW); } if (bWire){ DU_DRAW_SH(dxRenderDeviceRender::Instance().m_WireShader); FVF::L* pv = (FVF::L*)Stream->Lock(5,vs_L->vb_stride,vBase); pv->set (-scale.x, 0, -scale.y, clr_w); M.transform_tiny(pv->p); pv++; pv->set (+scale.x, 0, -scale.y, clr_w); M.transform_tiny(pv->p); pv++; pv->set (+scale.x, 0, +scale.y, clr_w); M.transform_tiny(pv->p); pv++; pv->set (-scale.x, 0, +scale.y, clr_w); M.transform_tiny(pv->p); pv++; pv->set (*(pv-4)); Stream->Unlock(5,vs_L->vb_stride); DU_DRAW_DP (D3DPT_LINESTRIP,vs_L,vBase,4); } }
void CIKLimb::Calculate(CKinematics* K,const Fmatrix &obj) { SCalculateData cd(this,K,obj); m_prev_state_anim=true; Collide(&cd); if(cd.m_tri) { Matrix m ; GoalMatrix (m,&cd) ; #ifdef DEBUG if(m_limb.SetGoal(m,ph_dbg_draw_mask.test(phDbgIKLimits))) #else if(m_limb.SetGoal(m,TRUE)) #endif { Fmatrix hip; CBoneData& BD=K->LL_GetData(m_bones[0]); hip.mul_43(K->LL_GetTransform(BD.GetParentID()),BD.bind_transform); hip.invert(); float x[7]; Fvector pos; pos.set(K->LL_GetTransform(m_bones[1]).c); hip.transform_tiny(pos); xm2im.transform_tiny(pos); if(m_limb.SolveByPos(cast_fp(pos),x)) { cd.m_angles=x; CalculateBones(&cd); m_prev_state_anim=false; } } } }
void CEditableObject::GetFaceWorld(const Fmatrix& parent, CEditableMesh* M, int idx, Fvector* verts) { const Fvector* PT[3]; M->GetFacePT(idx, PT); parent.transform_tiny(verts[0],*PT[0]); parent.transform_tiny(verts[1],*PT[1]); parent.transform_tiny(verts[2],*PT[2]); }
//---------------------------------------------------- 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 CWallmarksEngine::RecurseTri(u32 t, Fmatrix &mView, CWallmarksEngine::static_wallmark &W) { CDB::TRI* T = sml_collector.getT()+t; if (T->dummy) return; T->dummy = 0xffffffff; // Some vars u32* v_ids = T->verts; Fvector* v_data = sml_collector.getV(); sml_poly_src.clear (); sml_poly_src.push_back (v_data[v_ids[0]]); sml_poly_src.push_back (v_data[v_ids[1]]); sml_poly_src.push_back (v_data[v_ids[2]]); sml_poly_dest.clear (); sPoly* P = sml_clipper.ClipPoly (sml_poly_src, sml_poly_dest); //. todo // uv_gen = mView * [] // UV = pos*uv_gen if (P) { // Create vertices and triangulate poly (tri-fan style triangulation) FVF::LIT V0,V1,V2; Fvector UV; mView.transform_tiny(UV, (*P)[0]); V0.set ((*P)[0],0,(1+UV.x)*.5f,(1-UV.y)*.5f); mView.transform_tiny(UV, (*P)[1]); V1.set ((*P)[1],0,(1+UV.x)*.5f,(1-UV.y)*.5f); for (u32 i=2; i<P->size(); i++) { mView.transform_tiny(UV, (*P)[i]); V2.set ((*P)[i],0,(1+UV.x)*.5f,(1-UV.y)*.5f); W.verts.push_back (V0); W.verts.push_back (V1); W.verts.push_back (V2); V1 = V2; } // recurse for (auto i=0; i<3; i++) { u32 adj = sml_adjacency[3*t+i]; if (0xffffffff==adj) continue; CDB::TRI* SML = sml_collector.getT() + adj; v_ids = SML->verts; Fvector test_normal; test_normal.mknormal (v_data[v_ids[0]],v_data[v_ids[1]],v_data[v_ids[2]]); float cosa = test_normal.dotproduct(sml_normal); if (cosa<0.034899f) continue; // cos(88) RecurseTri (adj,mView,W); } } }
void xrMU_Model::export_cform_rcast (CDB::CollectorPacked& CL, Fmatrix& xform) { for (u32 fit=0; fit<m_faces.size(); fit++) m_faces[fit]->flags.bProcessed = false; v_faces adjacent; adjacent.reserve(6*2*3); for (v_faces_it it = m_faces.begin(); it!=m_faces.end(); it++) { _face* F = (*it); Shader_xrLC& SH = F->Shader(); if (!SH.flags.bLIGHT_CastShadow) continue; // Collect adjacent.clear (); for (int vit=0; vit<3; vit++) { _vertex* V = F->v[vit]; for (u32 adj=0; adj<V->adjacent.size(); adj++) adjacent.push_back(V->adjacent[adj]); } // Unique std::sort (adjacent.begin(),adjacent.end()); adjacent.erase (std::unique(adjacent.begin(),adjacent.end()),adjacent.end()); BOOL bAlready = FALSE; for (u32 ait=0; ait<adjacent.size(); ait++) { _face* Test = adjacent[ait]; if (Test==F) continue; if (!Test->flags.bProcessed)continue; if (F->isEqual(*Test)) { bAlready = TRUE; break; } } // if (!bAlready) { F->flags.bProcessed = true; Fvector P[3]; xform.transform_tiny (P[0],F->v[0]->P); xform.transform_tiny (P[1],F->v[1]->P); xform.transform_tiny (P[2],F->v[2]->P); #ifdef _WIN64 CL.add_face_D (P[0],P[1],P[2],*((u64*)&F) ); #else CL.add_face_D (P[0],P[1],P[2],*((u32*)&F) ); #endif } } }
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 CSpaceRestrictorWrapper::inside (const Fvector &position, float radius) const { Fsphere sphere; sphere.P = position; sphere.R = radius; typedef CShapeData::ShapeVec ShapeVec; ShapeVec::const_iterator I = object().shapes.begin(); ShapeVec::const_iterator E = object().shapes.end(); for ( ; I != E; ++I) { switch ((*I).type) { case 0 : { Fsphere temp; m_xform.transform_tiny(temp.P,(*I).data.sphere.P); temp.R = (*I).data.sphere.R; if (sphere.intersect(temp)) return (true); continue; } case 1 : { Fmatrix temp; temp.mul_43 (m_xform,(*I).data.box); // Build points Fvector vertices; Fvector points[8]; Fplane plane; vertices.set(-.5f, -.5f, -.5f); temp.transform_tiny(points[0],vertices); vertices.set(-.5f, -.5f, +.5f); temp.transform_tiny(points[1],vertices); vertices.set(-.5f, +.5f, +.5f); temp.transform_tiny(points[2],vertices); vertices.set(-.5f, +.5f, -.5f); temp.transform_tiny(points[3],vertices); vertices.set(+.5f, +.5f, +.5f); temp.transform_tiny(points[4],vertices); vertices.set(+.5f, +.5f, -.5f); temp.transform_tiny(points[5],vertices); vertices.set(+.5f, -.5f, +.5f); temp.transform_tiny(points[6],vertices); vertices.set(+.5f, -.5f, -.5f); temp.transform_tiny(points[7],vertices); plane.build(points[0],points[3],points[5]); if (plane.classify(sphere.P)>sphere.R) break; plane.build(points[1],points[2],points[3]); if (plane.classify(sphere.P)>sphere.R) break; plane.build(points[6],points[5],points[4]); if (plane.classify(sphere.P)>sphere.R) break; plane.build(points[4],points[2],points[1]); if (plane.classify(sphere.P)>sphere.R) break; plane.build(points[3],points[2],points[4]); if (plane.classify(sphere.P)>sphere.R) break; plane.build(points[1],points[0],points[6]); if (plane.classify(sphere.P)>sphere.R) break; return (true); } default : NODEFAULT; } } return (false); }
int CPortalUtils::CalculateSelectedPortals(ObjectList& sectors){ // calculate portals Fbox bb; Scene->GetBox(bb,OBJCLASS_SCENEOBJECT); sCollector* CL = xr_new<sCollector>(bb); Fmatrix T; //1. xform + weld UI->SetStatus("xform + weld..."); for (ObjectIt s_it=sectors.begin(); s_it!=sectors.end(); s_it++){ CSector* S=(CSector*)(*s_it); for (SItemIt s_it=S->sector_items.begin();s_it!=S->sector_items.end();s_it++){ if (s_it->object->IsMUStatic()) continue; s_it->GetTransform(T); Fvector* m_verts=s_it->mesh->m_Verts; for (u32 f_id=0; f_id<s_it->mesh->GetFCount(); f_id++){ Fvector v0, v1, v2; st_Face& P=s_it->mesh->GetFaces()[f_id]; T.transform_tiny(v0,m_verts[P.pv[0].pindex]); T.transform_tiny(v1,m_verts[P.pv[1].pindex]); T.transform_tiny(v2,m_verts[P.pv[2].pindex]); CL->add_face(v0,v1,v2,S); } } } //2. update pervertex adjacency UI->SetStatus("updating per-vertex adjacency..."); CL->update_adjacency(); //3. find edges UI->SetStatus("searching edges..."); CL->find_edges(); //4. sort edges UI->SetStatus("sorting edges..."); CL->sort_edges(); //5. make portals UI->SetStatus("calculating portals..."); CL->make_portals(); //6. export portals UI->SetStatus("building portals..."); CL->export_portals(); Scene->UndoSave(); int iRes = CL->portals.size(); xr_delete(CL); return iRes; }
u16 CIKFoot::get_ref_bone ( const Fmatrix & foot_transform, const Fmatrix &toe_transform ) const { Fvector n0,n1; get_local_vector( 2, n0, m_foot_normal ); get_local_vector( 3, n1, m_foot_normal ); foot_transform.transform_tiny( n0 ); toe_transform.transform_tiny( n1 ); n0.normalize();n1.normalize(); if( n0.dotproduct( n1 ) < 0.99f ) return 3 ; else return 2 ; }
void CIKFoot::SetFootGeom ( ik_foot_geom &fg, const Fmatrix &ref_bone, const Fmatrix& object_matrix ) const { Fmatrix gl_bone; gl_bone.mul_43( object_matrix, ref_bone ); Fvector pos_toe; ToePosition( pos_toe ); gl_bone.transform_tiny( pos_toe ); Fvector heel; Fvector pos_hill; Fmatrix foot =( Fmatrix( ).mul_43( object_matrix, ref_bone_to_foot( foot, ref_bone ) ) ); foot.transform_tiny( pos_hill, HeelPosition( heel ) ); const Fvector v_m = Fvector().add(pos_toe, pos_hill ).mul(0.5f) ; Fvector normal, direction; get_local_vector( normal, m_foot_normal ); get_local_vector( direction, m_foot_direction ); Fvector v_side = Fvector().crossproduct( normal, direction ); gl_bone.transform_dir ( v_side ); float vsm = v_side.magnitude(); VERIFY( vsm > EPS_L ); v_side.mul( Fvector().sub(pos_toe, pos_hill ).magnitude()/vsm ); fg.set( pos_toe, pos_hill, Fvector().add( v_m, v_side ) ); }
bool CIKFoot::make_shift( Fmatrix &xm,const Fvector &cl_point, bool collide, const Fplane &p, const Fvector &pick_dir )const { Fvector shift = pick_dir; //Fvector toe; ToePosition( toe ); xm.transform_tiny( toe ); Fvector point; xm.transform_tiny( point, cl_point ); float dot = p.n.dotproduct( shift ); if( _abs( dot ) < min_dot ) { shift.add( Fvector( ).mul( p.n, min_dot - _abs( dot ) ) ); dot = p.n.dotproduct( shift ); } VERIFY( !fis_zero( dot ) ); float shift_m = ( -p.d - p.n.dotproduct( point ) )/dot; if(collide && shift_m > 0.f ) return false; clamp( shift_m, -collide_dist, collide_dist ); shift.mul( shift_m ); xm.c.add( shift ); #if 0 if(shift_m > 0.f) { DBG_OpenCashedDraw(); DBG_DrawLine( toe, Fvector().add( toe, shift ), D3DCOLOR_XRGB( 255, 255, 255 ) ); DBG_ClosedCashedDraw( 1000 ); } #endif return true; }
// Fill Vertices void CSkeletonX::_FillVerticesSoft1W(const Fmatrix& view, CSkeletonWallmark& wm, const Fvector& normal, float size, u16* indices, CBoneData::FacesVec& faces) { VERIFY (*Vertices1W); for (CBoneData::FacesVecIt it=faces.begin(); it!=faces.end(); it++){ Fvector p[3]; u32 idx = (*it)*3; CSkeletonWallmark::WMFace F; for (u32 k=0; k<3; k++){ vertBoned1W& vert = Vertices1W[indices[idx+k]]; F.bone_id[k][0] = (u16)vert.matrix; F.bone_id[k][1] = F.bone_id[k][0]; F.weight[k] = 0.f; const Fmatrix& xform = Parent->LL_GetBoneInstance(F.bone_id[k][0]).mRenderTransform; F.vert[k].set (vert.P); xform.transform_tiny (p[k],F.vert[k]); } Fvector test_normal; test_normal.mknormal (p[0],p[1],p[2]); float cosa = test_normal.dotproduct(normal); if (cosa<EPS) continue; if (CDB::TestSphereTri(wm.ContactPoint(),size,p)) { Fvector UV; for (u32 k=0; k<3; k++){ Fvector2& uv = F.uv[k]; view.transform_tiny(UV,p[k]); uv.x = (1+UV.x)*.5f; uv.y = (1-UV.y)*.5f; } wm.m_Faces.push_back(F); } } }
void CDetail::transfer (Fmatrix& mXform, fvfVertexOut* vDest, u32 C, u16* iDest, u32 iOffset, float du, float dv) { // Transfer vertices { CDetail::fvfVertexIn *srcIt = vertices, *srcEnd = vertices+number_vertices; CDetail::fvfVertexOut *dstIt = vDest; for (; srcIt!=srcEnd; srcIt++, dstIt++) { mXform.transform_tiny (dstIt->P,srcIt->P); dstIt->C = C; dstIt->u = srcIt->u+du; dstIt->v = srcIt->v+dv; } } // Transfer indices (in 32bit lines) VERIFY (iOffset<65535); { u32 item = (iOffset<<16) | iOffset; u32 count = number_indices/2; LPDWORD sit = LPDWORD(indices); LPDWORD send = sit+count; LPDWORD dit = LPDWORD(iDest); for (; sit!=send; dit++,sit++) *dit=*sit+item; if (number_indices&1) iDest[number_indices-1]=u16(indices[number_indices-1]+u16(iOffset)); } }
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 CDrawUtilities::DrawSpotLight(const Fvector& p, const Fvector& d, float range, float phi, u32 clr) { Fmatrix T; Fvector p1; float H,P; float da = PI_MUL_2/LINE_DIVISION; float b = range*_cos(PI_DIV_2-phi/2); float a = range*_sin(PI_DIV_2-phi/2); d.getHP (H,P); T.setHPB (H,P,0); T.translate_over(p); _VertexStream* Stream = &RCache.Vertex; u32 vBase; FVF::L* pv = (FVF::L*)Stream->Lock(LINE_DIVISION*2+2,vs_L->vb_stride,vBase); for (float angle=0; angle<PI_MUL_2; angle+=da){ float _sa =_sin(angle); float _ca =_cos(angle); p1.x = b * _ca; p1.y = b * _sa; p1.z = a; T.transform_tiny(p1); // fill VB pv->set (p,clr); pv++; pv->set (p1,clr); pv++; } p1.mad (p,d,range); pv->set (p,clr); pv++; pv->set (p1,clr); pv++; Stream->Unlock (LINE_DIVISION*2+2,vs_L->vb_stride); // and Render it as triangle list DU_DRAW_DP (D3DPT_LINELIST,vs_L,vBase,LINE_DIVISION+1); }
bool object::inside (Fvector const &position) const { CCF_Shape *shape = static_cast<CCF_Shape*>(collidable.model); VERIFY (shape); typedef xr_vector<CCF_Shape::shape_def> Shapes; Shapes::const_iterator i = shape->shapes.begin(); Shapes::const_iterator e = shape->shapes.end(); for ( ; i != e; ++i) { switch ((*i).type) { case 0 : { if ((*i).data.sphere.P.distance_to(position) <= (*i).data.sphere.R) return (true); continue; } case 1 : { Fmatrix matrix; const Fmatrix &box = (*i).data.box; matrix.mul_43 (XFORM(),box); Fvector A,B[8]; Fplane plane; A.set (-.5f, -.5f, -.5f); matrix.transform_tiny(B[0],A); A.set (-.5f, -.5f, +.5f); matrix.transform_tiny(B[1],A); A.set (-.5f, +.5f, +.5f); matrix.transform_tiny(B[2],A); A.set (-.5f, +.5f, -.5f); matrix.transform_tiny(B[3],A); A.set (+.5f, +.5f, +.5f); matrix.transform_tiny(B[4],A); A.set (+.5f, +.5f, -.5f); matrix.transform_tiny(B[5],A); A.set (+.5f, -.5f, +.5f); matrix.transform_tiny(B[6],A); A.set (+.5f, -.5f, -.5f); matrix.transform_tiny(B[7],A); plane.build (B[0],B[3],B[5]); if (plane.classify(position) <= 0.f) return (true); plane.build (B[1],B[2],B[3]); if (plane.classify(position) <= 0.f) return (true); plane.build (B[6],B[5],B[4]); if (plane.classify(position) <= 0.f) return (true); plane.build (B[4],B[2],B[1]); if (plane.classify(position) <= 0.f) return (true); plane.build (B[3],B[2],B[4]); if (plane.classify(position) <= 0.f) return (true); plane.build (B[1],B[0],B[6]); if (plane.classify(position) <= 0.f) return (true); continue; } default : NODEFAULT; } } return (false); }
void CDrawUtilities::DrawPlane (const Fvector& p, const Fvector& n, const Fvector2& scale, u32 clr_s, u32 clr_w, BOOL bCull, BOOL bSolid, BOOL bWire) { if (n.square_magnitude()<EPS_S) return; // build final rotation / translation Fvector L_dir,L_up=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 (); 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 = p; mR._44 = 1; // fill VB _VertexStream* Stream = &RCache.Vertex; u32 vBase; if (bSolid){ DU_DRAW_SH(dxRenderDeviceRender::Instance().m_SelectionShader); FVF::L* pv = (FVF::L*)Stream->Lock(5,vs_L->vb_stride,vBase); pv->set (-scale.x, 0, -scale.y, clr_s); mR.transform_tiny(pv->p); pv++; pv->set (-scale.x, 0, +scale.y, clr_s); mR.transform_tiny(pv->p); pv++; pv->set (+scale.x, 0, +scale.y, clr_s); mR.transform_tiny(pv->p); pv++; pv->set (+scale.x, 0, -scale.y, clr_s); mR.transform_tiny(pv->p); pv++; pv->set (*(pv-4)); Stream->Unlock(5,vs_L->vb_stride); if (!bCull) DU_DRAW_RS(D3DRS_CULLMODE,D3DCULL_NONE); DU_DRAW_DP (D3DPT_TRIANGLEFAN,vs_L,vBase,2); if (!bCull) DU_DRAW_RS(D3DRS_CULLMODE,D3DCULL_CCW); } if (bWire){ DU_DRAW_SH(dxRenderDeviceRender::Instance().m_WireShader); FVF::L* pv = (FVF::L*)Stream->Lock(5,vs_L->vb_stride,vBase); pv->set (-scale.x, 0, -scale.y, clr_w); mR.transform_tiny(pv->p); pv++; pv->set (+scale.x, 0, -scale.y, clr_w); mR.transform_tiny(pv->p); pv++; pv->set (+scale.x, 0, +scale.y, clr_w); mR.transform_tiny(pv->p); pv++; pv->set (-scale.x, 0, +scale.y, clr_w); mR.transform_tiny(pv->p); pv++; pv->set (*(pv-4)); Stream->Unlock(5,vs_L->vb_stride); DU_DRAW_DP (D3DPT_LINESTRIP,vs_L,vBase,4); } }
bool CKinematics:: PickBone (const Fmatrix &parent_xform, IKinematics::pick_result &r, 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(r,dist,S,D,bone_id)) { parent_xform.transform_dir (r.normal); parent_xform.transform_tiny (r.tri[0]); parent_xform.transform_tiny (r.tri[1]); parent_xform.transform_tiny (r.tri[2]); return true; } return false; }
void CSpectator::cam_Update (CActor* A) { if (A){ const Fmatrix& M = A->XFORM(); CCameraBase* pACam = A->cam_Active(); CCameraBase* cam = cameras[cam_active]; switch(cam_active) { case eacFirstEye:{ Fvector P, D, N; pACam->Get (P, D, N); cam->Set (P, D, N); }break; case eacLookAt:{ float y,p,r; M.getHPB (y,p,r); cam->Set (pACam->yaw,pACam->pitch,-r); } case eacFreeLook:{ cam->SetParent (A); Fmatrix tmp; tmp.identity(); Fvector point, point1, dangle; point.set (0.f,1.6f,0.f); point1.set (0.f,1.6f,0.f); M.transform_tiny (point); tmp.translate_over(point); tmp.transform_tiny (point1); if (!A->g_Alive()) point.set(point1); cam->Update (point,dangle); }break; } //----------------------------------- Fvector P, D, N; cam->Get(P, D, N); cameras[eacFreeFly]->Set(P, D, N); cameras[eacFreeFly]->Set(cam->yaw, cam->pitch, 0); P.y -= 1.6f; XFORM().translate_over(P); //----------------------------------- g_pGameLevel->Cameras().Update(cam); }else{ CCameraBase* cam = cameras[eacFreeFly]; Fvector point, dangle; point.set (0.f,1.6f,0.f); XFORM().transform_tiny (point); // apply shift dangle.set (0,0,0); cam->Update (point,dangle); // cam->vPosition.set(point0); g_pGameLevel->Cameras().Update (cam); // hud output }; }
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::NumSetPosition(const Fvector& pos) { inherited::NumSetPosition(pos); Fmatrix prev; prev.invert(FTransform); UpdateTransform(true); for (ObjectIt it=m_Objects.begin(); it!=m_Objects.end(); it++){ Fvector v=(*it)->PPosition; prev.transform_tiny(v); FTransform.transform_tiny(v); (*it)->PPosition=v; } }
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); }
void CGroupObject::NumSetScale(const Fvector& scale) { Fvector old_s = PScale; inherited::NumSetScale(scale); Fmatrix prev; prev.invert(FTransform); UpdateTransform(true); Fvector ds; ds.sub(FScale,old_s); for (ObjectIt it=m_Objects.begin(); it!=m_Objects.end(); it++){ Fvector s=(*it)->PScale; s.add(ds); (*it)->PScale=s; Fvector v=(*it)->PPosition; prev.transform_tiny(v); FTransform.transform_tiny(v); (*it)->PPosition=v; } }
void CGroupObject::Move(Fvector& amount) { Fvector old_r=FRotation; inherited::Move(amount); Fmatrix prev; prev.invert(FTransform); UpdateTransform(true); Fvector dr; dr.sub(FRotation,old_r); for (ObjectIt it=m_Objects.begin(); it!=m_Objects.end(); it++){ Fvector r=(*it)->PRotation; r.add(dr); (*it)->PRotation=r; Fvector v=(*it)->PPosition; prev.transform_tiny(v); FTransform.transform_tiny(v); (*it)->PPosition=v; } }
ICF BOOL test_point(xrXRC& xrc, const Fmatrix& xform, const Fmatrix33& mat, const Fvector& ext, float radius, float angle) { Fvector pt; calc_point (pt,radius,VIEWPORT_NEAR/2,angle); xform.transform_tiny(pt); CDB::RESULT* it =xrc.r_begin(); CDB::RESULT* end=xrc.r_end (); for (; it!=end; it++) { CDB::RESULT& O = *it; if (GMLib.GetMaterialByIdx(O.material)->Flags.is(SGameMtl::flPassable)) continue; if (CDB::TestBBoxTri(mat,pt,ext,O.verts,FALSE)) return TRUE; } return FALSE; }
//---------------------------------------------------- void CEditableMesh::Transform(const Fmatrix& parent) { // transform position for(u32 k=0; k<m_VertCount; k++) parent.transform_tiny(m_Verts[k]); // RecomputeBBox RecomputeBBox (); // update normals & cform #ifdef _EDITOR UnloadRenderBuffers (); UnloadCForm (); #endif UnloadFNormals (true); UnloadVNormals (true); UnloadSVertices (true); }
void CHelicopter::UpdateMGunDir() { 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_fire_dir.sub (m_enemy.destEnemyPos,m_fire_pos).normalize_safe(); m_left_rocket_bone_xform = K->LL_GetTransform(m_left_rocket_bone); m_left_rocket_bone_xform.mulA_43 (XFORM()); m_left_rocket_bone_xform.c.y += 1.0f; //.fake m_right_rocket_bone_xform = K->LL_GetTransform(m_right_rocket_bone); m_right_rocket_bone_xform.mulA_43 (XFORM()); m_right_rocket_bone_xform.c.y += 1.0f; //.fake m_allow_fire = TRUE; Fmatrix XFi; XFi.invert (XFORM()); Fvector dep; XFi.transform_tiny (dep,m_enemy.destEnemyPos); {// x angle Fvector A_; A_.sub(dep,m_bind_x); m_i_bind_x_xform.transform_dir(A_); A_.normalize(); m_tgt_rot.x = angle_normalize_signed(m_bind_rot.x-A_.getP()); float sv_x = m_tgt_rot.x; clamp (m_tgt_rot.x,-m_lim_x_rot.y,-m_lim_x_rot.x); if (!fsimilar(sv_x,m_tgt_rot.x,EPS_L)) m_allow_fire=FALSE; } {// y angle Fvector A_; A_.sub(dep,m_bind_y); m_i_bind_y_xform.transform_dir(A_); A_.normalize(); m_tgt_rot.y = angle_normalize_signed(m_bind_rot.y-A_.getH()); float sv_y = m_tgt_rot.y; clamp (m_tgt_rot.y,-m_lim_y_rot.y,-m_lim_y_rot.x); if (!fsimilar(sv_y,m_tgt_rot.y,EPS_L)) m_allow_fire=FALSE; } if ((angle_difference(m_cur_rot.x,m_tgt_rot.x)>deg2rad(m_barrel_dir_tolerance))|| (angle_difference(m_cur_rot.y,m_tgt_rot.y)>deg2rad(m_barrel_dir_tolerance))) m_allow_fire=FALSE; }
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; }