mirror of https://github.com/axmolengine/axmol.git
1083 lines
31 KiB
C
1083 lines
31 KiB
C
|
|
|||
|
#ifndef __EFFEKSEERRENDERER_TRACK_RENDERER_BASE_H__
|
|||
|
#define __EFFEKSEERRENDERER_TRACK_RENDERER_BASE_H__
|
|||
|
|
|||
|
//----------------------------------------------------------------------------------
|
|||
|
// Include
|
|||
|
//----------------------------------------------------------------------------------
|
|||
|
#include <Effekseer.h>
|
|||
|
#include <assert.h>
|
|||
|
#include <string.h>
|
|||
|
|
|||
|
#include "EffekseerRenderer.CommonUtils.h"
|
|||
|
#include "EffekseerRenderer.IndexBufferBase.h"
|
|||
|
#include "EffekseerRenderer.RenderStateBase.h"
|
|||
|
#include "EffekseerRenderer.StandardRenderer.h"
|
|||
|
#include "EffekseerRenderer.VertexBufferBase.h"
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------------
|
|||
|
//
|
|||
|
//-----------------------------------------------------------------------------------
|
|||
|
|
|||
|
namespace EffekseerRenderer
|
|||
|
{
|
|||
|
//----------------------------------------------------------------------------------
|
|||
|
//
|
|||
|
//----------------------------------------------------------------------------------
|
|||
|
typedef ::Effekseer::TrackRenderer::NodeParameter efkTrackNodeParam;
|
|||
|
typedef ::Effekseer::TrackRenderer::InstanceParameter efkTrackInstanceParam;
|
|||
|
typedef ::Effekseer::SIMD::Vec3f efkVector3D;
|
|||
|
|
|||
|
template <typename RENDERER, bool FLIP_RGB_FLAG>
|
|||
|
class TrackRendererBase : public ::Effekseer::TrackRenderer, public ::Effekseer::SIMD::AlignedAllocationPolicy<16>
|
|||
|
{
|
|||
|
protected:
|
|||
|
RENDERER* m_renderer;
|
|||
|
int32_t m_ribbonCount;
|
|||
|
|
|||
|
int32_t m_ringBufferOffset;
|
|||
|
uint8_t* m_ringBufferData;
|
|||
|
|
|||
|
Effekseer::CustomAlignedVector<efkTrackInstanceParam> instances;
|
|||
|
Effekseer::CustomAlignedVector<Effekseer::SIMD::Quaternionf> rotations_temp_;
|
|||
|
Effekseer::CustomAlignedVector<Effekseer::SIMD::Quaternionf> rotations_;
|
|||
|
Effekseer::SplineGenerator spline;
|
|||
|
|
|||
|
int32_t vertexCount_ = 0;
|
|||
|
int32_t stride_ = 0;
|
|||
|
|
|||
|
int32_t customData1Count_ = 0;
|
|||
|
int32_t customData2Count_ = 0;
|
|||
|
|
|||
|
template <typename VERTEX, int TARGET>
|
|||
|
void AssignUV(StrideView<VERTEX>& v, float uvX1, float uvX2, float uvX3, float uvY1, float uvY2)
|
|||
|
{
|
|||
|
if (TARGET == 0)
|
|||
|
{
|
|||
|
v[0].UV[0] = uvX1;
|
|||
|
v[0].UV[1] = uvY1;
|
|||
|
|
|||
|
v[1].UV[0] = uvX2;
|
|||
|
v[1].UV[1] = uvY1;
|
|||
|
|
|||
|
v[4].UV[0] = uvX2;
|
|||
|
v[4].UV[1] = uvY1;
|
|||
|
|
|||
|
v[5].UV[0] = uvX3;
|
|||
|
v[5].UV[1] = uvY1;
|
|||
|
|
|||
|
v[2].UV[0] = uvX1;
|
|||
|
v[2].UV[1] = uvY2;
|
|||
|
|
|||
|
v[3].UV[0] = uvX2;
|
|||
|
v[3].UV[1] = uvY2;
|
|||
|
|
|||
|
v[6].UV[0] = uvX2;
|
|||
|
v[6].UV[1] = uvY2;
|
|||
|
|
|||
|
v[7].UV[0] = uvX3;
|
|||
|
v[7].UV[1] = uvY2;
|
|||
|
}
|
|||
|
else if (TARGET == 1)
|
|||
|
{
|
|||
|
v[0].UV2[0] = uvX1;
|
|||
|
v[0].UV2[1] = uvY1;
|
|||
|
|
|||
|
v[1].UV2[0] = uvX2;
|
|||
|
v[1].UV2[1] = uvY1;
|
|||
|
|
|||
|
v[4].UV2[0] = uvX2;
|
|||
|
v[4].UV2[1] = uvY1;
|
|||
|
|
|||
|
v[5].UV2[0] = uvX3;
|
|||
|
v[5].UV2[1] = uvY1;
|
|||
|
|
|||
|
v[2].UV2[0] = uvX1;
|
|||
|
v[2].UV2[1] = uvY2;
|
|||
|
|
|||
|
v[3].UV2[0] = uvX2;
|
|||
|
v[3].UV2[1] = uvY2;
|
|||
|
|
|||
|
v[6].UV2[0] = uvX2;
|
|||
|
v[6].UV2[1] = uvY2;
|
|||
|
|
|||
|
v[7].UV2[0] = uvX3;
|
|||
|
v[7].UV2[1] = uvY2;
|
|||
|
}
|
|||
|
else if (TARGET == 2)
|
|||
|
{
|
|||
|
SetVertexAlphaUV(v[0], uvX1, 0);
|
|||
|
SetVertexAlphaUV(v[0], uvY1, 1);
|
|||
|
|
|||
|
SetVertexAlphaUV(v[1], uvX2, 0);
|
|||
|
SetVertexAlphaUV(v[1], uvY1, 1);
|
|||
|
|
|||
|
SetVertexAlphaUV(v[4], uvX2, 0);
|
|||
|
SetVertexAlphaUV(v[4], uvY1, 1);
|
|||
|
|
|||
|
SetVertexAlphaUV(v[5], uvX3, 0);
|
|||
|
SetVertexAlphaUV(v[5], uvY1, 1);
|
|||
|
|
|||
|
SetVertexAlphaUV(v[2], uvX1, 0);
|
|||
|
SetVertexAlphaUV(v[2], uvY2, 1);
|
|||
|
|
|||
|
SetVertexAlphaUV(v[3], uvX2, 0);
|
|||
|
SetVertexAlphaUV(v[3], uvY2, 1);
|
|||
|
|
|||
|
SetVertexAlphaUV(v[6], uvX2, 0);
|
|||
|
SetVertexAlphaUV(v[6], uvY2, 1);
|
|||
|
|
|||
|
SetVertexAlphaUV(v[7], uvX3, 0);
|
|||
|
SetVertexAlphaUV(v[7], uvY2, 1);
|
|||
|
}
|
|||
|
else if (TARGET == 3)
|
|||
|
{
|
|||
|
SetVertexUVDistortionUV(v[0], uvX1, 0);
|
|||
|
SetVertexUVDistortionUV(v[0], uvY1, 1);
|
|||
|
|
|||
|
SetVertexUVDistortionUV(v[1], uvX2, 0);
|
|||
|
SetVertexUVDistortionUV(v[1], uvY1, 1);
|
|||
|
|
|||
|
SetVertexUVDistortionUV(v[4], uvX2, 0);
|
|||
|
SetVertexUVDistortionUV(v[4], uvY1, 1);
|
|||
|
|
|||
|
SetVertexUVDistortionUV(v[5], uvX3, 0);
|
|||
|
SetVertexUVDistortionUV(v[5], uvY1, 1);
|
|||
|
|
|||
|
SetVertexUVDistortionUV(v[2], uvX1, 0);
|
|||
|
SetVertexUVDistortionUV(v[2], uvY2, 1);
|
|||
|
|
|||
|
SetVertexUVDistortionUV(v[3], uvX2, 0);
|
|||
|
SetVertexUVDistortionUV(v[3], uvY2, 1);
|
|||
|
|
|||
|
SetVertexUVDistortionUV(v[6], uvX2, 0);
|
|||
|
SetVertexUVDistortionUV(v[6], uvY2, 1);
|
|||
|
|
|||
|
SetVertexUVDistortionUV(v[7], uvX3, 0);
|
|||
|
SetVertexUVDistortionUV(v[7], uvY2, 1);
|
|||
|
}
|
|||
|
else if (TARGET == 4)
|
|||
|
{
|
|||
|
SetVertexBlendUV(v[0], uvX1, 0);
|
|||
|
SetVertexBlendUV(v[0], uvY1, 1);
|
|||
|
|
|||
|
SetVertexBlendUV(v[1], uvX2, 0);
|
|||
|
SetVertexBlendUV(v[1], uvY1, 1);
|
|||
|
|
|||
|
SetVertexBlendUV(v[4], uvX2, 0);
|
|||
|
SetVertexBlendUV(v[4], uvY1, 1);
|
|||
|
|
|||
|
SetVertexBlendUV(v[5], uvX3, 0);
|
|||
|
SetVertexBlendUV(v[5], uvY1, 1);
|
|||
|
|
|||
|
SetVertexBlendUV(v[2], uvX1, 0);
|
|||
|
SetVertexBlendUV(v[2], uvY2, 1);
|
|||
|
|
|||
|
SetVertexBlendUV(v[3], uvX2, 0);
|
|||
|
SetVertexBlendUV(v[3], uvY2, 1);
|
|||
|
|
|||
|
SetVertexBlendUV(v[6], uvX2, 0);
|
|||
|
SetVertexBlendUV(v[6], uvY2, 1);
|
|||
|
|
|||
|
SetVertexBlendUV(v[7], uvX3, 0);
|
|||
|
SetVertexBlendUV(v[7], uvY2, 1);
|
|||
|
}
|
|||
|
else if (TARGET == 5)
|
|||
|
{
|
|||
|
SetVertexBlendAlphaUV(v[0], uvX1, 0);
|
|||
|
SetVertexBlendAlphaUV(v[0], uvY1, 1);
|
|||
|
|
|||
|
SetVertexBlendAlphaUV(v[1], uvX2, 0);
|
|||
|
SetVertexBlendAlphaUV(v[1], uvY1, 1);
|
|||
|
|
|||
|
SetVertexBlendAlphaUV(v[4], uvX2, 0);
|
|||
|
SetVertexBlendAlphaUV(v[4], uvY1, 1);
|
|||
|
|
|||
|
SetVertexBlendAlphaUV(v[5], uvX3, 0);
|
|||
|
SetVertexBlendAlphaUV(v[5], uvY1, 1);
|
|||
|
|
|||
|
SetVertexBlendAlphaUV(v[2], uvX1, 0);
|
|||
|
SetVertexBlendAlphaUV(v[2], uvY2, 1);
|
|||
|
|
|||
|
SetVertexBlendAlphaUV(v[3], uvX2, 0);
|
|||
|
SetVertexBlendAlphaUV(v[3], uvY2, 1);
|
|||
|
|
|||
|
SetVertexBlendAlphaUV(v[6], uvX2, 0);
|
|||
|
SetVertexBlendAlphaUV(v[6], uvY2, 1);
|
|||
|
|
|||
|
SetVertexBlendAlphaUV(v[7], uvX3, 0);
|
|||
|
SetVertexBlendAlphaUV(v[7], uvY2, 1);
|
|||
|
}
|
|||
|
else if (TARGET == 6)
|
|||
|
{
|
|||
|
SetVertexBlendUVDistortionUV(v[0], uvX1, 0);
|
|||
|
SetVertexBlendUVDistortionUV(v[0], uvY1, 1);
|
|||
|
|
|||
|
SetVertexBlendUVDistortionUV(v[1], uvX2, 0);
|
|||
|
SetVertexBlendUVDistortionUV(v[1], uvY1, 1);
|
|||
|
|
|||
|
SetVertexBlendUVDistortionUV(v[4], uvX2, 0);
|
|||
|
SetVertexBlendUVDistortionUV(v[4], uvY1, 1);
|
|||
|
|
|||
|
SetVertexBlendUVDistortionUV(v[5], uvX3, 0);
|
|||
|
SetVertexBlendUVDistortionUV(v[5], uvY1, 1);
|
|||
|
|
|||
|
SetVertexBlendUVDistortionUV(v[2], uvX1, 0);
|
|||
|
SetVertexBlendUVDistortionUV(v[2], uvY2, 1);
|
|||
|
|
|||
|
SetVertexBlendUVDistortionUV(v[3], uvX2, 0);
|
|||
|
SetVertexBlendUVDistortionUV(v[3], uvY2, 1);
|
|||
|
|
|||
|
SetVertexBlendUVDistortionUV(v[6], uvX2, 0);
|
|||
|
SetVertexBlendUVDistortionUV(v[6], uvY2, 1);
|
|||
|
|
|||
|
SetVertexBlendUVDistortionUV(v[7], uvX3, 0);
|
|||
|
SetVertexBlendUVDistortionUV(v[7], uvY2, 1);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
template <typename VERTEX, int TARGET>
|
|||
|
void AssignUVs(const efkTrackNodeParam& parameter, StrideView<VERTEX> verteies)
|
|||
|
{
|
|||
|
float uvx = 0.0f;
|
|||
|
float uvw = 1.0f;
|
|||
|
float uvy = 0.0f;
|
|||
|
float uvh = 1.0f;
|
|||
|
|
|||
|
if (parameter.TextureUVTypeParameterPtr->Type == ::Effekseer::TextureUVType::Strech)
|
|||
|
{
|
|||
|
verteies.Reset();
|
|||
|
for (size_t loop = 0; loop < instances.size() - 1; loop++)
|
|||
|
{
|
|||
|
const auto& param = instances[loop];
|
|||
|
if (TARGET == 0)
|
|||
|
{
|
|||
|
uvx = param.UV.X;
|
|||
|
uvw = param.UV.Width;
|
|||
|
uvy = param.UV.Y;
|
|||
|
uvh = param.UV.Height;
|
|||
|
}
|
|||
|
else if (TARGET == 2)
|
|||
|
{
|
|||
|
uvx = param.AlphaUV.X;
|
|||
|
uvw = param.AlphaUV.Width;
|
|||
|
uvy = param.AlphaUV.Y;
|
|||
|
uvh = param.AlphaUV.Height;
|
|||
|
}
|
|||
|
else if (TARGET == 3)
|
|||
|
{
|
|||
|
uvx = param.UVDistortionUV.X;
|
|||
|
uvw = param.UVDistortionUV.Width;
|
|||
|
uvy = param.UVDistortionUV.Y;
|
|||
|
uvh = param.UVDistortionUV.Height;
|
|||
|
}
|
|||
|
else if (TARGET == 4)
|
|||
|
{
|
|||
|
uvx = param.BlendUV.X;
|
|||
|
uvw = param.BlendUV.Width;
|
|||
|
uvy = param.BlendUV.Y;
|
|||
|
uvh = param.BlendUV.Height;
|
|||
|
}
|
|||
|
else if (TARGET == 5)
|
|||
|
{
|
|||
|
uvx = param.BlendAlphaUV.X;
|
|||
|
uvw = param.BlendAlphaUV.Width;
|
|||
|
uvy = param.BlendAlphaUV.Y;
|
|||
|
uvh = param.BlendAlphaUV.Height;
|
|||
|
}
|
|||
|
else if (TARGET == 6)
|
|||
|
{
|
|||
|
uvx = param.BlendUVDistortionUV.X;
|
|||
|
uvw = param.BlendUVDistortionUV.Width;
|
|||
|
uvy = param.BlendUVDistortionUV.Y;
|
|||
|
uvh = param.BlendUVDistortionUV.Height;
|
|||
|
}
|
|||
|
|
|||
|
for (int32_t sploop = 0; sploop < parameter.SplineDivision; sploop++)
|
|||
|
{
|
|||
|
float percent1 = (float)(param.InstanceIndex * parameter.SplineDivision + sploop) /
|
|||
|
(float)((param.InstanceCount - 1) * parameter.SplineDivision);
|
|||
|
|
|||
|
float percent2 = (float)(param.InstanceIndex * parameter.SplineDivision + sploop + 1) /
|
|||
|
(float)((param.InstanceCount - 1) * parameter.SplineDivision);
|
|||
|
|
|||
|
auto uvX1 = uvx;
|
|||
|
auto uvX2 = uvx + uvw * 0.5f;
|
|||
|
auto uvX3 = uvx + uvw;
|
|||
|
auto uvY1 = uvy + percent1 * uvh;
|
|||
|
auto uvY2 = uvy + percent2 * uvh;
|
|||
|
|
|||
|
AssignUV<VERTEX, TARGET>(verteies, uvX1, uvX2, uvX3, uvY1, uvY2);
|
|||
|
|
|||
|
verteies += 8;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else if (parameter.TextureUVTypeParameterPtr->Type == ::Effekseer::TextureUVType::Tile)
|
|||
|
{
|
|||
|
const auto& uvParam = *parameter.TextureUVTypeParameterPtr;
|
|||
|
verteies.Reset();
|
|||
|
|
|||
|
for (size_t loop = 0; loop < instances.size() - 1; loop++)
|
|||
|
{
|
|||
|
auto& param = instances[loop];
|
|||
|
if (TARGET == 0)
|
|||
|
{
|
|||
|
uvx = param.UV.X;
|
|||
|
uvw = param.UV.Width;
|
|||
|
uvy = param.UV.Y;
|
|||
|
uvh = param.UV.Height;
|
|||
|
}
|
|||
|
else if (TARGET == 2)
|
|||
|
{
|
|||
|
uvx = param.AlphaUV.X;
|
|||
|
uvw = param.AlphaUV.Width;
|
|||
|
uvy = param.AlphaUV.Y;
|
|||
|
uvh = param.AlphaUV.Height;
|
|||
|
}
|
|||
|
else if (TARGET == 3)
|
|||
|
{
|
|||
|
uvx = param.UVDistortionUV.X;
|
|||
|
uvw = param.UVDistortionUV.Width;
|
|||
|
uvy = param.UVDistortionUV.Y;
|
|||
|
uvh = param.UVDistortionUV.Height;
|
|||
|
}
|
|||
|
else if (TARGET == 4)
|
|||
|
{
|
|||
|
uvx = param.BlendUV.X;
|
|||
|
uvw = param.BlendUV.Width;
|
|||
|
uvy = param.BlendUV.Y;
|
|||
|
uvh = param.BlendUV.Height;
|
|||
|
}
|
|||
|
else if (TARGET == 5)
|
|||
|
{
|
|||
|
uvx = param.BlendAlphaUV.X;
|
|||
|
uvw = param.BlendAlphaUV.Width;
|
|||
|
uvy = param.BlendAlphaUV.Y;
|
|||
|
uvh = param.BlendAlphaUV.Height;
|
|||
|
}
|
|||
|
else if (TARGET == 6)
|
|||
|
{
|
|||
|
uvx = param.BlendUVDistortionUV.X;
|
|||
|
uvw = param.BlendUVDistortionUV.Width;
|
|||
|
uvy = param.BlendUVDistortionUV.Y;
|
|||
|
uvh = param.BlendUVDistortionUV.Height;
|
|||
|
}
|
|||
|
|
|||
|
if (loop < uvParam.TileEdgeTail)
|
|||
|
{
|
|||
|
float uvBegin = uvy;
|
|||
|
float uvEnd = uvy + uvh * uvParam.TileLoopAreaBegin;
|
|||
|
|
|||
|
for (int32_t sploop = 0; sploop < parameter.SplineDivision; sploop++)
|
|||
|
{
|
|||
|
float percent1 = (float)(param.InstanceIndex * parameter.SplineDivision + sploop) /
|
|||
|
(float)((uvParam.TileEdgeTail) * parameter.SplineDivision);
|
|||
|
|
|||
|
float percent2 = (float)(param.InstanceIndex * parameter.SplineDivision + sploop + 1) /
|
|||
|
(float)((uvParam.TileEdgeTail) * parameter.SplineDivision);
|
|||
|
|
|||
|
auto uvX1 = uvx;
|
|||
|
auto uvX2 = uvx + uvw * 0.5f;
|
|||
|
auto uvX3 = uvx + uvw;
|
|||
|
auto uvY1 = uvBegin + (uvEnd - uvBegin) * percent1;
|
|||
|
auto uvY2 = uvBegin + (uvEnd - uvBegin) * percent2;
|
|||
|
|
|||
|
AssignUV<VERTEX, TARGET>(verteies, uvX1, uvX2, uvX3, uvY1, uvY2);
|
|||
|
|
|||
|
verteies += 8;
|
|||
|
}
|
|||
|
}
|
|||
|
else if (loop >= param.InstanceCount - 1 - uvParam.TileEdgeHead)
|
|||
|
{
|
|||
|
float uvBegin = uvy + uvh * uvParam.TileLoopAreaEnd;
|
|||
|
float uvEnd = uvy + uvh * 1.0f;
|
|||
|
|
|||
|
for (int32_t sploop = 0; sploop < parameter.SplineDivision; sploop++)
|
|||
|
{
|
|||
|
float percent1 =
|
|||
|
(float)((param.InstanceIndex - (param.InstanceCount - 1 - uvParam.TileEdgeHead)) * parameter.SplineDivision +
|
|||
|
sploop) /
|
|||
|
(float)((uvParam.TileEdgeHead) * parameter.SplineDivision);
|
|||
|
|
|||
|
float percent2 =
|
|||
|
(float)((param.InstanceIndex - (param.InstanceCount - 1 - uvParam.TileEdgeHead)) * parameter.SplineDivision +
|
|||
|
sploop + 1) /
|
|||
|
(float)((uvParam.TileEdgeHead) * parameter.SplineDivision);
|
|||
|
|
|||
|
auto uvX1 = uvx;
|
|||
|
auto uvX2 = uvx + uvw * 0.5f;
|
|||
|
auto uvX3 = uvx + uvw;
|
|||
|
auto uvY1 = uvBegin + (uvEnd - uvBegin) * percent1;
|
|||
|
auto uvY2 = uvBegin + (uvEnd - uvBegin) * percent2;
|
|||
|
|
|||
|
AssignUV<VERTEX, TARGET>(verteies, uvX1, uvX2, uvX3, uvY1, uvY2);
|
|||
|
|
|||
|
verteies += 8;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
float uvBegin = uvy + uvh * uvParam.TileLoopAreaBegin;
|
|||
|
float uvEnd = uvy + uvh * uvParam.TileLoopAreaEnd;
|
|||
|
|
|||
|
for (int32_t sploop = 0; sploop < parameter.SplineDivision; sploop++)
|
|||
|
{
|
|||
|
float percent1 = (float)(sploop) / (float)(parameter.SplineDivision);
|
|||
|
|
|||
|
float percent2 = (float)(sploop + 1) / (float)(parameter.SplineDivision);
|
|||
|
|
|||
|
auto uvX1 = uvx;
|
|||
|
auto uvX2 = uvx + uvx + uvw * 0.5f;
|
|||
|
auto uvX3 = uvx + uvw;
|
|||
|
auto uvY1 = uvBegin + (uvEnd - uvBegin) * percent1;
|
|||
|
auto uvY2 = uvBegin + (uvEnd - uvBegin) * percent2;
|
|||
|
|
|||
|
AssignUV<VERTEX, TARGET>(verteies, uvX1, uvX2, uvX3, uvY1, uvY2);
|
|||
|
|
|||
|
verteies += 8;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
template <typename VERTEX, bool FLIP_RGB>
|
|||
|
void RenderSplines(const efkTrackNodeParam& parameter, const ::Effekseer::SIMD::Mat44f& camera)
|
|||
|
{
|
|||
|
if (instances.size() == 0)
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (parameter.SmoothingType == Effekseer::TrailSmoothingType::On)
|
|||
|
{
|
|||
|
// Calculate rotations
|
|||
|
for (size_t i = 0; i < instances.size(); i++)
|
|||
|
{
|
|||
|
Effekseer::SIMD::Vec3f axis;
|
|||
|
if (i == 0)
|
|||
|
{
|
|||
|
axis = (instances[i + 1].SRTMatrix43.GetTranslation() - instances[i].SRTMatrix43.GetTranslation());
|
|||
|
}
|
|||
|
else if (i == instances.size() - 1)
|
|||
|
{
|
|||
|
axis = (instances[i].SRTMatrix43.GetTranslation() - instances[i - 1].SRTMatrix43.GetTranslation());
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
axis = (instances[i + 1].SRTMatrix43.GetTranslation() - instances[i - 1].SRTMatrix43.GetTranslation());
|
|||
|
}
|
|||
|
|
|||
|
auto U = SafeNormalize(axis);
|
|||
|
auto F = ::Effekseer::SIMD::Vec3f(m_renderer->GetCameraFrontDirection());
|
|||
|
auto R = SafeNormalize(::Effekseer::SIMD::Vec3f::Cross(U, F));
|
|||
|
U = ::Effekseer::SIMD::Vec3f::Cross(F, R);
|
|||
|
|
|||
|
Effekseer::SIMD::Mat44f mat;
|
|||
|
mat.X = R.s;
|
|||
|
mat.Y = U.s;
|
|||
|
mat.Z = F.s;
|
|||
|
mat = mat.Transpose();
|
|||
|
|
|||
|
auto q = Effekseer::SIMD::Quaternionf::FromMatrix(mat);
|
|||
|
|
|||
|
auto qq = (q.s * q.s);
|
|||
|
auto len = sqrtf(qq.GetX() + qq.GetY() + qq.GetZ() + qq.GetW()) + 0.00001f;
|
|||
|
|
|||
|
q.s /= len;
|
|||
|
|
|||
|
rotations_temp_[i] = q;
|
|||
|
}
|
|||
|
|
|||
|
// Make smooth
|
|||
|
rotations_[0] = rotations_temp_[0];
|
|||
|
rotations_.back() = rotations_temp_.back();
|
|||
|
|
|||
|
for (size_t i = 1; i < instances.size() - 1; i++)
|
|||
|
{
|
|||
|
const auto q1 = Effekseer::SIMD::Quaternionf::Slerp(rotations_temp_[i - 1], rotations_temp_[i + 1], 0.5f);
|
|||
|
rotations_[i] = Effekseer::SIMD::Quaternionf::Slerp(q1, rotations_temp_[i], 2.0f / 3.0f);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Calculate spline
|
|||
|
if (parameter.SplineDivision > 1)
|
|||
|
{
|
|||
|
spline.Reset();
|
|||
|
|
|||
|
for (size_t loop = 0; loop < instances.size(); loop++)
|
|||
|
{
|
|||
|
auto p = efkVector3D();
|
|||
|
auto& param = instances[loop];
|
|||
|
|
|||
|
auto mat = param.SRTMatrix43;
|
|||
|
|
|||
|
if (parameter.EnableViewOffset == true)
|
|||
|
{
|
|||
|
ApplyViewOffset(mat, camera, param.ViewOffsetDistance);
|
|||
|
}
|
|||
|
|
|||
|
ApplyDepthParameters(mat,
|
|||
|
m_renderer->GetCameraFrontDirection(),
|
|||
|
m_renderer->GetCameraPosition(),
|
|||
|
// s,
|
|||
|
parameter.DepthParameterPtr,
|
|||
|
parameter.IsRightHand);
|
|||
|
|
|||
|
p = mat.GetTranslation();
|
|||
|
spline.AddVertex(p);
|
|||
|
}
|
|||
|
|
|||
|
spline.Calculate();
|
|||
|
}
|
|||
|
|
|||
|
StrideView<VERTEX> verteies(m_ringBufferData, stride_, vertexCount_);
|
|||
|
|
|||
|
for (size_t loop = 0; loop < instances.size(); loop++)
|
|||
|
{
|
|||
|
auto& param = instances[loop];
|
|||
|
|
|||
|
for (int32_t sploop = 0; sploop < parameter.SplineDivision; sploop++)
|
|||
|
{
|
|||
|
auto mat = param.SRTMatrix43;
|
|||
|
|
|||
|
if (parameter.EnableViewOffset == true)
|
|||
|
{
|
|||
|
ApplyViewOffset(mat, camera, param.ViewOffsetDistance);
|
|||
|
}
|
|||
|
|
|||
|
::Effekseer::SIMD::Vec3f s;
|
|||
|
::Effekseer::SIMD::Mat43f r;
|
|||
|
::Effekseer::SIMD::Vec3f t;
|
|||
|
mat.GetSRT(s, r, t);
|
|||
|
|
|||
|
ApplyDepthParameters(r,
|
|||
|
t,
|
|||
|
s,
|
|||
|
m_renderer->GetCameraFrontDirection(),
|
|||
|
m_renderer->GetCameraPosition(),
|
|||
|
parameter.DepthParameterPtr,
|
|||
|
parameter.IsRightHand);
|
|||
|
|
|||
|
bool isFirst = param.InstanceIndex == 0 && sploop == 0;
|
|||
|
bool isLast = param.InstanceIndex == (param.InstanceCount - 1);
|
|||
|
|
|||
|
float size = 0.0f;
|
|||
|
::Effekseer::Color leftColor;
|
|||
|
::Effekseer::Color centerColor;
|
|||
|
::Effekseer::Color rightColor;
|
|||
|
|
|||
|
float percent = (float)(param.InstanceIndex * parameter.SplineDivision + sploop) /
|
|||
|
(float)((param.InstanceCount - 1) * parameter.SplineDivision);
|
|||
|
|
|||
|
if (param.InstanceIndex < param.InstanceCount / 2)
|
|||
|
{
|
|||
|
float l = percent;
|
|||
|
l = l * 2.0f;
|
|||
|
size = param.SizeFor + (param.SizeMiddle - param.SizeFor) * l;
|
|||
|
|
|||
|
leftColor.R = (uint8_t)Effekseer::Clamp(param.ColorLeft.R + (param.ColorLeftMiddle.R - param.ColorLeft.R) * l, 255, 0);
|
|||
|
leftColor.G = (uint8_t)Effekseer::Clamp(param.ColorLeft.G + (param.ColorLeftMiddle.G - param.ColorLeft.G) * l, 255, 0);
|
|||
|
leftColor.B = (uint8_t)Effekseer::Clamp(param.ColorLeft.B + (param.ColorLeftMiddle.B - param.ColorLeft.B) * l, 255, 0);
|
|||
|
leftColor.A = (uint8_t)Effekseer::Clamp(param.ColorLeft.A + (param.ColorLeftMiddle.A - param.ColorLeft.A) * l, 255, 0);
|
|||
|
|
|||
|
centerColor.R =
|
|||
|
(uint8_t)Effekseer::Clamp(param.ColorCenter.R + (param.ColorCenterMiddle.R - param.ColorCenter.R) * l, 255, 0);
|
|||
|
centerColor.G =
|
|||
|
(uint8_t)Effekseer::Clamp(param.ColorCenter.G + (param.ColorCenterMiddle.G - param.ColorCenter.G) * l, 255, 0);
|
|||
|
centerColor.B =
|
|||
|
(uint8_t)Effekseer::Clamp(param.ColorCenter.B + (param.ColorCenterMiddle.B - param.ColorCenter.B) * l, 255, 0);
|
|||
|
centerColor.A =
|
|||
|
(uint8_t)Effekseer::Clamp(param.ColorCenter.A + (param.ColorCenterMiddle.A - param.ColorCenter.A) * l, 255, 0);
|
|||
|
|
|||
|
rightColor.R =
|
|||
|
(uint8_t)Effekseer::Clamp(param.ColorRight.R + (param.ColorRightMiddle.R - param.ColorRight.R) * l, 255, 0);
|
|||
|
rightColor.G =
|
|||
|
(uint8_t)Effekseer::Clamp(param.ColorRight.G + (param.ColorRightMiddle.G - param.ColorRight.G) * l, 255, 0);
|
|||
|
rightColor.B =
|
|||
|
(uint8_t)Effekseer::Clamp(param.ColorRight.B + (param.ColorRightMiddle.B - param.ColorRight.B) * l, 255, 0);
|
|||
|
rightColor.A =
|
|||
|
(uint8_t)Effekseer::Clamp(param.ColorRight.A + (param.ColorRightMiddle.A - param.ColorRight.A) * l, 255, 0);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
float l = percent;
|
|||
|
l = 1.0f - (l * 2.0f - 1.0f);
|
|||
|
size = param.SizeBack + (param.SizeMiddle - param.SizeBack) * l;
|
|||
|
|
|||
|
leftColor.R = (uint8_t)Effekseer::Clamp(param.ColorLeft.R + (param.ColorLeftMiddle.R - param.ColorLeft.R) * l, 255, 0);
|
|||
|
leftColor.G = (uint8_t)Effekseer::Clamp(param.ColorLeft.G + (param.ColorLeftMiddle.G - param.ColorLeft.G) * l, 255, 0);
|
|||
|
leftColor.B = (uint8_t)Effekseer::Clamp(param.ColorLeft.B + (param.ColorLeftMiddle.B - param.ColorLeft.B) * l, 255, 0);
|
|||
|
leftColor.A = (uint8_t)Effekseer::Clamp(param.ColorLeft.A + (param.ColorLeftMiddle.A - param.ColorLeft.A) * l, 255, 0);
|
|||
|
|
|||
|
centerColor.R =
|
|||
|
(uint8_t)Effekseer::Clamp(param.ColorCenter.R + (param.ColorCenterMiddle.R - param.ColorCenter.R) * l, 255, 0);
|
|||
|
centerColor.G =
|
|||
|
(uint8_t)Effekseer::Clamp(param.ColorCenter.G + (param.ColorCenterMiddle.G - param.ColorCenter.G) * l, 255, 0);
|
|||
|
centerColor.B =
|
|||
|
(uint8_t)Effekseer::Clamp(param.ColorCenter.B + (param.ColorCenterMiddle.B - param.ColorCenter.B) * l, 255, 0);
|
|||
|
centerColor.A =
|
|||
|
(uint8_t)Effekseer::Clamp(param.ColorCenter.A + (param.ColorCenterMiddle.A - param.ColorCenter.A) * l, 255, 0);
|
|||
|
|
|||
|
rightColor.R =
|
|||
|
(uint8_t)Effekseer::Clamp(param.ColorRight.R + (param.ColorRightMiddle.R - param.ColorRight.R) * l, 255, 0);
|
|||
|
rightColor.G =
|
|||
|
(uint8_t)Effekseer::Clamp(param.ColorRight.G + (param.ColorRightMiddle.G - param.ColorRight.G) * l, 255, 0);
|
|||
|
rightColor.B =
|
|||
|
(uint8_t)Effekseer::Clamp(param.ColorRight.B + (param.ColorRightMiddle.B - param.ColorRight.B) * l, 255, 0);
|
|||
|
rightColor.A =
|
|||
|
(uint8_t)Effekseer::Clamp(param.ColorRight.A + (param.ColorRightMiddle.A - param.ColorRight.A) * l, 255, 0);
|
|||
|
}
|
|||
|
|
|||
|
VERTEX v[3];
|
|||
|
|
|||
|
v[0].Pos.X = (-size / 2.0f) * s.GetX();
|
|||
|
v[0].Pos.Y = 0.0f;
|
|||
|
v[0].Pos.Z = 0.0f;
|
|||
|
v[0].SetColor(leftColor, FLIP_RGB);
|
|||
|
|
|||
|
v[1].Pos.X = 0.0f;
|
|||
|
v[1].Pos.Y = 0.0f;
|
|||
|
v[1].Pos.Z = 0.0f;
|
|||
|
v[1].SetColor(centerColor, FLIP_RGB);
|
|||
|
|
|||
|
v[2].Pos.X = (size / 2.0f) * s.GetX();
|
|||
|
v[2].Pos.Y = 0.0f;
|
|||
|
v[2].Pos.Z = 0.0f;
|
|||
|
v[2].SetColor(rightColor, FLIP_RGB);
|
|||
|
|
|||
|
v[0].SetFlipbookIndexAndNextRate(param.FlipbookIndexAndNextRate);
|
|||
|
v[1].SetFlipbookIndexAndNextRate(param.FlipbookIndexAndNextRate);
|
|||
|
v[2].SetFlipbookIndexAndNextRate(param.FlipbookIndexAndNextRate);
|
|||
|
|
|||
|
v[0].SetAlphaThreshold(param.AlphaThreshold);
|
|||
|
v[1].SetAlphaThreshold(param.AlphaThreshold);
|
|||
|
v[2].SetAlphaThreshold(param.AlphaThreshold);
|
|||
|
|
|||
|
if (parameter.SplineDivision > 1)
|
|||
|
{
|
|||
|
v[1].Pos = ToStruct(spline.GetValue(param.InstanceIndex + sploop / (float)parameter.SplineDivision));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
v[1].Pos = ToStruct(t);
|
|||
|
}
|
|||
|
|
|||
|
if (isFirst)
|
|||
|
{
|
|||
|
verteies[0] = v[0];
|
|||
|
verteies[1] = v[1];
|
|||
|
verteies[4] = v[1];
|
|||
|
verteies[5] = v[2];
|
|||
|
verteies += 2;
|
|||
|
}
|
|||
|
else if (isLast)
|
|||
|
{
|
|||
|
verteies[0] = v[0];
|
|||
|
verteies[1] = v[1];
|
|||
|
verteies[4] = v[1];
|
|||
|
verteies[5] = v[2];
|
|||
|
verteies += 6;
|
|||
|
m_ribbonCount += 2;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
verteies[0] = v[0];
|
|||
|
verteies[1] = v[1];
|
|||
|
verteies[4] = v[1];
|
|||
|
verteies[5] = v[2];
|
|||
|
|
|||
|
verteies[6] = v[0];
|
|||
|
verteies[7] = v[1];
|
|||
|
verteies[10] = v[1];
|
|||
|
verteies[11] = v[2];
|
|||
|
|
|||
|
verteies += 8;
|
|||
|
m_ribbonCount += 2;
|
|||
|
}
|
|||
|
|
|||
|
if (isLast)
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// transform all vertecies
|
|||
|
{
|
|||
|
StrideView<VERTEX> vs_(m_ringBufferData, stride_, vertexCount_);
|
|||
|
Effekseer::SIMD::Vec3f axisBefore{};
|
|||
|
|
|||
|
for (size_t i = 0; i < (instances.size() - 1) * parameter.SplineDivision + 1; i++)
|
|||
|
{
|
|||
|
bool isFirst_ = (i == 0);
|
|||
|
bool isLast_ = (i == ((instances.size() - 1) * parameter.SplineDivision));
|
|||
|
Effekseer::SIMD::Vec3f axis;
|
|||
|
Effekseer::SIMD::Vec3f pos;
|
|||
|
|
|||
|
if (isFirst_)
|
|||
|
{
|
|||
|
axis = (vs_[3].Pos - vs_[1].Pos);
|
|||
|
axis = SafeNormalize(axis);
|
|||
|
axisBefore = axis;
|
|||
|
}
|
|||
|
else if (isLast_)
|
|||
|
{
|
|||
|
axis = axisBefore;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Effekseer::SIMD::Vec3f axisOld = axisBefore;
|
|||
|
axis = vs_[9].Pos - vs_[7].Pos;
|
|||
|
axis = SafeNormalize(axis);
|
|||
|
axisBefore = axis;
|
|||
|
|
|||
|
axis = (axisBefore + axisOld) / 2.0f;
|
|||
|
}
|
|||
|
|
|||
|
pos = vs_[1].Pos;
|
|||
|
|
|||
|
VERTEX vl = vs_[0];
|
|||
|
VERTEX vm = vs_[1];
|
|||
|
VERTEX vr = vs_[5];
|
|||
|
|
|||
|
vm.Pos.X = 0.0f;
|
|||
|
vm.Pos.Y = 0.0f;
|
|||
|
vm.Pos.Z = 0.0f;
|
|||
|
|
|||
|
assert(vl.Pos.Y == 0.0f);
|
|||
|
assert(vr.Pos.Y == 0.0f);
|
|||
|
assert(vl.Pos.Z == 0.0f);
|
|||
|
assert(vr.Pos.Z == 0.0f);
|
|||
|
assert(vm.Pos.X == 0.0f);
|
|||
|
assert(vm.Pos.Y == 0.0f);
|
|||
|
assert(vm.Pos.Z == 0.0f);
|
|||
|
|
|||
|
if (parameter.SmoothingType == Effekseer::TrailSmoothingType::On)
|
|||
|
{
|
|||
|
Effekseer::SIMD::Quaternionf rotq;
|
|||
|
|
|||
|
if (isLast_)
|
|||
|
{
|
|||
|
rotq = rotations_.back();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int instInd = (int)i / parameter.SplineDivision;
|
|||
|
int splInd = i % parameter.SplineDivision;
|
|||
|
|
|||
|
auto q0 = rotations_[instInd];
|
|||
|
auto q1 = rotations_[instInd + 1];
|
|||
|
rotq = Effekseer::SIMD::Quaternionf::Slerp(q0, q1, splInd / static_cast<float>(parameter.SplineDivision));
|
|||
|
}
|
|||
|
|
|||
|
const auto rdir = Effekseer::SIMD::Quaternionf::Transform({-1, 0, 0}, rotq);
|
|||
|
|
|||
|
vl.Pos = ToStruct(rdir * vl.Pos.X + pos);
|
|||
|
vm.Pos = ToStruct(pos);
|
|||
|
vr.Pos = ToStruct(rdir * vr.Pos.X + pos);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
|
|||
|
::Effekseer::SIMD::Vec3f F;
|
|||
|
::Effekseer::SIMD::Vec3f R;
|
|||
|
::Effekseer::SIMD::Vec3f U;
|
|||
|
|
|||
|
// It can be optimized because X is only not zero.
|
|||
|
/*
|
|||
|
U = axis;
|
|||
|
|
|||
|
F = ::Effekseer::SIMD::Vec3f(m_renderer->GetCameraFrontDirection()).Normalize();
|
|||
|
R = ::Effekseer::SIMD::Vec3f::Cross(U, F).Normalize();
|
|||
|
F = ::Effekseer::SIMD::Vec3f::Cross(R, U).Normalize();
|
|||
|
|
|||
|
::Effekseer::SIMD::Mat43f mat_rot(
|
|||
|
-R.GetX(), -R.GetY(), -R.GetZ(),
|
|||
|
U.GetX(), U.GetY(), U.GetZ(),
|
|||
|
F.GetX(), F.GetY(), F.GetZ(),
|
|||
|
pos.GetX(), pos.GetY(), pos.GetZ());
|
|||
|
|
|||
|
vl.Pos = ToStruct(::Effekseer::SIMD::Vec3f::Transform(vl.Pos, mat_rot));
|
|||
|
vm.Pos = ToStruct(::Effekseer::SIMD::Vec3f::Transform(vm.Pos, mat_rot));
|
|||
|
vr.Pos = ToStruct(::Effekseer::SIMD::Vec3f::Transform(vr.Pos,mat_rot));
|
|||
|
*/
|
|||
|
|
|||
|
U = axis;
|
|||
|
F = m_renderer->GetCameraFrontDirection();
|
|||
|
R = SafeNormalize(::Effekseer::SIMD::Vec3f::Cross(U, F));
|
|||
|
|
|||
|
vl.Pos = ToStruct(-R * vl.Pos.X + pos);
|
|||
|
vm.Pos = ToStruct(pos);
|
|||
|
vr.Pos = ToStruct(-R * vr.Pos.X + pos);
|
|||
|
}
|
|||
|
|
|||
|
if (VertexNormalRequired<VERTEX>())
|
|||
|
{
|
|||
|
::Effekseer::SIMD::Vec3f tangent = SafeNormalize(Effekseer::SIMD::Vec3f(vl.Pos - vr.Pos));
|
|||
|
Effekseer::SIMD::Vec3f normal = SafeNormalize(Effekseer::SIMD::Vec3f::Cross(tangent, axis));
|
|||
|
|
|||
|
if (!parameter.IsRightHand)
|
|||
|
{
|
|||
|
normal = -normal;
|
|||
|
}
|
|||
|
|
|||
|
Effekseer::Color normal_ = PackVector3DF(normal);
|
|||
|
Effekseer::Color tangent_ = PackVector3DF(tangent);
|
|||
|
|
|||
|
vl.SetPackedNormal(normal_, FLIP_RGB);
|
|||
|
vm.SetPackedNormal(normal_, FLIP_RGB);
|
|||
|
vr.SetPackedNormal(normal_, FLIP_RGB);
|
|||
|
|
|||
|
vl.SetPackedTangent(tangent_, FLIP_RGB);
|
|||
|
vm.SetPackedTangent(tangent_, FLIP_RGB);
|
|||
|
vr.SetPackedTangent(tangent_, FLIP_RGB);
|
|||
|
}
|
|||
|
|
|||
|
if (isFirst_)
|
|||
|
{
|
|||
|
vs_[0] = vl;
|
|||
|
vs_[1] = vm;
|
|||
|
vs_[4] = vm;
|
|||
|
vs_[5] = vr;
|
|||
|
vs_ += 2;
|
|||
|
}
|
|||
|
else if (isLast_)
|
|||
|
{
|
|||
|
vs_[0] = vl;
|
|||
|
vs_[1] = vm;
|
|||
|
vs_[4] = vm;
|
|||
|
vs_[5] = vr;
|
|||
|
vs_ += 6;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
vs_[0] = vl;
|
|||
|
vs_[1] = vm;
|
|||
|
vs_[4] = vm;
|
|||
|
vs_[5] = vr;
|
|||
|
|
|||
|
vs_[6] = vl;
|
|||
|
vs_[7] = vm;
|
|||
|
vs_[10] = vm;
|
|||
|
vs_[11] = vr;
|
|||
|
|
|||
|
vs_ += 8;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// calculate UV
|
|||
|
AssignUVs<VERTEX, 0>(parameter, verteies);
|
|||
|
|
|||
|
if (VertexUV2Required<VERTEX>())
|
|||
|
{
|
|||
|
AssignUVs<VERTEX, 1>(parameter, verteies);
|
|||
|
}
|
|||
|
|
|||
|
AssignUVs<VERTEX, 2>(parameter, verteies);
|
|||
|
AssignUVs<VERTEX, 3>(parameter, verteies);
|
|||
|
AssignUVs<VERTEX, 4>(parameter, verteies);
|
|||
|
AssignUVs<VERTEX, 5>(parameter, verteies);
|
|||
|
AssignUVs<VERTEX, 6>(parameter, verteies);
|
|||
|
|
|||
|
// custom parameter
|
|||
|
if (customData1Count_ > 0)
|
|||
|
{
|
|||
|
StrideView<float> custom(m_ringBufferData + sizeof(DynamicVertex), stride_, vertexCount_);
|
|||
|
for (size_t loop = 0; loop < instances.size() - 1; loop++)
|
|||
|
{
|
|||
|
auto& param = instances[loop];
|
|||
|
|
|||
|
for (int32_t sploop = 0; sploop < parameter.SplineDivision; sploop++)
|
|||
|
{
|
|||
|
for (size_t i = 0; i < 8; i++)
|
|||
|
{
|
|||
|
auto c = (float*)(&custom[0]);
|
|||
|
memcpy(c, param.CustomData1.data(), sizeof(float) * customData1Count_);
|
|||
|
custom += 1;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (customData2Count_ > 0)
|
|||
|
{
|
|||
|
StrideView<float> custom(m_ringBufferData + sizeof(DynamicVertex) + sizeof(float) * customData1Count_, stride_, vertexCount_);
|
|||
|
for (size_t loop = 0; loop < instances.size() - 1; loop++)
|
|||
|
{
|
|||
|
auto& param = instances[loop];
|
|||
|
|
|||
|
for (int32_t sploop = 0; sploop < parameter.SplineDivision; sploop++)
|
|||
|
{
|
|||
|
for (size_t i = 0; i < 8; i++)
|
|||
|
{
|
|||
|
auto c = (float*)(&custom[0]);
|
|||
|
memcpy(c, param.CustomData2.data(), sizeof(float) * customData2Count_);
|
|||
|
custom += 1;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public:
|
|||
|
TrackRendererBase(RENDERER* renderer)
|
|||
|
: m_renderer(renderer)
|
|||
|
, m_ribbonCount(0)
|
|||
|
, m_ringBufferOffset(0)
|
|||
|
, m_ringBufferData(nullptr)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
virtual ~TrackRendererBase()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
protected:
|
|||
|
void Rendering_(const efkTrackNodeParam& parameter,
|
|||
|
const efkTrackInstanceParam& instanceParameter,
|
|||
|
const ::Effekseer::SIMD::Mat44f& camera)
|
|||
|
{
|
|||
|
if (m_ringBufferData == nullptr)
|
|||
|
return;
|
|||
|
if (instanceParameter.InstanceCount <= 1)
|
|||
|
return;
|
|||
|
|
|||
|
const auto& state = m_renderer->GetStandardRenderer()->GetState();
|
|||
|
const ShaderParameterCollector& collector = state.Collector;
|
|||
|
|
|||
|
if (collector.ShaderType == RendererShaderType::Material)
|
|||
|
{
|
|||
|
Rendering_Internal<DynamicVertex, FLIP_RGB_FLAG>(parameter, instanceParameter, camera);
|
|||
|
}
|
|||
|
else if (collector.ShaderType == RendererShaderType::AdvancedLit)
|
|||
|
{
|
|||
|
Rendering_Internal<AdvancedLightingVertex, FLIP_RGB_FLAG>(parameter, instanceParameter, camera);
|
|||
|
}
|
|||
|
else if (collector.ShaderType == RendererShaderType::AdvancedBackDistortion)
|
|||
|
{
|
|||
|
Rendering_Internal<AdvancedLightingVertex, FLIP_RGB_FLAG>(parameter, instanceParameter, camera);
|
|||
|
}
|
|||
|
else if (collector.ShaderType == RendererShaderType::AdvancedUnlit)
|
|||
|
{
|
|||
|
Rendering_Internal<AdvancedSimpleVertex, FLIP_RGB_FLAG>(parameter, instanceParameter, camera);
|
|||
|
}
|
|||
|
else if (collector.ShaderType == RendererShaderType::Lit)
|
|||
|
{
|
|||
|
Rendering_Internal<LightingVertex, FLIP_RGB_FLAG>(parameter, instanceParameter, camera);
|
|||
|
}
|
|||
|
else if (collector.ShaderType == RendererShaderType::BackDistortion)
|
|||
|
{
|
|||
|
Rendering_Internal<LightingVertex, FLIP_RGB_FLAG>(parameter, instanceParameter, camera);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Rendering_Internal<SimpleVertex, FLIP_RGB_FLAG>(parameter, instanceParameter, camera);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
template <typename VERTEX, bool FLIP_RGB>
|
|||
|
void Rendering_Internal(const efkTrackNodeParam& parameter,
|
|||
|
const efkTrackInstanceParam& instanceParameter,
|
|||
|
const ::Effekseer::SIMD::Mat44f& camera)
|
|||
|
{
|
|||
|
if (m_ringBufferData == nullptr)
|
|||
|
return;
|
|||
|
if (instanceParameter.InstanceCount < 2)
|
|||
|
return;
|
|||
|
|
|||
|
const efkTrackInstanceParam& param = instanceParameter;
|
|||
|
|
|||
|
bool isFirst = param.InstanceIndex == 0;
|
|||
|
bool isLast = param.InstanceIndex == (param.InstanceCount - 1);
|
|||
|
|
|||
|
if (isFirst)
|
|||
|
{
|
|||
|
if (parameter.SmoothingType == Effekseer::TrailSmoothingType::On)
|
|||
|
{
|
|||
|
rotations_.resize(param.InstanceCount);
|
|||
|
rotations_temp_.resize(param.InstanceCount);
|
|||
|
}
|
|||
|
|
|||
|
instances.reserve(param.InstanceCount);
|
|||
|
instances.resize(0);
|
|||
|
}
|
|||
|
|
|||
|
instances.push_back(param);
|
|||
|
|
|||
|
if (isLast)
|
|||
|
{
|
|||
|
RenderSplines<VERTEX, FLIP_RGB>(parameter, camera);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public:
|
|||
|
void Rendering(const efkTrackNodeParam& parameter, const efkTrackInstanceParam& instanceParameter, void* userData) override
|
|||
|
{
|
|||
|
Rendering_(parameter, instanceParameter, m_renderer->GetCameraMatrix());
|
|||
|
}
|
|||
|
|
|||
|
void BeginRenderingGroup(const efkTrackNodeParam& param, int32_t count, void* userData) override
|
|||
|
{
|
|||
|
m_ribbonCount = 0;
|
|||
|
int32_t vertexCount = ((count - 1) * param.SplineDivision) * 8;
|
|||
|
if (vertexCount <= 0)
|
|||
|
return;
|
|||
|
|
|||
|
EffekseerRenderer::StandardRendererState state;
|
|||
|
state.AlphaBlend = param.BasicParameterPtr->AlphaBlend;
|
|||
|
state.CullingType = ::Effekseer::CullingType::Double;
|
|||
|
state.DepthTest = param.ZTest;
|
|||
|
state.DepthWrite = param.ZWrite;
|
|||
|
|
|||
|
state.Flipbook = ToState(param.BasicParameterPtr->Flipbook);
|
|||
|
|
|||
|
state.UVDistortionIntensity = param.BasicParameterPtr->UVDistortionIntensity;
|
|||
|
|
|||
|
state.TextureBlendType = param.BasicParameterPtr->TextureBlendType;
|
|||
|
|
|||
|
state.BlendUVDistortionIntensity = param.BasicParameterPtr->BlendUVDistortionIntensity;
|
|||
|
|
|||
|
state.EmissiveScaling = param.BasicParameterPtr->EmissiveScaling;
|
|||
|
|
|||
|
state.EdgeThreshold = param.BasicParameterPtr->EdgeThreshold;
|
|||
|
state.EdgeColor[0] = param.BasicParameterPtr->EdgeColor[0];
|
|||
|
state.EdgeColor[1] = param.BasicParameterPtr->EdgeColor[1];
|
|||
|
state.EdgeColor[2] = param.BasicParameterPtr->EdgeColor[2];
|
|||
|
state.EdgeColor[3] = param.BasicParameterPtr->EdgeColor[3];
|
|||
|
state.EdgeColorScaling = param.BasicParameterPtr->EdgeColorScaling;
|
|||
|
state.IsAlphaCuttoffEnabled = param.BasicParameterPtr->IsAlphaCutoffEnabled;
|
|||
|
state.Maginification = param.Maginification;
|
|||
|
|
|||
|
state.Distortion = param.BasicParameterPtr->MaterialType == Effekseer::RendererMaterialType::BackDistortion;
|
|||
|
state.DistortionIntensity = param.BasicParameterPtr->DistortionIntensity;
|
|||
|
state.MaterialType = param.BasicParameterPtr->MaterialType;
|
|||
|
|
|||
|
state.RenderingUserData = param.UserData;
|
|||
|
state.HandleUserData = userData;
|
|||
|
|
|||
|
state.LocalTime = param.LocalTime;
|
|||
|
|
|||
|
state.CopyMaterialFromParameterToState(
|
|||
|
m_renderer,
|
|||
|
param.EffectPointer,
|
|||
|
param.BasicParameterPtr);
|
|||
|
|
|||
|
customData1Count_ = state.CustomData1Count;
|
|||
|
customData2Count_ = state.CustomData2Count;
|
|||
|
|
|||
|
m_renderer->GetStandardRenderer()->BeginRenderingAndRenderingIfRequired(state, vertexCount, stride_, (void*&)m_ringBufferData);
|
|||
|
vertexCount_ = vertexCount;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
//----------------------------------------------------------------------------------
|
|||
|
//
|
|||
|
//----------------------------------------------------------------------------------
|
|||
|
} // namespace EffekseerRenderer
|
|||
|
//----------------------------------------------------------------------------------
|
|||
|
//
|
|||
|
//----------------------------------------------------------------------------------
|
|||
|
#endif // __EFFEKSEERRENDERER_RIBBON_RENDERER_H__
|