Particle, map and line renderer fixes

This commit is contained in:
Jack Andersen 2018-10-25 18:37:22 -10:00
parent a2da358fd3
commit 29dad50cca
7 changed files with 157 additions and 69 deletions

View File

@ -183,9 +183,9 @@ struct RELifetimePercent : IRealElement
struct RESineWave : IRealElement struct RESineWave : IRealElement
{ {
AT_DECL_DNA_YAML AT_DECL_DNA_YAML
RealElementFactory magnitude; RealElementFactory frequency;
RealElementFactory linearAngle; RealElementFactory amplitude;
RealElementFactory constantAngle; RealElementFactory phase;
const char* ClassID() const {return "SINE";} const char* ClassID() const {return "SINE";}
}; };

View File

@ -59,8 +59,8 @@ void CMapArea::PostConstruct()
m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, m_verts.data(), 16, m_verts.size()); m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, m_verts.data(), 16, m_verts.size());
m_ibo = ctx.newStaticBuffer(boo::BufferUse::Index, index.data(), 4, index.size()); m_ibo = ctx.newStaticBuffer(boo::BufferUse::Index, index.data(), 4, index.size());
/* Only the map universe specifies Always; it draws a maximum of 133 instances */ /* Only the map universe specifies Always; it draws a maximum of 1016 instances */
size_t instCount = (xc_visibilityMode == EVisMode::Always) ? 133 : 1; size_t instCount = (xc_visibilityMode == EVisMode::Always) ? 1024 : 1;
for (u32 i = 0 ; i<x30_surfaceCount ; ++i) for (u32 i = 0 ; i<x30_surfaceCount ; ++i)
{ {

View File

@ -93,7 +93,7 @@ void CMapUniverse::Draw(const CMapUniverseDrawParms& parms, const zeus::CVector3
std::sort(sortInfos.begin(), sortInfos.end(), std::sort(sortInfos.begin(), sortInfos.end(),
[](const CMapObjectSortInfo& a, const CMapObjectSortInfo& b) [](const CMapObjectSortInfo& a, const CMapObjectSortInfo& b)
{ {
return a.GetZDistance() < b.GetZDistance(); return a.GetZDistance() > b.GetZDistance();
}); });
int lastWldIdx = -1; int lastWldIdx = -1;

View File

@ -39,13 +39,11 @@ CLineRenderer::CLineRenderer(boo::IGraphicsDataFactory::Context& ctx,
switch (mode) switch (mode)
{ {
case EPrimitiveMode::Lines: case EPrimitiveMode::Lines:
maxTriVerts = maxVerts * 3;
break;
case EPrimitiveMode::LineStrip: case EPrimitiveMode::LineStrip:
maxTriVerts = maxVerts * 2; maxTriVerts = maxVerts * 4;
break; break;
case EPrimitiveMode::LineLoop: case EPrimitiveMode::LineLoop:
maxTriVerts = maxVerts * 2 + 2; maxTriVerts = maxVerts * 4 + 4;
break; break;
} }
@ -75,13 +73,11 @@ CLineRenderer::CLineRenderer(EPrimitiveMode mode, u32 maxVerts,
switch (mode) switch (mode)
{ {
case EPrimitiveMode::Lines: case EPrimitiveMode::Lines:
maxTriVerts = maxVerts * 3;
break;
case EPrimitiveMode::LineStrip: case EPrimitiveMode::LineStrip:
maxTriVerts = maxVerts * 2; maxTriVerts = maxVerts * 4;
break; break;
case EPrimitiveMode::LineLoop: case EPrimitiveMode::LineLoop:
maxTriVerts = maxVerts * 2 + 2; maxTriVerts = maxVerts * 4 + 4;
break; break;
} }
@ -102,18 +98,17 @@ CLineRenderer::CLineRenderer(EPrimitiveMode mode, u32 maxVerts,
rstl::reserved_vector<CLineRenderer::SDrawVertTex, 1024> CLineRenderer::g_StaticLineVertsTex = {}; rstl::reserved_vector<CLineRenderer::SDrawVertTex, 1024> CLineRenderer::g_StaticLineVertsTex = {};
rstl::reserved_vector<CLineRenderer::SDrawVertNoTex, 1024> CLineRenderer::g_StaticLineVertsNoTex = {}; rstl::reserved_vector<CLineRenderer::SDrawVertNoTex, 1024> CLineRenderer::g_StaticLineVertsNoTex = {};
static zeus::CVector2f IntersectLines(const zeus::CVector2f& pa1, const zeus::CVector2f& pa2, static bool IntersectLines(const zeus::CVector2f& pa1, const zeus::CVector2f& pa2,
const zeus::CVector2f& pb1, const zeus::CVector2f& pb2) const zeus::CVector2f& pb1, const zeus::CVector2f& pb2,
zeus::CVector3f& intersect)
{ {
zeus::CVector2f pa1mpa2 = pa1 - pa2; float det = (pa1.x - pa2.x) * (pb1.y - pb2.y) - (pa1.y - pa2.y) * (pb1.x - pb2.x);
zeus::CVector2f pb1mpb2 = pb1 - pb2; if (std::fabs(det) < 0.01f)
float denom = pa1mpa2.x * pb1mpb2.y - pa1mpa2.y * pb1mpb2.x; return false;
if (denom < 0.01f) float c0 = pa1.x * pa2.y - pa1.y * pa2.x;
return pa2; float c1 = pb1.x * pb2.y - pb1.y * pb2.x;
float numt1 = pa1.x * pa2.y - pa1.y * pa2.x; intersect = (c0 * (pb1 - pb2) - c1 * (pa1 - pa2)) / det;
float numt2 = pb1.x * pb2.y - pb1.y * pb2.x; return true;
return {(numt1 * pb1mpb2.x - pa1mpa2.x * numt2) / denom,
(numt1 * pb1mpb2.y - pa1mpa2.y * numt2) / denom};
} }
void CLineRenderer::Reset() void CLineRenderer::Reset()
@ -186,16 +181,32 @@ void CLineRenderer::AddVertex(const zeus::CVector3f& position, const zeus::CColo
} }
else else
{ {
zeus::CVector3f intersect1 = IntersectLines(m_lastPos2.toVec2f() + dva, m_lastPos.toVec2f() + dva, zeus::CVector3f intersect1;
m_lastPos.toVec2f() + dvb, projPt.toVec2f() + dvb); bool good1 = IntersectLines(m_lastPos2.toVec2f() + dva, m_lastPos.toVec2f() + dva,
intersect1.z = m_lastPos.z; m_lastPos.toVec2f() + dvb, projPt.toVec2f() + dvb, intersect1);
if ((intersect1.toVec2f() - m_lastPos.toVec2f()).magnitude() > m_lastWidth * 4.f)
good1 = false;
zeus::CVector3f intersect2 = IntersectLines(m_lastPos2.toVec2f() - dva, m_lastPos.toVec2f() - dva, zeus::CVector3f intersect2;
m_lastPos.toVec2f() - dvb, projPt.toVec2f() - dvb); bool good2 = IntersectLines(m_lastPos2.toVec2f() - dva, m_lastPos.toVec2f() - dva,
intersect2.z = m_lastPos.z; m_lastPos.toVec2f() - dvb, projPt.toVec2f() - dvb, intersect2);
if ((intersect2.toVec2f() - m_lastPos.toVec2f()).magnitude() > m_lastWidth * 4.f)
good2 = false;
g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor, m_lastUV}); if (good1 && good2)
g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor, m_lastUV}); {
intersect1.z = m_lastPos.z;
intersect2.z = m_lastPos.z;
g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor, m_lastUV});
g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor, m_lastUV});
}
else
{
g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dva, m_lastW), m_lastColor, m_lastUV});
g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dva, m_lastW), m_lastColor, m_lastUV});
g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dvb, m_lastW), m_lastColor, m_lastUV});
g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dvb, m_lastW), m_lastColor, m_lastUV});
}
} }
} }
else else
@ -217,16 +228,32 @@ void CLineRenderer::AddVertex(const zeus::CVector3f& position, const zeus::CColo
} }
else else
{ {
zeus::CVector3f intersect1 = IntersectLines(m_lastPos2.toVec2f() + dva, m_lastPos.toVec2f() + dva, zeus::CVector3f intersect1;
m_lastPos.toVec2f() + dvb, projPt.toVec2f() + dvb); bool good1 = IntersectLines(m_lastPos2.toVec2f() + dva, m_lastPos.toVec2f() + dva,
intersect1.z = m_lastPos.z; m_lastPos.toVec2f() + dvb, projPt.toVec2f() + dvb, intersect1);
if ((intersect1.toVec2f() - m_lastPos.toVec2f()).magnitude() > m_lastWidth * 4.f)
good1 = false;
zeus::CVector3f intersect2 = IntersectLines(m_lastPos2.toVec2f() - dva, m_lastPos.toVec2f() - dva, zeus::CVector3f intersect2;
m_lastPos.toVec2f() - dvb, projPt.toVec2f() - dvb); bool good2 = IntersectLines(m_lastPos2.toVec2f() - dva, m_lastPos.toVec2f() - dva,
intersect2.z = m_lastPos.z; m_lastPos.toVec2f() - dvb, projPt.toVec2f() - dvb, intersect2);
if ((intersect2.toVec2f() - m_lastPos.toVec2f()).magnitude() > m_lastWidth * 4.f)
good2 = false;
g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor}); if (good1 && good2)
g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor}); {
intersect1.z = m_lastPos.z;
intersect2.z = m_lastPos.z;
g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor});
g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor});
}
else
{
g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dva, m_lastW), m_lastColor});
g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dva, m_lastW), m_lastColor});
g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dvb, m_lastW), m_lastColor});
g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dvb, m_lastW), m_lastColor});
}
} }
} }
} }
@ -277,23 +304,51 @@ void CLineRenderer::Render(const zeus::CColor& moduColor)
dvb = dvb.normalized().perpendicularVector() * m_lastWidth; dvb = dvb.normalized().perpendicularVector() * m_lastWidth;
dvb.x /= CGraphics::g_ProjAspect; dvb.x /= CGraphics::g_ProjAspect;
zeus::CVector3f intersect1 = IntersectLines(m_lastPos2.toVec2f() + dva, m_lastPos.toVec2f() + dva, zeus::CVector3f intersect1;
m_lastPos.toVec2f() + dvb, m_firstPos.toVec2f() + dvb); bool good1 = IntersectLines(m_lastPos2.toVec2f() + dva, m_lastPos.toVec2f() + dva,
intersect1.z = m_lastPos.z; m_lastPos.toVec2f() + dvb, m_firstPos.toVec2f() + dvb, intersect1);
if ((intersect1.toVec2f() - m_lastPos.toVec2f()).magnitude() > m_lastWidth * 4.f)
good1 = false;
zeus::CVector3f intersect2 = IntersectLines(m_lastPos2.toVec2f() - dva, m_lastPos.toVec2f() - dva, zeus::CVector3f intersect2;
m_lastPos.toVec2f() - dvb, m_firstPos.toVec2f() - dvb); bool good2 = IntersectLines(m_lastPos2.toVec2f() - dva, m_lastPos.toVec2f() - dva,
intersect2.z = m_lastPos.z; m_lastPos.toVec2f() - dvb, m_firstPos.toVec2f() - dvb, intersect2);
if ((intersect2.toVec2f() - m_lastPos.toVec2f()).magnitude() > m_lastWidth * 4.f)
good2 = false;
if (m_textured) if (m_textured)
{ {
g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor, m_lastUV}); if (good1 && good2)
g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor, m_lastUV}); {
intersect1.z = m_lastPos.z;
intersect2.z = m_lastPos.z;
g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor, m_lastUV});
g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor, m_lastUV});
}
else
{
g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dva, m_lastW), m_lastColor, m_lastUV});
g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dva, m_lastW), m_lastColor, m_lastUV});
g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dvb, m_lastW), m_lastColor, m_lastUV});
g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dvb, m_lastW), m_lastColor, m_lastUV});
}
} }
else else
{ {
g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor}); if (good1 && good2)
g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor}); {
intersect1.z = m_lastPos.z;
intersect2.z = m_lastPos.z;
g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor});
g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor});
}
else
{
g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dva, m_lastW), m_lastColor});
g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dva, m_lastW), m_lastColor});
g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dvb, m_lastW), m_lastColor});
g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dvb, m_lastW), m_lastColor});
}
} }
} }
{ {
@ -309,23 +364,51 @@ void CLineRenderer::Render(const zeus::CColor& moduColor)
dvb = dvb.normalized().perpendicularVector() * m_firstWidth; dvb = dvb.normalized().perpendicularVector() * m_firstWidth;
dvb.x /= CGraphics::g_ProjAspect; dvb.x /= CGraphics::g_ProjAspect;
zeus::CVector3f intersect1 = IntersectLines(m_lastPos.toVec2f() + dva, m_firstPos.toVec2f() + dva, zeus::CVector3f intersect1;
m_firstPos.toVec2f() + dvb, m_secondPos.toVec2f() + dvb); bool good1 = IntersectLines(m_lastPos.toVec2f() + dva, m_firstPos.toVec2f() + dva,
intersect1.z = m_firstPos.z; m_firstPos.toVec2f() + dvb, m_secondPos.toVec2f() + dvb, intersect1);
if ((intersect1.toVec2f() - m_firstPos.toVec2f()).magnitude() > m_firstWidth * 4.f)
good1 = false;
zeus::CVector3f intersect2 = IntersectLines(m_lastPos.toVec2f() - dva, m_firstPos.toVec2f() - dva, zeus::CVector3f intersect2;
m_firstPos.toVec2f() - dvb, m_secondPos.toVec2f() - dvb); bool good2 = IntersectLines(m_lastPos.toVec2f() - dva, m_firstPos.toVec2f() - dva,
intersect2.z = m_firstPos.z; m_firstPos.toVec2f() - dvb, m_secondPos.toVec2f() - dvb, intersect2);
if ((intersect2.toVec2f() - m_firstPos.toVec2f()).magnitude() > m_firstWidth * 4.f)
good2 = false;
if (m_textured) if (m_textured)
{ {
g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect1, m_firstW), m_firstColor, m_firstUV}); if (good1 && good2)
g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect2, m_firstW), m_firstColor, m_firstUV}); {
intersect1.z = m_firstPos.z;
intersect2.z = m_firstPos.z;
g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor, m_lastUV});
g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor, m_lastUV});
}
else
{
g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_firstPos + dva, m_lastW), m_lastColor, m_lastUV});
g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_firstPos - dva, m_lastW), m_lastColor, m_lastUV});
g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_firstPos + dvb, m_lastW), m_lastColor, m_lastUV});
g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_firstPos - dvb, m_lastW), m_lastColor, m_lastUV});
}
} }
else else
{ {
g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect1, m_firstW), m_firstColor}); if (good1 && good2)
g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect2, m_firstW), m_firstColor}); {
intersect1.z = m_firstPos.z;
intersect2.z = m_firstPos.z;
g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor});
g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor});
}
else
{
g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_firstPos + dva, m_lastW), m_lastColor});
g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_firstPos - dva, m_lastW), m_lastColor});
g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_firstPos + dvb, m_lastW), m_lastColor});
g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_firstPos - dvb, m_lastW), m_lastColor});
}
} }
} }
} }

