// // ForceModule.cpp // libcocos2d Mac // // Created by 徐俊杰 on 2020/4/24. // #include "rparticle/Modules/ForceModule.h" //#include "UnityPrefix.h" //#include "rparticle/Modules/ForceModule.h" //#include "Runtime/BaseClasses/ObjectDefines.h" #include "rparticle/Serialize/TransferFunctions/SerializeTransfer.h" #include "rparticle/ParticleSystemUtils.h" #include "rparticle/Math/Random/Random.h" // Vec3 #define zero ZERO // MinMaxAABB #define m_Max _max #define m_Min _min NS_RRP_BEGIN template void UpdateTpl(const MinMaxCurve& x, const MinMaxCurve& y, const MinMaxCurve& z, const ParticleSystemReadOnlyState& roState, ParticleSystemParticles& ps, const size_t fromIndex, const size_t toIndex, bool transform, const Matrix4x4f& matrix, float dt) { for (size_t q = fromIndex; q < toIndex; ++q) { Vector3f random; GenerateRandom3(random, ps.randomSeed[q] + kParticleSystemForceCurveId); const float time = NormalizedTime(ps, q); Vector3f f = Vector3f (Evaluate (x, time, random.x), Evaluate (y, time, random.y), Evaluate (z, time, random.z)) * roState.GetRenderScale(); if(transform) f = matrix.MultiplyVector3 (f); ps.velocity[q] += f * dt; } } template void UpdateProceduralTpl(const DualMinMax3DPolyCurves& pos, const DualMinMax3DPolyCurves& vel, ParticleSystemParticles& ps, const Matrix4x4f& matrix, bool transform) { const size_t count = ps.array_size(); for (int q=0; q(m_X, m_Y, m_Z, roState, ps, fromIndex, toIndex, transform, matrix, dt); else if(isOptimized && usesMinMax) UpdateTpl(m_X, m_Y, m_Z, roState, ps, fromIndex, toIndex, transform, matrix, dt); else if(isOptimized) UpdateTpl(m_X, m_Y, m_Z, roState, ps, fromIndex, toIndex, transform, matrix, dt); else UpdateTpl(m_X, m_Y, m_Z, roState, ps, fromIndex, toIndex, transform, matrix, dt); } } void ForceModule::UpdateProcedural (const ParticleSystemReadOnlyState& roState, const ParticleSystemState& state, ParticleSystemParticles& ps) { Assert(!m_RandomizePerFrame); Matrix4x4f matrix; bool transform = GetTransformationMatrix(matrix, !roState.useLocalSpace, m_InWorldSpace, state.localToWorld); DualMinMax3DPolyCurves posCurves; DualMinMax3DPolyCurves velCurves; if(m_X.IsOptimized() && m_Y.IsOptimized() && m_Z.IsOptimized()) { posCurves.optX = m_X.polyCurves; posCurves.optX.DoubleIntegrate(); posCurves.optY = m_Y.polyCurves; posCurves.optY.DoubleIntegrate(); posCurves.optZ = m_Z.polyCurves; posCurves.optZ.DoubleIntegrate(); velCurves.optX = m_X.polyCurves; velCurves.optX.Integrate(); velCurves.optY = m_Y.polyCurves; velCurves.optY.Integrate(); velCurves.optZ = m_Z.polyCurves; velCurves.optZ.Integrate(); UpdateProceduralTpl(posCurves, velCurves, ps, matrix, transform); } else { DebugAssert(CurvesSupportProcedural (m_X.editorCurves, m_X.minMaxState)); DebugAssert(CurvesSupportProcedural (m_Y.editorCurves, m_Y.minMaxState)); DebugAssert(CurvesSupportProcedural (m_Z.editorCurves, m_Z.minMaxState)); BuildCurves(posCurves.x, m_X.editorCurves, m_X.GetScalar(), m_X.minMaxState); posCurves.x.DoubleIntegrate(); BuildCurves(posCurves.y, m_Y.editorCurves, m_Y.GetScalar(), m_Y.minMaxState); posCurves.y.DoubleIntegrate(); BuildCurves(posCurves.z, m_Z.editorCurves, m_Z.GetScalar(), m_Z.minMaxState); posCurves.z.DoubleIntegrate(); BuildCurves(velCurves.x, m_X.editorCurves, m_X.GetScalar(), m_X.minMaxState); velCurves.x.Integrate(); BuildCurves(velCurves.y, m_Y.editorCurves, m_Y.GetScalar(), m_Y.minMaxState); velCurves.y.Integrate(); BuildCurves(velCurves.z, m_Z.editorCurves, m_Z.GetScalar(), m_Z.minMaxState); velCurves.z.Integrate(); UpdateProceduralTpl(posCurves, velCurves, ps, matrix, transform); } } void ForceModule::CalculateProceduralBounds(MinMaxAABB& bounds, const Matrix4x4f& localToWorld, float maxLifeTime) { Vector2f xRange = m_X.FindMinMaxDoubleIntegrated(); Vector2f yRange = m_Y.FindMinMaxDoubleIntegrated(); Vector2f zRange = m_Z.FindMinMaxDoubleIntegrated(); bounds.m_Min = Vector3f(xRange.x, yRange.x, zRange.x) * maxLifeTime * maxLifeTime; bounds.m_Max = Vector3f(xRange.y, yRange.y, zRange.y) * maxLifeTime * maxLifeTime; if(m_InWorldSpace) { Matrix4x4f matrix; Matrix4x4f::Invert_General3D(localToWorld, matrix); matrix.SetPosition(Vector3f::zero); MinMaxAABB aabb = bounds; TransformAABBSlow(aabb, matrix, aabb); bounds = aabb; } } template void ForceModule::Transfer (TransferFunction& transfer) { ParticleSystemModule::Transfer (transfer); transfer.Transfer (m_X, "x"); transfer.Transfer (m_Y, "y"); transfer.Transfer (m_Z, "z"); transfer.Transfer (m_InWorldSpace, "inWorldSpace"); transfer.Transfer (m_RandomizePerFrame, "randomizePerFrame"); transfer.Align (); } INSTANTIATE_TEMPLATE_TRANSFER(ForceModule) NS_RRP_END