void CBulletManager::Render () { #ifdef DEBUG //0-рикошет //1-застрявание пули в материале //2-пробивание материала if(g_bDrawBulletHit){ extern FvectorVec g_hit[]; FvectorIt it; u32 C[3] = {0xffff0000,0xff00ff00,0xff0000ff}; RCache.set_xform_world(Fidentity); for(int i=0; i<3; ++i) for(it=g_hit[i].begin();it!=g_hit[i].end();++it){ Level().debug_renderer().draw_aabb(*it,0.01f,0.01f,0.01f,C[i]); } } #endif if(m_BulletsRendered.empty()) return; u32 vOffset = 0 ; u32 bullet_num = m_BulletsRendered.size(); FVF::LIT *verts = (FVF::LIT *) RCache.Vertex.Lock((u32)bullet_num*8, tracers.sh_Geom->vb_stride, vOffset); FVF::LIT *start = verts; for(BulletVecIt it = m_BulletsRendered.begin(); it!=m_BulletsRendered.end(); it++){ SBullet* bullet = &(*it); if(!bullet->flags.allow_tracer) continue; if (!bullet->flags.skipped_frame) continue; float length = bullet->speed*float(m_dwStepTime)/1000.f;//dist.magnitude(); if(length<m_fTracerLengthMin) continue; if(length>m_fTracerLengthMax) length = m_fTracerLengthMax; float width = m_fTracerWidth; float dist2segSqr = SqrDistancePointToSegment(Device.vCameraPosition, bullet->pos, Fvector().mul(bullet->dir, length)); //--------------------------------------------- float MaxDistSqr = 1.0f; float MinDistSqr = 0.09f; if (dist2segSqr < MaxDistSqr) { if (dist2segSqr < MinDistSqr) dist2segSqr = MinDistSqr; width *= _sqrt(dist2segSqr/MaxDistSqr);//*MaxDistWidth/0.08f; } if (Device.vCameraPosition.distance_to_sqr(bullet->pos)<(length*length)) { length = Device.vCameraPosition.distance_to(bullet->pos) - 0.3f; } /* //--------------------------------------------- Fvector vT, v0, v1; vT.mad(Device.vCameraPosition, Device.vCameraDirection, _sqrt(dist2segSqr)); v0.mad(vT, Device.vCameraTop, width*.5f); v1.mad(vT, Device.vCameraTop, -width*.5f); Fvector v0r, v1r; Device.mFullTransform.transform(v0r, v0); Device.mFullTransform.transform(v1r, v1); float ViewWidth = v1r.distance_to(v0r); */ // float dist = _sqrt(dist2segSqr); // Msg("dist - [%f]; ViewWidth - %f, [%f]", dist, ViewWidth, ViewWidth*float(Device.dwHeight)); // Msg("dist - [%f]", dist); //--------------------------------------------- Fvector center; center.mad (bullet->pos, bullet->dir, -length*.5f); tracers.Render (verts, bullet->pos, center, bullet->dir, length, width, bullet->m_u8ColorID); } u32 vCount = (u32)(verts-start); RCache.Vertex.Unlock (vCount,tracers.sh_Geom->vb_stride); if (vCount) { RCache.set_CullMode (CULL_NONE); RCache.set_xform_world (Fidentity); RCache.set_Shader (tracers.sh_Tracer); RCache.set_Geometry (tracers.sh_Geom); RCache.Render (D3DPT_TRIANGLELIST,vOffset,0,vCount,0,vCount/2); RCache.set_CullMode (CULL_CCW); } }
void SSceneSummary::STextureInfo::FillProp (PropItemVec& items, LPCSTR main_pref, u32& mem_use) { if (file_name.size()){ int tex_mem = info.MemoryUsage(*file_name); mem_use += tex_mem; AnsiString pref = PrepareKey(AnsiString(main_pref).c_str(),*file_name).c_str(); PropValue* V=0; V=PHelper().CreateChoose(items,PrepareKey(pref.c_str(),"Texture"), &file_name, smTexture); V->Owner()->Enable(FALSE); PHelper().CreateCaption(items,PrepareKey(pref.c_str(),"Format"), info.FormatString()); PHelper().CreateCaption(items,PrepareKey(pref.c_str(),"Size"), shared_str().printf("%d x %d x %s",info.width,info.height,info.HasAlpha()?"32b":"24b")); PHelper().CreateCaption(items,PrepareKey(pref.c_str(),"Memory Usage"), shared_str().printf("%d Kb",iFloor(tex_mem/1024))); PHelper().CreateCaption(items,PrepareKey(pref.c_str(),"Effective Area"),shared_str().printf("%3.2f m^2",effective_area)); PHelper().CreateCaption(items,PrepareKey(pref.c_str(),"Pixel Density"), shared_str().printf("%3.2f p/m",_sqrt((pixel_area*info.width*info.height)/effective_area))); /* //. убрал из-за кол-ва > 4096 AnsiString tmp = "on demand"; for (objinf_map_it o_it=objects.begin(); o_it!=objects.end(); o_it++){ tmp += AnsiString().sprintf("%s%s[%d*%3.2f]",tmp.Length()?"; ":"",o_it->first.c_str(),o_it->second.ref_count,o_it->second.area); } PHelper().CreateCaption(items,PrepareKey(pref.c_str(),"Objects"), tmp.c_str()); */ if (info.flags.is_any(STextureParams::flDiffuseDetail|STextureParams::flBumpDetail)){ if (0!=info.detail_name.size()){ V=PHelper().CreateChoose(items,PrepareKey(pref.c_str(),"Detail Texture"), &info.detail_name,smTexture); V->Owner()->Enable(FALSE); PHelper().CreateCaption(items,PrepareKey(pref.c_str(), "Detail Scale"), shared_str().printf("%3.2f",info.detail_scale)); }else{ PHelper().CreateCaption(items,PrepareKey(pref.c_str(), "Detail Texture"), "INVALID"); ELog.Msg(mtError,"Empty details on texture: '%s'",*file_name); } } if (info.bump_mode==STextureParams::tbmUse){ if (0!=info.bump_name.size()){ V=PHelper().CreateChoose(items,PrepareKey(pref.c_str(),"Bump Texture"), &info.bump_name,smTexture); V->Owner()->Enable(FALSE); }else{ PHelper().CreateCaption(items,PrepareKey(pref.c_str(), "Bump Texture"), "INVALID"); ELog.Msg(mtError,"Empty bump on texture: '%s'",*file_name); } } ButtonValue* B = PHelper().CreateButton(items,PrepareKey(pref.c_str(),"Highlight Texture"), "Select,Density =,Density +,Clear", 0); B->OnBtnClickEvent.bind(this,&SSceneSummary::STextureInfo::OnHighlightClick); B->tag = (int)(*file_name); } }
// length of a vector // float norm(float v[3]) { return _sqrt(DOT(v,v)); }
void objpose(mat33_t *R, vec3_t *t, int *it, real_t *obj_err, real_t *img_err, bool calc_img_err, const vec3_t *_P, const vec3_t *Qp, const options_t options, const int n) { int i, j; //vec3_array P(_P.begin(),_P.end()); vec3_t P[n]; memcpy(&*P, _P, n*sizeof(vec3_t)); //const int n = (unsigned int) P.size(); vec3_t pbar; vec3_array_sum(&pbar, &*P, n); vec3_div(&pbar, (real_t)(n)); vec3_array_sub(&*P, &pbar, n); //vec3_array Q(Qp.begin(),Qp.end()); vec3_t Q[n]; memcpy(&*Q, Qp, n*sizeof(vec3_t)); vec3_t ones; ones.v[0] = 1; ones.v[1] = 1; ones.v[2] = 1; const bool mask_z[3] = {0,0,1}; vec3_array_set(&*Q, &ones, mask_z, n); //mat33_array F; //F.resize(n); mat33_t F[n]; vec3_t V; for(i=0; i<n; i++) { V.v[0] = Q[i].v[0] / Q[i].v[2]; V.v[1] = Q[i].v[1] / Q[i].v[2]; V.v[2] = 1.0; mat33_t _m; vec3_mul_vec3trans(&_m, &V, &V); mat33_div(&_m, vec3trans_mul_vec3(&V,&V)); F[i] = _m; } mat33_t tFactor; mat33_t _m1,_m2,_m3; mat33_eye(&_m1); mat33_array_sum(&_m2, &*F, n); mat33_div(&_m2, (real_t)(n)); mat33_sub_mat2(&_m3, &_m1, &_m2); mat33_inv(&tFactor, &_m3); mat33_div(&tFactor, (real_t)(n)); *it = 0; int initR_approximate = mat33_all_zeros(&options.initR); mat33_t Ri; vec3_t ti; //vec3_array Qi; //Qi.resize(n); vec3_t Qi[n]; real_t old_err = 0.0, new_err = 0.0; // ---------------------------------------------------------------------------------------- if(initR_approximate == 0) { mat33_copy(&Ri, &options.initR); vec3_t _sum; vec3_t _v1, _v2; mat33_t _m1,_m2; vec3_clear(&_sum); for(j=0; j<n; j++) { mat33_eye(&_m1); mat33_sub_mat2(&_m2, &F[j], &_m1); vec3_mult_mat(&_v1, &Ri, &P[j]); vec3_mult_mat(&_v2, &_m2, &_v1); vec3_add_vec(&_sum, &_v2); } vec3_mult_mat(&ti,&tFactor,&_sum); xform(&*Qi, &*P, &Ri, &ti, n); old_err = 0; vec3_t _v; for(j=0; j<n; j++) { mat33_eye(&_m1); mat33_sub_mat2(&_m2, &F[j], &_m1); vec3_mult_mat(&_v, &_m2, &Qi[j]); old_err += vec3_dot(&_v, &_v); } // ---------------------------------------------------------------------------------------- } else { abskernel(&Ri, &ti, &*Qi, &old_err, &*P, &*Q, &*F, &tFactor, n); *it = 1; } // ---------------------------------------------------------------------------------------- abskernel(&Ri, &ti, &*Qi, &new_err, &*P, &*Qi, &*F, &tFactor, n); *it = *it + 1; while((_abs((old_err-new_err)/old_err) > options.tol) && (new_err > options.epsilon) && (options.max_iter == 0 || *it < options.max_iter)) { old_err = new_err; abskernel(&Ri, &ti, &*Qi, &new_err, &*P, &*Qi, &*F, &tFactor, n); *it = *it + 1; } mat33_copy(R, &Ri); vec3_copy(t, &ti); *obj_err = _sqrt(new_err/(real_t)(n)); if(calc_img_err == 1) { //vec3_array Qproj; //Qproj.resize(n); vec3_t Qproj[n]; xformproj(&*Qproj, &*P, &Ri, &ti, n); *img_err = 0; vec3_t _v; for(j=0; j<n; j++) { vec3_sub_vec2(&_v, &Qproj[j], &Qp[j]); *img_err += vec3_dot(&_v, &_v); } *img_err = _sqrt(*img_err/(real_t)(n)); } if(t->v[2] < 0) { mat33_mult(R, -1.0); vec3_mult(t, -1.0); } vec3_t _ts; vec3_mult_mat(&_ts, &Ri, &pbar); vec3_sub_vec(t, &_ts); }
void CRenderTarget::accum_direct (u32 sub_phase) { // Choose normal code-path or filtered phase_accumulator (); if (RImplementation.o.sunfilter) { accum_direct_f (sub_phase); return ; } // *** assume accumulator setted up *** light* fuckingsun = (light*)RImplementation.Lights.sun_adapted._get() ; // Common calc for quad-rendering u32 Offset; u32 C = color_rgba (255,255,255,255); float _w = float (Device.dwWidth); float _h = float (Device.dwHeight); Fvector2 p0,p1; p0.set (.5f/_w, .5f/_h); p1.set ((_w+.5f)/_w, (_h+.5f)/_h ); float d_Z = EPS_S, d_W = 1.f; // Common constants (light-related) 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 (); // Perform masking (only once - on the first/near phase) RCache.set_CullMode (CULL_NONE ); if (SE_SUN_NEAR==sub_phase) //. { // Fill vertex buffer FVF::TL* pv = (FVF::TL*) RCache.Vertex.Lock (4,g_combine->vb_stride,Offset); pv->set (EPS, float(_h+EPS), d_Z, d_W, C, p0.x, p1.y); pv++; pv->set (EPS, EPS, d_Z, d_W, C, p0.x, p0.y); pv++; pv->set (float(_w+EPS), float(_h+EPS), d_Z, d_W, C, p1.x, p1.y); pv++; pv->set (float(_w+EPS), EPS, d_Z, d_W, C, p1.x, p0.y); pv++; RCache.Vertex.Unlock (4,g_combine->vb_stride); RCache.set_Geometry (g_combine); // setup float intensity = 0.3f*fuckingsun->color.r + 0.48f*fuckingsun->color.g + 0.22f*fuckingsun->color.b; Fvector dir = L_dir; dir.normalize().mul (- _sqrt(intensity+EPS)); RCache.set_Element (s_accum_mask->E[SE_MASK_DIRECT]); // masker RCache.set_c ("Ldynamic_dir", dir.x,dir.y,dir.z,0 ); // if (stencil>=1 && aref_pass) stencil = light_id RCache.set_ColorWriteEnable (FALSE ); RCache.set_Stencil (TRUE,D3DCMP_LESSEQUAL,dwLightMarkerID,0x01,0xff,D3DSTENCILOP_KEEP,D3DSTENCILOP_REPLACE,D3DSTENCILOP_KEEP); RCache.Render (D3DPT_TRIANGLELIST,Offset,0,4,0,2); } // recalculate d_Z, to perform depth-clipping Fvector center_pt; center_pt.mad (Device.vCameraPosition,Device.vCameraDirection,ps_r2_sun_near); Device.mFullTransform.transform(center_pt) ; d_Z = center_pt.z ; // nv-stencil recompression if (RImplementation.o.nvstencil && (SE_SUN_NEAR==sub_phase)) u_stencil_optimize(); //. driver bug? // Perform lighting { phase_accumulator () ; RCache.set_CullMode (CULL_NONE); RCache.set_ColorWriteEnable () ; // texture adjustment matrix float fTexelOffs = (.5f / float(RImplementation.o.smapsize)); float fRange = (SE_SUN_NEAR==sub_phase)?ps_r2_sun_depth_near_scale:ps_r2_sun_depth_far_scale; float fBias = (SE_SUN_NEAR==sub_phase)?ps_r2_sun_depth_near_bias:ps_r2_sun_depth_far_bias; Fmatrix m_TexelAdjust = { 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, fRange, 0.0f, 0.5f + fTexelOffs, 0.5f + fTexelOffs, fBias, 1.0f }; // compute xforms FPU::m64r (); Fmatrix xf_invview; xf_invview.invert (Device.mView) ; // shadow xform Fmatrix m_shadow; { Fmatrix xf_project; xf_project.mul (m_TexelAdjust,fuckingsun->X.D.combine); m_shadow.mul (xf_project, xf_invview); // tsm-bias if ( (SE_SUN_FAR == sub_phase) && (RImplementation.o.HW_smap) ) { Fvector bias; bias.mul (L_dir,ps_r2_sun_tsm_bias); Fmatrix bias_t; bias_t.translate(bias); m_shadow.mulB_44 (bias_t); } FPU::m24r (); } // clouds xform Fmatrix m_clouds_shadow; { static float w_shift = 0; Fmatrix m_xform; Fvector direction = fuckingsun->direction ; float w_dir = g_pGamePersistent->Environment().CurrentEnv.wind_direction ; //float w_speed = g_pGamePersistent->Environment().CurrentEnv.wind_velocity ; Fvector normal ; normal.setHP(w_dir,0); w_shift += 0.003f*Device.fTimeDelta; Fvector position; position.set(0,0,0); m_xform.build_camera_dir (position,direction,normal) ; Fvector localnormal;m_xform.transform_dir(localnormal,normal); localnormal.normalize(); m_clouds_shadow.mul (m_xform,xf_invview) ; m_xform.scale (0.002f,0.002f,1.f) ; m_clouds_shadow.mulA_44 (m_xform) ; m_xform.translate (localnormal.mul(w_shift)) ; m_clouds_shadow.mulA_44 (m_xform) ; } // Make jitter texture Fvector2 j0,j1; float scale_X = float(Device.dwWidth) / float(TEX_jitter); //float scale_Y = float(Device.dwHeight)/ float(TEX_jitter); float offset = (.5f / float(TEX_jitter)); j0.set (offset,offset); j1.set (scale_X,scale_X).add(offset); // Fill vertex buffer FVF::TL2uv* pv = (FVF::TL2uv*) RCache.Vertex.Lock (4,g_combine_2UV->vb_stride,Offset); pv->set (EPS, float(_h+EPS), d_Z, d_W, C, p0.x, p1.y, j0.x, j1.y); pv++; pv->set (EPS, EPS, d_Z, d_W, C, p0.x, p0.y, j0.x, j0.y); pv++; pv->set (float(_w+EPS), float(_h+EPS), d_Z, d_W, C, p1.x, p1.y, j1.x, j1.y); pv++; pv->set (float(_w+EPS), EPS, d_Z, d_W, C, p1.x, p0.y, j1.x, j0.y); pv++; RCache.Vertex.Unlock (4,g_combine_2UV->vb_stride); RCache.set_Geometry (g_combine_2UV); // setup RCache.set_Element (s_accum_direct->E[sub_phase]); RCache.set_c ("Ldynamic_dir", L_dir.x,L_dir.y,L_dir.z,0 ); RCache.set_c ("Ldynamic_color", L_clr.x,L_clr.y,L_clr.z,L_spec ); RCache.set_c ("m_shadow", m_shadow ); RCache.set_c ("m_sunmask", m_clouds_shadow ); // nv-DBT if (RImplementation.o.nvdbt && ps_r2_ls_flags.test(R2FLAG_USE_NVDBT)) { float zMin,zMax; if (SE_SUN_NEAR==sub_phase) { zMin = 0; zMax = ps_r2_sun_near; } else { extern float OLES_SUN_LIMIT_27_01_07; zMin = ps_r2_sun_near; zMax = OLES_SUN_LIMIT_27_01_07; } center_pt.mad(Device.vCameraPosition,Device.vCameraDirection,zMin); Device.mFullTransform.transform (center_pt); zMin = center_pt.z ; center_pt.mad(Device.vCameraPosition,Device.vCameraDirection,zMax); Device.mFullTransform.transform (center_pt); zMax = center_pt.z ; // enable cheat HW.pDevice->SetRenderState(D3DRS_ADAPTIVETESS_X,MAKEFOURCC('N','V','D','B')); HW.pDevice->SetRenderState(D3DRS_ADAPTIVETESS_Z,*(DWORD*)&zMin); HW.pDevice->SetRenderState(D3DRS_ADAPTIVETESS_W,*(DWORD*)&zMax); // z-test always HW.pDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); HW.pDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); } // Fetch4 : enable if (RImplementation.o.HW_smap_FETCH4) { //. we hacked the shader to force smap on S0 # define FOURCC_GET4 MAKEFOURCC('G','E','T','4') HW.pDevice->SetSamplerState ( 0, D3DSAMP_MIPMAPLODBIAS, FOURCC_GET4 ); } // setup stencil RCache.set_Stencil (TRUE,D3DCMP_LESSEQUAL,dwLightMarkerID,0xff,0x00); RCache.Render (D3DPT_TRIANGLELIST,Offset,0,4,0,2); // Fetch4 : disable if (RImplementation.o.HW_smap_FETCH4) { //. we hacked the shader to force smap on S0 # define FOURCC_GET1 MAKEFOURCC('G','E','T','1') HW.pDevice->SetSamplerState ( 0, D3DSAMP_MIPMAPLODBIAS, FOURCC_GET1 ); } // disable depth bounds if (RImplementation.o.nvdbt && ps_r2_ls_flags.test(R2FLAG_USE_NVDBT)) HW.pDevice->SetRenderState(D3DRS_ADAPTIVETESS_X,0); } }
/* #include "MathUtils.h" enum EBoxSideNearestPointCode { box_inside , side_invisible , on_side , on_edge , on_vertex }; EBoxSideNearestPointCode GetNearestPointOnOBBSide(const Fmatrix &xform,const Fvector ¢er,const Fvector &sides,u16 side,const Fvector &p,Fvector &point) { //to plane dist const Fvector &norm=xform[side]; u16 side1=(side+1)%3,side2=(side+2)%3; float h=sides[side],h1=sides[side1],h2=sides[side2]; //Fvector vdiffc;vdiffc.sub(center,p); float c_prg=norm.dotproduct(center); float p_prg=norm.dotproduct(p); float diffc=c_prg-p_prg;norm.dotproduct(vdiffc); float diffs; if(diffc<0.f) { diffs=diffc+h; point.set(norm); point.mul(diffs); point.add(p); Fvector d;d.sub(center,point); bool inside1 =_abs(d[side1])<h1; bool inside2 =_abs(d[side2])<h2; if(diffs>0.f) { if(inside1&&inside2) return box_inside; else return side_invisible; } else { if(inside1&&inside2) return on_side; else if(inside1) { float dd=h2-_abs(d[side2]); Fvector s;s.set(xform[side2]);s. } } } float diffs=diffc<0.f ? diffc+h : diffc-h; } */ IC bool RAYvsCYLINDER(const Fcylinder& c_cylinder, const Fvector &S, const Fvector &D, float &R, BOOL bCull) { const float &r=c_cylinder.m_radius; float h=c_cylinder.m_height/2.f; const Fvector& p=S; const Fvector& dir=D; const Fvector &c=c_cylinder.m_center; const Fvector &ax=c_cylinder.m_direction; //c.set(-IM.c.dotproduct(IM.i),-IM.c.dotproduct(IM.j),-IM.c.dotproduct(IM.k)); //Fvector ax;ax.set(IM.i.z,IM.j.z,IM.k.z);//?? ////////////////////////////////////////////////////////////// Fvector v; v .sub (c,p) ; float cs =dir .dotproduct (ax) ; float Lc =v .dotproduct (ax) ; float Lr =v .dotproduct (dir) ; //////////////////////////////////////////////// float sq_cos=cs*cs; float sq_sin=1-sq_cos; float v_smag=v.square_magnitude(); const float sq_r=r*r; if(sq_sin<EPS)//paralel { float tr1,tr2 ; float sq_dist=v_smag-Lr*Lr;// if(sq_dist>sq_r) return false; float r_dist=_sqrt(sq_r-sq_dist)+h; tr1=Lr-r_dist; if(tr1>R) return false;// if(tr1<0.f) { if(bCull)return false; else{ tr2=Lr+r_dist; if(tr2<0.f) return false;// if(tr2<R) { R=tr2; return true; } return false; } } R=tr1; return true; } if(sq_cos<EPS) { float tr1,tr2 ; //perp// float abs_c_dist=_abs(Lc); if(abs_c_dist>h+r)return false; float sq_dist=v_smag-Lr*Lr-Lc*Lc; if(sq_dist>sq_r) return false; float lc_h=abs_c_dist-h; if(lc_h>0.f) { float sq_sphere_dist=lc_h*lc_h+sq_dist*sq_dist; if(sq_sphere_dist>sq_r)return false; float diff=_sqrt(sq_r-sq_sphere_dist); tr1=Lr-diff; if(tr1>R) return false;// if(tr1<0.f) { if(bCull)return false; else{ tr2=Lr+diff; if(tr2<0.f) return false;// if(tr2<R) { R=tr2; return true; } return false; } } } float diff=_sqrt(sq_r-sq_dist); tr1=Lr-diff; if(tr1>R) return false;// if(tr1<0.f) { if(bCull)return false; else{ tr2=Lr+diff; if(tr2<0.f) return false;// if(tr2<R) { R=tr2; return true; } return false; } } R=tr1; return true; } ////////////////////////////////////////////////// float tr1,tr2 ; float r_sq_sin =1.f/sq_sin ; float tr =(Lr-cs*Lc)*r_sq_sin ; float tc =(cs*Lr-Lc)*r_sq_sin ; //more frequent separation - axes dist> radius //v^2+tc^2+tr^2-2*(cos*tc*tr-Lc*tc+Lr*tr) float sq_nearest_dist=v_smag+tr*tr+tc*tc-2*(cs*tc*tr-Lc*tc+Lr*tr); if(sq_nearest_dist>sq_r) return false; //float max_c_diff=//; float sq_horde=(sq_r-sq_nearest_dist) ; //float horde=_sqrt(sq_horde) ; float sq_c_diff=sq_horde*sq_cos*r_sq_sin ; float c_diff=_sqrt(sq_c_diff) ;//ccc float cp1=tc-c_diff ; float cp2=tc+c_diff ; //cp1<cp2 if(cp1>h) { //sphere float tc_h=tc-h;//!! hi (=)/; float sq_sphere_dist=sq_sin*tc_h*tc_h; if(sq_sphere_dist>sq_horde)return false; float tr_c=tr-tc_h*cs;// float diff=_sqrt(sq_horde-sq_sphere_dist); tr1=tr_c-diff; if(tr1>R) return false;// if(tr1<0.f) { if(bCull)return false; else{ tr2=tr_c+diff; if(tr2<0.f) return false;// if(tr2<R){R=tr2;return true;} } } R=tr1 ; return true ; } if(cp2<-h) { //sphere lo /(=) float tc_h=tc+h;//!! float sq_sphere_dist=sq_sin*tc_h*tc_h; if(sq_sphere_dist>sq_horde)return false; float tr_c=tr-tc_h*cs;//!! float diff=_sqrt(sq_horde-sq_sphere_dist); tr1=tr_c-diff; if(tr1>R) return false;// if(tr1<0.f) { if(bCull)return false; else{ tr2=tr_c+diff; if(tr2<0.f) return false;// if(tr2<R){R=tr2;return true;} } } R=tr1 ; return true ; } //////////////////////////////////////////////////////////////// if(cs>0.f) { if(cp1 >-h) { if(cp2<h) { //cylinder (=/=) float diff=c_diff/cs; tr1=tr-diff; if(tr1>R) return false;// if(tr1<0.f) { if(bCull)return false; else{ tr2=tr+diff; if(tr2<0.f) return false;// if(tr2<R){R=tr2;return true;} } } R=tr1 ; return true ; } else{ //mixed//cyl hi sphere (=/) float diff=c_diff/cs ; tr1=tr-diff ; if(tr1>R) return false;// if(tr1<0.f) { if(bCull)return false; else{ float tc_h=tc-h ; float sq_sphere_dist=sq_sin*tc_h*tc_h; //if(sq_sphere_dist>sq_horde)return false ; float tr_c=tr-tc_h*cs ; float diff=_sqrt(sq_horde-sq_sphere_dist) ; tr2=tr_c+diff ; if(tr2<0.f) return false ;// if(tr2<R){R=tr2;return true;} } } R=tr1 ; return true ; } }else//cp1<=-h { if(cp2<h) { //mixed//lo sphere cyl (/=) float tc_h=tc+h ;//(tc-(-h)) float sq_sphere_dist=sq_sin*tc_h*tc_h; //if(sq_sphere_dist>sq_horde)return false; float diff=_sqrt(sq_horde-sq_sphere_dist) ; float tr_c=tr-tc_h*cs ; tr1=tr_c-diff ; if(tr1>R) return false ;// if(tr1<0.f) { if(bCull)return false; else{ float diff=c_diff/cs ; tr2=tr+diff ; if(tr2<0.f) return false ;// if(tr2<R){R=tr2;return true;} } } R=tr1 ; return true ; }else { //-(--)- //sphere lo&&hi ///////////////////////////////////////////// float tc_h=tc+h ; float tr_c=tr-tc_h*cs ; float diff=_sqrt(sq_horde-sq_sin*tc_h*tc_h) ; tr1=tr_c-diff ; if(tr1>R) return false ;// if(tr1<0.f) { if(bCull)return false; else{ float tc_h=tc-h ; float tr_c=tr-tc_h*cs ; float diff=_sqrt(sq_horde-sq_sin*tc_h*tc_h) ; tr2=tr_c+diff ; if(tr2<R){R=tr2;return true;} } } R=tr1 ; return true ; } } } else { if(cp1 >-h) { if(cp2<h) { //cylinder float diff=-c_diff/cs; tr1=tr-diff; if(tr1>R) return false;// if(tr1<0.f) { if(bCull)return false; else{ tr2=tr+diff; if(tr2<0.f) return false;// if(tr2<R){R=tr2;return true;} } } R=tr1 ; return true ; } else{//cp1>-h&&cp2>h float tc_h=tc-h; //hi sphere/cyl float tr_c=tr-tc_h*cs; float diff=_sqrt(sq_horde-sq_sin*tc_h*tc_h); tr1=tr_c-diff; if(tr1>R) return false ;// if(tr1<0.f) { if(bCull)return false; else{ diff=-c_diff/cs; tr2=tr+diff; if(tr2<0.f) return false;// if(tr2<R){R=tr2;return true;} } } R=tr1 ; return true ; } }else//cp1<-h { if(cp2<h) { //cyl/lo sphere float diff=-c_diff/cs; tr1=tr-diff; if(tr1>R) return false ;// if(tr1<0.f) { if(bCull)return false; else{ //mixed//lo float tc_h=tc+h; float tr_c=tr-tc_h*cs; diff=_sqrt(sq_horde-sq_sin*tc_h*tc_h); tr2=tr_c+diff; if(tr2<0.f) return false;// if(tr2<R){R=tr2;return true;} } } R=tr1 ; return true ; }else//cp2>=h { //-(--)- //sphere hi&&lo float tc_h=tc-h ; float tr_c=tr-tc_h*cs ; float diff=_sqrt(sq_horde-sq_sin*tc_h*tc_h) ; tr1=tr_c-diff ; if(tr1>R) return false ;// ///////////////////////////////////////////// if(tr1<0.f) { if(bCull)return false; else{ tc_h=tc+h ; tr_c=tr-tc_h*cs ; diff=_sqrt(sq_horde-sq_sin*tc_h*tc_h) ; tr2=tr_c+diff ; if(tr2<0.f) return false ;// if(tr2<R){R=tr2;return true;} } } R=tr1 ; return true ; } } } }
void CSector::traverse (CFrustum &F, _scissor& R_scissor) { // Register traversal process if (r_marker != PortalTraverser.i_marker) { r_marker = PortalTraverser.i_marker; PortalTraverser.r_sectors.push_back (this); r_frustums.clear (); r_scissors.clear (); } r_frustums.push_back (F); r_scissors.push_back (R_scissor); // Search visible portals and go through them sPoly S,D; for (u32 I=0; I<m_portals.size(); I++) { if (m_portals[I]->marker == PortalTraverser.i_marker) continue; CPortal* PORTAL = m_portals[I]; CSector* pSector; // Select sector (allow intersecting portals to be finely classified) if (PORTAL->bDualRender) { pSector = PORTAL->getSector (this); } else { pSector = PORTAL->getSectorBack (PortalTraverser.i_vBase); if (pSector==this) continue; if (pSector==PortalTraverser.i_start) continue; } // Early-out sphere if (!F.testSphere_dirty(PORTAL->S.P,PORTAL->S.R)) continue; // SSA (if required) if (PortalTraverser.i_options&CPortalTraverser::VQ_SSA) { Fvector dir2portal; dir2portal.sub (PORTAL->S.P, PortalTraverser.i_vBase); float R = PORTAL->S.R ; float distSQ = dir2portal.square_magnitude(); float ssa = R*R/distSQ; dir2portal.div (_sqrt(distSQ)); ssa *= _abs(PORTAL->P.n.dotproduct(dir2portal)); if (ssa<r_ssaDISCARD) continue; if (PortalTraverser.i_options&CPortalTraverser::VQ_FADE) { if (ssa<r_ssaLOD_A) PortalTraverser.fade_portal (PORTAL,ssa); if (ssa<r_ssaLOD_B) continue ; } } // Clip by frustum svector<Fvector,8>& POLY = PORTAL->getPoly(); S.assign (&*POLY.begin(),POLY.size()); D.clear(); sPoly* P = F.ClipPoly(S,D); if (0==P) continue; // Scissor and optimized HOM-testing _scissor scissor ; if (PortalTraverser.i_options&CPortalTraverser::VQ_SCISSOR && (!PORTAL->bDualRender)) { // Build scissor rectangle in projection-space Fbox2 bb; bb.invalidate(); float depth = flt_max; sPoly& p = *P; for (u32 vit=0; vit<p.size(); vit++) { Fvector4 t; Fmatrix& M = PortalTraverser.i_mXFORM_01; Fvector& v = p[vit]; t.x = v.x*M._11 + v.y*M._21 + v.z*M._31 + M._41; t.y = v.x*M._12 + v.y*M._22 + v.z*M._32 + M._42; t.z = v.x*M._13 + v.y*M._23 + v.z*M._33 + M._43; t.w = v.x*M._14 + v.y*M._24 + v.z*M._34 + M._44; t.mul (1.f/t.w); if (t.x < bb.min.x) bb.min.x = t.x; if (t.x > bb.max.x) bb.max.x = t.x; if (t.y < bb.min.y) bb.min.y = t.y; if (t.y > bb.max.y) bb.max.y = t.y; if (t.z < depth) depth = t.z; } // Msg ("bb(%s): (%f,%f)-(%f,%f), d=%f", PORTAL->bDualRender?"true":"false",bb.min.x, bb.min.y, bb.max.x, bb.max.y,depth); if (depth<EPS) { scissor = R_scissor; // Cull by HOM (slower algo) if ( (PortalTraverser.i_options&CPortalTraverser::VQ_HOM) && (!RImplementation.HOM.visible(*P)) ) continue; } else { // perform intersection (this is just to be sure, it is probably clipped in 3D already) if (bb.min.x > R_scissor.min.x) scissor.min.x = bb.min.x; else scissor.min.x = R_scissor.min.x; if (bb.min.y > R_scissor.min.y) scissor.min.y = bb.min.y; else scissor.min.y = R_scissor.min.y; if (bb.max.x < R_scissor.max.x) scissor.max.x = bb.max.x; else scissor.max.x = R_scissor.max.x; if (bb.max.y < R_scissor.max.y) scissor.max.y = bb.max.y; else scissor.max.y = R_scissor.max.y; scissor.depth = depth; // Msg ("scissor: (%f,%f)-(%f,%f)", scissor.min.x, scissor.min.y, scissor.max.x, scissor.max.y); // Check if box is non-empty if (scissor.min.x >= scissor.max.x) continue; if (scissor.min.y >= scissor.max.y) continue; // Cull by HOM (faster algo) if ( (PortalTraverser.i_options&CPortalTraverser::VQ_HOM) && (!RImplementation.HOM.visible(scissor,depth)) ) continue; } } else { scissor = R_scissor; // Cull by HOM (slower algo) if ( (PortalTraverser.i_options&CPortalTraverser::VQ_HOM) && (!RImplementation.HOM.visible(*P)) ) continue; } // Create _new_ frustum and recurse CFrustum Clip; Clip.CreateFromPortal (P, PORTAL->P.n, PortalTraverser.i_vBase,PortalTraverser.i_mXFORM); PORTAL->marker = PortalTraverser.i_marker; PORTAL->bDualRender = FALSE; pSector->traverse (Clip,scissor); } }
int dcTriListCollider::dSortedTriCyl ( const dReal* triSideAx0,const dReal* triSideAx1, const dReal* triAx, //const dReal* v0, //const dReal* v1, //const dReal* v2, CDB::TRI* T, dReal dist, dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip ) { VERIFY (dGeomGetClass(o1)== dCylinderClassUser); const dReal *R = dGeomGetRotation(o1); const dReal* p=dGeomGetPosition(o1); dReal radius; dReal hlz; dGeomCylinderGetParams(o1,&radius,&hlz); hlz/=2.f; // find number of contacts requested int maxc = flags & NUMC_MASK; if (maxc < 1) maxc = 1; if (maxc > 3) maxc = 3; // no more than 3 contacts per box allowed dReal signum, outDepth,cos1,sin1; //////////////////////////////////////////////////////////////////////////// //sepparation along tri plane normal;/////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //cos0=dDOT14(triAx,R+0); cos1=dFabs(dDOT14(triAx,R+1)); //cos2=dDOT14(triAx,R+2); //sin1=_sqrt(cos0*cos0+cos2*cos2); //////////////////////// //another way ////////// cos1=cos1<REAL(1.) ? cos1 : REAL(1.); //cos1 may slightly exeed 1.f sin1=_sqrt(REAL(1.)-cos1*cos1); ////////////////////////////// dReal sidePr=cos1*hlz+sin1*radius; if(dist>0.f) return 0; dReal depth=sidePr-dist; outDepth=depth; signum=-1.f; int code=0; if(depth<0.f) return 0; dVector3 norm; unsigned int ret=0; dVector3 pos; if(code==0){ norm[0]=triAx[0]*signum; norm[1]=triAx[1]*signum; norm[2]=triAx[2]*signum; dReal Q1 = signum*dDOT14(triAx,R+0); dReal Q2 = signum*dDOT14(triAx,R+1); dReal Q3 = signum*dDOT14(triAx,R+2); dReal factor =_sqrt(Q1*Q1+Q3*Q3); dReal C1,C3; dReal centerDepth;//depth in the cirle centre if(factor>0.f) { C1=Q1/factor; C3=Q3/factor; } else { C1=1.f; C3=0.f; } dReal A1 = radius * C1;//cosinus dReal A2 = hlz*Q2; dReal A3 = radius * C3;//sinus if(factor>0.f) centerDepth=outDepth-A1*Q1-A3*Q3; else centerDepth=outDepth; pos[0]=p[0]; pos[1]=p[1]; pos[2]=p[2]; pos[0]+= A2>0 ? hlz*R[1]:-hlz*R[1]; pos[1]+= A2>0 ? hlz*R[5]:-hlz*R[5]; pos[2]+= A2>0 ? hlz*R[9]:-hlz*R[9]; ret=0; contact->pos[0] = pos[0]+A1*R[0]+A3*R[2]; contact->pos[1] = pos[1]+A1*R[4]+A3*R[6]; contact->pos[2] = pos[2]+A1*R[8]+A3*R[10]; { contact->depth = outDepth; ret=1; } if(dFabs(Q2)>M_SQRT1_2){ A1=(-C1*M_COS_PI_3-C3*M_SIN_PI_3)*radius; A3=(-C3*M_COS_PI_3+C1*M_SIN_PI_3)*radius; CONTACT(contact,ret*skip)->pos[0]=pos[0]+A1*R[0]+A3*R[2]; CONTACT(contact,ret*skip)->pos[1]=pos[1]+A1*R[4]+A3*R[6]; CONTACT(contact,ret*skip)->pos[2]=pos[2]+A1*R[8]+A3*R[10]; CONTACT(contact,ret*skip)->depth=centerDepth+Q1*A1+Q3*A3; if(CONTACT(contact,ret*skip)->depth>0.f)++ret; A1=(-C1*M_COS_PI_3+C3*M_SIN_PI_3)*radius; A3=(-C3*M_COS_PI_3-C1*M_SIN_PI_3)*radius; CONTACT(contact,ret*skip)->pos[0]=pos[0]+A1*R[0]+A3*R[2]; CONTACT(contact,ret*skip)->pos[1]=pos[1]+A1*R[4]+A3*R[6]; CONTACT(contact,ret*skip)->pos[2]=pos[2]+A1*R[8]+A3*R[10]; CONTACT(contact,ret*skip)->depth=centerDepth+Q1*A1+Q3*A3; if(CONTACT(contact,ret*skip)->depth>0.f)++ret; } else { CONTACT(contact,ret*skip)->pos[0]=contact->pos[0]-2.f*(A2>0 ? hlz*R[1]:-hlz*R[1]); CONTACT(contact,ret*skip)->pos[1]=contact->pos[1]-2.f*(A2>0 ? hlz*R[5]:-hlz*R[5]); CONTACT(contact,ret*skip)->pos[2]=contact->pos[2]-2.f*(A2>0 ? hlz*R[9]:-hlz*R[9]); CONTACT(contact,ret*skip)->depth=outDepth-Q2*2.f*A2; if(CONTACT(contact,ret*skip)->depth>0.f)++ret; } } if((int)ret>maxc) ret=(unsigned int)maxc; for (unsigned int i=0; i<ret; ++i) { CONTACT(contact,i*skip)->g1 = const_cast<dxGeom*> (o2); CONTACT(contact,i*skip)->g2 = const_cast<dxGeom*> (o1); CONTACT(contact,i*skip)->normal[0] = norm[0]; CONTACT(contact,i*skip)->normal[1] = norm[1]; CONTACT(contact,i*skip)->normal[2] = norm[2]; SURFACE(contact,i*skip)->mode=T->material; } if(ret&&dGeomGetUserData(o1)->callback)dGeomGetUserData(o1)->callback(T,contact); return ret; }
void CLevelGraph::draw_nodes () { CGameObject* O = smart_cast<CGameObject*> (Level().CurrentEntity()); Fvector POSITION = O->Position(); POSITION.y += 0.5f; // display Fvector P = POSITION; // CPosition Local; // vertex_position (Local,P); u32 ID = O->ai_location().level_vertex_id(); CGameFont* F = HUD().Font().pFontDI; F->SetHeightI (.02f); F->OutI (0.f,0.5f,"%f,%f,%f",VPUSH(P)); // float x,z; // unpack_xz (Local,x,z); // F->Out (0.f,0.55f,"%3d,%4d,%3d -> %d", iFloor(x),iFloor(Local.y()),iFloor(z),u32(ID)); svector<u32,128> linked; { const_iterator i,e; begin (ID,i,e); for(; i != e; ++i) linked.push_back(value(ID,i)); } // render float sc = header().cell_size()/16; float st = 0.98f*header().cell_size()/2; float tt = 0.01f; Fvector DUP; DUP.set(0,1,0); RCache.set_Shader (sh_debug); F->SetColor (color_rgba(255,255,255,255)); // если включён ai_dbg_frustum раскрасить ноды по light // иначе раскрашивать по cover bool b_light = false; ////////////////////////////////////////////////////////////////////////// Fvector min_position,max_position; max_position = min_position = Device.vCameraPosition; min_position.sub(30.f); max_position.add(30.f); CLevelGraph::const_vertex_iterator I, E; if (valid_vertex_position(min_position)) I = std::lower_bound(begin(),end(),vertex_position(min_position).xz()); else I = begin(); if (valid_vertex_position(max_position)) { E = std::upper_bound(begin(),end(),vertex_position(max_position).xz()); if (E != end()) ++E; } else E = end(); ////////////////////////////////////////////////////////////////////////// for ( ; I != E; ++I) { const CLevelGraph::CVertex& N = *I; Fvector PC; PC = vertex_position(N); u32 Nid = vertex_id(I); if (Device.vCameraPosition.distance_to(PC)>30) continue; float sr = header().cell_size(); if (::Render->ViewBase.testSphere_dirty(PC,sr)) { u32 LL = ((b_light) ? iFloor(float(N.light())/15.f*255.f) : iFloor(vertex_cover(I)/4*255.f)); u32 CC = D3DCOLOR_XRGB(0,0,255); u32 CT = D3DCOLOR_XRGB(LL,LL,LL); u32 CH = D3DCOLOR_XRGB(0,128,0); BOOL bHL = FALSE; if (Nid==u32(ID)) { bHL = TRUE; CT = D3DCOLOR_XRGB(0,255,0); } else { for (u32 t=0; t<linked.size(); ++t) { if (linked[t]==Nid) { bHL = TRUE; CT = CH; break; } } } // unpack plane Fplane PL; Fvector vNorm; pvDecompress(vNorm,N.plane()); PL.build (PC,vNorm); // create vertices Fvector v,v1,v2,v3,v4; v.set(PC.x-st,PC.y,PC.z-st); PL.intersectRayPoint(v,DUP,v1); v1.mad(v1,PL.n,tt); // minX,minZ v.set(PC.x+st,PC.y,PC.z-st); PL.intersectRayPoint(v,DUP,v2); v2.mad(v2,PL.n,tt); // maxX,minZ v.set(PC.x+st,PC.y,PC.z+st); PL.intersectRayPoint(v,DUP,v3); v3.mad(v3,PL.n,tt); // maxX,maxZ v.set(PC.x-st,PC.y,PC.z+st); PL.intersectRayPoint(v,DUP,v4); v4.mad(v4,PL.n,tt); // minX,maxZ // render quad RCache.dbg_DrawTRI (Fidentity,v3,v2,v1,CT); RCache.dbg_DrawTRI (Fidentity,v1,v4,v3,CT); // render center Level().debug_renderer().draw_aabb (PC,sc,sc,sc,CC); // render id if (bHL) { Fvector T; Fvector4 S; T.set (PC); T.y+=0.3f; Device.mFullTransform.transform (S,T); if (S.z < 0 || S.z < 0) continue; if (S.x < -1.f || S.x > 1.f || S.y<-1.f || S.x>1.f) continue; F->SetHeightI (0.05f/_sqrt(_abs(S.w))); F->SetColor (0xffffffff); F->OutI (S.x,-S.y,"~%d",Nid); } } } }
void PS::CPEDef::CollisionCutoffOnDraw(PropValue* sender, xr_string& draw_val) { FloatValue* V = dynamic_cast<FloatValue*>(sender); VERIFY(V); draw_sprintf(draw_val,_sqrt(V->GetValue()),V->dec); }
int dcTriListCollider::dTriCyl ( const dReal* v0,const dReal* v1,const dReal* v2, Triangle* T, dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip ) { // VERIFY (skip >= (int)sizeof(dContactGeom)); VERIFY (dGeomGetClass(o1)== dCylinderClassUser); const dReal *R = dGeomGetRotation(o1); const dReal* p=dGeomGetPosition(o1); dReal radius; dReal hlz; dGeomCylinderGetParams(o1,&radius,&hlz); hlz/=2.f; // find number of contacts requested int maxc = flags & NUMC_MASK; if (maxc < 1) maxc = 1; if (maxc > 3) maxc = 3; // no more than 3 contacts per box allowed const dVector3 &triAx=T->norm; dVector3 triSideAx0={T->side0[0],T->side0[1],T->side0[2]}; //{v1[0]-v0[0],v1[1]-v0[1],v1[2]-v0[2]}; dVector3 triSideAx1={T->side1[0],T->side1[1],T->side1[2]}; //{v2[0]-v1[0],v2[1]-v1[1],v2[2]-v1[2]}; dVector3 triSideAx2={v0[0]-v2[0],v0[1]-v2[1],v0[2]-v2[2]}; //dCROSS(triAx,=,triSideAx0,triSideAx1); int code=0; dReal signum, outDepth,cos0,cos1,cos2,sin1; //////////////////////////////////////////////////////////////////////////// //sepparation along tri plane normal;/////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //accurate_normalize(triAx); //cos0=dDOT14(triAx,R+0); cos1=dFabs(dDOT14(triAx,R+1)); //cos2=dDOT14(triAx,R+2); //sin1=_sqrt(cos0*cos0+cos2*cos2); //////////////////////// //another way ////////// cos1=cos1<REAL(1.) ? cos1 : REAL(1.); //cos1 may slightly exeed 1.f sin1=_sqrt(REAL(1.)-cos1*cos1); ////////////////////////////// dReal sidePr=cos1*hlz+sin1*radius; dReal dist=-T->dist; //dDOT(triAx,v0)-dDOT(triAx,p); if(dist>0.f) RETURN0; dReal depth=sidePr-dFabs(dist); outDepth=depth; signum=dist>0.f ? 1.f : -1.f; code=0; if(depth<0.f) RETURN0; dReal depth0,depth1,depth2,dist0,dist1,dist2; bool isPdist0,isPdist1,isPdist2; bool testV0,testV1,testV2; bool sideTestV00,sideTestV01,sideTestV02; bool sideTestV10,sideTestV11,sideTestV12; bool sideTestV20,sideTestV21,sideTestV22; ////////////////////////////////////////////////////////////////////////////// //cylinder axis - one of the triangle vertexes touches cylinder's flat surface ////////////////////////////////////////////////////////////////////////////// dist0=dDOT14(v0,R+1)-dDOT14(p,R+1); dist1=dDOT14(v1,R+1)-dDOT14(p,R+1); dist2=dDOT14(v2,R+1)-dDOT14(p,R+1); isPdist0=dist0>0.f; isPdist1=dist1>0.f; isPdist2=dist2>0.f; depth0=hlz-dFabs(dist0); depth1=hlz-dFabs(dist1); depth2=hlz-dFabs(dist2); testV0=depth0>0.f; testV1=depth1>0.f; testV2=depth2>0.f; if(isPdist0==isPdist1 && isPdist1== isPdist2) //(here and lower) check the tryangle is on one side of the cylinder { if(depth0>depth1) if(depth0>depth2) if(testV0){ if(depth0<outDepth) { signum= isPdist0 ? 1.f : -1.f; outDepth=depth0; code=1; } } else RETURN0; else if(testV2){ if(depth2<outDepth) { outDepth=depth2; signum= isPdist2 ? 1.f : -1.f; code=3; } } else RETURN0; else if(depth1>depth2) if(testV1){ if(depth1<outDepth) { outDepth=depth1; signum= isPdist1 ? 1.f : -1.f; code=2; } } else RETURN0; else if(testV2){ if(depth2<outDepth) { outDepth=depth2; signum= isPdist2 ? 1.f : -1.f; code=2; } } else RETURN0; } dVector3 axis,outAx; dReal posProj; dReal pointDepth=0.f; #define TEST(vx,ox1,ox2,c) \ {\ posProj=dDOT14(v##vx,R+1)-dDOT14(p,R+1);\ \ axis[0]=v##vx[0]-p[0]-R[1]*posProj;\ axis[1]=v##vx[1]-p[1]-R[5]*posProj;\ axis[2]=v##vx[2]-p[2]-R[9]*posProj;\ \ accurate_normalize(axis);\ \ \ dist0=dDOT(v0,axis)-dDOT(p,axis);\ dist1=dDOT(v1,axis)-dDOT(p,axis);\ dist2=dDOT(v2,axis)-dDOT(p,axis);\ \ isPdist0=dist0>0.f;\ isPdist1=dist1>0.f;\ isPdist2=dist2>0.f;\ \ depth0=radius-dFabs(dist0);\ depth1=radius-dFabs(dist1);\ depth2=radius-dFabs(dist2);\ \ sideTestV##vx##0=depth0>0.f;\ sideTestV##vx##1=depth1>0.f;\ sideTestV##vx##2=depth2>0.f;\ \ if(isPdist0==isPdist1 && isPdist1== isPdist2)\ \ {\ if(sideTestV##vx##0||sideTestV##vx##1||sideTestV##vx##2){\ if(!(depth##vx<depth##ox1 || depth##vx<depth##ox2))\ {\ if(depth##vx<outDepth && depth##vx > pointDepth)\ {\ pointDepth=depth##vx;\ signum= isPdist##vx ? 1.f : -1.f;\ outAx[0]=axis[0];\ outAx[1]=axis[1];\ outAx[2]=axis[2];\ code=c;\ }\ }\ }\ else RETURN0;\ \ \ \ }\ } if(testV0) TEST(0,1,2,4) if(testV1 ) TEST(1,2,0,5) //&& sideTestV01 if(testV2 ) TEST(2,0,1,6) //&& sideTestV02 && sideTestV12 #undef TEST dVector3 tpos,pos; if(code>3) outDepth=pointDepth; //deepest vertex axis used if its depth less than outDepth //else{ //bool outV0=!(testV0&&sideTestV00&&sideTestV10&&sideTestV20); //bool outV1=!(testV1&&sideTestV01&&sideTestV11&&sideTestV21); //bool outV2=!(testV2&&sideTestV02&&sideTestV12&&sideTestV22); bool outV0=true; bool outV1=true; bool outV2=true; ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ///crosses between triangle sides and cylinder axis////////////////////////// ///////////////////////////////////////////////////////////////////////////// #define TEST(ax,nx,ox,c) if(cylinderCrossesLine(p,R+1,hlz,v##ax,v##nx,triSideAx##ax,tpos)) {\ dCROSS114(axis,=,triSideAx##ax,R+1);\ accurate_normalize(axis);\ dist##ax=dDOT(v##ax,axis)-dDOT(p,axis);\ dist##ox=dDOT(v##ox,axis)-dDOT(p,axis);\ \ isPdist##ax=dist##ax>0.f;\ isPdist##ox=dist##ox>0.f;\ \ if(isPdist##ax == isPdist##ox)\ {\ depth##ax=radius-dFabs(dist##ax);\ depth##ox=radius-dFabs(dist##ox);\ \ if(depth##ax>0.f){\ if(depth##ax<=outDepth && depth##ax>=depth##ox) \ {\ outDepth=depth##ax;\ signum= isPdist##ax ? 1.f : -1.f;\ outAx[0]=axis[0];\ outAx[1]=axis[1];\ outAx[2]=axis[2];\ pos[0]=tpos[0];\ pos[1]=tpos[1];\ pos[2]=tpos[2];\ code=c;\ }\ }\ else if(depth##ox<0.f) RETURN0;\ \ }\ } accurate_normalize(triSideAx0); if(outV0&&outV1) TEST(0,1,2,7) accurate_normalize(triSideAx1); if(outV1&&outV2) TEST(1,2,0,8) accurate_normalize(triSideAx2); if(outV2&&outV0) TEST(2,0,1,9) #undef TEST //////////////////////////////////// //test cylinder rings on triangle sides//// //////////////////////////////////// dVector3 tAx,cen; dReal sign; bool cs; #define TEST(ax,nx,ox,c) \ {\ posProj=dDOT(p,triSideAx##ax)-dDOT(v##ax,triSideAx##ax);\ axis[0]=p[0]-v0[0]-triSideAx##ax[0]*posProj;\ axis[1]=p[1]-v0[1]-triSideAx##ax[1]*posProj;\ axis[2]=p[2]-v0[2]-triSideAx##ax[2]*posProj;\ \ sign=dDOT14(axis,R+1)>0.f ? 1.f :-1.f;\ cen[0]=p[0]-sign*R[1]*hlz;\ cen[1]=p[1]-sign*R[5]*hlz;\ cen[2]=p[2]-sign*R[9]*hlz;\ \ cs=circleLineIntersection(R+1,cen,radius,triSideAx##ax,v##ax,-sign,tpos);\ \ axis[0]=tpos[0]-cen[0];\ axis[1]=tpos[1]-cen[1];\ axis[2]=tpos[2]-cen[2];\ \ if(cs){ \ \ cos0=dDOT14(axis,R+0);\ cos2=dDOT14(axis,R+2);\ tAx[0]=R[2]*cos0-R[0]*cos2;\ tAx[1]=R[6]*cos0-R[4]*cos2;\ tAx[2]=R[10]*cos0-R[8]*cos2;\ \ dCROSS(axis,=,triSideAx##ax,tAx);\ \ }\ accurate_normalize(axis);\ dist##ax=dDOT(v##ax,axis)-dDOT(p,axis);\ if(dist##ax*dDOT(axis,triSideAx##nx)>0.f){\ \ cos0=dDOT14(axis,R+0);\ cos1=dFabs(dDOT14(axis,R+1));\ cos2=dDOT14(axis,R+2);\ \ \ sin1=_sqrt(cos0*cos0+cos2*cos2);\ \ sidePr=cos1*hlz+sin1*radius;\ \ \ dist##ox=dDOT(v##ox,axis)-dDOT(p,axis);\ \ isPdist##ax=dist##ax>0.f;\ isPdist##ox=dist##ox>0.f;\ \ if(isPdist##ax == isPdist##ox) \ \ {\ depth##ax=sidePr-dFabs(dist##ax);\ depth##ox=sidePr-dFabs(dist##ox);\ \ if(depth##ax>0.f){\ if(depth##ax<outDepth) \ {\ outDepth=depth##ax;\ signum= isPdist##ax ? 1.f : -1.f;\ outAx[0]=axis[0];\ outAx[1]=axis[1];\ outAx[2]=axis[2];\ pos[0]=tpos[0];\ pos[1]=tpos[1];\ pos[2]=tpos[2];\ code=c;\ }\ }\ else if(depth##ox<0.f) RETURN0;\ \ \ }\ }\ } if(7!=code) TEST(0,1,2,10) if(8!=code) TEST(1,2,0,11) if(9!=code) TEST(2,0,1,12) #undef TEST //} ////////////////////////////////////////////////////////////////////// ///if we get to this poit tri touches cylinder/////////////////////// ///////////////////////////////////////////////////////////////////// //VERIFY( g_pGameLevel ); CDB::TRI* T_array = inl_ph_world().ObjectSpace().GetStaticTris(); dVector3 norm; unsigned int ret; flags8& gl_state=gl_cl_tries_state[I-B]; if(code==0){ norm[0]=triAx[0]*signum; norm[1]=triAx[1]*signum; norm[2]=triAx[2]*signum; dReal Q1 = dDOT14(norm,R+0); dReal Q2 = dDOT14(norm,R+1); dReal Q3 = dDOT14(norm,R+2); dReal factor =_sqrt(Q1*Q1+Q3*Q3); dReal C1,C3; dReal centerDepth;//depth in the cirle centre if(factor>0.f) { C1=Q1/factor; C3=Q3/factor; } else { C1=1.f; C3=0.f; } dReal A1 = radius * C1;//cosinus dReal A2 = hlz;//Q2 dReal A3 = radius * C3;//sinus if(factor>0.f) centerDepth=outDepth-A1*Q1-A3*Q3; else centerDepth=outDepth; pos[0]=p[0]; pos[1]=p[1]; pos[2]=p[2]; pos[0]+= Q2>0 ? hlz*R[1]:-hlz*R[1]; pos[1]+= Q2>0 ? hlz*R[5]:-hlz*R[5]; pos[2]+= Q2>0 ? hlz*R[9]:-hlz*R[9]; ret=0; dVector3 cross0, cross1, cross2; dReal ds0,ds1,ds2; dCROSS(cross0,=,triAx,triSideAx0); ds0=dDOT(cross0,v0); dCROSS(cross1,=,triAx,triSideAx1); ds1=dDOT(cross1,v1); dCROSS(cross2,=,triAx,triSideAx2); ds2=dDOT(cross2,v2); contact->pos[0] = pos[0]+A1*R[0]+A3*R[2]; contact->pos[1] = pos[1]+A1*R[4]+A3*R[6]; contact->pos[2] = pos[2]+A1*R[8]+A3*R[10]; if(dDOT(cross0,contact->pos)-ds0>0.f && dDOT(cross1,contact->pos)-ds1>0.f && dDOT(cross2,contact->pos)-ds2>0.f){ contact->depth = outDepth; ret=1; } if(dFabs(Q2)>M_SQRT1_2){ A1=(-C1*M_COS_PI_3-C3*M_SIN_PI_3)*radius; A3=(-C3*M_COS_PI_3+C1*M_SIN_PI_3)*radius; CONTACT(contact,ret*skip)->pos[0]=pos[0]+A1*R[0]+A3*R[2]; CONTACT(contact,ret*skip)->pos[1]=pos[1]+A1*R[4]+A3*R[6]; CONTACT(contact,ret*skip)->pos[2]=pos[2]+A1*R[8]+A3*R[10]; CONTACT(contact,ret*skip)->depth=centerDepth+Q1*A1+Q3*A3; if(CONTACT(contact,ret*skip)->depth>0.f) if(dDOT(cross0,CONTACT(contact,ret*skip)->pos)-ds0>0.f && dDOT(cross1,CONTACT(contact,ret*skip)->pos)-ds1>0.f && dDOT(cross2,CONTACT(contact,ret*skip)->pos)-ds2>0.f) ++ret; A1=(-C1*M_COS_PI_3+C3*M_SIN_PI_3)*radius; A3=(-C3*M_COS_PI_3-C1*M_SIN_PI_3)*radius; CONTACT(contact,ret*skip)->pos[0]=pos[0]+A1*R[0]+A3*R[2]; CONTACT(contact,ret*skip)->pos[1]=pos[1]+A1*R[4]+A3*R[6]; CONTACT(contact,ret*skip)->pos[2]=pos[2]+A1*R[8]+A3*R[10]; CONTACT(contact,ret*skip)->depth=centerDepth+Q1*A1+Q3*A3; if(CONTACT(contact,ret*skip)->depth>0.f) if(dDOT(cross0,CONTACT(contact,ret*skip)->pos)-ds0>0.f && dDOT(cross1,CONTACT(contact,ret*skip)->pos)-ds1>0.f && dDOT(cross2,CONTACT(contact,ret*skip)->pos)-ds2>0.f) ++ret; } else { CONTACT(contact,ret*skip)->pos[0]=contact->pos[0]-2.f*(Q2>0 ? hlz*R[1]:-hlz*R[1]); CONTACT(contact,ret*skip)->pos[1]=contact->pos[1]-2.f*(Q2>0 ? hlz*R[5]:-hlz*R[5]); CONTACT(contact,ret*skip)->pos[2]=contact->pos[2]-2.f*(Q2>0 ? hlz*R[9]:-hlz*R[9]); CONTACT(contact,ret*skip)->depth=outDepth-dFabs(Q2*2.f*A2); if(CONTACT(contact,ret*skip)->depth>0.f) if(dDOT(cross0,CONTACT(contact,ret*skip)->pos)-ds0>0.f && dDOT(cross1,CONTACT(contact,ret*skip)->pos)-ds1>0.f && dDOT(cross2,CONTACT(contact,ret*skip)->pos)-ds2>0.f) ++ret; } }
void PS::CPEDef::CollisionCutoffOnBeforeEdit(PropValue* sender, float& edit_val) { edit_val = _sqrt(edit_val);}
float CCar::GravityFactorImpulse() { return _sqrt(EffectiveGravity()/physics_world()->Gravity()); }
ISTBOOL GetSphereFrom4Points(struct sphere_model *model) { ISTFLOAT a[4][4] = {{0}}; ISTFLOAT ho[3] = {0}; ISTFLOAT norm = 0; ISTFLOAT rad = 0; ISTFLOAT tmpf = 0; ISTFLOAT two = _float(2); ISTFLOAT m11, m12, m13, m14, m15; ISTINT i, j; // Get sphere from 4 points for (i = 0; i < 4; i++) { /* find minor 11 */ a[i][0] = model->p4s[i][0]; a[i][1] = model->p4s[i][1]; a[i][2] = model->p4s[i][2]; a[i][3] = _one; } m11 = GetDet(a, 4); for (i = 0; i < 4; i++) { /* find minor 12 */ a[i][0] = _add(_add(_mul(model->p4s[i][0], model->p4s[i][0]), _mul(model->p4s[i][1], model->p4s[i][1])), _mul(model->p4s[i][2], model->p4s[i][2])); a[i][1] = model->p4s[i][1]; a[i][2] = model->p4s[i][2]; a[i][3] = _one; } m12 = GetDet(a, 4); for (i = 0; i < 4; i++) { /* find minor 13 */ a[i][0] = _add(_add(_mul(model->p4s[i][0], model->p4s[i][0]), _mul(model->p4s[i][1], model->p4s[i][1])), _mul(model->p4s[i][2], model->p4s[i][2])); a[i][1] = model->p4s[i][0]; a[i][2] = model->p4s[i][2]; a[i][3] = _one; } m13 = GetDet(a, 4); for (i = 0; i < 4; i++) { /* find minor 14 */ a[i][0] = _add(_add(_mul(model->p4s[i][0], model->p4s[i][0]), _mul(model->p4s[i][1], model->p4s[i][1])), _mul(model->p4s[i][2], model->p4s[i][2])); a[i][1] = model->p4s[i][0]; a[i][2] = model->p4s[i][1]; a[i][3] = _one; } m14 = GetDet(a, 4); for (i = 0; i < 4; i++) { /* find minor 15 */ a[i][0] = _add(_add(_mul(model->p4s[i][0], model->p4s[i][0]), _mul(model->p4s[i][1], model->p4s[i][1])), _mul(model->p4s[i][2], model->p4s[i][2])); a[i][1] = model->p4s[i][0]; a[i][2] = model->p4s[i][1]; a[i][3] = model->p4s[i][2]; } m15 = GetDet(a, 4); if (_eq(m11, 0)) { rad = 0; } else { /* center of sphere */ ho[0] = _div(_div(m12, m11), two); ho[1] = _neg(_div(_div(m13, m11), two)); ho[2] = _div(_div(m14, m11), two); norm = _sub(_add(_add(_mul(ho[0], ho[0]), _mul(ho[1], ho[1])), _mul(ho[2], ho[2])), _div(m15, m11)); if (_ge(norm, 0)) { rad = _sqrt(norm); } } if (_le(rad, 0)) { goto EXIT; } // Check distance for (i = 0; i < 4; i++) { for (j = (i + 1); j < 4; j++) { tmpf = GetDistance(model->p4s[i], model->p4s[j]); if (_lt(tmpf, rad) || _lt(tmpf, model->rad_min)) { goto EXIT; } } } // Update offset for (i = 1; i < IST_SPHERE_OFFSET_NUM; i++) { for (j = 0; j < 3; ++j) { model->offsets[IST_SPHERE_OFFSET_NUM - i][j] = model->offsets[IST_SPHERE_OFFSET_NUM - i - 1][j]; } } for (j = 0; j < 3; ++j) { model->offsets[0][j] = ho[j]; } for (i = (IST_SPHERE_DATAMAX >> 1); i < IST_SPHERE_DATAMAX; i++) { for (j = 0; j < 3; ++j) { model->data[i][j] = _max; } } // Check offset buffer full if (IsInitedVector(model->offsets[IST_SPHERE_OFFSET_NUM - 1])) { goto EXIT; } // Calculate mean bias and radius if (!GetParams(model, rad)) { goto EXIT; } return ISTTRUE; EXIT: return ISTFALSE; }
void CLevelGraph::draw_objects (const int &vertex_id) { if (!ai().get_alife()) return; const float radius = .0105f; const u32 color = D3DCOLOR_XRGB(255,0,0); const CGameGraph &graph = ai().game_graph(); CGameFont &font = *HUD().Font().pFontDI; Fvector position = convert_position(graph.vertex(vertex_id)->game_point()); font.SetColor (D3DCOLOR_XRGB(255,255,0)); bool show_text = true; for (;;) { Fvector4 temp; Device.mFullTransform.transform (temp,position); font.OutSetI (temp.x,-temp.y); font.SetHeightI (.05f/_sqrt(temp.w)); if (temp.z < 0.f) { show_text = false; break; } if (temp.w < 0.f) { show_text = false; break; } if (temp.x < -1.f) { show_text = false; break; } if (temp.x > 1.f) { show_text = false; break; } if (temp.y < -1.f) { show_text = false; break; } if (temp.x > 1.f) { show_text = false; break; } break; } typedef CALifeGraphRegistry::OBJECT_REGISTRY OBJECT_REGISTRY; typedef OBJECT_REGISTRY::_const_iterator const_iterator; typedef CALifeMonsterDetailPathManager::PATH PATH; const OBJECT_REGISTRY &objects = ai().alife().graph().objects()[vertex_id].objects(); CDebugRenderer &render = Level().debug_renderer(); if (show_text) { bool first_time = true; const_iterator I = objects.objects().begin(); const_iterator E = objects.objects().end(); for (; I != E; ++I) { CSE_ALifeDynamicObject *object = (*I).second; CSE_ALifeMonsterAbstract*monster = smart_cast<CSE_ALifeMonsterAbstract*>(object); if (!monster) continue; const PATH &path = monster->brain().movement().detail().path(); const float &walked_distance = (path.size() < 2) ? 0.f : monster->brain().movement().detail().walked_distance(); // font.OutNext ("%s",monster->name_replace()); if ((path.size() >= 2) && !fis_zero(walked_distance)) continue; if (!first_time) continue; Fvector position = convert_position(graph.vertex(monster->m_tGraphID)->game_point()); render.draw_aabb (position,radius,radius,radius,color); first_time = false; continue; } } const_iterator I = objects.objects().begin(); const_iterator E = objects.objects().end(); for (; I != E; ++I) { CSE_ALifeDynamicObject *object = (*I).second; CSE_ALifeMonsterAbstract*monster = smart_cast<CSE_ALifeMonsterAbstract*>(object); if (!monster) continue; const PATH &path = monster->brain().movement().detail().path(); if (path.size() < 2) continue; u32 game_vertex_id0 = monster->m_tGraphID; u32 game_vertex_id1 = path[path.size() - 2]; const float &walked_distance = monster->brain().movement().detail().walked_distance(); if (fis_zero(walked_distance)) continue; Fvector position0 = graph.vertex(game_vertex_id0)->game_point(); Fvector position1 = graph.vertex(game_vertex_id1)->game_point(); const float distance = position0.distance_to(position1); position0 = convert_position(position0); position1 = convert_position(position1); Fvector direction = Fvector().sub(position1,position0); float magnitude = direction.magnitude(); direction.normalize (); direction.mul (magnitude*walked_distance/distance); direction.add (position0); render.draw_aabb (direction,radius,radius,radius,color); Fvector4 temp; Device.mFullTransform.transform (temp,direction); if (temp.z < 0.f) continue; if (temp.w < 0.f) continue; if (temp.x < -1.f) continue; if (temp.x > 1.f) continue; if (temp.y < -1.f) continue; if (temp.x > 1.f) continue; font.SetHeightI (.05f/_sqrt(temp.w)); } }
float CExplosive::ExplosionEffect(collide::rq_results& storage, CExplosive*exp_obj,CPhysicsShellHolder*blasted_obj, const Fvector &expl_centre, const float expl_radius) { const Fmatrix &obj_xform=blasted_obj->XFORM(); Fmatrix inv_obj_form;inv_obj_form.invert(obj_xform); Fvector local_exp_center;inv_obj_form.transform_tiny(local_exp_center,expl_centre); const Fbox &l_b1 = blasted_obj->BoundingBox(); if(l_b1.contains(local_exp_center)) return 1.f; Fvector l_c, l_d;l_b1.get_CD(l_c,l_d); float effective_volume=l_d.x*l_d.y*l_d.z; float max_s=effective_volume/(_min(_min(l_d.x,l_d.y),l_d.z)); if(blasted_obj->PPhysicsShell()&&blasted_obj->PPhysicsShell()->isActive()) { float ph_volume=blasted_obj->PPhysicsShell()->getVolume(); if(ph_volume<effective_volume)effective_volume=ph_volume; } float effect=0.f; #ifdef DEBUG if(ph_dbg_draw_mask.test(phDbgDrawExplosions)) { Fmatrix dbg_box_m;dbg_box_m.set(obj_xform); dbg_box_m.c.set(l_c);obj_xform.transform(dbg_box_m.c); DBG_DrawOBB(dbg_box_m,l_d,D3DCOLOR_XRGB(255,255,0)); } #endif for(u16 i=0;i<TEST_RAYS_PER_OBJECT;++i){ Fvector l_source_p,l_end_p; l_end_p.random_point(l_d); l_end_p.add(l_c); obj_xform.transform_tiny(l_end_p); GetRaySourcePos(exp_obj,expl_centre,l_source_p); Fvector l_local_source_p;inv_obj_form.transform_tiny(l_local_source_p,l_source_p); if(l_b1.contains(l_local_source_p)) { effect+=1.f;continue; } Fvector l_dir; l_dir.sub(l_end_p,l_source_p); float mag=l_dir.magnitude(); if(fis_zero(mag)) return 1.f; l_dir.mul(1.f/mag); #ifdef DEBUG if(ph_dbg_draw_mask.test(phDbgDrawExplosions)) { DBG_DrawPoint(l_source_p,0.1f,D3DCOLOR_XRGB(0,0,255)); DBG_DrawPoint(l_end_p,0.1f,D3DCOLOR_XRGB(0,0,255)); DBG_DrawLine(l_source_p,l_end_p,D3DCOLOR_XRGB(0,0,255)); } #endif #ifdef DEBUG float l_S=effective_volume*(_abs(l_dir.dotproduct(obj_xform.i))/l_d.x+_abs(l_dir.dotproduct(obj_xform.j))/l_d.y+_abs(l_dir.dotproduct(obj_xform.k))/l_d.z); float add_eff=_sqrt(l_S/max_s)*TestPassEffect(l_source_p,l_dir,mag,expl_radius,storage,blasted_obj); effect+=add_eff; if(ph_dbg_draw_mask.test(phDbgDrawExplosions)) { Msg("dist %f,effect R %f",mag,expl_radius); Msg("test pass effect %f",add_eff); Msg("S effect %f",_sqrt(l_S/max_s)); Msg("dist/overlap effect, %f",add_eff/_sqrt(l_S/max_s)); } #else float l_S=effective_volume*(_abs(l_dir.dotproduct(obj_xform.i))/l_d.x+_abs(l_dir.dotproduct(obj_xform.j))/l_d.y+_abs(l_dir.dotproduct(obj_xform.k))/l_d.z); effect+=_sqrt(l_S/max_s)*TestPassEffect(l_source_p,l_dir,mag,expl_radius,storage,blasted_obj); #endif } #ifdef DEBUG if(ph_dbg_draw_mask.test(phDbgDrawExplosions)) { Msg("damage effect %f",effect/TEST_RAYS_PER_OBJECT); } #endif return effect/TEST_RAYS_PER_OBJECT; }
mat3& tangent_basis(mat3& basis, const vec3& v0, const vec3& v1, const vec3& v2, const vec2& t0, const vec2& t1, const vec2& t2, const vec3 & n) { vec3 cp; vec3 e0(v1.x - v0.x, t1.s - t0.s, t1.t - t0.t); vec3 e1(v2.x - v0.x, t2.s - t0.s, t2.t - t0.t); cross(cp,e0,e1); if ( _abs(cp.x) > nv_eps) { basis.a00 = -cp.y / cp.x; basis.a10 = -cp.z / cp.x; } e0.x = v1.y - v0.y; e1.x = v2.y - v0.y; cross(cp,e0,e1); if ( _abs(cp.x) > nv_eps) { basis.a01 = -cp.y / cp.x; basis.a11 = -cp.z / cp.x; } e0.x = v1.z - v0.z; e1.x = v2.z - v0.z; cross(cp,e0,e1); if ( _abs(cp.x) > nv_eps) { basis.a02 = -cp.y / cp.x; basis.a12 = -cp.z / cp.x; } // tangent... nv_scalar oonorm = nv_one / _sqrt(basis.a00 * basis.a00 + basis.a01 * basis.a01 + basis.a02 * basis.a02); basis.a00 *= oonorm; basis.a01 *= oonorm; basis.a02 *= oonorm; // binormal... oonorm = nv_one / _sqrt(basis.a10 * basis.a10 + basis.a11 * basis.a11 + basis.a12 * basis.a12); basis.a10 *= oonorm; basis.a11 *= oonorm; basis.a12 *= oonorm; // normal... // compute the cross product TxB basis.a20 = basis.a01*basis.a12 - basis.a02*basis.a11; basis.a21 = basis.a02*basis.a10 - basis.a00*basis.a12; basis.a22 = basis.a00*basis.a11 - basis.a01*basis.a10; oonorm = nv_one / _sqrt(basis.a20 * basis.a20 + basis.a21 * basis.a21 + basis.a22 * basis.a22); basis.a20 *= oonorm; basis.a21 *= oonorm; basis.a22 *= oonorm; // Gram-Schmidt orthogonalization process for B // compute the cross product B=NxT to obtain // an orthogonal basis basis.a10 = basis.a21*basis.a02 - basis.a22*basis.a01; basis.a11 = basis.a22*basis.a00 - basis.a20*basis.a02; basis.a12 = basis.a20*basis.a01 - basis.a21*basis.a00; if (basis.a20 * n.x + basis.a21 * n.y + basis.a22 * n.z < nv_zero) { basis.a20 = -basis.a20; basis.a21 = -basis.a21; basis.a22 = -basis.a22; } return basis; }
void CGlowManager::render_selected() { // 2. Sort by shader std::sort (Selected.begin(),Selected.end(),glow_compare); FVF::LIT *pv; u32 pos = 0, count; ref_shader T; Fplane NP; NP.build (Device.vCameraPosition,Device.vCameraDirection); float dlim2 = MAX_GlowsDist2; for (;pos<Selected.size();) { T = ((CGlow*)Selected[pos]._get())->shader; count = 0; while ((pos+count<Selected.size()) && (((CGlow*)Selected[pos+count]._get())->shader==T)) count++; u32 vOffset; u32 end = pos+count; FVF::LIT* pvs = pv = (FVF::LIT*) RCache.Vertex.Lock(count*4,hGeom->vb_stride,vOffset); for (; pos<end; pos++) { // Cull invisible CGlow& G = *( (CGlow*)Selected[pos]._get() ); if (G.fade<=1.f) continue; // Now perform dotproduct if need it float scale = 1.f, dist_sq; Fvector dir; dir.sub (Device.vCameraPosition,G.position); dist_sq = dir.square_magnitude(); if (G.direction.square_magnitude()>EPS) { dir.div (_sqrt(dist_sq)); scale = dir.dotproduct(G.direction); } if (G.fade*scale<=1.f) continue; // near fade float dist_np = NP.distance(G.position)-VIEWPORT_NEAR; float snear = dist_np/0.15f; clamp (snear,0.f,1.f); scale *= snear; if (G.fade*scale<=1.f) continue; u32 C = iFloor(G.fade*scale*(1-(dist_sq/dlim2))); u32 clr = color_rgba(C,C,C,C); Fvector gp ; gp.mad (G.position,dir,G.radius*scale); FillSprite (pv,G.position,G.radius,clr); } int vCount = int(pv-pvs); RCache.Vertex.Unlock (vCount,hGeom->vb_stride); if (vCount) { RCache.set_Shader (T); RCache.set_Geometry (hGeom); RCache.Render (D3DPT_TRIANGLELIST,vOffset,0,vCount,0,vCount/2); } } Selected.clear_not_free (); }
void CTeleWhirlwindObject:: raise (float step) { CPhysicsShell* p = get_object() ->PPhysicsShell(); if(!p||!p->isActive()) return; else { p->SetAirResistance(0.f,0.f); p->set_ApplyByGravity(TRUE); } u16 element_number = p ->get_ElementsNumber(); Fvector center = m_telekinesis ->Center(); CPhysicsElement* maxE=p->get_ElementByStoreOrder(0); for(u16 element=0;element<element_number;++element) { float k=strength;//600.f; float predict_v_eps=0.1f; float mag_eps =.01f; CPhysicsElement* E= p->get_ElementByStoreOrder(element); if(maxE->getMass()<E->getMass()) maxE=E; if (!E->isActive()) continue; Fvector pos=E->mass_Center(); Fvector diff; diff.sub(center,pos); float mag=_sqrt(diff.x*diff.x+diff.z*diff.z); Fvector lc;lc.set(center); if(mag>1.f) { lc.y/=mag; } diff.sub(lc,pos); mag=diff.magnitude(); float accel=k/mag/mag/mag;//*E->getMass() Fvector dir; if(mag<mag_eps) { accel=0.f; //Fvector zer;zer.set(0,0,0); //E->set_LinearVel(zer); dir.random_dir(); } else { dir.set(diff);dir.mul(1.f/mag); } Fvector vel; E->get_LinearVel(vel); float delta_v=accel*fixed_step; Fvector delta_vel; delta_vel.set(dir);delta_vel.mul(delta_v); Fvector predict_vel;predict_vel.add(vel,delta_vel); Fvector delta_pos;delta_pos.set(predict_vel);delta_pos.mul(fixed_step); Fvector predict_pos;predict_pos.add(pos,delta_pos); Fvector predict_diff;predict_diff.sub(lc,predict_pos); float predict_mag=predict_diff.magnitude(); float predict_v=predict_vel.magnitude(); Fvector force;force.set(dir); if(predict_mag>mag && predict_vel.dotproduct(dir)>0.f && predict_v>predict_v_eps) { Fvector motion_dir;motion_dir.set(predict_vel);motion_dir.mul(1.f/predict_v); float needed_d=diff.dotproduct(motion_dir); Fvector needed_diff;needed_diff.set(motion_dir);needed_diff.mul(needed_d); Fvector nearest_p;nearest_p.add(pos,needed_diff);// Fvector needed_vel;needed_vel.set(needed_diff);needed_vel.mul(1.f/fixed_step); force.sub(needed_vel,vel); force.mul(E->getMass()/fixed_step); } else { force.mul(accel*E->getMass()); } E->applyForce(force.x,force.y+get_object()->EffectiveGravity()*E->getMass(),force.z); } Fvector dist;dist.sub(center,maxE->mass_Center()); if(dist.magnitude()<m_telekinesis->keep_radius()&&b_destroyable) { p->setTorque(Fvector().set(0,0,0)); p->setForce(Fvector().set(0,0,0)); p->set_LinearVel(Fvector().set(0,0,0)); p->set_AngularVel(Fvector().set(0,0,0)); switch_state(TS_Keep); } }
void CRenderTarget::accum_direct_f (u32 sub_phase) { // Select target if (SE_SUN_LUMINANCE==sub_phase) { accum_direct_lum (); return ; } phase_accumulator (); u_setrt (rt_Generic_0,NULL,NULL,HW.pBaseZB); // *** assume accumulator setted up *** light* fuckingsun = (light*)RImplementation.Lights.sun_adapted._get() ; // Common calc for quad-rendering u32 Offset; u32 C = color_rgba (255,255,255,255); float _w = float (Device.dwWidth); float _h = float (Device.dwHeight); Fvector2 p0,p1; p0.set (.5f/_w, .5f/_h); p1.set ((_w+.5f)/_w, (_h+.5f)/_h ); float d_Z = EPS_S, d_W = 1.f; // Common constants (light-related) 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 (); // Perform masking (only once - on the first/near phase) RCache.set_CullMode (CULL_NONE ); if (SE_SUN_NEAR==sub_phase) //. { // For sun-filter - clear to zero CHK_DX (HW.pDevice->Clear ( 0L, NULL, D3DCLEAR_TARGET, 0, 1.0f, 0L)); // Fill vertex buffer FVF::TL* pv = (FVF::TL*) RCache.Vertex.Lock (4,g_combine->vb_stride,Offset); pv->set (EPS, float(_h+EPS), d_Z, d_W, C, p0.x, p1.y); pv++; pv->set (EPS, EPS, d_Z, d_W, C, p0.x, p0.y); pv++; pv->set (float(_w+EPS), float(_h+EPS), d_Z, d_W, C, p1.x, p1.y); pv++; pv->set (float(_w+EPS), EPS, d_Z, d_W, C, p1.x, p0.y); pv++; RCache.Vertex.Unlock (4,g_combine->vb_stride); RCache.set_Geometry (g_combine); // setup float intensity = 0.3f*fuckingsun->color.r + 0.48f*fuckingsun->color.g + 0.22f*fuckingsun->color.b; Fvector dir = L_dir; dir.normalize().mul (- _sqrt(intensity+EPS)); RCache.set_Element (s_accum_mask->E[SE_MASK_DIRECT]); // masker RCache.set_c ("Ldynamic_dir", dir.x,dir.y,dir.z,0 ); // if (stencil>=1 && aref_pass) stencil = light_id RCache.set_ColorWriteEnable (FALSE ); RCache.set_Stencil (TRUE,D3DCMP_LESSEQUAL,dwLightMarkerID,0x01,0xff,D3DSTENCILOP_KEEP,D3DSTENCILOP_REPLACE,D3DSTENCILOP_KEEP); RCache.Render (D3DPT_TRIANGLELIST,Offset,0,4,0,2); } // recalculate d_Z, to perform depth-clipping Fvector center_pt; center_pt.mad (Device.vCameraPosition,Device.vCameraDirection,ps_r2_sun_near); Device.mFullTransform.transform(center_pt) ; d_Z = center_pt.z ; // nv-stencil recompression if (RImplementation.o.nvstencil && (SE_SUN_NEAR==sub_phase)) u_stencil_optimize(); //. driver bug? // Perform lighting { u_setrt (rt_Generic_0,NULL,NULL,HW.pBaseZB); // enshure RT setup RCache.set_CullMode (CULL_NONE ); RCache.set_ColorWriteEnable (); // texture adjustment matrix float fTexelOffs = (.5f / float(RImplementation.o.smapsize)); float fRange = (SE_SUN_NEAR==sub_phase)?ps_r2_sun_depth_near_scale:ps_r2_sun_depth_far_scale; float fBias = (SE_SUN_NEAR==sub_phase)?ps_r2_sun_depth_near_bias:ps_r2_sun_depth_far_bias; Fmatrix m_TexelAdjust = { 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, fRange, 0.0f, 0.5f + fTexelOffs, 0.5f + fTexelOffs, fBias, 1.0f }; // compute xforms Fmatrix m_shadow; { FPU::m64r (); Fmatrix xf_invview; xf_invview.invert (Device.mView) ; Fmatrix xf_project; xf_project.mul (m_TexelAdjust,fuckingsun->X.D.combine); m_shadow.mul (xf_project, xf_invview); // tsm-bias if (SE_SUN_FAR == sub_phase) { Fvector bias; bias.mul (L_dir,ps_r2_sun_tsm_bias); Fmatrix bias_t; bias_t.translate(bias); m_shadow.mulB_44 (bias_t); } FPU::m24r (); } // Make jitter texture Fvector2 j0,j1; float scale_X = float(Device.dwWidth) / float(TEX_jitter); //float scale_Y = float(Device.dwHeight)/ float(TEX_jitter); float offset = (.5f / float(TEX_jitter)); j0.set (offset,offset); j1.set (scale_X,scale_X).add(offset); // Fill vertex buffer FVF::TL2uv* pv = (FVF::TL2uv*) RCache.Vertex.Lock (4,g_combine_2UV->vb_stride,Offset); pv->set (EPS, float(_h+EPS), d_Z, d_W, C, p0.x, p1.y, j0.x, j1.y); pv++; pv->set (EPS, EPS, d_Z, d_W, C, p0.x, p0.y, j0.x, j0.y); pv++; pv->set (float(_w+EPS), float(_h+EPS), d_Z, d_W, C, p1.x, p1.y, j1.x, j1.y); pv++; pv->set (float(_w+EPS), EPS, d_Z, d_W, C, p1.x, p0.y, j1.x, j0.y); pv++; RCache.Vertex.Unlock (4,g_combine_2UV->vb_stride); RCache.set_Geometry (g_combine_2UV); // setup RCache.set_Element (s_accum_direct->E[sub_phase]); RCache.set_c ("Ldynamic_dir", L_dir.x,L_dir.y,L_dir.z,0 ); RCache.set_c ("Ldynamic_color", L_clr.x,L_clr.y,L_clr.z,L_spec ); RCache.set_c ("m_shadow", m_shadow ); // setup stencil RCache.set_Stencil (TRUE,D3DCMP_LESSEQUAL,dwLightMarkerID,0xff,0x00); RCache.Render (D3DPT_TRIANGLELIST,Offset,0,4,0,2); } }
void CPhysicObject::net_Export_PH_Params(NET_Packet& P, SPHNetState& State, mask_num_items& num_items) { //UI().Font().pFontStat->OutSet(100.0f,100.0f); P.w_vec3 (State.force); //Msg("Export State.force.y:%4.6f",State.force.y); P.w_vec3 (State.torque); //UI().Font().pFontStat->OutNext("Export State.torque:%4.6f",State.torque.magnitude()); P.w_vec3 (State.position); //Msg("Export State.position.y:%4.6f",State.position.y); //Msg("Export State.enabled:%i",int(State.enabled)); float magnitude = _sqrt(State.quaternion.magnitude()); if (fis_zero(magnitude)) { magnitude = 1; State.quaternion.x = 0.f; State.quaternion.y = 0.f; State.quaternion.z = 1.f; State.quaternion.w = 0.f; } else { /* float invert_magnitude = 1.f/magnitude; State.quaternion.x *= invert_magnitude; State.quaternion.y *= invert_magnitude; State.quaternion.z *= invert_magnitude; State.quaternion.w *= invert_magnitude; clamp (State.quaternion.x,-1.f,1.f); clamp (State.quaternion.y,-1.f,1.f); clamp (State.quaternion.z,-1.f,1.f); clamp (State.quaternion.w,-1.f,1.f);*/ } P.w_float (State.quaternion.x); P.w_float (State.quaternion.y); P.w_float (State.quaternion.z); P.w_float (State.quaternion.w); if (!(num_items.mask & CSE_ALifeObjectPhysic::inventory_item_angular_null)) { /* clamp (State.angular_vel.x,-10.f*PI_MUL_2,10.f*PI_MUL_2); clamp (State.angular_vel.y,-10.f*PI_MUL_2,10.f*PI_MUL_2); clamp (State.angular_vel.z,-10.f*PI_MUL_2,10.f*PI_MUL_2);*/ P.w_float (State.angular_vel.x); P.w_float (State.angular_vel.y); P.w_float (State.angular_vel.z); } if (!(num_items.mask & CSE_ALifeObjectPhysic::inventory_item_linear_null)) { /*clamp (State.linear_vel.x,-32.f,32.f); clamp (State.linear_vel.y,-32.f,32.f); clamp (State.linear_vel.z,-32.f,32.f);*/ P.w_float (State.linear_vel.x); P.w_float (State.linear_vel.y); P.w_float (State.linear_vel.z); //Msg("Export State.linear_vel.y:%4.6f",State.linear_vel.y); } else { //Msg("Export State.linear_vel.y:%4.6f",0.0f); } }
void CInventoryItem::net_Export (NET_Packet& P) { if (object().H_Parent() || IsGameTypeSingle()) { P.w_u8 (0); return; } CPHSynchronize* pSyncObj = NULL; SPHNetState State; pSyncObj = object().PHGetSyncItem (0); if (pSyncObj && !object().H_Parent()) pSyncObj->get_State (State); else State.position.set (object().Position()); mask_num_items num_items; num_items.mask = 0; u16 temp = bone_count_to_synchronize(); R_ASSERT (temp < (u16(1) << 5)); num_items.num_items = u8(temp); if (State.enabled) num_items.mask |= CSE_ALifeInventoryItem::inventory_item_state_enabled; if (fis_zero(State.angular_vel.square_magnitude())) num_items.mask |= CSE_ALifeInventoryItem::inventory_item_angular_null; if (fis_zero(State.linear_vel.square_magnitude())) num_items.mask |= CSE_ALifeInventoryItem::inventory_item_linear_null; P.w_u8 (num_items.common); P.w_vec3 (State.position); float magnitude = _sqrt(State.quaternion.magnitude()); if (fis_zero(magnitude)) { magnitude = 1; State.quaternion.x = 0.f; State.quaternion.y = 0.f; State.quaternion.z = 1.f; State.quaternion.w = 0.f; } else { float invert_magnitude = 1.f/magnitude; State.quaternion.x *= invert_magnitude; State.quaternion.y *= invert_magnitude; State.quaternion.z *= invert_magnitude; State.quaternion.w *= invert_magnitude; clamp (State.quaternion.x,0.f,1.f); clamp (State.quaternion.y,0.f,1.f); clamp (State.quaternion.z,0.f,1.f); clamp (State.quaternion.w,0.f,1.f); } P.w_float_q8 (State.quaternion.x,0.f,1.f); P.w_float_q8 (State.quaternion.y,0.f,1.f); P.w_float_q8 (State.quaternion.z,0.f,1.f); P.w_float_q8 (State.quaternion.w,0.f,1.f); if (!(num_items.mask & CSE_ALifeInventoryItem::inventory_item_angular_null)) { clamp (State.angular_vel.x,0.f,10.f*PI_MUL_2); clamp (State.angular_vel.y,0.f,10.f*PI_MUL_2); clamp (State.angular_vel.z,0.f,10.f*PI_MUL_2); P.w_float_q8 (State.angular_vel.x,0.f,10.f*PI_MUL_2); P.w_float_q8 (State.angular_vel.y,0.f,10.f*PI_MUL_2); P.w_float_q8 (State.angular_vel.z,0.f,10.f*PI_MUL_2); } if (!(num_items.mask & CSE_ALifeInventoryItem::inventory_item_linear_null)) { clamp (State.linear_vel.x,-32.f,32.f); clamp (State.linear_vel.y,-32.f,32.f); clamp (State.linear_vel.z,-32.f,32.f); P.w_float_q8 (State.linear_vel.x,-32.f,32.f); P.w_float_q8 (State.linear_vel.y,-32.f,32.f); P.w_float_q8 (State.linear_vel.z,-32.f,32.f); } };