Example #1
0
void CDrawUtilities::DrawSpotLight(const Fvector& p, const Fvector& d, float range, float phi, u32 clr)
{
    Fmatrix T;
	Fvector p1;
    float H,P;
    float da	= PI_MUL_2/LINE_DIVISION;
	float b		= range*_cos(PI_DIV_2-phi/2);
	float a		= range*_sin(PI_DIV_2-phi/2);
    d.getHP		(H,P);
    T.setHPB	(H,P,0);     
    T.translate_over(p);
    _VertexStream*	Stream	= &RCache.Vertex;
    u32				vBase;
    FVF::L*	pv	 	= (FVF::L*)Stream->Lock(LINE_DIVISION*2+2,vs_L->vb_stride,vBase);
	for (float angle=0; angle<PI_MUL_2; angle+=da){
        float _sa	=_sin(angle);
        float _ca	=_cos(angle);
		p1.x		= b * _ca;
		p1.y		= b * _sa;
        p1.z		= a;
        T.transform_tiny(p1);
        // fill VB
        pv->set		(p,clr); pv++;
        pv->set		(p1,clr); pv++;
    }
    p1.mad			(p,d,range);
    pv->set			(p,clr); pv++;
    pv->set			(p1,clr); pv++;
    Stream->Unlock	(LINE_DIVISION*2+2,vs_L->vb_stride);
    // and Render it as triangle list
    DU_DRAW_DP		(D3DPT_LINELIST,vs_L,vBase,LINE_DIVISION+1);
}
Example #2
0
//---------------------------------------------------------------------
Fmatrix	CPhantom::XFORM_center()
{
	Fvector			center;
	Center			(center);
	Fmatrix	xform	= XFORM();
	return			xform.translate_over(center);
}
Example #3
0
void CDrawUtilities::DrawPlane  (const Fvector& center, const Fvector2& scale, const Fvector& rotate, u32 clr_s, u32 clr_w, BOOL bCull, BOOL bSolid, BOOL bWire)
{
    Fmatrix M;
    M.setHPB		(rotate.y,rotate.x,rotate.z);
    M.translate_over(center);
	// fill VB
	_VertexStream*	Stream	= &RCache.Vertex;
	u32			vBase;
    
    if (bSolid){
	    DU_DRAW_SH(dxRenderDeviceRender::Instance().m_SelectionShader);
        FVF::L*	pv	 = (FVF::L*)Stream->Lock(5,vs_L->vb_stride,vBase);
        pv->set		(-scale.x, 0, -scale.y, clr_s); M.transform_tiny(pv->p); pv++;
        pv->set		(-scale.x, 0, +scale.y, clr_s); M.transform_tiny(pv->p); pv++;
        pv->set		(+scale.x, 0, +scale.y, clr_s); M.transform_tiny(pv->p); pv++;
        pv->set		(+scale.x, 0, -scale.y, clr_s); M.transform_tiny(pv->p); pv++;
        pv->set		(*(pv-4));
        Stream->Unlock(5,vs_L->vb_stride);
        if (!bCull) DU_DRAW_RS(D3DRS_CULLMODE,D3DCULL_NONE);
        DU_DRAW_DP		(D3DPT_TRIANGLEFAN,vs_L,vBase,2);
        if (!bCull) DU_DRAW_RS(D3DRS_CULLMODE,D3DCULL_CCW);
    }

    if (bWire){
	    DU_DRAW_SH(dxRenderDeviceRender::Instance().m_WireShader);
        FVF::L*	pv	 = (FVF::L*)Stream->Lock(5,vs_L->vb_stride,vBase);
        pv->set		(-scale.x, 0, -scale.y, clr_w); M.transform_tiny(pv->p); pv++;
        pv->set		(+scale.x, 0, -scale.y, clr_w); M.transform_tiny(pv->p); pv++;
        pv->set		(+scale.x, 0, +scale.y, clr_w); M.transform_tiny(pv->p); pv++;
        pv->set		(-scale.x, 0, +scale.y, clr_w); M.transform_tiny(pv->p); pv++;
        pv->set		(*(pv-4));
        Stream->Unlock(5,vs_L->vb_stride);
	    DU_DRAW_DP	(D3DPT_LINESTRIP,vs_L,vBase,4);
    }
}
Example #4
0
void	CCustomZone::Hit					(SHit* pHDS)
{
	Fmatrix M;
	M.identity();
	M.translate_over	(pHDS->p_in_bone_space);
	M.mulA_43			(XFORM());
	PlayBulletParticles	(M.c);	
}
Example #5
0
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);
}
Example #6
0
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);
}
Example #7
0
void CSpectator::cam_Update	(CActor* A)
{
	if (A){
		const Fmatrix& M			= A->XFORM();
		CCameraBase* pACam			= A->cam_Active();
		CCameraBase* cam			= cameras[cam_active];
		switch(cam_active) {
		case eacFirstEye:{
			Fvector P, D, N;
			pACam->Get				(P, D, N);
			cam->Set				(P, D, N);
			}break;
		case eacLookAt:{
			float y,p,r;
			M.getHPB				(y,p,r);
			cam->Set				(pACam->yaw,pACam->pitch,-r);
			}
		case eacFreeLook:{
			cam->SetParent			(A);
			Fmatrix tmp; tmp.identity();
			
			Fvector point, point1, dangle;
			point.set	(0.f,1.6f,0.f);
			point1.set	(0.f,1.6f,0.f);			
			M.transform_tiny		(point);
			tmp.translate_over(point);
			tmp.transform_tiny		(point1);
			if (!A->g_Alive()) point.set(point1);
			cam->Update				(point,dangle);
			}break;
		}
		//-----------------------------------
		Fvector P, D, N;
		cam->Get(P, D, N);
		cameras[eacFreeFly]->Set(P, D, N);
		cameras[eacFreeFly]->Set(cam->yaw, cam->pitch, 0);
		P.y -= 1.6f;
		XFORM().translate_over(P);
		//-----------------------------------
		g_pGameLevel->Cameras().Update(cam);
	}else{
		CCameraBase* cam			= cameras[eacFreeFly];
		Fvector point, dangle;
		point.set					(0.f,1.6f,0.f);
		XFORM().transform_tiny	(point);

		// apply shift
		dangle.set					(0,0,0);
		
		cam->Update					(point,dangle);
//		cam->vPosition.set(point0);
		g_pGameLevel->Cameras().Update	(cam);
		// hud output
	};
}
Example #8
0
void CEnvironment::RenderSky		()
{
#ifndef _EDITOR
	if (0==g_pGameLevel)		return	;
#endif
	// clouds_sh.create		("clouds","null");
	//. this is the bug-fix for the case when the sky is broken
	//. for some unknown reason the geoms happen to be invalid sometimes
	//. if vTune show this in profile, please add simple cache (move-to-forward last found) 
	//. to the following functions:
	//.		CResourceManager::_CreateDecl
	//.		CResourceManager::CreateGeom
	if(bNeed_re_create_env)
	{
		sh_2sky.create			(&m_b_skybox,"skybox_2t");
		sh_2geom.create			(v_skybox_fvf,RCache.Vertex.Buffer(), RCache.Index.Buffer());
		clouds_sh.create		("clouds","null");
		clouds_geom.create		(v_clouds_fvf,RCache.Vertex.Buffer(), RCache.Index.Buffer());
		bNeed_re_create_env		= FALSE;
	}
	::Render->rmFar				();

	// draw sky box
	Fmatrix						mSky;
	mSky.rotateY				(CurrentEnv.sky_rotation);
	mSky.translate_over			(Device.vCameraPosition);

	u32		i_offset,v_offset;
	u32		C					= color_rgba(iFloor(CurrentEnv.sky_color.x*255.f), iFloor(CurrentEnv.sky_color.y*255.f), iFloor(CurrentEnv.sky_color.z*255.f), iFloor(CurrentEnv.weight*255.f));

	// Fill index buffer
	u16*	pib					= RCache.Index.Lock	(20*3,i_offset);
	CopyMemory					(pib,hbox_faces,20*3*2);
	RCache.Index.Unlock			(20*3);

	// Fill vertex buffer
	v_skybox* pv				= (v_skybox*)	RCache.Vertex.Lock	(12,sh_2geom.stride(),v_offset);
	for (u32 v=0; v<12; v++)	pv[v].set		(hbox_verts[v*2],C,hbox_verts[v*2+1]);
	RCache.Vertex.Unlock		(12,sh_2geom.stride());

	// Render
	RCache.set_xform_world		(mSky);
	RCache.set_Geometry			(sh_2geom);
	RCache.set_Shader			(sh_2sky);
	RCache.set_Textures			(&CurrentEnv.sky_r_textures);
	RCache.Render				(D3DPT_TRIANGLELIST,v_offset,0,12,i_offset,20);

	// Sun
	::Render->rmNormal			();
	eff_LensFlare->Render		(TRUE,FALSE,FALSE);
}
Example #9
0
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);
            }
        }
    }
}
Example #10
0
CParticlesObject* CBaseMonster::PlayParticles(const shared_str& name, const Fvector &position, const Fvector &dir, BOOL auto_remove, BOOL xformed)
{
	CParticlesObject* ps = CParticlesObject::Create(name.c_str(),auto_remove);
	
	// вычислить позицию и направленность партикла
	Fmatrix	matrix; 

	matrix.identity			();
	matrix.k.set			(dir);
	Fvector::generate_orthonormal_basis_normalized(matrix.k,matrix.j,matrix.i);
	matrix.translate_over	(position);
	
	(xformed) ?				ps->SetXFORM (matrix) : ps->UpdateParent(matrix,zero_vel); 
	ps->Play				(false);

	return ps;
}
Example #11
0
void CPoltergeist::Die(CObject* who)
{
	if (m_tele) {
		if (state_invisible) {
			setVisible(true);

			if (PPhysicsShell()) {
				Fmatrix M;
				M.set							(XFORM());
				M.translate_over				(m_current_position);
				PPhysicsShell()->SetTransform	(M);
			} else 
				Position() = m_current_position;
		}
	}

	inherited::Die				(who);
	Energy::disable				();

	ability()->on_die			();
}
Example #12
0
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;
}
bool ESceneObjectTool::ExportBreakableObjects(SExportStreams* F)
{
	bool bResult = true;
    CGeomPartExtractor* extractor=0;

    Fbox 		bb;
    if (!GetBox(bb)) return false;

    extractor	= xr_new<CGeomPartExtractor>();
    extractor->Initialize(bb,EPS_L,2);

    UI->SetStatus	("Export breakable objects...");
	// collect verts&&faces
    {
	    SPBItem* pb = UI->ProgressStart(m_Objects.size(),"Prepare geometry...");
        for (ObjectIt it=m_Objects.begin(); it!=m_Objects.end(); it++){
	        pb->Inc();
            CSceneObject* obj 		= dynamic_cast<CSceneObject*>(*it); VERIFY(obj);
            if (obj->IsStatic()){
                CEditableObject *O 	= obj->GetReference();
                const Fmatrix& T 	= obj->_Transform();
                for(EditMeshIt M=O->FirstMesh();M!=O->LastMesh();M++)
                    if (!build_mesh	(T,*M,extractor,SGameMtl::flBreakable,FALSE)){bResult=false;break;}
            }
        }
	    UI->ProgressEnd(pb);
    }
    if (!extractor->Process())		bResult = false;
    // export parts
    if (bResult){
    	SBPartVec& parts			= extractor->GetParts();
	    SPBItem* pb = UI->ProgressStart(parts.size(),"Export Parts...");
        for (SBPartVecIt p_it=parts.begin(); p_it!=parts.end(); p_it++){
	        pb->Inc();
            SBPart*	P				= *p_it;
        	if (P->Valid()){
                // export visual
                AnsiString sn		= AnsiString().sprintf("meshes\\brkbl#%d.ogf",(p_it-parts.begin()));
                xr_string fn		= Scene->LevelPath()+sn.c_str();
                IWriter* W			= FS.w_open(fn.c_str()); R_ASSERT(W);
                if (!P->Export(*W,1)){
                    ELog.DlgMsg		(mtError,"Invalid breakable object.");
                    bResult 		= false;
                    break;
                }
                FS.w_close			(W);
                // export spawn object
                {
                    AnsiString entity_ref		= "breakable_object";
                    ISE_Abstract*	m_Data		= create_entity(entity_ref.c_str()); 	VERIFY(m_Data);
                    CSE_Visual* m_Visual		= m_Data->visual();	VERIFY(m_Visual);
                    // set params
                    m_Data->set_name			(entity_ref.c_str());
                    m_Data->set_name_replace	(sn.c_str());
                    m_Data->position().set		(P->m_RefOffset);
                    m_Data->angle().set			(P->m_RefRotate);
                    m_Visual->set_visual		(sn.c_str(),false);

					if (s_draw_dbg){
                        Fmatrix MX;
                        MX.setXYZi				(P->m_RefRotate);
                        MX.translate_over		(P->m_RefOffset);
                        Fvector DR				= {0,0,1};
                        MX.transform_dir		(DR);
                        Tools->m_DebugDraw.AppendLine(P->m_RefOffset,Fvector().mad(P->m_RefOffset,MX.k,1.f),0xFF0000FF,false,false);
                    }

                    NET_Packet					Packet;
                    m_Data->Spawn_Write			(Packet,TRUE);

                    F->spawn.stream.open_chunk	(F->spawn.chunk++);
                    F->spawn.stream.w			(Packet.B.data,Packet.B.count);
                    F->spawn.stream.close_chunk	();
                    destroy_entity				(m_Data);
                }
            }else{
            	ELog.Msg(mtError,"Can't export invalid part #%d",p_it-parts.begin());
            }
        }
	    UI->ProgressEnd(pb);
    }
    // clean up
    xr_delete(extractor);

    return bResult;
}
Example #14
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);
}
Example #15
0
void CActor::cam_Update(float dt, float fFOV)
{
	if(m_holder)		return;

	if( (mstate_real & mcClimb) && (cam_active!=eacFreeLook) )
		camUpdateLadder(dt);
	on_weapon_shot_update();
	float y_shift =0;
	
	if( GamePersistent().GameType() != eGameIDSingle && ik_cam_shift && character_physics_support() && character_physics_support()->ik_controller() )
	{
		y_shift = character_physics_support()->ik_controller()->Shift();
		float cam_smooth_k = 1.f;
		if(_abs(y_shift-current_ik_cam_shift)>ik_cam_shift_tolerance)
		{

			cam_smooth_k = 1.f - ik_cam_shift_speed * dt/0.01f;

		}

		if(_abs(y_shift)<ik_cam_shift_tolerance/2.f)
			cam_smooth_k = 1.f - ik_cam_shift_speed * 1.f/0.01f * dt;
		clamp( cam_smooth_k, 0.f, 1.f );
		current_ik_cam_shift = cam_smooth_k * current_ik_cam_shift + y_shift * ( 1.f - cam_smooth_k );
	} else
		current_ik_cam_shift = 0;

	Fvector point		= {0,CameraHeight() + current_ik_cam_shift,0}; 
	Fvector dangle		= {0,0,0};
	Fmatrix				xform;
	xform.setXYZ		(0,r_torso.yaw,0);
	xform.translate_over(XFORM().c);

	// lookout
	if (this == Level().CurrentControlEntity())
		cam_Lookout( xform, point.y  );


	if (!fis_zero(r_torso.roll))
	{
		float radius		= point.y*0.5f;
		float valid_angle	= r_torso.roll/2.f;
		calc_point			(point,radius,0,valid_angle);
		dangle.z			= (PI_DIV_2-((PI+valid_angle)/2));
	}

	float flCurrentPlayerY	= xform.c.y;

	// Smooth out stair step ups
	if ((character_physics_support()->movement()->Environment()==CPHMovementControl::peOnGround) && (flCurrentPlayerY-fPrevCamPos>0)){
		fPrevCamPos			+= dt*1.5f;
		if (fPrevCamPos > flCurrentPlayerY)
			fPrevCamPos		= flCurrentPlayerY;
		if (flCurrentPlayerY-fPrevCamPos>0.2f)
			fPrevCamPos		= flCurrentPlayerY-0.2f;
		point.y				+= fPrevCamPos-flCurrentPlayerY;
	}else{
		fPrevCamPos			= flCurrentPlayerY;
	}

	float _viewport_near			= VIEWPORT_NEAR;
	// calc point
	xform.transform_tiny			(point);

	CCameraBase* C					= cam_Active();

	C->Update						(point,dangle);
	C->f_fov						= fFOV;

	if(eacFirstEye != cam_active)
	{
		cameras[eacFirstEye]->Update	(point,dangle);
		cameras[eacFirstEye]->f_fov		= fFOV;
	} 
	if (Level().CurrentEntity() == this)
	{
		collide_camera( *cameras[eacFirstEye], _viewport_near, this );
	}
	if( psActorFlags.test(AF_PSP) )
	{
		Cameras().UpdateFromCamera			(C);
	}else
	{
		Cameras().UpdateFromCamera			(cameras[eacFirstEye]);
	}

	fCurAVelocity			= vPrevCamDir.sub(cameras[eacFirstEye]->vDirection).magnitude()/Device.fTimeDelta;
	vPrevCamDir				= cameras[eacFirstEye]->vDirection;

#ifdef DEBUG
	if( dbg_draw_camera_collision )
	{
		dbg_draw_viewport( *cameras[eacFirstEye], _viewport_near );
		dbg_draw_viewport( Cameras(), _viewport_near );
	}
#endif

	if (Level().CurrentEntity() == this)
	{
		Level().Cameras().UpdateFromCamera	(C);
		if(eacFirstEye == cam_active && !Level().Cameras().GetCamEffector(cefDemo)){
			Cameras().ApplyDevice	(_viewport_near);
		}
	}
}
void CActor::cam_Update(float dt, float fFOV)
{
	if(m_holder)		return;

	if( (mstate_real & mcClimb) && (cam_active!=eacFreeLook) )
		camUpdateLadder(dt);
	on_weapon_shot_update();

	// Alex ADD: smooth crouch fix
	if (!CurrentHeight)CurrentHeight = CameraHeight();
	float HeightInterpolationSpeed = 9.f;
	if (CurrentHeight != CameraHeight() && !Device.dwPrecacheFrame)
	{
		CurrentHeight = (CurrentHeight * (1.0f - HeightInterpolationSpeed*dt)) + (CameraHeight() * HeightInterpolationSpeed*dt);
	}
	Fvector point = { 0, CurrentHeight, 0 };
	//Fvector point		= {0,CameraHeight(),0}; 
	
	Fvector dangle		= {0,0,0};
	Fmatrix				xform;
	xform.setXYZ		(0,r_torso.yaw,0);
	xform.translate_over(XFORM().c);

	// lookout
	if (this == Level().CurrentControlEntity())
		cam_Lookout( xform, point.y  );


	if (!fis_zero(r_torso.roll))
	{
		float radius		= point.y*0.5f;
		float valid_angle	= r_torso.roll/2.f;
		calc_point			(point,radius,0,valid_angle);
		dangle.z			= (PI_DIV_2-((PI+valid_angle)/2));
	}

	float flCurrentPlayerY	= xform.c.y;

	// Smooth out stair step ups
	if ((character_physics_support()->movement()->Environment()==peOnGround) && (flCurrentPlayerY-fPrevCamPos>0)){
		fPrevCamPos			+= dt*1.5f;
		if (fPrevCamPos > flCurrentPlayerY)
			fPrevCamPos		= flCurrentPlayerY;
		if (flCurrentPlayerY-fPrevCamPos>0.2f)
			fPrevCamPos		= flCurrentPlayerY-0.2f;
		point.y				+= fPrevCamPos-flCurrentPlayerY;
	}else{
		fPrevCamPos			= flCurrentPlayerY;
	}

	float _viewport_near			= VIEWPORT_NEAR;
	// calc point
	xform.transform_tiny			(point);

	CCameraBase* C					= cam_Active();

	C->Update						(point,dangle);
	C->f_fov						= fFOV;

	if(eacFirstEye != cam_active)
	{
		cameras[eacFirstEye]->Update	(point,dangle);
		cameras[eacFirstEye]->f_fov		= fFOV;
	} 
	if (Level().CurrentEntity() == this)
		collide_camera( *cameras[eacFirstEye], _viewport_near );

	if( psActorFlags.test(AF_PSP) )
	{
		Cameras().UpdateFromCamera			(C);
	}else
	{
		Cameras().UpdateFromCamera			(cameras[eacFirstEye]);
	}

	fCurAVelocity			= vPrevCamDir.sub(cameras[eacFirstEye]->vDirection).magnitude()/Device.fTimeDelta;
	vPrevCamDir				= cameras[eacFirstEye]->vDirection;

#ifdef DEBUG
	if( dbg_draw_camera_collision )
	{
		dbg_draw_viewport( *cameras[eacFirstEye], _viewport_near );
		dbg_draw_viewport( Cameras(), _viewport_near );
	}
#endif

	if (Level().CurrentEntity() == this)
	{
		Level().Cameras().UpdateFromCamera	(C);
		if(eacFirstEye == cam_active && !Level().Cameras().GetCamEffector(cefDemo)){
			Cameras().ApplyDevice	(_viewport_near);
		}
	}
}