-
Notifications
You must be signed in to change notification settings - Fork 21
DrawBillboardStrategy improvements #137
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
9d5fa67
6006e08
e2355b6
7529fa6
3f7a0d2
6644d7a
2815bf0
095d3df
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,9 @@ orig/*/* | |
| *.o | ||
| *.map | ||
| *.MAP | ||
| *.rep | ||
| *.gpr | ||
| *.lock* | ||
|
|
||
| # Build files | ||
| build/ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the value |
||
| continue; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could we put the if (pIt->GetLifeStatus() != NW4R_EF_LS_ACTIVE) {
continue;
} |
||
|
|
||
| f32 sx = pIt->Draw_GetSizeX(); | ||
| if (sx < std::numeric_limits<f32>::epsilon()) | ||
| continue; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if (sx < std::numeric_limits<f32>::epsilon()) {
continue;
} |
||
|
|
||
| f32 sy = pIt->Draw_GetSizeY(); | ||
| if (sy < std::numeric_limits<f32>::epsilon()) | ||
| continue; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if (sy < std::numeric_limits<f32>::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<f32>::epsilon()) { | ||
| continue; | ||
| } | ||
|
|
||
| f32 sy = pIt->Draw_GetSizeY(); | ||
| if (sy < std::numeric_limits<f32>::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) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| const math::VEC3& v0 = *reinterpret_cast<const math::VEC3*>( | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
some functions use |
||
| reinterpret_cast<const u8*>(pIt) + 0xAC); | ||
| const math::VEC3& v1 = *reinterpret_cast<const math::VEC3*>( | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| reinterpret_cast<const u8*>(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, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DrawNormalBillboard does
mNumTexmap > 0 ? 1 : 0, does that work here too?