//------------------------------------------------------------------------------------- static void generate_orthonormal_basis(const Fvector& dir,Fmatrix &result) { result.identity (); result.k.normalize (dir); Fvector::generate_orthonormal_basis(result.k, result.j, result.i); }
void CLensFlare::OnFrame(int id) { if (dwFrame==Device.dwFrame)return; #ifndef _EDITOR if (!g_pGameLevel) return; #endif dwFrame = Device.dwFrame; vSunDir.mul (g_pGamePersistent->Environment().CurrentEnv.sun_dir,-1); // color float tf = g_pGamePersistent->Environment().fTimeFactor; Fvector& c = g_pGamePersistent->Environment().CurrentEnv.sun_color; LightColor.set (c.x,c.y,c.z,1.f); CLensFlareDescriptor* desc = (id==-1)?0:&m_Palette[id]; switch(m_State){ case lfsNone: m_State=lfsShow; m_Current=desc; break; case lfsIdle: if (desc!=m_Current) m_State=lfsHide; break; case lfsShow: m_StateBlend = m_Current?(m_StateBlend + m_Current->m_StateBlendUpSpeed * Device.fTimeDelta * tf):1.f+EPS; if (m_StateBlend>=1.f) m_State=lfsIdle; break; case lfsHide: m_StateBlend = m_Current?(m_StateBlend - m_Current->m_StateBlendDnSpeed * Device.fTimeDelta * tf):0.f-EPS; if (m_StateBlend<=0.f){ m_State = lfsShow; m_Current = desc; m_StateBlend= m_Current?m_Current->m_StateBlendUpSpeed * Device.fTimeDelta * tf:0; } break; } clamp(m_StateBlend,0.f,1.f); if ((m_Current==0)||(LightColor.magnitude_rgb()==0.f)){bRender=false; return;} // // Compute center and axis of flares // float fDot; Fvector vecPos; Fmatrix matEffCamPos; matEffCamPos.identity(); // Calculate our position and direction matEffCamPos.i.set(Device.vCameraRight); matEffCamPos.j.set(Device.vCameraTop); matEffCamPos.k.set(Device.vCameraDirection); vecPos.set(Device.vCameraPosition); vecDir.set(0.0f, 0.0f, 1.0f); matEffCamPos.transform_dir(vecDir); vecDir.normalize(); // Figure out of light (or flare) might be visible vecLight.set(vSunDir); vecLight.normalize(); fDot = vecLight.dotproduct(vecDir); if(fDot <= 0.01f){ bRender = false; return;} else bRender = true; // Calculate the point directly in front of us, on the far clip plane float fDistance = FAR_DIST*0.75f; vecCenter.mul(vecDir, fDistance); vecCenter.add(vecPos); // Calculate position of light on the far clip plane vecLight.mul(fDistance / fDot); vecLight.add(vecPos); // Compute axis which goes from light through the center of the screen vecAxis.sub(vecLight, vecCenter); // // Figure out if light is behind something else vecX.set(1.0f, 0.0f, 0.0f); matEffCamPos.transform_dir(vecX); vecX.normalize(); vecY.crossproduct(vecX, vecDir); #ifdef _EDITOR float dist = UI->ZFar(); if (Tools->RayPick(Device.m_Camera.GetPosition(),vSunDir,dist)) fBlend = fBlend - BLEND_DEC_SPEED * Device.fTimeDelta; else fBlend = fBlend + BLEND_INC_SPEED * Device.fTimeDelta; #else CObject* o_main = g_pGameLevel->CurrentViewEntity(); STranspParam TP (this,Device.vCameraPosition,vSunDir,1000.f,EPS_L); collide::ray_defs RD (TP.P,TP.D,TP.f,CDB::OPT_CULL,collide::rqtBoth); if (m_ray_cache.result&&m_ray_cache.similar(TP.P,TP.D,TP.f)){ // similar with previous query == 0 TP.vis = 0.f; }else{ float _u,_v,_range; if (CDB::TestRayTri(TP.P,TP.D,m_ray_cache.verts,_u,_v,_range,false)&&(_range>0 && _range<TP.f)){ TP.vis = 0.f; }else{ // cache outdated. real query. r_dest.r_clear (); if (g_pGameLevel->ObjectSpace.RayQuery (r_dest,RD,material_callback,&TP,NULL,o_main)) m_ray_cache.result = FALSE ; } } blend_lerp(fBlend,TP.vis,BLEND_DEC_SPEED,Device.fTimeDelta); #endif clamp( fBlend, 0.0f, 1.0f ); // gradient if (m_Current->m_Flags.is(CLensFlareDescriptor::flGradient)) { Fvector scr_pos; Device.mFullTransform.transform ( scr_pos, vecLight ); float kx = 1, ky = 1; float sun_blend = 0.5f; float sun_max = 2.5f; scr_pos.y *= -1; if (_abs(scr_pos.x) > sun_blend) kx = ((sun_max - (float)_abs(scr_pos.x))) / (sun_max - sun_blend); if (_abs(scr_pos.y) > sun_blend) ky = ((sun_max - (float)_abs(scr_pos.y))) / (sun_max - sun_blend); if (!((_abs(scr_pos.x) > sun_max) || (_abs(scr_pos.y) > sun_max))){ float op = m_StateBlend*m_Current->m_Gradient.fOpacity; fGradientValue = kx * ky * op * fBlend; }else fGradientValue = 0; } }
void CBurer::UpdateGraviObject() { if ( !m_gravi_object.active ) { return; } if ( !m_gravi_object.enemy || (m_gravi_object.enemy && m_gravi_object.enemy->getDestroy()) ) { m_gravi_object.deactivate(); return; } if ( m_gravi_object.from_pos.distance_to(m_gravi_object.cur_pos) > m_gravi_object.from_pos.distance_to(m_gravi_object.target_pos) ) { m_gravi_object.deactivate(); return; } float dt = float(Device.dwTimeGlobal - m_gravi_object.time_last_update); float dist = dt * float(m_gravi.speed)/1000.f; if (dist < m_gravi.step) return; Fvector new_pos; Fvector dir; dir.sub(m_gravi_object.target_pos,m_gravi_object.cur_pos); dir.normalize(); new_pos.mad(m_gravi_object.cur_pos,dir,dist); // Trace to enemy Fvector enemy_center; m_gravi_object.enemy->Center(enemy_center); dir.sub(enemy_center, new_pos); dir.normalize(); float trace_dist = float(m_gravi.step); collide::rq_result l_rq; if (Level().ObjectSpace.RayPick(new_pos, dir, trace_dist, collide::rqtBoth, l_rq, NULL)) { const CObject *enemy = smart_cast<const CObject *>(m_gravi_object.enemy); if ((l_rq.O == enemy) && (l_rq.range < trace_dist)) { // check for visibility bool b_enemy_visible = false; xr_vector<CObject *> visible_objects; feel_vision_get(visible_objects); // find object for (u32 i = 0; i<visible_objects.size(); i++) { if (visible_objects[i] == enemy) { b_enemy_visible = true; break; } } if (b_enemy_visible) { Fvector impulse_dir; impulse_dir.set(0.0f,0.0f,1.0f); impulse_dir.normalize(); HitEntity(m_gravi_object.enemy, m_gravi.hit_power, m_gravi.impulse_to_enemy, impulse_dir, ALife::eHitTypeStrike, false); m_gravi_object.deactivate(); return; } } } m_gravi_object.cur_pos = new_pos; m_gravi_object.time_last_update = Device.dwTimeGlobal; // --------------------------------------------------------------------- // draw particle CParticlesObject* ps = CParticlesObject::Create(particle_gravi_wave,TRUE); // вычислить позицию и направленность партикла Fmatrix pos; pos.identity(); pos.k.set(dir); Fvector::generate_orthonormal_basis_normalized(pos.k,pos.j,pos.i); // установить позицию pos.translate_over(m_gravi_object.cur_pos); ps->UpdateParent(pos, zero_vel); ps->Play(false); // hit objects m_nearest.clear_not_free (); Level().ObjectSpace.GetNearest (m_nearest,m_gravi_object.cur_pos, m_gravi.radius, NULL); //xr_vector<CObject*> &m_nearest = Level().ObjectSpace.q_nearest; for (u32 i=0;i<m_nearest.size();i++) { CPhysicsShellHolder *obj = smart_cast<CPhysicsShellHolder *>(m_nearest[i]); if (!obj || !obj->m_pPhysicsShell) continue; Fvector dir; dir.sub(obj->Position(), m_gravi_object.cur_pos); dir.normalize(); obj->m_pPhysicsShell->applyImpulse(dir,m_gravi.impulse_to_objects * obj->m_pPhysicsShell->getMass()); } // играть звук Fvector snd_pos = m_gravi_object.cur_pos; snd_pos.y += 0.5f; if (sound_gravi_wave._feedback()) { sound_gravi_wave.set_position (snd_pos); } else ::Sound->play_at_pos (sound_gravi_wave,0,snd_pos); }
BOOL CAlienEffector::ProcessCam(SCamEffectorInfo& info) { // »нициализаци¤ Fmatrix Mdef; Mdef.identity (); Mdef.j.set (info.n); Mdef.k.set (info.d); Mdef.i.crossproduct (info.n, info.d); Mdef.c.set (info.p); // set angle if (angle_lerp(dangle_current.x, dangle_target.x, ANGLE_SPEED, Device.fTimeDelta)) { dangle_target.x = angle_normalize(Random.randFs(DELTA_ANGLE_X)); } if (angle_lerp(dangle_current.y, dangle_target.y, ANGLE_SPEED, Device.fTimeDelta)) { dangle_target.y = angle_normalize(Random.randFs(DELTA_ANGLE_Y)); } if (angle_lerp(dangle_current.z, dangle_target.z, ANGLE_SPEED, Device.fTimeDelta)) { dangle_target.z = angle_normalize(Random.randFs(DELTA_ANGLE_Z)); } // update inertion Fmatrix cur_matrix; cur_matrix.k = monster->Direction(); cur_matrix.c = get_head_position(monster); float rel_dist = m_prev_eye_matrix.c.distance_to(cur_matrix.c) / MAX_CAMERA_DIST; clamp (rel_dist, 0.f, 1.f); def_lerp(m_inertion, 1 - rel_dist, rel_dist, Device.fTimeDelta); // set pos and dir with inertion m_prev_eye_matrix.c.inertion(cur_matrix.c, m_inertion); m_prev_eye_matrix.k.inertion(cur_matrix.k, m_inertion); Fvector::generate_orthonormal_basis_normalized(m_prev_eye_matrix.k,m_prev_eye_matrix.j,m_prev_eye_matrix.i); // apply position and direction Mdef = m_prev_eye_matrix; //set fov float rel_speed = monster->m_fCurSpeed / 15.f; clamp (rel_speed,0.f,1.f); float m_target_fov = MIN_FOV + (MAX_FOV-MIN_FOV) * rel_speed; def_lerp(m_current_fov, m_target_fov, FOV_SPEED, Device.fTimeDelta); info.fFov = m_current_fov; ////////////////////////////////////////////////////////////////////////// // ”становить углы смещени¤ Fmatrix R; R.setHPB (dangle_current.x,dangle_current.y,dangle_current.z); Fmatrix mR; mR.mul (Mdef,R); info.d.set (mR.k); info.n.set (mR.j); info.p.set (mR.c); return TRUE; }
void CSphereGeom::get_local_form(Fmatrix& form) { form.identity(); form.c.set(m_sphere.P); }
BOOL CEffectorBobbing::Process (Fvector &p, Fvector &d, Fvector &n, float& /**fFov/**/, float& /**fFar/**/, float& /**fAspect/**/) { fTime += Device.fTimeDelta; if (dwMState&ACTOR_DEFS::mcAnyMove){ if (fReminderFactor<1.f) fReminderFactor += SPEED_REMINDER*Device.fTimeDelta; else fReminderFactor = 1.f; }else{ if (fReminderFactor>0.f) fReminderFactor -= SPEED_REMINDER*Device.fTimeDelta; else fReminderFactor = 0.f; } if (!fsimilar(fReminderFactor,0)){ Fmatrix M; M.identity (); M.j.set (n); M.k.set (d); M.i.crossproduct(n,d); M.c.set (p); // apply footstep bobbing effect Fvector dangle; float k = ((dwMState& ACTOR_DEFS::mcCrouch)?CROUCH_FACTOR:1.f); float A, ST; if(isActorAccelerated(dwMState, m_bZoomMode)) { A = m_fAmplitudeRun*k; ST = m_fSpeedRun*fTime*k; } else if(is_limping) { A = m_fAmplitudeLimp*k; ST = m_fSpeedLimp*fTime*k; } else { A = m_fAmplitudeWalk*k; ST = m_fSpeedWalk*fTime*k; } float _sinA = _abs(_sin(ST)*A)*fReminderFactor; float _cosA = _cos(ST)*A*fReminderFactor; p.y += _sinA; dangle.x = _cosA; dangle.z = _cosA; dangle.y = _sinA; Fmatrix R; R.setHPB (dangle.x,dangle.y,dangle.z); Fmatrix mR; mR.mul (M,R); d.set (mR.k); n.set (mR.j); } // else{ // fTime = 0; // } return TRUE; }
void render_box (IRenderVisual *visual, const Fmatrix &xform, const Fvector &additional, bool draw_child_boxes, const u32 &color) { CDebugRenderer &renderer = Level().debug_renderer(); IKinematics *kinematics = smart_cast<IKinematics*>(visual); VERIFY (kinematics); u16 bone_count = kinematics->LL_BoneCount(); VERIFY (bone_count); u16 visible_bone_count = kinematics->LL_VisibleBoneCount(); if (!visible_bone_count) return; Fmatrix matrix; Fvector *points = (Fvector*)_alloca(visible_bone_count*8*sizeof(Fvector)); Fvector *I = points; for (u16 i=0; i<bone_count; ++i) { if (!kinematics->LL_GetBoneVisible(i)) continue; const Fobb &obb = kinematics->LL_GetData(i).obb; if (fis_zero(obb.m_halfsize.square_magnitude())) { VERIFY (visible_bone_count > 1); --visible_bone_count; continue; } Fmatrix Mbox; obb.xform_get (Mbox); const Fmatrix &Mbone = kinematics->LL_GetBoneInstance(i).mTransform; Fmatrix X; matrix.mul_43 (xform,X.mul_43(Mbone,Mbox)); Fvector half_size = Fvector().add(obb.m_halfsize,additional); matrix.mulB_43 (Fmatrix().scale(half_size)); if (draw_child_boxes) renderer.draw_obb (matrix,color); static const Fvector local_points[8] = { Fvector().set(-1.f,-1.f,-1.f), Fvector().set(-1.f,-1.f,+1.f), Fvector().set(-1.f,+1.f,+1.f), Fvector().set(-1.f,+1.f,-1.f), Fvector().set(+1.f,+1.f,+1.f), Fvector().set(+1.f,+1.f,-1.f), Fvector().set(+1.f,-1.f,+1.f), Fvector().set(+1.f,-1.f,-1.f) }; for (u32 i=0; i<8; ++i, ++I) matrix.transform_tiny (*I,local_points[i]); } VERIFY (visible_bone_count); if (visible_bone_count == 1) { renderer.draw_obb (matrix,color); return; } VERIFY ((I - points) == (visible_bone_count*8)); MagicBox3 box = MagicMinBox(visible_bone_count*8,points); box.ComputeVertices (points); Fmatrix result; result.identity (); result.c = box.Center(); result.i.sub(points[3],points[2]).normalize(); result.j.sub(points[2],points[1]).normalize(); result.k.sub(points[2],points[6]).normalize(); Fvector scale; scale.x = points[3].distance_to(points[2])*.5f; scale.y = points[2].distance_to(points[1])*.5f; scale.z = points[2].distance_to(points[6])*.5f; result.mulB_43 (Fmatrix().scale(scale)); renderer.draw_obb (result,color); }
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); if (Device.Paused()) { Device.fTimeDelta = m_fTimeDelta; //fake, to update cam (problem with fov) g_pGameLevel->Cameras().UpdateFromCamera(cam); Device.fTimeDelta = 0.0f; //fake, to update cam (problem with fov) } else { g_pGameLevel->Cameras().UpdateFromCamera(cam); } //----------------------------------- } else { CCameraBase* cam = cameras[eacFreeFly]; if (cam_active == eacFixedLookAt) { cam = cameras[eacFixedLookAt]; } 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); if (Device.Paused()) { Device.fTimeDelta = m_fTimeDelta; //fake, to update cam (problem with fov) g_pGameLevel->Cameras().UpdateFromCamera(cam); Device.fTimeDelta = 0.0f; //fake, to update cam (problem with fov) } else { g_pGameLevel->Cameras().UpdateFromCamera(cam); } // hud output }; }
void CParticleEffect::Render(float ) { u32 dwOffset,dwCount; // Get a pointer to the particles in gp memory PAPI::Particle* particles; u32 p_cnt; ParticleManager()->GetParticles(m_HandleEffect,particles,p_cnt); if(p_cnt>0){ if (m_Def&&m_Def->m_Flags.is(CPEDef::dfSprite)){ FVF::LIT* pv_start = (FVF::LIT*)RCache.Vertex.Lock(p_cnt*4*4,geom->vb_stride,dwOffset); FVF::LIT* pv = pv_start; for(u32 i = 0; i < p_cnt; i++){ PAPI::Particle &m = particles[i]; Fvector2 lt,rb; lt.set (0.f,0.f); rb.set (1.f,1.f); if (m_Def->m_Flags.is(CPEDef::dfFramed)) m_Def->m_Frame.CalculateTC(iFloor(float(m.frame)/255.f),lt,rb); float r_x = m.size.x*0.5f; float r_y = m.size.y*0.5f; if (m_Def->m_Flags.is(CPEDef::dfVelocityScale)){ float speed = m.vel.magnitude(); r_x += speed*m_Def->m_VelocityScale.x; r_y += speed*m_Def->m_VelocityScale.y; } if (m_Def->m_Flags.is(CPEDef::dfAlignToPath)){ float speed = m.vel.magnitude(); if ((speed<EPS_S)&&m_Def->m_Flags.is(CPEDef::dfWorldAlign)){ Fmatrix M; M.setXYZ (m_Def->m_APDefaultRotation); if (m_RT_Flags.is(flRT_XFORM)){ Fvector p; m_XFORM.transform_tiny(p,m.pos); M.mulA_43 (m_XFORM); FillSprite (pv,M.k,M.i,p,lt,rb,r_x,r_y,m.color,m.rot.x); }else{ FillSprite (pv,M.k,M.i,m.pos,lt,rb,r_x,r_y,m.color,m.rot.x); } }else if ((speed>=EPS_S)&&m_Def->m_Flags.is(CPEDef::dfFaceAlign)){ Fmatrix M; M.identity(); M.k.div (m.vel,speed); M.j.set (0,1,0); if (_abs(M.j.dotproduct(M.k))>.99f) M.j.set(0,0,1); M.i.crossproduct (M.j,M.k); M.i.normalize (); M.j.crossproduct (M.k,M.i); M.j.normalize (); if (m_RT_Flags.is(flRT_XFORM)){ Fvector p; m_XFORM.transform_tiny(p,m.pos); M.mulA_43 (m_XFORM); FillSprite (pv,M.j,M.i,p,lt,rb,r_x,r_y,m.color,m.rot.x); }else{ FillSprite (pv,M.j,M.i,m.pos,lt,rb,r_x,r_y,m.color,m.rot.x); } }else{ Fvector dir; if (speed>=EPS_S) dir.div (m.vel,speed); else dir.setHP(-m_Def->m_APDefaultRotation.y,-m_Def->m_APDefaultRotation.x); if (m_RT_Flags.is(flRT_XFORM)){ Fvector p,d; m_XFORM.transform_tiny (p,m.pos); m_XFORM.transform_dir (d,dir); FillSprite (pv,p,d,lt,rb,r_x,r_y,m.color,m.rot.x); }else{ FillSprite (pv,m.pos,dir,lt,rb,r_x,r_y,m.color,m.rot.x); } } }else{ if (m_RT_Flags.is(flRT_XFORM)){ Fvector p; m_XFORM.transform_tiny (p,m.pos); FillSprite (pv,Device.vCameraTop,Device.vCameraRight,p,lt,rb,r_x,r_y,m.color,m.rot.x); }else{ FillSprite (pv,Device.vCameraTop,Device.vCameraRight,m.pos,lt,rb,r_x,r_y,m.color,m.rot.x); } } } dwCount = u32(pv-pv_start); RCache.Vertex.Unlock(dwCount,geom->vb_stride); if (dwCount) { RCache.set_xform_world (Fidentity); RCache.set_Geometry (geom); // u32 cm = RCache.get_CullMode(); RCache.set_CullMode (m_Def->m_Flags.is(CPEDef::dfCulling)?(m_Def->m_Flags.is(CPEDef::dfCullCCW)?CULL_CCW:CULL_CW):CULL_NONE); RCache.Render (D3DPT_TRIANGLELIST,dwOffset,0,dwCount,0,dwCount/2); RCache.set_CullMode (CULL_CCW ); } } } }