diff --git a/.gitignore b/.gitignore index 49db154d..0aa37949 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,9 @@ orig/*/* *.o *.map *.MAP +*.rep +*.gpr +*.lock* # Build files build/ diff --git a/configure.py b/configure.py old mode 100755 new mode 100644 diff --git a/src/nw4r/ef/drawstrategy/ef_drawbillboardstrategy.cpp b/src/nw4r/ef/drawstrategy/ef_drawbillboardstrategy.cpp index 5830bc94..f3b0f76f 100644 --- a/src/nw4r/ef/drawstrategy/ef_drawbillboardstrategy.cpp +++ b/src/nw4r/ef/drawstrategy/ef_drawbillboardstrategy.cpp @@ -132,7 +132,8 @@ inline void DrawBillboardStrategy::DispParticle_Normal( if (rot.z != 0.0f) { f32 cr, sr; - math::SinCosRad(&sr, &cr, -rot.z); + // math::SinCosRad(&sr, &cr, -rot.z); + math::SinCosFIdx(&sr, &cr, -rot.z); f32 cr_sx = cr * sx; f32 sr_sx = sr * sx; @@ -167,25 +168,294 @@ inline void DrawBillboardStrategy::DispParticle_Normal( d1.y = vx_rs_cr_sx + vx_rs_sr_sy + vy_rc_sr_sx - vy_rc_cr_sy; d1.z = 0.0f; } else { - // todo + f32 dx0 = sx * px; + f32 dy0 = sy * py; + + f32 exp0 = px - dx0; + f32 exp1 = py - dy0; + + p0.x = vy_rc * exp0 + vy_rs * exp1 + pos.x; + p0.y = vy * exp1 + pos.y; + p0.z = (-vy * rs) * exp0 + (vy * rc) * exp1 + pos.z; + + d0.x = vy_rc * sx; + d0.y = 0.0f; + d0.z = (-vy * rs) * sx; + + d1.x = vy_rs * sy; + d1.y = vy * sy; + d1.z = (vy * rc) * sy; } DispPolygon(p0, d0, d1, flags); } void DrawBillboardStrategy::DrawYBillboard(const DrawInfo& rInfo, - ParticleManager* pManager); + ParticleManager* pManager) { + InitGraphics(rInfo, pManager); + + const EmitterDrawSetting& rSetting = + *pManager->mResource->GetEmitterDrawSetting(); + + int flags = mNumTexmap != 0; + + math::VEC2 pivot; + pivot.x = rSetting.pivotY / 100.0f; + pivot.y = rSetting.pivotX / 100.0f; + + math::MTX34 viewMtx; + pManager->CalcGlobalMtx(&viewMtx); + math::MTX34Mult(&viewMtx, rInfo.GetViewMtx(), &viewMtx); + + if (rSetting.zOffset != 0.0f) { + CalcZOffset(&viewMtx, pManager, rInfo, rSetting.zOffset); + } + + f32 vx = math::FSqrt(viewMtx._00 * viewMtx._00 + viewMtx._10 * viewMtx._10 + + viewMtx._20 * viewMtx._20); + + f32 vy = math::FSqrt(viewMtx._01 * viewMtx._01 + viewMtx._11 * viewMtx._11 + + viewMtx._21 * viewMtx._21); + + f32 rc, rs; + { + const math::MTX34* pView = rInfo.GetViewMtx(); + f32 mag = + math::FSqrt(pView->_01 * pView->_01 + pView->_21 * pView->_21); + if (mag == 0.0f) { + rc = 1.0f; + rs = 0.0f; + } else { + f32 invMag = math::FInv(mag); + rc = pView->_21 * invMag; + rs = pView->_01 * invMag; + } + } + + GetFirstDrawParticleFunc pGetFirstFunc = GetGetFirstDrawParticleFunc( + rSetting.mFlags & EmitterDrawSetting::FLAG_DRAW_ORDER); + GetNextDrawParticleFunc pGetNextFunc = GetGetNextDrawParticleFunc( + rSetting.mFlags & EmitterDrawSetting::FLAG_DRAW_ORDER); + + bool first = true; + + for (Particle* pIt = pGetFirstFunc(pManager); pIt != NULL; + pIt = pGetNextFunc(pManager, pIt)) { + + if (pIt->GetLifeStatus() != 1) + continue; + + f32 sx = pIt->Draw_GetSizeX(); + if (sx < std::numeric_limits::epsilon()) + continue; + + f32 sy = pIt->Draw_GetSizeY(); + if (sy < std::numeric_limits::epsilon()) + continue; + + SetupGP(pIt, rSetting, rInfo, first, false); + first = false; + + DispParticle_YBillboard(pIt, viewMtx, vx, vy, 0.0f, rc, rs, sx, sy, + pivot, flags); + } +} inline void DrawBillboardStrategy::DispParticle_YBillboard( Particle* pParticle, const math::MTX34& rViewMtx, f32 vx, f32 vy, f32 vz, - f32 rc, f32 rs, f32 sx, f32 sy, const math::VEC2& rPivot, int flags); + f32 rs, f32 rc, f32 sx, f32 sy, const math::VEC2& rPivot, int flags) { + +#pragma unused(vz) + + math::VEC3 rot; + pParticle->Draw_GetRotate(&rot); + + math::VEC3 p0; + math::VEC3 d0; + math::VEC3 d1; + math::VEC3 pos; + + math::VEC3Transform(&pos, &rViewMtx, &pParticle->mParameter.mPosition); + + f32 px = rPivot.x; + f32 py = rPivot.y; -void DrawBillboardStrategy::DrawDirectionalBillboard(const DrawInfo& rInfo, - ParticleManager* pManager); + f32 vx_rc = vx * rc; + f32 vx_invrs = vx * -rs; + f32 upY = vy; + f32 vx_rs = vx * rs; + + f32 cr = 1.0f; + f32 sr = 0.0f; + if (rot.z != 0.0f) { + math::SinCosRad(&sr, &cr, -rot.z); + + f32 cr_sx = cr * sx; + f32 sr_sx = sr * sx; + f32 cr_sy = cr * sy; + f32 sr_sy = sr * sy; + + f32 exp0 = (px - cr_sx * px) - sr_sy * py; + f32 exp1 = (py + sr_sx * px) - cr_sy * py; + + p0.x = vx_rc * exp0 + vx_rs * exp1 + pos.x; + p0.y = upY * exp1 + pos.y; + p0.z = vx_invrs * exp0 + vx_rc * exp1 + pos.z; + + f32 dxLocalX = cr_sx; + f32 dyLocalX = sr_sx; + f32 dxLocalY = -sr_sy; + f32 dyLocalY = cr_sy; + + d0.x = vx_rc * dxLocalX + vx_rs * dyLocalX; + d0.y = upY * dyLocalX; + d0.z = vx_invrs * dxLocalX + vx_rc * dyLocalX; + + d1.x = vx_rc * dxLocalY + vx_rs * dyLocalY; + d1.y = upY * dyLocalY; + d1.z = vx_invrs * dxLocalY + vx_rc * dyLocalY; + } else { + // todo + } + + DispPolygon(p0, d0, d1, flags); +} + +void DrawBillboardStrategy::DrawDirectionalBillboard( + const DrawInfo& rInfo, ParticleManager* pManager) { + InitGraphics(rInfo, pManager); + + const EmitterDrawSetting& rSetting = + *pManager->mResource->GetEmitterDrawSetting(); + + int flags = mNumTexmap > 0 ? 1 : 0; + const math::MTX34& rInfoMtx = *rInfo.GetViewMtx(); + + math::VEC2 pivot; + pivot.x = rSetting.pivotX / 100.0f; + pivot.y = rSetting.pivotY / 100.0f; + + math::MTX34 viewMtx; + pManager->CalcGlobalMtx(&viewMtx); + math::MTX34Mult(&viewMtx, &rInfoMtx, &viewMtx); + + if (rSetting.zOffset != 0.0f) { + CalcZOffset(&viewMtx, pManager, rInfo, rSetting.zOffset); + } + + f32 vx = math::FSqrt(viewMtx._00 * viewMtx._00 + viewMtx._10 * viewMtx._10 + + viewMtx._20 * viewMtx._20); + + f32 vy = math::FSqrt(viewMtx._01 * viewMtx._01 + viewMtx._11 * viewMtx._11 + + viewMtx._21 * viewMtx._21); + + f32 vz = 0.0f; + + DrawStrategyImpl::AheadContext ahead(viewMtx, pManager); + CalcAheadFunc pCalcAheadFunc = GetCalcAheadFunc(pManager); + + GetFirstDrawParticleFunc pGetFirstFunc = GetGetFirstDrawParticleFunc( + rSetting.mFlags & EmitterDrawSetting::FLAG_DRAW_ORDER); + + GetNextDrawParticleFunc pGetNextFunc = GetGetNextDrawParticleFunc( + rSetting.mFlags & EmitterDrawSetting::FLAG_DRAW_ORDER); + + bool first = true; + + for (Particle* pIt = pGetFirstFunc(pManager); pIt != NULL; + pIt = pGetNextFunc(pManager, pIt)) { + f32 sx = pIt->Draw_GetSizeX(); + if (sx < std::numeric_limits::epsilon()) { + continue; + } + + f32 sy = pIt->Draw_GetSizeY(); + if (sy < std::numeric_limits::epsilon()) { + continue; + } + + SetupGP(pIt, rSetting, rInfo, first, false); + first = false; + + math::VEC3 aheadVec; + pCalcAheadFunc(&aheadVec, &ahead, pIt); + math::VEC3TransformNormal(&aheadVec, &viewMtx, &aheadVec); + + f32 mag = + math::FSqrt(aheadVec.x * aheadVec.x + aheadVec.y * aheadVec.y); + + f32 rc, rs; + if (mag == 0.0f) { + rs = 0.0f; + rc = 1.0f; + } else { + f32 denom = 1.0f / mag; + rs = -aheadVec.x * denom; + rc = aheadVec.y * denom; + } + + f32 dirScale = 1.0f; + if (rSetting.typeDir != 0) { + const math::VEC3& v0 = *reinterpret_cast( + reinterpret_cast(pIt) + 0xAC); + const math::VEC3& v1 = *reinterpret_cast( + reinterpret_cast(pIt) + 0xB8); + math::VEC3 diff; + + diff.x = v0.x - v1.x; + diff.y = v0.y - v1.y; + diff.z = v0.z - v1.z; + + f32 len = math::FSqrt(diff.x * diff.x + diff.y * diff.y + + diff.z * diff.z); + dirScale += 0.5f * len / sy; + } + + DispParticle_Directional(pIt, viewMtx, vx, vy, vz, rc, rs, sx, sy, + pivot, flags); + } +} inline void DrawBillboardStrategy::DispParticle_Directional( Particle* pParticle, const math::MTX34& rViewMtx, f32 vx, f32 vy, f32 vz, - f32 rc, f32 rs, f32 sx, f32 sy, const math::VEC2& rPivot, int flags); + f32 rc, f32 rs, f32 sx, f32 sy, const math::VEC2& rPivot, int flags) { +#pragma unused(vz) + + math::VEC3 p0; + math::VEC3 d0; + math::VEC3 d1; + math::VEC3 pos; + + math::VEC3Transform(&pos, &rViewMtx, &pParticle->mParameter.mPosition); + + f32 px = rPivot.x; + f32 py = rPivot.y; + + f32 vx_rc = vx * rc; + f32 vx_rs = vx * rs; + f32 vy_rc = vy * rc; + f32 vy_rs = vy * rs; + + f32 dx0 = sx * px; + f32 dy0 = sy * py; + + f32 exp0 = px - dx0; + f32 exp1 = py - dy0; + + p0.x = vx_rc * exp0 + vy_rs * exp1 + pos.x; + p0.y = vx_rs * exp0 - vy_rc * exp1 + pos.y; + p0.z = pos.z; + + d0.x = vx_rc * sx; + d0.y = vx_rs * sx; + d0.z = 0.0f; + + d1.x = vy_rs * sy; + d1.y = -vy_rc * sy; + d1.z = 0.0f; + + DispPolygon(p0, d0, d1, flags); +} void DrawBillboardStrategy::DispPolygon(const math::VEC3& rP, const math::VEC3& rD1, diff --git a/tools/transform_dep.py b/tools/transform_dep.py old mode 100755 new mode 100644 diff --git a/tools/upload_progress.py b/tools/upload_progress.py old mode 100755 new mode 100644