void CGameObject::OnRender () { if (!ai().get_level_graph()) return; CDebugRenderer &renderer = Level().debug_renderer(); if (/**bDebug && /**/Visual()) { float half_cell_size = 1.f*ai().level_graph().header().cell_size()*.5f; Fvector additional = Fvector().set(half_cell_size,half_cell_size,half_cell_size); render_box (Visual(),XFORM(),Fvector().set(0.f,0.f,0.f),true,color_rgba(0,0,255,255)); render_box (Visual(),XFORM(),additional,false,color_rgba(0,255,0,255)); } if (0) { Fvector bc,bd; Visual()->getVisData().box.get_CD (bc,bd); Fmatrix M = Fidentity; float half_cell_size = ai().level_graph().header().cell_size()*.5f; bd.add (Fvector().set(half_cell_size,half_cell_size,half_cell_size)); M.scale (bd); Fmatrix T = XFORM(); T.c.add (bc); renderer.draw_obb (T,bd,color_rgba(255,255,255,255)); } }
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 CDrawUtilities::DrawAABB(const Fvector& p0, const Fvector& p1, u32 clr_s, u32 clr_w, BOOL bSolid, BOOL bWire) { Fmatrix R; Fvector C; C.set((p1.x+p0.x)*0.5f,(p1.y+p0.y)*0.5f,(p1.z+p0.z)*0.5f); R.scale (_abs(p1.x-p0.x),_abs(p1.y-p0.y),_abs(p1.z-p0.z)); R.translate_over(C); RCache.set_xform_world(R); DrawIdentBox (bSolid,bWire,clr_s,clr_w); }
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 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); } } } }
bool CLevelTool::GetSelectionPosition(Fmatrix& result) { if(pCurTool) { Fvector center; Fbox BB; BB.invalidate (); // pCurTool->GetBBox (BB, true); const CCustomObject* object = pCurTool->LastSelected(); if(!object) return false; object->GetBox (BB); BB.getcenter (center); center.y = BB.max.y; Fvector2 pt_ss; pt_ss.set (10000,-10000); Fvector pt_ss_3d; BB.setb (center, Fvector().set(1.0f,1.0f,1.0f)); for(int k=0;k<8;++k) { Fvector pt; BB.getpoint(k,pt); EDevice.mFullTransform.transform(pt_ss_3d, pt); pt_ss.x = _min(pt_ss.x, pt_ss_3d.y); pt_ss.y = _max(pt_ss.y, pt_ss_3d.y); } float r_bb_ss = pt_ss.y - pt_ss.x; clamp(r_bb_ss, 0.0f,0.10f); float des_radius = 0.2f; float csale = des_radius/r_bb_ss; result.scale (csale,csale,csale); result.c = center; return true; }else return false; }
BOOL CBlackGraviArtefact::net_Spawn(CSE_Abstract* DC) { if(!inherited::net_Spawn(DC)) return FALSE; CParticlesObject* pStaticPG; pStaticPG = CParticlesObject::Create("anomaly\\galantine",FALSE); Fmatrix pos; //pos.rotateY(1.57); //pos.mulA(pos); pos.scale(0.7f,0.7f,0.7f); pos.translate_over(XFORM().c); Fvector vel; vel.set(0,0,0); pStaticPG->UpdateParent(pos, vel); pStaticPG->Play(); return TRUE; }
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); }
// Xforms void light::xform_calc () { if (Device.dwFrame == m_xform_frame) return; m_xform_frame = Device.dwFrame; // build final rotation / translation Fvector L_dir,L_up,L_right; // dir L_dir.set (direction); float l_dir_m = L_dir.magnitude(); if (_valid(l_dir_m) && l_dir_m>EPS_S) L_dir.div(l_dir_m); else L_dir.set(0,0,1); // R&N if (right.square_magnitude()>EPS) { // use specified 'up' and 'right', just enshure ortho-normalization L_right.set (right); L_right.normalize (); L_up.crossproduct (L_dir,L_right); L_up.normalize (); L_right.crossproduct (L_up,L_dir); L_right.normalize (); } else { // auto find 'up' and 'right' vectors 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 (); } // matrix 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 = position; mR._44 = 1; // switch switch(flags.type) { case IRender_Light::REFLECTED : case IRender_Light::POINT : { // scale of identity sphere float L_R = range; Fmatrix mScale; mScale.scale (L_R,L_R,L_R); m_xform.mul_43 (mR,mScale); } break; case IRender_Light::SPOT : { // scale to account range and angle float s = 2.f*range*tanf(cone/2.f); Fmatrix mScale; mScale.scale(s,s,range); // make range and radius m_xform.mul_43 (mR,mScale); } break; case IRender_Light::OMNIPART : { float L_R = 2*range; // volume is half-radius Fmatrix mScale; mScale.scale (L_R,L_R,L_R); m_xform.mul_43 (mR,mScale); } break; default: m_xform.identity (); break; } }
void CLightProjector::calculate () { #ifdef _GPA_ENABLED TAL_SCOPED_TASK_NAMED( "CLightProjector::calculate()" ); #endif // _GPA_ENABLED if (receivers.empty()) return; // perform validate / markup for (u32 r_it=0; r_it<receivers.size(); r_it++) { // validate BOOL bValid = TRUE; IRenderable* O = receivers[r_it]; CROS_impl* LT = (CROS_impl*)O->renderable_ROS(); int slot = LT->shadow_recv_slot; if (slot<0 || slot>=P_o_count) bValid = FALSE; // invalid slot else if (cache[slot].O!=O) bValid = FALSE; // not the same object else { // seems to be valid Fbox bb; bb.xform (O->renderable.visual->getVisData().box,O->renderable.xform); if (cache[slot].BB.contains(bb)) { // inside, but maybe timelimit exceeded? if (Device.dwTimeGlobal > cache[slot].dwTimeValid) bValid = FALSE; // timeout } else bValid = FALSE; // out of bounds } // if (bValid) { // Ok, use cached version cache[slot].dwFrame = Device.dwFrame; } else { taskid.push_back (r_it); } } if (taskid.empty()) return; // Begin Device.Statistic->RenderDUMP_Pcalc.Begin (); RCache.set_RT (RT->pRT); RCache.set_ZB (RImplementation.Target->pTempZB); CHK_DX(HW.pDevice->Clear (0,0, D3DCLEAR_ZBUFFER | (HW.Caps.bStencil?D3DCLEAR_STENCIL:0), 0,1,0 )); RCache.set_xform_world (Fidentity); // reallocate/reassociate structures + perform all the work for (u32 c_it=0; c_it<cache.size(); c_it++) { if (taskid.empty()) break; if (Device.dwFrame==cache[c_it].dwFrame) continue; // found not used slot int tid = taskid.back(); taskid.pop_back(); recv& R = cache [c_it]; IRenderable* O = receivers [tid]; const vis_data& vis = O->renderable.visual->getVisData(); CROS_impl* LT = (CROS_impl*)O->renderable_ROS(); VERIFY2 (_valid(O->renderable.xform),"Invalid object transformation"); VERIFY2 (_valid(vis.sphere.P),"Invalid object's visual sphere"); Fvector C; O->renderable.xform.transform_tiny (C,vis.sphere.P); R.O = O; R.C = C; R.C.y += vis.sphere.R*0.1f; //. YURA: 0.1 can be more R.BB.xform (vis.box,O->renderable.xform).scale(0.1f); R.dwTimeValid = Device.dwTimeGlobal + ::Random.randI(time_min,time_max); LT->shadow_recv_slot = c_it; // Msg ("[%f,%f,%f]-%f",C.C.x,C.C.y,C.C.z,C.O->renderable.visual->vis.sphere.R); // calculate projection-matrix Fmatrix mProject; float p_R = R.O->renderable.visual->getVisData().sphere.R * 1.1f; //VERIFY2 (p_R>EPS_L,"Object has no physical size"); VERIFY3 (p_R>EPS_L,"Object has no physical size", R.O->renderable.visual->getDebugName().c_str()); float p_hat = p_R/P_cam_dist; float p_asp = 1.f; float p_near = P_cam_dist-EPS_L; float p_far = P_cam_dist+p_R+P_cam_range; mProject.build_projection_HAT (p_hat,p_asp,p_near,p_far); RCache.set_xform_project (mProject); // calculate view-matrix Fmatrix mView; Fvector v_C, v_Cs, v_N; v_C.set (R.C); v_Cs = v_C; v_C.y += P_cam_dist; v_N.set (0,0,1); VERIFY (_valid(v_C) && _valid(v_Cs) && _valid(v_N)); // validate Fvector v; v.sub (v_Cs,v_C);; #ifdef DEBUG if ((v.x*v.x+v.y*v.y+v.z*v.z)<=flt_zero) { CObject* OO = dynamic_cast<CObject*>(R.O); Msg("Object[%s] Visual[%s] has invalid position. ",*OO->cName(),*OO->cNameVisual()); Fvector cc; OO->Center(cc); Log("center=",cc); Log("visual_center=",OO->Visual()->getVisData().sphere.P); Log("full_matrix=",OO->XFORM()); Log ("v_N",v_N); Log ("v_C",v_C); Log ("v_Cs",v_Cs); Log("all bones transform:--------"); CKinematics* K = dynamic_cast<CKinematics*>(OO->Visual()); for(u16 ii=0; ii<K->LL_BoneCount();++ii){ Fmatrix tr; tr = K->LL_GetTransform(ii); Log("bone ",K->LL_BoneName_dbg(ii)); Log("bone_matrix",tr); } Log("end-------"); } #endif // handle invalid object-bug if ((v.x*v.x+v.y*v.y+v.z*v.z)<=flt_zero) { // invalidate record, so that object will be unshadowed, but doesn't crash R.dwTimeValid = Device.dwTimeGlobal; LT->shadow_recv_frame = Device.dwFrame-1; LT->shadow_recv_slot = -1; continue ; } mView.build_camera (v_C,v_Cs,v_N); RCache.set_xform_view (mView); // Select slot, set viewport int s_x = c_it%P_o_line; int s_y = c_it/P_o_line; D3DVIEWPORT9 VP = {s_x*P_o_size,s_y*P_o_size,P_o_size,P_o_size,0,1 }; CHK_DX (HW.pDevice->SetViewport(&VP)); // Clear color to ambience Fvector& cap = LT->get_approximate(); CHK_DX (HW.pDevice->Clear(0,0, D3DCLEAR_TARGET, color_rgba_f(cap.x,cap.y,cap.z, (cap.x+cap.y+cap.z)/4.f), 1, 0 )); // calculate uv-gen matrix and clamper Fmatrix mCombine; mCombine.mul (mProject,mView); Fmatrix mTemp; float fSlotSize = float(P_o_size)/float(P_rt_size); float fSlotX = float(s_x*P_o_size)/float(P_rt_size); float fSlotY = float(s_y*P_o_size)/float(P_rt_size); float fTexelOffs = (.5f / P_rt_size); Fmatrix m_TexelAdjust = { 0.5f/*x-scale*/, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f/*y-scale*/, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f/*z-range*/, 0.0f, 0.5f/*x-bias*/, 0.5f + fTexelOffs/*y-bias*/, 0.0f/*z-bias*/, 1.0f }; R.UVgen.mul (m_TexelAdjust,mCombine); mTemp.scale (fSlotSize,fSlotSize,1); R.UVgen.mulA_44 (mTemp); mTemp.translate (fSlotX+fTexelOffs,fSlotY+fTexelOffs,0); R.UVgen.mulA_44 (mTemp); // Build bbox and render Fvector min,max; Fbox BB; min.set (R.C.x-p_R, R.C.y-(p_R+P_cam_range), R.C.z-p_R); max.set (R.C.x+p_R, R.C.y+0, R.C.z+p_R); BB.set (min,max); R.UVclamp_min.set (min).add (.05f); // shrink a little R.UVclamp_max.set (max).sub (.05f); // shrink a little ISpatial* spatial = dynamic_cast<ISpatial*> (O); if (spatial) { spatial->spatial_updatesector (); if (spatial->spatial.sector) RImplementation.r_dsgraph_render_R1_box (spatial->spatial.sector,BB,SE_R1_LMODELS); } //if (spatial) RImplementation.r_dsgraph_render_subspace (spatial->spatial.sector,mCombine,v_C,FALSE); } // Blur /* { // Fill vertex buffer u32 Offset; FVF::TL4uv* pv = (FVF::TL4uv*) RCache.Vertex.Lock (4,geom_Blur.stride(),Offset); RImplementation.ApplyBlur4 (pv,P_rt_size,P_rt_size,P_blur_kernel); RCache.Vertex.Unlock (4,geom_Blur.stride()); // Actual rendering (pass0, temp2real) RCache.set_RT (RT->pRT); RCache.set_ZB (NULL); RCache.set_Shader (sh_BlurTR ); RCache.set_Geometry (geom_Blur ); RCache.Render (D3DPT_TRIANGLELIST,Offset,0,4,0,2); } */ // Finita la comedia Device.Statistic->RenderDUMP_Pcalc.End (); RCache.set_xform_project (Device.mProject); RCache.set_xform_view (Device.mView); }
void CMatrix::Calculate() { if (dwFrame==Device.dwFrame) return; dwFrame = Device.dwFrame; // Switch on mode switch (dwMode) { case modeProgrammable: case modeDetail: return; case modeTCM: { Fmatrix T; float sU=1,sV=1,t=Device.fTimeGlobal; tc_trans (xform,.5f,.5f); if (tcm&tcmRotate) { T.rotateZ (rotate.Calculate(t)*t); xform.mulA_43 (T); } if (tcm&tcmScale) { sU = scaleU.Calculate(t); sV = scaleV.Calculate(t); T.scale (sU,sV,1); xform.mulA_43 (T); } if (tcm&tcmScroll) { float u = scrollU.Calculate(t)*t; float v = scrollV.Calculate(t)*t; u*=sU; v*=sV; tc_trans (T, u, v ); xform.mulA_43 (T); } tc_trans (T, -0.5f, -0.5f ); xform.mulB_43 (T); } return; case modeS_refl: { float Ux= .5f*Device.mView._11, Uy= .5f*Device.mView._21, Uz= .5f*Device.mView._31, Uw = .5f; float Vx=-.5f*Device.mView._12, Vy=-.5f*Device.mView._22, Vz=-.5f*Device.mView._32, Vw = .5f; xform._11=Ux; xform._12=Vx; xform._13=0; xform._14=0; xform._21=Uy; xform._22=Vy; xform._23=0; xform._24=0; xform._31=Uz; xform._32=Vz; xform._33=0; xform._34=0; xform._41=Uw; xform._42=Vw; xform._43=0; xform._44=0; } return; case modeC_refl: { Fmatrix M = Device.mView; M._41 = 0.f; M._42 = 0.f; M._43 = 0.f; xform.invert(M); } return; default: return; } }