View File

@ -193,10 +193,10 @@ bool CRELifetimePercent::GetValue(int frame, float& valOut) const
bool CRESineWave::GetValue(int frame, float& valOut) const bool CRESineWave::GetValue(int frame, float& valOut) const
{ {
float a, b, c; float a, b, c;
x4_magnitude->GetValue(frame, a); x4_frequency->GetValue(frame, a);
x8_linearFrame->GetValue(frame, b); x8_amplitude->GetValue(frame, b);
xc_constantFrame->GetValue(frame, c); xc_phase->GetValue(frame, c);
valOut = std::sin(zeus::degToRad(frame * b + c)) * a; valOut = std::sin(zeus::degToRad(frame * a + c)) * b;
return false; return false;
} }

View File

@ -146,13 +146,13 @@ public:
class CRESineWave : public CRealElement class CRESineWave : public CRealElement
{ {
std::unique_ptr<CRealElement> x4_magnitude; std::unique_ptr<CRealElement> x4_frequency;
std::unique_ptr<CRealElement> x8_linearFrame; std::unique_ptr<CRealElement> x8_amplitude;
std::unique_ptr<CRealElement> xc_constantFrame; std::unique_ptr<CRealElement> xc_phase;
public: public:
CRESineWave(std::unique_ptr<CRealElement>&& a, std::unique_ptr<CRealElement>&& b, CRESineWave(std::unique_ptr<CRealElement>&& a, std::unique_ptr<CRealElement>&& b,
std::unique_ptr<CRealElement>&& c) std::unique_ptr<CRealElement>&& c)
: x4_magnitude(std::move(a)), x8_linearFrame(std::move(b)), xc_constantFrame(std::move(c)) {} : x4_frequency(std::move(a)), x8_amplitude(std::move(b)), xc_phase(std::move(c)) {}
bool GetValue(int frame, float& valOut) const; bool GetValue(int frame, float& valOut) const;
}; };

View File

@ -64,6 +64,11 @@ public:
void Render(const CStateManager&) const; void Render(const CStateManager&) const;
void Think(float, CStateManager&); void Think(float, CStateManager&);
bool CanRenderUnsorted(const CStateManager&) const { return false; } bool CanRenderUnsorted(const CStateManager&) const { return false; }
void SetActive(bool active)
{
CActor::SetActive(active);
xe7_29_drawEnabled = true;
}
void CalculateRenderBounds(); void CalculateRenderBounds();
zeus::CAABox GetSortingBounds(const CStateManager&) const; zeus::CAABox GetSortingBounds(const CStateManager&) const;
bool AreBothSystemsDeleteable(); bool AreBothSystemsDeleteable();