123
This commit is contained in:
427
CryGame/XPlayerLight.cpp
Normal file
427
CryGame/XPlayerLight.cpp
Normal file
@@ -0,0 +1,427 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Game Source Code
|
||||
//
|
||||
// File: XPlayerLight.cpp
|
||||
// Description: Entity player class.
|
||||
// flashlight funtionality
|
||||
//
|
||||
// History:
|
||||
// - apr 17,2003: Created by Kirill - splitting Xplayer.cpp in multiple files
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "XPlayer.h"
|
||||
|
||||
#include <IAgent.h>
|
||||
|
||||
// <<FIXME>> look above
|
||||
#include "I3DEngine.h"
|
||||
|
||||
// remove this
|
||||
#include <IAISystem.h>
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
|
||||
Vec3d CPlayer::GetFLightPos( )
|
||||
{
|
||||
|
||||
if(IsMyPlayer())
|
||||
{
|
||||
Vec3d pos;
|
||||
Vec3d ang;
|
||||
GetFirePosAngles(pos, ang);
|
||||
|
||||
ang = ConvertToRadAngles(ang);
|
||||
|
||||
return pos - ang;
|
||||
|
||||
}
|
||||
if(m_pGame->pl_head->GetIVal()==0)
|
||||
{
|
||||
ICryCharInstance *pChar = m_pEntity->GetCharInterface()->GetCharacter(0);
|
||||
if(pChar)
|
||||
{
|
||||
ICryBone * bone = pChar->GetBoneByName("weapon_bone"); // find bone in the list of bones;
|
||||
if(bone)
|
||||
{
|
||||
Matrix44 mat;
|
||||
mat.SetIdentity();
|
||||
Vec3d rot = m_pEntity->GetAngles();
|
||||
rot.x=0;
|
||||
//mat.RotateMatrix_fix(angles);
|
||||
mat=Matrix44::CreateRotationZYX(-gf_DEGTORAD*rot)*mat; //NOTE: angles in radians and negated
|
||||
return m_pEntity->GetPos() + mat.TransformPointOLD(bone->GetBonePosition()) - Vec3d(0,0,0.3f);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Vec3d pos;
|
||||
Vec3d ang;
|
||||
GetFirePosAngles(pos, ang);
|
||||
|
||||
return pos + Vec3d(0.f,0.f,.3f);
|
||||
|
||||
/*
|
||||
if(m_pBoneHead)
|
||||
{
|
||||
// light->m_Origin = m_pEntity->GetPos() + m_pBoneHead->GetBonePosition();
|
||||
Matrix44 mat;
|
||||
mat.Identity();
|
||||
Vec3d rot = m_pEntity->GetAngles();
|
||||
rot.x=0;
|
||||
//mat.RotateMatrix_fix(angles);
|
||||
mat=GetRotationZYX44(-gf_DEGTORAD*rot)*mat; //NOTE: angles in radians and negated
|
||||
return m_pEntity->GetPos() + mat.TransformPoint(m_pBoneHead->GetBonePosition());
|
||||
}
|
||||
*/
|
||||
}
|
||||
return m_pEntity->GetPos() + Vec3d(0,0,2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
//-----------------------------------------------------------------
|
||||
void CPlayer::ProceedFLight( )
|
||||
{
|
||||
if(!m_bLightOn)
|
||||
return;
|
||||
|
||||
if( !m_pDynLight )
|
||||
return;
|
||||
|
||||
FUNCTION_PROFILER( GetISystem(),PROFILE_GAME );
|
||||
|
||||
float totalLightScale = 1.0f - m_pGame->GetSystem( )->GetI3DEngine()->GetAmbientLightAmountForEntity(m_pEntity)*2.0f;
|
||||
|
||||
// for local player make it always bright
|
||||
if( IsMyPlayer() )
|
||||
totalLightScale = 1.0f;
|
||||
|
||||
if(totalLightScale<.2f)
|
||||
totalLightScale = .2f;
|
||||
|
||||
//
|
||||
// fixme - this causes crach in destructor
|
||||
m_pDynLight->m_Flags = DLF_PROJECT;
|
||||
if(IsMyPlayer())
|
||||
m_pDynLight->m_fLightFrustumAngle = 30;
|
||||
else
|
||||
m_pDynLight->m_fLightFrustumAngle = m_pGame->p_lightfrustum->GetFVal(); // for other players - more light
|
||||
m_pDynLight->m_fRadius = m_pGame->p_lightrange->GetFVal();
|
||||
|
||||
m_pDynLight->m_Origin = GetFLightPos();
|
||||
// light->m_ProjAngles = m_pEntity->GetAngles();
|
||||
m_pDynLight->m_ProjAngles = Vec3d(m_pEntity->GetAngles().y,m_pEntity->GetAngles().x,m_pEntity->GetAngles().z-90);
|
||||
|
||||
m_pDynLight->m_Color = CFColor(totalLightScale,totalLightScale,totalLightScale, 1.0f);
|
||||
m_pDynLight->m_SpecColor = CFColor(totalLightScale,totalLightScale,totalLightScale);
|
||||
|
||||
// m_pDynLight->m_Color = CFColor(.45f,.45f,.45f, 1.0f);
|
||||
// m_pDynLight->m_SpecColor = CFColor(.45f,.45f,.45f);
|
||||
|
||||
m_pDynLight->m_Flags |= (DLF_LIGHTSOURCE | DLF_SPECULAR_ONLY_FOR_HIGHSPEC);
|
||||
|
||||
|
||||
/*
|
||||
light->m_pShader = 0;
|
||||
if (!light->m_pLightImage)
|
||||
{
|
||||
//Light.m_pLightImage = m_IndInterface.m_pRenderer->EF_LoadTexture("FlashLightCube", 0, FT2_FORCECUBEMAP, eTT_Cubemap);
|
||||
light->m_pLightImage = m_pGame->GetSystem()->GetIRenderer()->EF_LoadTexture("Textures/Lights/Light_testgrid", 0, FT2_FORCECUBEMAP, eTT_Cubemap);
|
||||
}
|
||||
*/
|
||||
|
||||
// m_pGame->GetSystem()->GetIRenderer()->EF_UpdateDLight(light);
|
||||
m_pGame->GetSystem()->GetI3DEngine()->AddDynamicLightSource(*m_pDynLight, GetEntity());
|
||||
|
||||
if (m_pLightTarget)
|
||||
{
|
||||
ray_hit hit;
|
||||
Vec3d dir = ConvertToRadAngles(m_pEntity->GetAngles());
|
||||
dir*=20;
|
||||
int colliders = m_pGame->GetSystem()->GetIPhysicalWorld()->RayWorldIntersection(GetFLightPos(),dir,ent_all,0,&hit,1,m_pEntity->GetPhysics());
|
||||
if (colliders)
|
||||
{
|
||||
hit.pt.z +=float (rand()%100/1000);
|
||||
Vec3d newPos = hit.pt -m_pEntity->GetPos();
|
||||
// move it about 10 cm away from the point of collision
|
||||
float fDIST = newPos.Length();
|
||||
newPos *= 1.f - 0.1f/fDIST;
|
||||
m_pLightTarget->SetPos(m_pEntity->GetPos()+newPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
void CPlayer::UpdateLightBlinding()
|
||||
{
|
||||
FUNCTION_PROFILER( GetISystem(),PROFILE_GAME );
|
||||
|
||||
//return;
|
||||
if (m_pGame->m_PlayersWithLighs.empty() &&
|
||||
((IsMyPlayer()&&m_vBlindingList.empty()) || (m_bIsAI&&!m_stats.bIsBlinded)) )
|
||||
return;
|
||||
|
||||
ListOfPlayers::iterator pl = m_pGame->m_PlayersWithLighs.begin();
|
||||
|
||||
Vec3d tmp;
|
||||
Vec3d thisForward;
|
||||
float totalLightScale = m_pGame->GetSystem( )->GetI3DEngine()->GetAmbientLightAmountForEntity(m_pEntity);
|
||||
|
||||
totalLightScale*=3.0f;
|
||||
|
||||
|
||||
if(totalLightScale>1.0f)
|
||||
totalLightScale=1.0f;
|
||||
//GetLightAmountForEntity( m_pEntity );
|
||||
|
||||
//if( m_bIsAI )
|
||||
//m_pGame->GetSystem()->GetILog()->Log("\003 lScale %.3f", totalLightScale );
|
||||
|
||||
|
||||
GetFirePosAngles(tmp, thisForward);
|
||||
thisForward=ConvertToRadAngles(thisForward);
|
||||
thisForward.normalize();
|
||||
|
||||
m_stats.curBlindingValue = 0.0f;
|
||||
|
||||
for( ; pl!=m_pGame->m_PlayersWithLighs.end(); pl++ )
|
||||
{
|
||||
if( (*pl)==this )
|
||||
continue;
|
||||
CPlayer *curPlayer = (*pl);
|
||||
Vec3d blindingPos = curPlayer->GetFLightPos();
|
||||
Vec3d direction = blindingPos - m_vEyePos;
|
||||
Vec3d curForward;
|
||||
float blindingValue=0.0f;
|
||||
float dist2 = 0;
|
||||
curPlayer->GetFirePosAngles(tmp, curForward);
|
||||
curForward=ConvertToRadAngles(curForward);
|
||||
curForward.normalize();
|
||||
dist2 = direction.len2();
|
||||
direction.normalize();
|
||||
|
||||
blindingValue = direction*thisForward;
|
||||
|
||||
if(blindingValue<0.0f)
|
||||
continue;
|
||||
|
||||
direction = -direction;
|
||||
|
||||
//dist2 = (direction*curForward);
|
||||
blindingValue = blindingValue*(direction*curForward);
|
||||
blindingValue *= blindingValue;
|
||||
blindingValue *= blindingValue;
|
||||
blindingValue *= blindingValue;
|
||||
// blindingValue = blindingValue*blindingValue*blindingValue;
|
||||
|
||||
dist2 = m_pGame->pl_dist->GetFVal()/dist2;
|
||||
|
||||
if(dist2 > 1.0f)
|
||||
dist2 = cry_sqrtf(dist2);
|
||||
blindingValue *= dist2;
|
||||
|
||||
blindingValue *= m_pGame->pl_intensity->GetFVal();
|
||||
|
||||
blindingValue *= (1.0f - totalLightScale);
|
||||
|
||||
if(blindingValue<.2f)
|
||||
continue;
|
||||
|
||||
ray_hit hit;
|
||||
IPhysicalEntity *physic = curPlayer->m_pEntity->GetPhysics();
|
||||
if( m_pGame->GetSystem()->GetIPhysicalWorld()->
|
||||
RayWorldIntersection(blindingPos,m_vEyePos-blindingPos,ent_terrain | ent_static,
|
||||
rwi_stop_at_pierceable,&hit,1, physic))
|
||||
continue;
|
||||
|
||||
if(IsMyPlayer())
|
||||
{
|
||||
Vec3d scrPos;
|
||||
GetGame()->GetSystem()->GetIRenderer()->ProjectToScreen( blindingPos.x, blindingPos.y, blindingPos.z,
|
||||
&scrPos.x,&scrPos.y,&scrPos.z);
|
||||
|
||||
scrPos.z = blindingValue;
|
||||
scrPos.x *= 8.0f;
|
||||
scrPos.y *= 6.0f;
|
||||
// m_vBlindingPosList.push_back(scrPos);
|
||||
BlindingList::iterator curB = m_vBlindingList.find(curPlayer);
|
||||
if( curB == m_vBlindingList.end() )
|
||||
{
|
||||
m_vBlindingList[curPlayer] = scrPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
(curB->second).x = scrPos.x;
|
||||
(curB->second).y = scrPos.y;
|
||||
if((curB->second).z < scrPos.z)
|
||||
(curB->second).z = scrPos.z;
|
||||
}
|
||||
}
|
||||
|
||||
if(m_bIsAI && m_stats.curBlindingValue < blindingValue)
|
||||
{
|
||||
m_stats.curBlindingValue = blindingValue;
|
||||
}
|
||||
}
|
||||
|
||||
float fade = m_pTimer->GetFrameTime()*m_pGame->pl_fadescale->GetFVal();
|
||||
BlindingList::iterator curB = m_vBlindingList.begin();
|
||||
for( ; curB != m_vBlindingList.end(); )
|
||||
{
|
||||
(curB->second).z -= fade;
|
||||
if((curB->second).z<=0.0f) // remove
|
||||
{
|
||||
BlindingList::iterator nextB = curB;
|
||||
nextB++;
|
||||
m_vBlindingList.erase( curB );
|
||||
curB = nextB;
|
||||
continue;
|
||||
}
|
||||
curB++;
|
||||
}
|
||||
|
||||
m_LastUsed = m_vBlindingList.begin();
|
||||
|
||||
if( m_bIsAI )
|
||||
{
|
||||
IAIObject *pObject = m_pEntity->GetAI();
|
||||
IPuppet *pPuppet=0;
|
||||
if (pObject->CanBeConvertedTo(AIOBJECT_PUPPET,(void**)&pPuppet))
|
||||
{
|
||||
if(m_stats.curBlindingValue > 1.6f)
|
||||
{
|
||||
if(!m_stats.bIsBlinded)
|
||||
{
|
||||
pObject->SetSignal(0, "SHARED_BLINDED");
|
||||
m_stats.bIsBlinded = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_stats.bIsBlinded)
|
||||
{
|
||||
pObject->SetSignal(0, "SHARED_UNBLINDED");
|
||||
m_stats.bIsBlinded = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if(m_stats.curBlindingValue > .1f)
|
||||
//m_pGame->GetSystem()->GetILog()->Log("\003 blind %.3f", m_stats.curBlindingValue );
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
void CPlayer::SwitchFlashLight( bool on )
|
||||
{
|
||||
// only perform switch, if the player actually has a flashlight
|
||||
// or if switching off
|
||||
if (!m_stats.has_flashlight && !m_bLightOn)
|
||||
return;
|
||||
|
||||
if(m_bLightOn == on)
|
||||
return;
|
||||
|
||||
FUNCTION_PROFILER( GetISystem(),PROFILE_GAME );
|
||||
|
||||
m_bLightOn = on;
|
||||
m_pEntity->SendScriptEvent( ScriptEvent_FlashLightSwitch , (int)(m_bLightOn));
|
||||
if( m_bLightOn )
|
||||
m_pGame->m_PlayersWithLighs.push_back( this );
|
||||
else
|
||||
{
|
||||
ListOfPlayers::iterator self = std::find(m_pGame->m_PlayersWithLighs.begin(), m_pGame->m_PlayersWithLighs.end(), this);
|
||||
if(self!=m_pGame->m_PlayersWithLighs.end())
|
||||
m_pGame->m_PlayersWithLighs.erase(self);
|
||||
}
|
||||
|
||||
if (on && !m_bIsAI)
|
||||
{
|
||||
m_pLightTarget = m_pGame->GetSystem()->GetAISystem()->CreateAIObject(AIOBJECT_ATTRIBUTE,0);
|
||||
if (m_pLightTarget)
|
||||
{
|
||||
m_pLightTarget->Bind(m_pEntity->GetAI());
|
||||
m_pLightTarget->SetPos(m_pEntity->GetPos());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_pLightTarget)
|
||||
{
|
||||
m_pGame->GetSystem()->GetAISystem()->RemoveObject(m_pLightTarget);
|
||||
m_pLightTarget = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------------------------------
|
||||
bool CPlayer::InitLight( const char* sImg, const char* sShader )
|
||||
{
|
||||
if (m_pDynLight)
|
||||
delete m_pDynLight;
|
||||
m_pDynLight = new CDLight();
|
||||
|
||||
if(sImg && sImg[0])
|
||||
{
|
||||
m_pDynLight->m_fAnimSpeed = 0;
|
||||
int nFlags2 = FT2_FORCECUBEMAP;
|
||||
// if (bUseAsCube)
|
||||
// nFlags2 |= FT2_REPLICATETOALLSIDES;
|
||||
// if (fAnimSpeed)
|
||||
// nFlags2 |= FT2_CHECKFORALLSEQUENCES;
|
||||
m_pDynLight->m_pLightImage = m_pGame->GetSystem()->GetIRenderer()->EF_LoadTexture(sImg, 0, nFlags2, eTT_Cubemap);
|
||||
m_pDynLight->m_Flags = DLF_PROJECT;
|
||||
}
|
||||
else
|
||||
m_pDynLight->m_Flags = DLF_POINT;
|
||||
|
||||
if(sShader && sShader[0])
|
||||
m_pDynLight->m_pShader = m_pGame->GetSystem()->GetIRenderer()->EF_LoadShader((char*)sShader, eSH_World);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPlayer::GiveFlashLight(bool val)
|
||||
{
|
||||
if (m_stats.has_flashlight == val)
|
||||
return;
|
||||
|
||||
m_stats.has_flashlight = val;
|
||||
|
||||
// make sure we turn off the flashlight, if we take it away
|
||||
if (val == false && m_bLightOn)
|
||||
{
|
||||
SwitchFlashLight(false);
|
||||
}
|
||||
}
|
||||
|
||||
float CPlayer::GetLightRadius()
|
||||
{
|
||||
if(m_pDynLight && m_bLightOn)
|
||||
return m_pDynLight->m_fRadius;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//GetLightAmountForEntity
|
||||
|
||||
//
|
||||
//-----------------------------------------------------------------
|
||||
Reference in New Issue
Block a user