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<atUint32> idx;
|
||||||
Value<bool> unk2;
|
Value<bool> unk2;
|
||||||
Value<float> weight;
|
Value<float> weight;
|
||||||
Value<atUint32> unk4;
|
Value<atUint32> charIdx;
|
||||||
Value<atUint32> unk5;
|
Value<atUint32> flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BoolPOINode : POINode
|
struct BoolPOINode : POINode
|
||||||
|
|
|
@ -647,7 +647,7 @@ void CAnimData::RecalcPoseBuilder(const CCharAnimTime* time)
|
||||||
|
|
||||||
void CAnimData::RenderAuxiliary(const zeus::CFrustum& frustum) const
|
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,
|
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<CParticlePOINode>& particleNodes = x4_sourceInfo->GetParticlePOIStream();
|
||||||
const std::vector<CSoundPOINode>& soundNodes = x4_sourceInfo->GetSoundPOIStream();
|
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)
|
auto& node = boolNodes[x14_passedBoolCount];
|
||||||
break;
|
if (node.GetIndex() >= 0)
|
||||||
if (node.GetIndex() != -1)
|
|
||||||
x24_boolStates[node.GetIndex()].second = node.GetValue();
|
x24_boolStates[node.GetIndex()].second = node.GetValue();
|
||||||
++x14_passedBoolCount;
|
++x14_passedBoolCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const CInt32POINode& node : int32Nodes)
|
while (x18_passedIntCount < int32Nodes.size() &&
|
||||||
|
int32Nodes[x18_passedIntCount].GetTime() <= xc_curTime)
|
||||||
{
|
{
|
||||||
if (node.GetTime() > xc_curTime)
|
auto& node = int32Nodes[x18_passedIntCount];
|
||||||
break;
|
if (node.GetIndex() >= 0)
|
||||||
if (node.GetIndex() != -1)
|
|
||||||
x34_int32States[node.GetIndex()].second = node.GetValue();
|
x34_int32States[node.GetIndex()].second = node.GetValue();
|
||||||
++x18_passedIntCount;
|
++x18_passedIntCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const CParticlePOINode& node : particleNodes)
|
while (x1c_passedParticleCount < particleNodes.size() &&
|
||||||
|
particleNodes[x1c_passedParticleCount].GetTime() <= xc_curTime)
|
||||||
{
|
{
|
||||||
if (node.GetTime() > xc_curTime)
|
auto& node = particleNodes[x1c_passedParticleCount];
|
||||||
break;
|
if (node.GetIndex() >= 0)
|
||||||
if (node.GetIndex() != -1)
|
|
||||||
x44_particleStates[node.GetIndex()].second = node.GetParticleData().GetParentedMode();
|
x44_particleStates[node.GetIndex()].second = node.GetParticleData().GetParentedMode();
|
||||||
++x1c_passedParticleCount;
|
++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;
|
++x20_passedSoundCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,11 +38,11 @@ public:
|
||||||
CPOINode(CInputStream& in);
|
CPOINode(CInputStream& in);
|
||||||
virtual ~CPOINode() = default;
|
virtual ~CPOINode() = default;
|
||||||
|
|
||||||
std::string_view GetString() const {return x8_name;}
|
std::string_view GetString() const { return x8_name; }
|
||||||
const CCharAnimTime& GetTime() const {return x1c_time;}
|
const CCharAnimTime& GetTime() const { return x1c_time; }
|
||||||
void SetTime(const CCharAnimTime& time) { x1c_time = time; }
|
void SetTime(const CCharAnimTime& time) { x1c_time = time; }
|
||||||
EPOIType GetPoiType() const { return x18_type; }
|
EPOIType GetPoiType() const { return x18_type; }
|
||||||
u32 GetIndex() const {return x24_index;}
|
u32 GetIndex() const { return x24_index; }
|
||||||
float GetWeight() const { return x2c_weight; }
|
float GetWeight() const { return x2c_weight; }
|
||||||
s32 GetCharacterIndex() const { return x30_charIdx; }
|
s32 GetCharacterIndex() const { return x30_charIdx; }
|
||||||
s32 GetFlags() const { return x34_flags; }
|
s32 GetFlags() const { return x34_flags; }
|
||||||
|
|
|
@ -14,7 +14,7 @@ class CParticlePOINode : public CPOINode
|
||||||
public:
|
public:
|
||||||
CParticlePOINode();
|
CParticlePOINode();
|
||||||
CParticlePOINode(CInputStream& in);
|
CParticlePOINode(CInputStream& in);
|
||||||
const CParticleData& GetParticleData() const {return x38_data;}
|
const CParticleData& GetParticleData() const { return x38_data; }
|
||||||
|
|
||||||
static CParticlePOINode CopyNodeMinusStartTime(const CParticlePOINode& node,
|
static CParticlePOINode CopyNodeMinusStartTime(const CParticlePOINode& node,
|
||||||
const CCharAnimTime& startTime);
|
const CCharAnimTime& startTime);
|
||||||
|
|
|
@ -1321,6 +1321,9 @@ void CElementGen::RenderParticles()
|
||||||
zeus::CTransform systemCameraMatrix = systemViewPointMatrix.inverse() * x22c_globalOrientation;
|
zeus::CTransform systemCameraMatrix = systemViewPointMatrix.inverse() * x22c_globalOrientation;
|
||||||
systemViewPointMatrix = ((zeus::CTransform::Translate(xe8_globalTranslation) * x10c_globalScaleTransform) *
|
systemViewPointMatrix = ((zeus::CTransform::Translate(xe8_globalTranslation) * x10c_globalScaleTransform) *
|
||||||
systemViewPointMatrix) * x178_localScaleTransform;
|
systemViewPointMatrix) * x178_localScaleTransform;
|
||||||
|
if (x26c_29_ORNT)
|
||||||
|
CGraphics::SetModelMatrix(systemViewPointMatrix * systemCameraMatrix);
|
||||||
|
else
|
||||||
CGraphics::SetModelMatrix(systemViewPointMatrix);
|
CGraphics::SetModelMatrix(systemViewPointMatrix);
|
||||||
|
|
||||||
CGraphics::SetAlphaCompare(ERglAlphaFunc::Always, 0, ERglAlphaOp::And, ERglAlphaFunc::Always, 0);
|
CGraphics::SetAlphaCompare(ERglAlphaFunc::Always, 0, ERglAlphaOp::And, ERglAlphaFunc::Always, 0);
|
||||||
|
@ -1397,6 +1400,34 @@ void CElementGen::RenderParticles()
|
||||||
CParticleGlobals::SetEmitterTime(x74_curFrame);
|
CParticleGlobals::SetEmitterTime(x74_curFrame);
|
||||||
if (!x26c_30_MBLR)
|
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)
|
switch (m_shaderClass)
|
||||||
{
|
{
|
||||||
case CElementGenShaders::EShaderClass::Tex:
|
case CElementGenShaders::EShaderClass::Tex:
|
||||||
|
@ -1411,7 +1442,10 @@ void CElementGen::RenderParticles()
|
||||||
Log.report(logvisor::Fatal, "unexpected particle shader class");
|
Log.report(logvisor::Fatal, "unexpected particle shader class");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (int i=0 ; i<x30_particles.size() ; ++i)
|
|
||||||
|
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;
|
int partIdx = desc->x44_28_x30_28_SORT ? sortItems[i].x0_partIdx : i;
|
||||||
CParticle& particle = x30_particles[partIdx];
|
CParticle& particle = x30_particles[partIdx];
|
||||||
|
@ -1463,7 +1497,8 @@ void CElementGen::RenderParticles()
|
||||||
inst.color = particle.x34_color;
|
inst.color = particle.x34_color;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: break;
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1480,8 +1515,10 @@ void CElementGen::RenderParticles()
|
||||||
SParticleInstanceTex& inst = g_instTexData.back();
|
SParticleInstanceTex& inst = g_instTexData.back();
|
||||||
inst.pos[0] = zeus::CVector4f{viewPoint.x + sinT + cosT, 0.f, viewPoint.z + cosT - sinT, 1.f};
|
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[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[2] = zeus::CVector4f{viewPoint.x + (cosT - sinT), 0.f, viewPoint.z + (-cosT - sinT),
|
||||||
inst.pos[3] = zeus::CVector4f{viewPoint.x - (sinT + cosT), 0.f, viewPoint.z - (cosT - sinT), 1.f};
|
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.color = particle.x34_color;
|
||||||
inst.uvs[0] = {uvs.xMax, uvs.yMax};
|
inst.uvs[0] = {uvs.xMax, uvs.yMax};
|
||||||
inst.uvs[1] = {uvs.xMin, uvs.yMax};
|
inst.uvs[1] = {uvs.xMin, uvs.yMax};
|
||||||
|
@ -1495,15 +1532,113 @@ void CElementGen::RenderParticles()
|
||||||
SParticleInstanceNoTex& inst = g_instNoTexData.back();
|
SParticleInstanceNoTex& inst = g_instNoTexData.back();
|
||||||
inst.pos[0] = zeus::CVector4f{viewPoint.x + sinT + cosT, 0.f, viewPoint.z + cosT - sinT, 1.f};
|
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[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[2] = zeus::CVector4f{viewPoint.x + (cosT - sinT), 0.f, viewPoint.z + (-cosT - sinT),
|
||||||
inst.pos[3] = zeus::CVector4f{viewPoint.x - (sinT + cosT), 0.f, viewPoint.z - (cosT - sinT), 1.f};
|
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.color = particle.x34_color;
|
||||||
break;
|
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)
|
switch (m_shaderClass)
|
||||||
{
|
{
|
||||||
case CElementGenShaders::EShaderClass::Tex:
|
case CElementGenShaders::EShaderClass::Tex:
|
||||||
|
|
|
@ -1036,14 +1036,22 @@ bool CParticleDataFactory::CreateGPSM(CGenDescription* fillDesc, CInputStream& i
|
||||||
fillDesc->xe8_xd4_SSPO.reset(GetVectorElement(in));
|
fillDesc->xe8_xd4_SSPO.reset(GetVectorElement(in));
|
||||||
break;
|
break;
|
||||||
case SBIG('TEXR'):
|
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;
|
break;
|
||||||
|
}
|
||||||
case SBIG('SSWH'):
|
case SBIG('SSWH'):
|
||||||
fillDesc->xd4_xc0_SSWH = GetSwooshGeneratorDesc(in, resPool);
|
fillDesc->xd4_xc0_SSWH = GetSwooshGeneratorDesc(in, resPool);
|
||||||
break;
|
break;
|
||||||
case SBIG('TIND'):
|
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;
|
break;
|
||||||
|
}
|
||||||
case SBIG('VMD4'):
|
case SBIG('VMD4'):
|
||||||
fillDesc->x45_29_x31_31_VMD4 = GetBool(in);
|
fillDesc->x45_29_x31_31_VMD4 = GetBool(in);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue