#include "nw4r/g3d.h" // IWYU pragma: export #include "nw4r/math.h" // IWYU pragma: export #include namespace nw4r { namespace g3d { /****************************************************************************** * * LightObj * ******************************************************************************/ LightObj &LightObj::operator=(const LightObj &rOther) { if (this != &rOther) { mFlag = rOther.mFlag; detail::Copy32ByteBlocks(&mObj, &rOther.mObj, sizeof(GXLightObj)); } return *this; } void LightObj::Clear() { mFlag = 0; detail::ZeroMemory32ByteBlocks(&mObj, sizeof(GXLightObj)); } void LightObj::InitLightColor(GXColor color) { GXInitLightColor(&mObj, color); } void LightObj::InitLightPos(f32 x, f32 y, f32 z) { GXInitLightPos(&mObj, x, y, z); mFlag &= ~FLAG_SPECULAR; } void LightObj::InitLightDir(f32 nx, f32 ny, f32 nz) { GXInitLightDir(&mObj, nx, ny, nz); mFlag &= ~FLAG_SPECULAR; mFlag |= FLAG_SPOT; } void LightObj::InitLightSpot(f32 cutoff, GXSpotFn spotFn) { GXInitLightSpot(&mObj, cutoff, spotFn); mFlag &= ~FLAG_SPECULAR; mFlag |= FLAG_SPOT; } void LightObj::InitLightAttnA(f32 aa, f32 ab, f32 ac) { GXInitLightAttnA(&mObj, aa, ab, ac); mFlag &= ~FLAG_SPECULAR; mFlag |= FLAG_SPOT; } void LightObj::InitLightDistAttn(f32 distance, f32 brightness, GXDistAttnFn distAttnFn) { GXInitLightDistAttn(&mObj, distance, brightness, distAttnFn); mFlag &= ~FLAG_SPECULAR; mFlag |= FLAG_SPOT; } void LightObj::InitLightAttnK(f32 ka, f32 kb, f32 kc) { GXInitLightAttnK(&mObj, ka, kb, kc); mFlag &= ~FLAG_SPECULAR; mFlag |= FLAG_SPOT; } void LightObj::InitSpecularDir(f32 nx, f32 ny, f32 nz) { GXInitLightDir(&mObj, nx, ny, nz); mFlag &= ~FLAG_SPOT; mFlag |= FLAG_SPECULAR; mFlag |= FLAG_SPECULAR_DIR; } void LightObj::InitLightShininess(f32 shininess) { GXInitLightAttn(&mObj, 0.0f, 0.0f, 1.0f, shininess / 2.0f, 0.0f, 1.0f - shininess / 2.0f); mFlag &= ~FLAG_SPOT; mFlag |= FLAG_SPECULAR; } void LightObj::GetLightPos(math::VEC3 *pPos) const { if (!pPos) { return; } GXGetLightPos(&mObj, &pPos->x, &pPos->y, &pPos->z); } void LightObj::GetLightDir(math::VEC3 *pDir) const { if (!pDir) { return; } GXGetLightDir(&mObj, &pDir->x, &pDir->y, &pDir->z); } void LightObj::ApplyViewMtx(const math::MTX34 &rCamera) { math::VEC3 dir; GetLightDir(&dir); math::VEC3TransformNormal(&dir, &rCamera, &dir); if (IsSpecularDir()) { GXInitSpecularDir(&mObj, dir.x, dir.y, dir.z); } else { math::VEC3 pos; GetLightPos(&pos); math::VEC3Transform(&pos, &rCamera, &pos); GXInitLightPos(&mObj, pos.x, pos.y, pos.z); GXInitLightDir(&mObj, dir.x, dir.y, dir.z); } } /****************************************************************************** * * LightSetting * ******************************************************************************/ LightSetting::LightSetting( LightObj *pLightObjArray, AmbLightObj *pAmbLightObjArray, u32 numLight, LightSetData *pLightSetDataArray, u32 numLightSet ) : mNumLight(numLight), mNumLightSet(numLightSet), mpLightObjArray(pLightObjArray), mpAmbLightObjArray(pAmbLightObjArray), mpLightSetDataArray(pLightSetDataArray) { for (u32 i = 0; i < mNumLightSet; i++) { LightSetData &rData = mpLightSetDataArray[i]; rData.idxAmbLight = -1; for (u32 j = 0; j < G3DState::NUM_LIGHT_IN_LIGHT_SET; j++) { rData.idxLight[j] = -1; } } mpLightSetDataArray[0].idxLight[0] = 0; mpLightSetDataArray[0].idxLight[1] = 2; mpLightSetDataArray[0].idxAmbLight = -1; GXColor white = {255, 255, 255, 255}; AmbLightObj ambWhite = {255, 255, 255, 255}; LightObj lobj0, lobj1, lobj2, lobj3; lobj0.Clear(); lobj1.Clear(); lobj2.Clear(); lobj3.Clear(); lobj0.InitLightColor(white); lobj0.InitLightPos(4000000.0f, 4000000.0f, 4000000.0f); lobj0.InitLightDir(0.0f, -1.0f, 0.0f); lobj0.InitLightSpot(90.0f, GX_SP_OFF); lobj0.InitLightDistAttn(10.0f, 0.5f, GX_DA_OFF); lobj0.Enable(); lobj1.InitLightColor(white); lobj1.InitLightPos(4000000.0f, 4000000.0f, 4000000.0f); lobj1.Enable(); lobj2.InitLightColor(white); lobj2.InitLightPos(4000000.0f, 4000000.0f, 4000000.0f); lobj2.InitSpecularDir(0.0f, -1.0f, 0.0f); lobj2.InitLightShininess(16.0f); lobj2.Enable(); lobj3.Disable(); if (mNumLight > 0) { mpLightObjArray[0] = lobj0; mpAmbLightObjArray[0] = ambWhite; } if (mNumLight > 1) { mpLightObjArray[1] = lobj1; mpAmbLightObjArray[1] = ambWhite; } if (mNumLight > 2) { mpLightObjArray[2] = lobj2; mpAmbLightObjArray[2] = ambWhite; } for (u32 i = 3; i < mNumLight; i++) { mpLightObjArray[i] = lobj3; mpAmbLightObjArray[i] = ambWhite; } } bool LightSetting::Import(const LightSetting &rSetting) { if (mNumLight < rSetting.mNumLight || mNumLightSet < rSetting.mNumLightSet) { return false; } for (u32 i = 0; i < rSetting.mNumLight; i++) { if (rSetting.mpLightObjArray[i].IsEnable()) { mpLightObjArray[i] = rSetting.mpLightObjArray[i]; } else { mpLightObjArray[i].Disable(); } mpAmbLightObjArray[i] = rSetting.mpAmbLightObjArray[i]; } for (u32 i = 0; i < rSetting.mNumLightSet; i++) { mpLightSetDataArray[i] = rSetting.mpLightSetDataArray[i]; } return true; } void LightSetting::ApplyViewMtx(const math::MTX34 &rCamera, u32 numLight) { numLight = std::max(numLight, mNumLight); for (u32 i = 0; i < numLight; i++) { if (mpLightObjArray[i].IsEnable()) { mpLightObjArray[i].ApplyViewMtx(rCamera); } } } /****************************************************************************** * * LightSet * ******************************************************************************/ bool LightSet::SelectLightObj(u32 lightIdx, int lightObjIdx) { if (IsValid() && lightIdx < G3DState::NUM_LIGHT_IN_LIGHT_SET) { if (lightObjIdx < 0) { mpLightSetData->idxLight[lightIdx] = -1; return true; } if (lightObjIdx < static_cast(mpSetting->GetNumLightObj())) { mpLightSetData->idxLight[lightIdx] = lightObjIdx; return true; } } return false; } bool LightSet::SelectAmbLightObj(int lightObjIdx) { if (IsValid()) { if (lightObjIdx < 0) { mpLightSetData->idxAmbLight = -1; return true; } if (lightObjIdx < static_cast(mpSetting->GetNumLightObj())) { mpLightSetData->idxAmbLight = lightObjIdx; return true; } } return false; } } // namespace g3d } // namespace nw4r