Files
FC1/ResourceCompilerPC/BoneLightBindInfo.cpp
romkazvo 34d6c5d489 123
2023-08-07 19:29:24 +08:00

201 lines
5.5 KiB
C++

#include "stdafx.h"
#ifdef _CRY_ANIMATION_BASE_HEADER_
#include "CVars.h"
#endif
#include "BoneLightBindInfo.h"
// initializes this from the structures found in the cgf file
void CBoneLightBindInfo::load (const SBoneLightBind& bind, const LIGHT_CHUNK_DESC& light, const char* szLightName, float fScale)
{
// set up the flags that will be set to the DLight
m_nDLightFlags = 0;
// the light source must have a name with substrings _ls and/or _hs
// _ls means a light source, _hs means a heat source
// if none is present, then the heat source flag is automatically set up
if (strstr(szLightName,"_ls"))
m_nDLightFlags |= DLF_LIGHTSOURCE;
if (strstr(szLightName, "_hs"))
m_nDLightFlags |= DLF_HEATSOURCE;
if (!(m_nDLightFlags & (DLF_HEATSOURCE|DLF_LIGHTSOURCE)))
m_nDLightFlags |= DLF_HEATSOURCE;
if (strstr(szLightName, "local"))
m_nDLightFlags |= DLF_LOCAL;
if (light.szLightImage[0])
m_nDLightFlags |= DLF_PROJECT;
else
m_nDLightFlags |= DLF_POINT;
m_nBone = bind.nBoneId;
m_vPos = bind.vLightOffset;
m_qRot = exp( quaternionf(0,bind.vRotLightOrientation) );
constructMatLight();
m_nType = light.type;
m_rgbColor.r = light.color.r / 255.0f;
m_rgbColor.g = light.color.g / 255.0f;
m_rgbColor.b = light.color.b / 255.0f;
m_rgbColor.a = 1.0f;
m_fIntensity = light.intens;
m_fHotSpotSize = light.hotsize;
m_fFalloffSize = light.fallsize;
m_fNearAttenStart = light.nearAttenStart;
m_fNearAttenEnd = light.nearAttenEnd;
m_fFarAttenStart = light.attenStart;
m_fFarAttenEnd = light.attenEnd;
m_vDirection = light.vDirection;
m_strLightImage = light.szLightImage;
m_bOn = light.on;
m_bUseNearAtten = light.useNearAtten;
m_bUseFarAtten = light.useAtten;
m_bShadow = light.shadow;
if (!m_bUseFarAtten)
{
#ifdef _CRY_ANIMATION_BASE_HEADER_
g_GetLog()->LogWarning ("\003no far attenuation in the heat source (bone) light, using default");
#endif
m_fFarAttenEnd = 40;
}
scale (fScale);
}
void CBoneLightBindInfo::scale (float fScale)
{
m_vPos *= fScale;
m_matLight.SetTranslationOLD (m_matLight.GetTranslationOLD()*fScale);
m_fNearAttenStart *= fScale;
m_fNearAttenEnd *= fScale;
m_fFarAttenStart *= fScale;
m_fFarAttenEnd *= fScale;
if (!m_bUseFarAtten)
m_fFarAttenEnd *= fScale;
}
void CBoneLightBindInfo::constructMatLight()
{
m_matLight=Matrix44(m_qRot);
m_matLight.SetTranslationOLD(m_vPos);
}
//////////////////////////////////////////////////////////////////////////
// initializes the given DLight structure out of the given bone instance
// this is one-time call that is only required after construction of the DLight
// to initialize its constant parameters
void CBoneLightBindInfo::initDLight (CDLight& rDLight)
{
rDLight.m_Flags &= ~(DLF_LIGHTSOURCE|DLF_HEATSOURCE|DLF_PROJECT|DLF_POINT);
rDLight.m_Flags |= m_nDLightFlags;
rDLight.m_Flags |= DLF_LOCAL;
rDLight.m_fDirectFactor = 0;
rDLight.m_Color = m_rgbColor;
rDLight.m_fRadius = m_fFarAttenEnd;
}
//////////////////////////////////////////////////////////////////////////
// per-frame update of the DLight structure. Updates the light position and radius
// PARAMETERS:
// matParentBone - the partent coordinate frame
// fRadiusFactor - the multiplier for the original radius of the light
// rDLight - the light to update
void CBoneLightBindInfo::updateDLight (const Matrix44& matParentBone, float fRadiusMultiplier, CDLight& DLight)
{
DLight.m_Origin = matParentBone.TransformPointOLD(m_vPos);
DLight.m_fRadius = m_fFarAttenEnd * fRadiusMultiplier;
}
// returns true if this light source is local (affects only the character)
bool CBoneLightBindInfo::isLocal()const
{
return (m_nDLightFlags & DLF_LOCAL) != 0;
}
bool CBoneLightBindInfo::isHeatSource()const
{
return (m_nDLightFlags & DLF_HEATSOURCE) != 0;
}
bool CBoneLightBindInfo::isLightSource()const
{
return (m_nDLightFlags & DLF_LIGHTSOURCE) != 0;
}
// returns the priority to sort
int CBoneLightBindInfo::getPriority()const
{
int nPriority = isLocal()?0:1;
nPriority <<= 1;
nPriority |= isHeatSource()?0:1;
nPriority <<= 1;
return nPriority;
}
//////////////////////////////////////////////////////////////////////////
// Serialization to/from memory buffer.
// if the buffer is NULL, and bSave is true, returns the required buffer size
// otherwise, tries to save/load from the buffer, returns the number of bytes written/read
// or 0 if the buffer is too small or some error occured
unsigned CBoneLightBindInfo::Serialize (bool bSave, void* pBuffer, unsigned nSize)
{
const int nVersion = 1;
typedef CBoneLightBindDesc Desc;
if (bSave)
{
// calculate the required size
unsigned nRequiredSize = unsigned(sizeof(nVersion) + sizeof(Desc) + m_strLightImage.length()+1);
if (!pBuffer)
return nRequiredSize;
if (nSize < nRequiredSize)
return 0;
*(int*)pBuffer = 1;
pBuffer = (int*)pBuffer+1;
*((Desc*)pBuffer) = *(Desc*)this;
pBuffer = ((Desc*)pBuffer)+1;
memcpy (pBuffer, m_strLightImage.c_str(), m_strLightImage.length()+1);
return nRequiredSize;
}
else
{
if (nSize < sizeof(nVersion) +sizeof(Desc))
return 0;
const char* pBufEnd = (const char*)pBuffer + nSize;
int nRealVersion = *(int*)pBuffer;
if (nRealVersion != nVersion)
return 0;
void* pRawData = (int*)pBuffer + 1;
*(Desc*)this = *(const Desc*)pRawData;
pRawData = ((Desc*)pRawData)+1;
const char* pName = (const char*)pRawData;
m_strLightImage = "";
for(;*pName && pName < pBufEnd;++pName)
m_strLightImage += *pName;
constructMatLight();
return (unsigned)(pName+1 - (const char*)pBuffer);
}
}