BVB Source Codes

CRYENGINE Show ParticleSystemUnit.cpp Source code

Return Download CRYENGINE: download ParticleSystemUnit.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. // -------------------------------------------------------------------------
  4. //  Created:     06/04/2014 by Filipe amim
  5. //  Description:
  6. // -------------------------------------------------------------------------
  7. //
  8. ////////////////////////////////////////////////////////////////////////////
  9.  
  10. #include "StdAfx.h"
  11. #include <CrySystem/CryUnitTest.h>
  12. #include "ParticleSystem.h"
  13. #include "ParticleContainer.h"
  14. #include "../ParticleEffect.h"
  15. #include "ParticleEffect.h"
  16. #include <CryMath/SNoise.h>
  17. #include <CryMath/RadixSort.h>
  18.  
  19. #include <CrySerialization/IArchiveHost.h>
  20. #include <CrySerialization/Color.h>
  21.  
  22. CRY_PFX2_DBG
  23.  
  24. CRY_UNIT_TEST_SUITE(CryParticleSystemTest)
  25. {
  26.  
  27.         using namespace pfx2;
  28.  
  29. #define arraysize(array) (sizeof(array) / sizeof(array[0]))
  30.  
  31. #define CRY_PFX2_UNIT_TEST_ASSERT(cond) \
  32.   CRY_PFX2_ASSERT(cond)                 \
  33.   CRY_UNIT_TEST_ASSERT(cond)
  34.  
  35.         CRY_UNIT_TEST_FIXTURE(CParticleContainerRemoveTests)
  36.         {
  37.                 void Test(size_t containerSz, TParticleId* toRemove, size_t toRemoveSz)
  38.                 {
  39.                         // create particles with SpawnId
  40.                         TParticleHeap heap;
  41.                         pfx2::CParticleContainer container;
  42.                         container.AddParticleData(EPDT_SpawnId);
  43.                         pfx2::CParticleContainer::SSpawnEntry spawn;
  44.                         spawn.m_count = containerSz;
  45.                         spawn.m_parentId = 0;
  46.                         container.AddRemoveParticles(&spawn, 1, 0, 0);
  47.                         container.ResetSpawnedParticles();
  48.                         IOPidStream spawnIds = container.GetIOPidStream(EPDT_SpawnId);
  49.                         for (uint i = 0; i < containerSz; ++i)
  50.                                 spawnIds.Store(i, i);
  51.  
  52.                         // remove particles
  53.                         TParticleIdArray toRemoveMem(heap);
  54.                         toRemoveMem.reserve(toRemoveSz);
  55.                         for (size_t i = 0; i < toRemoveSz; ++i)
  56.                                 toRemoveMem.push_back(toRemove[i]);
  57.                         TParticleIdArray swapIds(heap, container.GetNumParticles());
  58.                         container.AddRemoveParticles(0, 0, &toRemoveMem, &swapIds);
  59.  
  60.                         // check if none of the particles are in the toRemove list
  61.                         for (uint i = 0; i < containerSz - toRemoveSz; ++i)
  62.                         {
  63.                                 for (uint j = 0; j < toRemoveSz; ++j)
  64.                                 {
  65.                                         CRY_PFX2_UNIT_TEST_ASSERT(spawnIds.Load(i) != toRemove[j]);
  66.                                 }
  67.                         }
  68.  
  69.                         // check that no ids are repeated
  70.                         for (uint i = 0; i < containerSz - toRemoveSz; ++i)
  71.                         {
  72.                                 for (uint j = 0; j < containerSz - toRemoveSz; ++j)
  73.                                 {
  74.                                         if (i == j)
  75.                                                 continue;
  76.                                         CRY_PFX2_UNIT_TEST_ASSERT(spawnIds.Load(i) != spawnIds.Load(j));
  77.                                 }
  78.                         }
  79.  
  80.                         // check if SwapIds is consistent with the actual final locations of the particles
  81.                         TParticleIdArray expected(heap, containerSz);
  82.                         for (uint i = 0; i < containerSz - toRemoveSz; ++i)
  83.                                 expected[spawnIds.Load(i)] = i;
  84.                         for (uint i = 0; i < toRemoveSz; ++i)
  85.                                 expected[toRemove[i]] = gInvalidId;
  86.                         CRY_PFX2_UNIT_TEST_ASSERT(memcmp(swapIds.data(), expected.data(), sizeof(TParticleId) * containerSz) == 0);
  87.                 }
  88.         };
  89.  
  90.         CRY_UNIT_TEST_WITH_FIXTURE(CParticleContainer_Remove_Case1, CParticleContainerRemoveTests)
  91.         {
  92.                 TParticleId toRemove[] = { 3, 4 };
  93.                 Test(5, toRemove, arraysize(toRemove));
  94.         }
  95.  
  96.         CRY_UNIT_TEST_WITH_FIXTURE(CParticleContainer_Remove_Case2, CParticleContainerRemoveTests)
  97.         {
  98.                 TParticleId toRemove[] = { 8, 12 };
  99.                 Test(13, toRemove, arraysize(toRemove));
  100.         }
  101.  
  102.         CRY_UNIT_TEST_WITH_FIXTURE(CParticleContainer_Remove_Case3, CParticleContainerRemoveTests)
  103.         {
  104.                 TParticleId toRemove[] = { 0, 4 };
  105.                 Test(5, toRemove, arraysize(toRemove));
  106.         }
  107.  
  108.         CRY_UNIT_TEST_WITH_FIXTURE(CParticleContainer_Remove_Case4, CParticleContainerRemoveTests)
  109.         {
  110.                 TParticleId toRemove[] = { 4, 7, 9 };
  111.                 Test(10, toRemove, arraysize(toRemove));
  112.         }
  113.  
  114.         CRY_UNIT_TEST_WITH_FIXTURE(CParticleContainer_Remove_Case5, CParticleContainerRemoveTests)
  115.         {
  116.                 TParticleId toRemove[] = { 0, 1, 2, 4, 5, 6 };
  117.                 Test(7, toRemove, arraysize(toRemove));
  118.         }
  119.  
  120.         CRY_UNIT_TEST_WITH_FIXTURE(CParticleContainer_Remove_Case6, CParticleContainerRemoveTests)
  121.         {
  122.                 TParticleId toRemove[] = { 0 };
  123.                 Test(1, toRemove, arraysize(toRemove));
  124.         }
  125.  
  126.         CRY_UNIT_TEST_WITH_FIXTURE(CParticleContainer_Remove_Case7, CParticleContainerRemoveTests)
  127.         {
  128.                 TParticleId toRemove[] = { 9, 11 };
  129.                 Test(21, toRemove, arraysize(toRemove));
  130.         }
  131.  
  132. #if CRY_PFX2_PARTICLESGROUP_STRIDE == 4
  133.  
  134.         CRY_UNIT_TEST_FIXTURE(CParticleContainerSpawn)
  135.         {
  136.         public:
  137.                 virtual void Init()
  138.                 {
  139.                         static_assert(CRY_PFX2_PARTICLESGROUP_STRIDE == 4, "This unit test is assuming vectorization of 4 particles");
  140.                         pContainer = std::unique_ptr<pfx2::CParticleContainer>(new pfx2::CParticleContainer());
  141.                         pContainer->AddParticleData(EPDT_ParentId);
  142.                         pContainer->AddParticleData(EPDT_State);
  143.                 };
  144.  
  145.                 virtual void Done()
  146.                 {
  147.                         pContainer.reset();
  148.                 };
  149.  
  150.                 void AddParticles(uint32 count)
  151.                 {
  152.                         ResetSpawnedParticles();
  153.                         pfx2::CParticleContainer::SSpawnEntry spawn;
  154.                         spawn.m_count = count;
  155.                         spawn.m_parentId = 0;
  156.                         pContainer->AddRemoveParticles(&spawn, 1, 0, 0);
  157.                 }
  158.  
  159.                 void ResetSpawnedParticles()
  160.                 {
  161.                         pContainer->ResetSpawnedParticles();
  162.                 }
  163.  
  164.                 const pfx2::CParticleContainer& GetContainer() const
  165.                 {
  166.                         return *pContainer;
  167.                 }
  168.  
  169.                 void ResetAll()
  170.                 {
  171.                         pContainer->Clear();
  172.                 }
  173.  
  174.                 bool TestNewBornFlags(uint numParticles)
  175.                 {
  176.                         const uint bufferSize = 128;
  177.                         const uint8 validMask = ES_Alive;
  178.                         const uint8 overrunMask = 0xff;
  179.                         pContainer->Resize(bufferSize);
  180.                         uint8* pData = pContainer->GetData<uint8>(EPDT_State);
  181.  
  182.                         AddParticles(numParticles);
  183.                         pContainer->ResetSpawnedParticles();
  184.                         memset(pData, validMask | ESB_NewBorn, numParticles);
  185.                         memset(pData + numParticles, overrunMask, bufferSize - numParticles);
  186.  
  187.                         pContainer->RemoveNewBornFlags();
  188.  
  189.                         for (uint i = 0; i < numParticles; ++i)
  190.                                 if (pData[i] != validMask)
  191.                                         return false;
  192.                         for (uint i = numParticles; i < bufferSize; ++i)
  193.                                 if (pData[i] != overrunMask)
  194.                                         return false;
  195.                         return true;
  196.                 }
  197.  
  198.         private:
  199.                 std::unique_ptr<pfx2::CParticleContainer> pContainer;
  200.         };
  201.  
  202.         CRY_UNIT_TEST_WITH_FIXTURE(CParticleContainer_VectorizeSpawn, CParticleContainerSpawn)
  203.         {
  204.                 // PFX2_TODO : right now new born vectorization is a bit too simple. Should be profiled and tested later
  205.                 // particle memory should be segmented.
  206.  
  207.                 const pfx2::CParticleContainer& container = GetContainer();
  208.                 AddParticles(6);
  209.  
  210.                 AddParticles(3);
  211.                 CRY_PFX2_UNIT_TEST_ASSERT(container.GetNumParticles() == 9);
  212.                 CRY_PFX2_UNIT_TEST_ASSERT(container.GetLastParticleId() == 11);
  213.                 CRY_PFX2_UNIT_TEST_ASSERT(container.GetFirstSpawnParticleId() == 8);
  214.                 CRY_PFX2_UNIT_TEST_ASSERT(container.GetNumSpawnedParticles() == 3);
  215.                 CRY_PFX2_UNIT_TEST_ASSERT(container.GetMaxParticles() > 11);
  216.  
  217.                 ResetSpawnedParticles();
  218.                 CRY_PFX2_UNIT_TEST_ASSERT(container.GetNumParticles() == 9);
  219.                 CRY_PFX2_UNIT_TEST_ASSERT(container.GetLastParticleId() == 9);
  220.                 CRY_PFX2_UNIT_TEST_ASSERT(container.GetFirstSpawnParticleId() == 9);
  221.                 CRY_PFX2_UNIT_TEST_ASSERT(container.GetNumSpawnedParticles() == 0);
  222.                 CRY_PFX2_UNIT_TEST_ASSERT(container.GetMaxParticles() > 9);
  223.         }
  224.  
  225.         CRY_UNIT_TEST_WITH_FIXTURE(CParticleContainer_RealId, CParticleContainerSpawn)
  226.         {
  227.                 const pfx2::CParticleContainer& container = GetContainer();
  228.  
  229.                 AddParticles(1);
  230.                 CRY_PFX2_UNIT_TEST_ASSERT(container.GetRealId(4) == 0);
  231.                 ResetSpawnedParticles();
  232.  
  233.                 ResetAll();
  234.                 AddParticles(6);
  235.                 AddParticles(3);
  236.                 CRY_PFX2_UNIT_TEST_ASSERT(container.GetRealId(3) == 3);
  237.                 CRY_PFX2_UNIT_TEST_ASSERT(container.GetRealId(8) == 8);
  238.                 CRY_PFX2_UNIT_TEST_ASSERT(container.GetRealId(10) == 7);
  239.                 ResetSpawnedParticles();
  240.                 CRY_PFX2_UNIT_TEST_ASSERT(container.GetRealId(3) == 3);
  241.                 CRY_PFX2_UNIT_TEST_ASSERT(container.GetRealId(8) == 8);
  242.                 CRY_PFX2_UNIT_TEST_ASSERT(container.GetRealId(6) == 6);
  243.         }
  244.  
  245.         CRY_UNIT_TEST_WITH_FIXTURE(CParticleContainer_NewBornFlags_Case1, CParticleContainerSpawn)
  246.         {
  247.                 const bool result = TestNewBornFlags(16);
  248.                 CRY_PFX2_UNIT_TEST_ASSERT(result);
  249.         }
  250.         CRY_UNIT_TEST_WITH_FIXTURE(CParticleContainer_NewBornFlags_Case2, CParticleContainerSpawn)
  251.         {
  252.                 const bool result = TestNewBornFlags(18);
  253.                 CRY_PFX2_UNIT_TEST_ASSERT(result);
  254.         }
  255.         CRY_UNIT_TEST_WITH_FIXTURE(CParticleContainer_NewBornFlags_Case3, CParticleContainerSpawn)
  256.         {
  257.                 const bool result = TestNewBornFlags(39);
  258.                 CRY_PFX2_UNIT_TEST_ASSERT(result);
  259.         }
  260.         CRY_UNIT_TEST_WITH_FIXTURE(CParticleContainer_NewBornFlags_Case4, CParticleContainerSpawn)
  261.         {
  262.                 const bool result = TestNewBornFlags(52);
  263.                 CRY_PFX2_UNIT_TEST_ASSERT(result);
  264.         }
  265.  
  266.         CRY_UNIT_TEST_FIXTURE(CParticleEffectTests)
  267.         {
  268.         public:
  269.                 virtual void Init() override
  270.                 {
  271.                         m_pEffect = std::unique_ptr<pfx2::CParticleEffect>(new pfx2::CParticleEffect());
  272.                 };
  273.  
  274.                 virtual void Done() override
  275.                 {
  276.                         m_pEffect.reset();
  277.                 }
  278.  
  279.                 pfx2::CParticleEffect& GetEffect()
  280.                 {
  281.                         return *m_pEffect;
  282.                 }
  283.  
  284.                 void LoadSimpleEffect()
  285.                 {
  286.                         const char* jsonCode =
  287.                           "{ \"Version\": 3,\n"
  288.                           "     \"Components\": [\n"
  289.                           "             { \"Component\": { \"Name\": \"Test01\" }},\n"
  290.                           "             { \"Component\": { \"Name\": \"Test02\" }}]}\n";
  291.                         Serialization::LoadJsonBuffer(GetEffect(), jsonCode, strlen(jsonCode));
  292.                 }
  293.  
  294.                 void LoadDefaultComponent(TComponentId componentId)
  295.                 {
  296.                         const char* jsonCode =
  297.                           "{ \"Name\": \"Default\", \"Features\": [\n"
  298.                           "     { \"RenderSprites\": { \"SortMode\": \"None\" } },\n"
  299.                           "     { \"SpawnRate\": {\n"
  300.                           "             \"Amount\": { \"value\": 1.0, \"modifiers\": [ ] },\n"
  301.                           "             \"Delay\": { \"State\": false, \"Value\": { \"value\": 0.0, \"modifiers\": [ ] } },\n"
  302.                           "             \"Duration\": { \"State\": false, \"Value\": { \"value\": 0.0, \"modifiers\": [ ] } },\n"
  303.                           "             \"Mode\": \"ParticlesPerSecond\"} },\n"
  304.                           "     { \"LifeTime\": { \"LifeTime\": { \"value\": 1, \"var\": 0 } } },\n"
  305.                           "     { \"FieldSize\": { \"value\": { \"value\": 1, \"modifiers\": [ ] } } } ] }\n";
  306.                         Serialization::LoadJsonBuffer(*GetEffect().GetComponent(componentId), jsonCode, strlen(jsonCode));
  307.                 }
  308.  
  309.         private:
  310.                 std::unique_ptr<pfx2::CParticleEffect> m_pEffect;
  311.         };
  312.  
  313.         CRY_UNIT_TEST_WITH_FIXTURE(CParticleSystem_USimpleEffect, CParticleEffectTests)
  314.         {
  315.                 pfx2::CParticleEffect& effect = GetEffect();
  316.                 LoadSimpleEffect();
  317.                 CRY_PFX2_UNIT_TEST_ASSERT(strcmp(effect.GetComponent(0)->GetName(), "Test01") == 0);
  318.                 CRY_PFX2_UNIT_TEST_ASSERT(strcmp(effect.GetComponent(1)->GetName(), "Test02") == 0);
  319.         }
  320.  
  321.         CRY_UNIT_TEST_WITH_FIXTURE(CParticleSystem_UniqueAutoName, CParticleEffectTests)
  322.         {
  323.                 pfx2::CParticleEffect& effect = GetEffect();
  324.                 effect.AddComponent(0);
  325.                 effect.AddComponent(1);
  326.                 CRY_PFX2_UNIT_TEST_ASSERT(strcmp(effect.GetComponent(0)->GetName(), "Component01") == 0);
  327.                 CRY_PFX2_UNIT_TEST_ASSERT(strcmp(effect.GetComponent(1)->GetName(), "Component02") == 0);
  328.         }
  329.  
  330.         CRY_UNIT_TEST_WITH_FIXTURE(CParticleSystem_UniqueCustomName, CParticleEffectTests)
  331.         {
  332.                 pfx2::CParticleEffect& effect = GetEffect();
  333.                 effect.AddComponent(0);
  334.                 effect.GetComponent(0)->SetName("Test");
  335.                 effect.AddComponent(1);
  336.                 effect.GetComponent(1)->SetName("Test");
  337.                 effect.AddComponent(2);
  338.                 effect.GetComponent(2)->SetName("Test");
  339.                 CRY_PFX2_UNIT_TEST_ASSERT(strcmp(effect.GetComponent(0)->GetName(), "Test") == 0);
  340.                 CRY_PFX2_UNIT_TEST_ASSERT(strcmp(effect.GetComponent(1)->GetName(), "Test01") == 0);
  341.                 CRY_PFX2_UNIT_TEST_ASSERT(strcmp(effect.GetComponent(2)->GetName(), "Test02") == 0);
  342.         }
  343.  
  344.         CRY_UNIT_TEST_WITH_FIXTURE(CParticleSystem_UniqueLoadedName, CParticleEffectTests)
  345.         {
  346.                 pfx2::CParticleEffect& effect = GetEffect();
  347.                 effect.AddComponent(0);
  348.                 LoadDefaultComponent(0);
  349.                 effect.AddComponent(1);
  350.                 LoadDefaultComponent(1);
  351.                 effect.AddComponent(2);
  352.                 LoadDefaultComponent(2);
  353.                 CRY_PFX2_UNIT_TEST_ASSERT(strcmp(effect.GetComponent(0)->GetName(), "Default") == 0);
  354.                 CRY_PFX2_UNIT_TEST_ASSERT(strcmp(effect.GetComponent(1)->GetName(), "Default01") == 0);
  355.                 CRY_PFX2_UNIT_TEST_ASSERT(strcmp(effect.GetComponent(2)->GetName(), "Default02") == 0);
  356.         }
  357.  
  358. #endif
  359.  
  360. #ifdef CRY_PFX2_USE_SSE
  361.  
  362.         CRY_UNIT_TEST(ParticleSSE_IndexedLoad4)
  363.         {
  364.                 using namespace pfx2::detail;
  365.                 CRY_ALIGN(16) float stream[] = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f };
  366.                 uint32v index;
  367.                 floatv expected, got;
  368.  
  369.                 index = _mm_set1_epi32(2);
  370.                 expected = _mm_set_ps(2.0f, 2.0f, 2.0f, 2.0f);
  371.                 got = LoadIndexed4(stream, index, -1.0f);
  372.                 CRY_PFX2_UNIT_TEST_ASSERT(All(got == expected));
  373.  
  374.                 index = _mm_set_epi32(7, 6, 5, 4);
  375.                 expected = _mm_set_ps(7.0f, 6.0f, 5.0f, 4.0f);
  376.                 got = LoadIndexed4(stream, index, -1.0f);
  377.                 CRY_PFX2_UNIT_TEST_ASSERT(All(got == expected));
  378.  
  379.                 index = _mm_set_epi32(0, 1, 2, 0);
  380.                 expected = _mm_set_ps(0.0f, 1.0f, 2.0f, 0.0f);
  381.                 got = LoadIndexed4(stream, index, -1.0f);
  382.                 CRY_PFX2_UNIT_TEST_ASSERT(All(got == expected));
  383.  
  384.                 index = _mm_set_epi32(0, -1, 2, -1);
  385.                 expected = _mm_set_ps(0.0f, -1.0f, 2.0f, -1.0f);
  386.                 got = LoadIndexed4(stream, index, -1.0f);
  387.                 CRY_PFX2_UNIT_TEST_ASSERT(All(got == expected));
  388.  
  389.                 index = _mm_set_epi32(-1, -1, -1, -1);
  390.                 expected = _mm_set_ps(-1.0f, -1.0f, -1.0f, -1.0f);
  391.                 got = LoadIndexed4(stream, index, -1.0f);
  392.                 CRY_PFX2_UNIT_TEST_ASSERT(All(got == expected));
  393.  
  394.                 index = _mm_set_epi32(9, 9, 2, 2);
  395.                 expected = _mm_set_ps(9.0f, 9.0f, 2.0f, 2.0f);
  396.                 got = LoadIndexed4(stream, index, -1.0f);
  397.                 CRY_PFX2_UNIT_TEST_ASSERT(All(got == expected));
  398.         }
  399.  
  400. #endif
  401.  
  402. }
  403.  
  404. CRY_UNIT_TEST_SUITE(CryVectorTest)
  405. {
  406.  
  407. #if defined(CRY_PFX2_USE_SSE)
  408.  
  409.         using namespace pfx2;
  410.  
  411.         template<typename Real>
  412.         NO_INLINE Real SNoiseNoInline(Vec4_tpl<Real> v)
  413.         {
  414.                 return SNoise(v);
  415.         }
  416.  
  417.         template<typename Real>
  418.         void SnoiseTest()
  419.         {
  420.                 using namespace crydetail;
  421.                 const Vec4_tpl<Real> s0 = ToVec4(convert<Real>(0.0f));
  422.                 const Vec4_tpl<Real> s1 = Vec4_tpl<Real>(convert<Real>(104.2f), convert<Real>(504.85f), convert<Real>(32.0f), convert<Real>(10.25f));
  423.                 const Vec4_tpl<Real> s2 = Vec4_tpl<Real>(convert<Real>(-104.2f), convert<Real>(504.85f), convert<Real>(-32.0f), convert<Real>(1.25f));
  424.                 const Vec4_tpl<Real> s3 = Vec4_tpl<Real>(convert<Real>(-257.07f), convert<Real>(-25.85f), convert<Real>(-0.5f), convert<Real>(105.5f));
  425.                 const Vec4_tpl<Real> s4 = Vec4_tpl<Real>(convert<Real>(104.2f), convert<Real>(1504.85f), convert<Real>(78.57f), convert<Real>(-0.75f));
  426.                 Real p0 = SNoiseNoInline(s0);
  427.                 Real p1 = SNoiseNoInline(s1);
  428.                 Real p2 = SNoiseNoInline(s2);
  429.                 Real p3 = SNoiseNoInline(s3);
  430.                 Real p4 = SNoiseNoInline(s4);
  431.                 CRY_PFX2_UNIT_TEST_ASSERT(All(p0 == convert<Real>(0.0f)));
  432.                 CRY_PFX2_UNIT_TEST_ASSERT(All(p1 == convert<Real>(-0.291425288f)));
  433.                 CRY_PFX2_UNIT_TEST_ASSERT(All(p2 == convert<Real>(-0.295406163f)));
  434.                 CRY_PFX2_UNIT_TEST_ASSERT(All(p3 == convert<Real>(-0.127176195f)));
  435.                 CRY_PFX2_UNIT_TEST_ASSERT(All(p4 == convert<Real>(-0.0293087773f)));
  436.         }
  437.  
  438.         CRY_UNIT_TEST(SNoiseTest)
  439.         {
  440.                 SnoiseTest<float>();
  441.                 SnoiseTest<floatv>();
  442.         }
  443.  
  444.         CRY_UNIT_TEST(ChaosKeyTest)
  445.         {
  446.                 for (int rep = 0; rep < 8; ++rep)
  447.                 {
  448.                         uint32 key = cry_random(0U, 99999U);
  449.                         SChaosKey ch(key);
  450.                         SChaosKeyV chv(ToUint32v(key));
  451.  
  452.                         uint32 r = ch.Rand();
  453.                         uint32v rv = chv.Rand();
  454.                         CRY_PFX2_UNIT_TEST_ASSERT(All(ToUint32v(r) == rv));
  455.  
  456.                         float ss = ch.RandSNorm();
  457.                         floatv ssv = chv.RandSNorm();
  458.                         CRY_PFX2_UNIT_TEST_ASSERT(All(ToFloatv(ss) == ssv));
  459.                 }
  460.         }
  461.  
  462.         CRY_UNIT_TEST(RadixSortTest)
  463.         {
  464.                 TParticleHeap heap;
  465.  
  466.                 const uint64 data[] = { 15923216, 450445401561561, 5061954, 5491494, 56494109840, 500120, 520025710, 58974, 45842669, 3226, 995422665 };
  467.                 const uint sz = sizeof(data) / sizeof(data[0]);
  468.                 const uint32 expectedIndices[sz] = { 9, 7, 5, 2, 3, 0, 8, 6, 10, 4, 1 };
  469.                 uint32 indices[sz];
  470.  
  471.                 RadixSort(indices, indices + sz, data, data + sz, heap);
  472.  
  473.                 CRY_PFX2_UNIT_TEST_ASSERT(memcmp(expectedIndices, indices, sz * 4) == 0);
  474.         }
  475.  
  476.         template<typename T>
  477.         void SpecialTest(T z = 0)
  478.         {
  479.                 typedef std::numeric_limits<T> lim;
  480.  
  481.                 auto has_denorm = lim::has_denorm;
  482.                 auto denorm_loss = lim::has_denorm_loss;
  483.                 T infinity = lim::infinity();
  484.                 T max = lim::max();
  485.                 T epsilon = lim::epsilon();
  486.                 T pmin = lim::min();
  487.                 T dmin = lim::denorm_min();
  488.                 T lmin = lim::lowest();
  489.  
  490.                 T dz2 = infinity + infinity;
  491.                 T dzsq = infinity * infinity;
  492.                 T dzm = infinity - T(1000);
  493.                 T zz = T(1) / infinity;
  494.  
  495.                 T dd = dmin + dmin;
  496.                 T dnz = dmin - dmin;
  497.                 T dp = dmin * T(1000000);
  498.         }
  499.  
  500.         CRY_UNIT_TEST(SpecialTests)
  501.         {
  502.                 SpecialTest<float>();
  503.                 SpecialTest<double>();
  504.         }
  505.  
  506. #endif
  507.  
  508. }
  509.  
downloadParticleSystemUnit.cpp Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top