mirror of https://github.com/AxioDL/metaforce.git
Particle POI fix, implement ORNT mode for particles
This commit is contained in:
parent
41034fefda
commit
faf0ac7d27
|
@ -38,8 +38,8 @@ struct EVNT : BigDNA
|
|||
Value<atUint32> idx;
|
||||
Value<bool> unk2;
|
||||
Value<float> weight;
|
||||
Value<atUint32> unk4;
|
||||
Value<atUint32> unk5;
|
||||
Value<atUint32> charIdx;
|
||||
Value<atUint32> flags;
|
||||
};
|
||||
|
||||
struct BoolPOINode : POINode
|
||||
|
|
|
@ -647,7 +647,7 @@ void CAnimData::RecalcPoseBuilder(const CCharAnimTime* time)
|
|||
|
||||
void CAnimData::RenderAuxiliary(const zeus::CFrustum& frustum) const
|
||||
{
|
||||
const_cast<CParticleDatabase&>(x120_particleDB).AddToRendererClipped(frustum);
|
||||
x120_particleDB.AddToRendererClipped(frustum);
|
||||
}
|
||||
|
||||
void CAnimData::Render(CSkinnedModel& model, const CModelFlags& drawFlags,
|
||||
|
|
|
@ -126,37 +126,36 @@ void CAnimSourceReaderBase::UpdatePOIStates()
|
|||
const std::vector<CParticlePOINode>& particleNodes = x4_sourceInfo->GetParticlePOIStream();
|
||||
const std::vector<CSoundPOINode>& soundNodes = x4_sourceInfo->GetSoundPOIStream();
|
||||
|
||||
for (const CBoolPOINode& node : boolNodes)
|
||||
while (x14_passedBoolCount < boolNodes.size() &&
|
||||
boolNodes[x14_passedBoolCount].GetTime() <= xc_curTime)
|
||||
{
|
||||
if (node.GetTime() > xc_curTime)
|
||||
break;
|
||||
if (node.GetIndex() != -1)
|
||||
auto& node = boolNodes[x14_passedBoolCount];
|
||||
if (node.GetIndex() >= 0)
|
||||
x24_boolStates[node.GetIndex()].second = node.GetValue();
|
||||
++x14_passedBoolCount;
|
||||
}
|
||||
|
||||
for (const CInt32POINode& node : int32Nodes)
|
||||
while (x18_passedIntCount < int32Nodes.size() &&
|
||||
int32Nodes[x18_passedIntCount].GetTime() <= xc_curTime)
|
||||
{
|
||||
if (node.GetTime() > xc_curTime)
|
||||
break;
|
||||
if (node.GetIndex() != -1)
|
||||
auto& node = int32Nodes[x18_passedIntCount];
|
||||
if (node.GetIndex() >= 0)
|
||||
x34_int32States[node.GetIndex()].second = node.GetValue();
|
||||
++x18_passedIntCount;
|
||||
}
|
||||
|
||||
for (const CParticlePOINode& node : particleNodes)
|
||||
while (x1c_passedParticleCount < particleNodes.size() &&
|
||||
particleNodes[x1c_passedParticleCount].GetTime() <= xc_curTime)
|
||||
{
|
||||
if (node.GetTime() > xc_curTime)
|
||||
break;
|
||||
if (node.GetIndex() != -1)
|
||||
auto& node = particleNodes[x1c_passedParticleCount];
|
||||
if (node.GetIndex() >= 0)
|
||||
x44_particleStates[node.GetIndex()].second = node.GetParticleData().GetParentedMode();
|
||||
++x1c_passedParticleCount;
|
||||
}
|
||||
|
||||
for (const CSoundPOINode& node : soundNodes)
|
||||
while (x20_passedSoundCount < soundNodes.size() &&
|
||||
soundNodes[x20_passedSoundCount].GetTime() <= xc_curTime)
|
||||
{
|
||||
if (node.GetTime() > xc_curTime)
|
||||
break;
|
||||
++x20_passedSoundCount;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1321,6 +1321,9 @@ void CElementGen::RenderParticles()
|
|||
zeus::CTransform systemCameraMatrix = systemViewPointMatrix.inverse() * x22c_globalOrientation;
|
||||
systemViewPointMatrix = ((zeus::CTransform::Translate(xe8_globalTranslation) * x10c_globalScaleTransform) *
|
||||
systemViewPointMatrix) * x178_localScaleTransform;
|
||||
if (x26c_29_ORNT)
|
||||
CGraphics::SetModelMatrix(systemViewPointMatrix * systemCameraMatrix);
|
||||
else
|
||||
CGraphics::SetModelMatrix(systemViewPointMatrix);
|
||||
|
||||
CGraphics::SetAlphaCompare(ERglAlphaFunc::Always, 0, ERglAlphaOp::And, ERglAlphaFunc::Always, 0);
|
||||
|
@ -1397,6 +1400,34 @@ void CElementGen::RenderParticles()
|
|||
CParticleGlobals::SetEmitterTime(x74_curFrame);
|
||||
if (!x26c_30_MBLR)
|
||||
{
|
||||
#if 0
|
||||
if (!desc->x44_28_x30_28_SORT && constUVs && !x26c_29_ORNT)
|
||||
{
|
||||
if (!desc->x50_x3c_ROTA)
|
||||
{
|
||||
if (!zeus::close_enough(x80_timeDeltaScale, 1.f))
|
||||
{
|
||||
RenderBasicParticlesNoRotNoTS(systemCameraMatrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderBasicParticlesNoRotTS(systemCameraMatrix);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!zeus::close_enough(x80_timeDeltaScale, 1.f))
|
||||
{
|
||||
RenderBasicParticlesRotNoTS(systemCameraMatrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderBasicParticlesRotTS(systemCameraMatrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (m_shaderClass)
|
||||
{
|
||||
case CElementGenShaders::EShaderClass::Tex:
|
||||
|
@ -1411,6 +1442,9 @@ void CElementGen::RenderParticles()
|
|||
Log.report(logvisor::Fatal, "unexpected particle shader class");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!x26c_29_ORNT)
|
||||
{
|
||||
for (int i = 0; i < x30_particles.size(); ++i)
|
||||
{
|
||||
int partIdx = desc->x44_28_x30_28_SORT ? sortItems[i].x0_partIdx : i;
|
||||
|
@ -1463,7 +1497,8 @@ void CElementGen::RenderParticles()
|
|||
inst.color = particle.x34_color;
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1480,8 +1515,10 @@ void CElementGen::RenderParticles()
|
|||
SParticleInstanceTex& inst = g_instTexData.back();
|
||||
inst.pos[0] = zeus::CVector4f{viewPoint.x + sinT + cosT, 0.f, viewPoint.z + cosT - sinT, 1.f};
|
||||
inst.pos[1] = zeus::CVector4f{viewPoint.x + sinT - cosT, 0.f, viewPoint.z + sinT + cosT, 1.f};
|
||||
inst.pos[2] = zeus::CVector4f{viewPoint.x + (cosT - sinT), 0.f, viewPoint.z + (-cosT - sinT), 1.f};
|
||||
inst.pos[3] = zeus::CVector4f{viewPoint.x - (sinT + cosT), 0.f, viewPoint.z - (cosT - sinT), 1.f};
|
||||
inst.pos[2] = zeus::CVector4f{viewPoint.x + (cosT - sinT), 0.f, viewPoint.z + (-cosT - sinT),
|
||||
1.f};
|
||||
inst.pos[3] = zeus::CVector4f{viewPoint.x - (sinT + cosT), 0.f, viewPoint.z - (cosT - sinT),
|
||||
1.f};
|
||||
inst.color = particle.x34_color;
|
||||
inst.uvs[0] = {uvs.xMax, uvs.yMax};
|
||||
inst.uvs[1] = {uvs.xMin, uvs.yMax};
|
||||
|
@ -1495,15 +1532,113 @@ void CElementGen::RenderParticles()
|
|||
SParticleInstanceNoTex& inst = g_instNoTexData.back();
|
||||
inst.pos[0] = zeus::CVector4f{viewPoint.x + sinT + cosT, 0.f, viewPoint.z + cosT - sinT, 1.f};
|
||||
inst.pos[1] = zeus::CVector4f{viewPoint.x + sinT - cosT, 0.f, viewPoint.z + sinT + cosT, 1.f};
|
||||
inst.pos[2] = zeus::CVector4f{viewPoint.x + (cosT - sinT), 0.f, viewPoint.z + (-cosT - sinT), 1.f};
|
||||
inst.pos[3] = zeus::CVector4f{viewPoint.x - (sinT + cosT), 0.f, viewPoint.z - (cosT - sinT), 1.f};
|
||||
inst.pos[2] = zeus::CVector4f{viewPoint.x + (cosT - sinT), 0.f, viewPoint.z + (-cosT - sinT),
|
||||
1.f};
|
||||
inst.pos[3] = zeus::CVector4f{viewPoint.x - (sinT + cosT), 0.f, viewPoint.z - (cosT - sinT),
|
||||
1.f};
|
||||
inst.color = particle.x34_color;
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < x30_particles.size(); ++i)
|
||||
{
|
||||
int partIdx = desc->x44_28_x30_28_SORT ? sortItems[i].x0_partIdx : i;
|
||||
CParticle& particle = x30_particles[partIdx];
|
||||
g_currentParticle = &particle;
|
||||
|
||||
int partFrame = x74_curFrame - particle.x28_startFrame - 1;
|
||||
zeus::CVector3f viewPoint = ((particle.x4_pos - particle.x10_prevPos) *
|
||||
x80_timeDeltaScale + particle.x10_prevPos);
|
||||
float width = !desc->x50_x3c_ROTA ? 1.f : particle.x30_lineWidthOrRota;
|
||||
zeus::CVector3f dir;
|
||||
if (particle.x1c_vel.canBeNormalized())
|
||||
{
|
||||
dir = particle.x1c_vel.normalized();
|
||||
}
|
||||
else
|
||||
{
|
||||
zeus::CVector3f delta = particle.x4_pos - particle.x10_prevPos;
|
||||
if (delta.canBeNormalized())
|
||||
dir = delta.normalized();
|
||||
else
|
||||
dir = zeus::CVector3f::skUp;
|
||||
}
|
||||
|
||||
zeus::CVector3f foreVec = particle.x2c_lineLengthOrSize * dir;
|
||||
zeus::CVector3f rightVec;
|
||||
if (desc->x30_31_RSOP)
|
||||
{
|
||||
rightVec = dir.cross(CGraphics::g_ViewMatrix.basis[1]);
|
||||
if (rightVec.canBeNormalized())
|
||||
{
|
||||
rightVec = rightVec.normalized() * (particle.x2c_lineLengthOrSize * width);
|
||||
}
|
||||
else
|
||||
{
|
||||
rightVec = dir.cross((CGraphics::g_ViewMatrix.origin - particle.x4_pos).normalized());
|
||||
if (rightVec.canBeNormalized())
|
||||
{
|
||||
rightVec = rightVec.normalized() * (particle.x2c_lineLengthOrSize * width);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rightVec = foreVec.cross(CGraphics::g_ViewMatrix.basis[1]) * width;
|
||||
}
|
||||
|
||||
if (!constUVs)
|
||||
{
|
||||
CParticleGlobals::SetParticleLifetime(particle.x0_endFrame - particle.x28_startFrame);
|
||||
CParticleGlobals::UpdateParticleLifetimeTweenValues(partFrame);
|
||||
texr->GetValueUV(partFrame, uvs);
|
||||
}
|
||||
|
||||
switch (m_shaderClass)
|
||||
{
|
||||
case CElementGenShaders::EShaderClass::Tex:
|
||||
{
|
||||
g_instTexData.emplace_back();
|
||||
SParticleInstanceTex& inst = g_instTexData.back();
|
||||
viewPoint += rightVec * 0.5f;
|
||||
inst.pos[0] = zeus::CVector4f{viewPoint + 0.5f * foreVec};
|
||||
inst.pos[1] = zeus::CVector4f{viewPoint - 0.5f * foreVec};
|
||||
viewPoint -= rightVec;
|
||||
inst.pos[2] = zeus::CVector4f{viewPoint + 0.5f * foreVec};
|
||||
inst.pos[3] = zeus::CVector4f{viewPoint - 0.5f * foreVec};
|
||||
inst.color = particle.x34_color;
|
||||
inst.uvs[0] = {uvs.xMax, uvs.yMax};
|
||||
inst.uvs[1] = {uvs.xMin, uvs.yMax};
|
||||
inst.uvs[2] = {uvs.xMax, uvs.yMin};
|
||||
inst.uvs[3] = {uvs.xMin, uvs.yMin};
|
||||
break;
|
||||
}
|
||||
case CElementGenShaders::EShaderClass::NoTex:
|
||||
{
|
||||
g_instNoTexData.emplace_back();
|
||||
SParticleInstanceNoTex& inst = g_instNoTexData.back();
|
||||
viewPoint += rightVec * 0.5f;
|
||||
inst.pos[0] = zeus::CVector4f{viewPoint + 0.5f * foreVec};
|
||||
inst.pos[1] = zeus::CVector4f{viewPoint - 0.5f * foreVec};
|
||||
viewPoint -= rightVec;
|
||||
inst.pos[2] = zeus::CVector4f{viewPoint + 0.5f * foreVec};
|
||||
inst.pos[3] = zeus::CVector4f{viewPoint - 0.5f * foreVec};
|
||||
inst.color = particle.x34_color;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (m_shaderClass)
|
||||
{
|
||||
case CElementGenShaders::EShaderClass::Tex:
|
||||
|
|
|
@ -1036,14 +1036,22 @@ bool CParticleDataFactory::CreateGPSM(CGenDescription* fillDesc, CInputStream& i
|
|||
fillDesc->xe8_xd4_SSPO.reset(GetVectorElement(in));
|
||||
break;
|
||||
case SBIG('TEXR'):
|
||||
fillDesc->x54_x40_TEXR.reset(GetTextureElement(in, resPool));
|
||||
{
|
||||
std::unique_ptr<CUVElement> tex(GetTextureElement(in, resPool));
|
||||
if (tex->GetValueTexture(0))
|
||||
fillDesc->x54_x40_TEXR = std::move(tex);
|
||||
break;
|
||||
}
|
||||
case SBIG('SSWH'):
|
||||
fillDesc->xd4_xc0_SSWH = GetSwooshGeneratorDesc(in, resPool);
|
||||
break;
|
||||
case SBIG('TIND'):
|
||||
fillDesc->x58_x44_TIND.reset(GetTextureElement(in, resPool));
|
||||
{
|
||||
std::unique_ptr<CUVElement> tex(GetTextureElement(in, resPool));
|
||||
if (tex->GetValueTexture(0))
|
||||
fillDesc->x58_x44_TIND = std::move(tex);
|
||||
break;
|
||||
}
|
||||
case SBIG('VMD4'):
|
||||
fillDesc->x45_29_x31_31_VMD4 = GetBool(in);
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue