From 7115f60b91b5717d90f643fd692010905c7004db Mon Sep 17 00:00:00 2001 From: Bryan Galdrikian Date: Thu, 31 May 2018 11:36:08 -0700 Subject: Blast 1.1.3. See docs/release_notes.txt. --- test/src/unit/TkCompositeTests.cpp | 1550 ++++++++++++++++++------------------ 1 file changed, 775 insertions(+), 775 deletions(-) mode change 100644 => 100755 test/src/unit/TkCompositeTests.cpp (limited to 'test/src/unit/TkCompositeTests.cpp') diff --git a/test/src/unit/TkCompositeTests.cpp b/test/src/unit/TkCompositeTests.cpp old mode 100644 new mode 100755 index 8f55612..96fcc75 --- a/test/src/unit/TkCompositeTests.cpp +++ b/test/src/unit/TkCompositeTests.cpp @@ -1,775 +1,775 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#include "TkBaseTest.h" - -#include -#include -#include - -#include "PsMemoryBuffer.h" - -#include "NvBlastTime.h" - - -/* -Composite and joint tests: - -0) Test serialization of composites and assemblies - -1) Create assembly, actors and joints should be created automatically - -2) Create an actor with internal joints. Splitting the actor should cause joint create events to be dispatched - -3) Joint update events should be fired when attached actors change - -4) Joint delete events should be fired when at least one attached actor is deleted - -5) Creating a composite from assets with internal joints should have expected behaviors (1-4) above -*/ - - -struct Composite -{ - std::vector m_actorDescs; - std::vector m_relTMs; - std::vector m_jointDescs; -}; - - -template -class TkCompositeTest : public TkBaseTest -{ -public: - - // Composite/joint tests - void createAssembly(std::vector& actors, std::vector& joints, bool createNRFJoints) - { - TkFramework* fw = NvBlastTkFrameworkGet(); - - actors.resize(4, nullptr); - actors[0] = fw->createActor(TkActorDesc(testAssets[0])); - actors[1] = fw->createActor(TkActorDesc(testAssets[0])); - actors[2] = fw->createActor(TkActorDesc(testAssets[1])); - actors[3] = fw->createActor(TkActorDesc(testAssets[1])); - - std::vector families(4); - families[0] = &actors[0]->getFamily(); - families[1] = &actors[1]->getFamily(); - families[2] = &actors[2]->getFamily(); - families[3] = &actors[3]->getFamily(); - - EXPECT_FALSE(actors[0] == nullptr); - EXPECT_FALSE(actors[1] == nullptr); - EXPECT_FALSE(actors[2] == nullptr); - EXPECT_FALSE(actors[3] == nullptr); - - const TkJointDesc jointDescsNoNRF[8] = - { - // Actor indices, chunk indices, attach position in the composite frame - { { families[0], families[1] }, { 6, 5 }, { PxVec3(0.0f, -1.5f, 0.5f), PxVec3(0.0f, -1.5f, 0.5f) } }, - { { families[0], families[1] }, { 4, 3 }, { PxVec3(0.0f, -0.5f, -0.5f), PxVec3(0.0f, -0.5f, -0.5f) } }, - - { { families[0], families[2] }, { 8, 6 }, { PxVec3(-0.5f, 0.0f, 0.5f), PxVec3(-0.5f, 0.0f, 0.5f) } }, - { { families[0], families[2] }, { 3, 1 }, { PxVec3(-1.5f, 0.0f, -0.5f), PxVec3(-1.5f, 0.0f, -0.5f) } }, - - { { families[1], families[3] }, { 7, 5 }, { PxVec3(0.5f, 0.0f, 0.5f), PxVec3(0.5f, 0.0f, 0.5f) } }, - { { families[1], families[3] }, { 4, 2 }, { PxVec3(1.0f, 0.0f, -0.5f), PxVec3(1.0f, 0.0f, -0.5f) } }, - - { { families[2], families[3] }, { 8, 7 }, { PxVec3(0.0f, 1.5f, 0.5f), PxVec3(0.0f, 1.5f, 0.5f) } }, - { { families[2], families[3] }, { 2, 1 }, { PxVec3(0.0f, 0.5f, -0.5f), PxVec3(0.0f, 0.5f, -0.5f) } } - }; - - const TkJointDesc jointDescsWithNRF[12] = - { - // Actor indices, chunk indices, attach position in the composite frame - { { families[0], families[1] }, { 6, 5 }, { PxVec3(0.0f, -1.5f, 0.5f), PxVec3(0.0f, -1.5f, 0.5f) } }, - { { families[0], families[1] }, { 4, 3 }, { PxVec3(0.0f, -0.5f, -0.5f), PxVec3(0.0f, -0.5f, -0.5f) } }, - - { { families[0], nullptr }, { 8, 0xFFFFFFFF }, { PxVec3(-0.5f, 0.0f, 0.5f), PxVec3(-0.5f, 0.0f, 0.5f) } }, - { { families[0], nullptr }, { 3, 0xFFFFFFFF }, { PxVec3(-1.5f, 0.0f, -0.5f), PxVec3(-1.5f, 0.0f, -0.5f) } }, - - { { nullptr, families[2] }, { 0xFFFFFFFF, 6 }, { PxVec3(-0.5f, 0.0f, 0.5f), PxVec3(-0.5f, 0.0f, 0.5f) } }, - { { nullptr, families[2] }, { 0xFFFFFFFF, 1 }, { PxVec3(-1.5f, 0.0f, -0.5f), PxVec3(-1.5f, 0.0f, -0.5f) } }, - - { { families[1], nullptr }, { 7, 0xFFFFFFFF }, { PxVec3(0.5f, 0.0f, 0.5f), PxVec3(0.5f, 0.0f, 0.5f) } }, - { { families[1], nullptr }, { 4, 0xFFFFFFFF }, { PxVec3(1.0f, 0.0f, -0.5f), PxVec3(1.0f, 0.0f, -0.5f) } }, - - { { nullptr, families[3] }, { 0xFFFFFFFF, 5 }, { PxVec3(0.5f, 0.0f, 0.5f), PxVec3(0.5f, 0.0f, 0.5f) } }, - { { nullptr, families[3] }, { 0xFFFFFFFF, 2 }, { PxVec3(1.0f, 0.0f, -0.5f), PxVec3(1.0f, 0.0f, -0.5f) } }, - - { { families[2], families[3] }, { 8, 7 }, { PxVec3(0.0f, 1.5f, 0.5f), PxVec3(0.0f, 1.5f, 0.5f) } }, - { { families[2], families[3] }, { 2, 1 }, { PxVec3(0.0f, 0.5f, -0.5f), PxVec3(0.0f, 0.5f, -0.5f), } } - }; - - const TkJointDesc* jointDescs = createNRFJoints ? jointDescsWithNRF : jointDescsNoNRF; - const int jointCount = createNRFJoints ? 12 : 8; - - joints.resize(jointCount, nullptr); - for (int i = 0; i < jointCount; ++i) - { - joints[i] = fw->createJoint(jointDescs[i]); - EXPECT_FALSE(joints[i] == nullptr); - } - } - - void familySerialization(std::vector& families, TestFamilyTracker& tracker) - { -#if 1 - NV_UNUSED(families); - NV_UNUSED(tracker); -#else - TkFramework* fw = NvBlastTkFrameworkGet(); - - PsMemoryBuffer* membuf = PX_NEW(PsMemoryBuffer); - EXPECT_TRUE(membuf != nullptr); - if (membuf == nullptr) - { - return; - } - - std::vector oldFamilies = families; - - for (size_t familyNum = 0; familyNum < families.size(); ++familyNum) - { - GTEST_FATAL_FAILURE_("Serialization of families needs to be put into extensions."); -// families[familyNum]->serialize(*membuf); - } - - for (size_t familyNum = 0; familyNum < families.size(); ++familyNum) - { - TkFamily* f = families[familyNum]; - - std::vector actors(f->getActorCount()); - f->getActors(actors.data(), static_cast(actors.size())); - for (auto a : actors) - { - tracker.eraseActor(a); - } - - f->release(); - families[familyNum] = nullptr; - } - - for (size_t familyNum = 0; familyNum < families.size(); ++familyNum) - { - GTEST_FATAL_FAILURE_("Deserialization of families needs to be put into extensions."); -// TkFamily* f = reinterpret_cast(fw->deserialize(*membuf)); -// f->addListener(tracker); -// families[familyNum] = f; - } - - for (size_t familyNum = 0; familyNum < families.size(); ++familyNum) - { - TkFamily* f = families[familyNum]; - - std::vector actors(f->getActorCount()); - f->getActors(actors.data(), static_cast(actors.size())); - for (auto a : actors) - { - tracker.insertActor(a); - - std::vector joints(a->getJointCount()); - a->getJoints(joints.data(), (uint32_t)joints.size()); - - for (auto j : joints) - { - const TkJointData jd = j->getData(); - if (jd.actors[0] != jd.actors[1]) - { - tracker.joints.insert(j); - } - } - } - } - - membuf->release(); -#endif - } - - void recollectActors(std::vector& families, std::vector& actors) - { - uint32_t totalActorCount = 0; - for (auto family : families) - { - EXPECT_LE(family->getActorCount() + totalActorCount, actors.size()); - totalActorCount += family->getActors(actors.data() + totalActorCount, static_cast(actors.size()) - totalActorCount); - } - } - - void assemblyCreateAndRelease(bool createNRFJoints, bool serializationTest) - { - createFramework(); - createTestAssets(); - - TkFramework* fw = NvBlastTkFrameworkGet(); - - const TkType* familyType = fw->getType(TkTypeIndex::Family); - EXPECT_TRUE(familyType != nullptr); - - TestFamilyTracker tracker; - - std::vector families1; - std::vector families2; - - // Create one assembly - std::vector actors1; - std::vector joints1; - createAssembly(actors1, joints1, createNRFJoints); - tracker.joints.insert(joints1.begin(), joints1.end()); - - // Create another assembly - std::vector actors2; - std::vector joints2; - createAssembly(actors2, joints2, createNRFJoints); - tracker.joints.insert(joints2.begin(), joints2.end()); - - // Store families and fill group - for (size_t actorNum = 0; actorNum < actors1.size(); ++actorNum) - { - TkFamily& family = actors1[actorNum]->getFamily(); - families1.push_back(&family); - family.addListener(tracker); - } - for (size_t actorNum = 0; actorNum < actors2.size(); ++actorNum) - { - TkFamily& family = actors2[actorNum]->getFamily(); - families2.push_back(&family); - family.addListener(tracker); - } - - if (serializationTest) - { - familySerialization(families1, tracker); - recollectActors(families1, actors1); - familySerialization(families2, tracker); - recollectActors(families2, actors2); - } - - EXPECT_EQ(joints1.size() + joints2.size(), tracker.joints.size()); - - // Release 1st assembly's actors - for (size_t actorNum = 0; actorNum < actors1.size(); ++actorNum) - { - actors1[actorNum]->release(); - } - - if (serializationTest) - { - familySerialization(families2, tracker); - recollectActors(families2, actors2); - } - - EXPECT_EQ(joints2.size(), tracker.joints.size()); - - // Release 2nd assembly's actors - for (size_t actorNum = 0; actorNum < actors1.size(); ++actorNum) - { - actors2[actorNum]->release(); - } - - EXPECT_EQ(0, tracker.joints.size()); - - releaseTestAssets(); - releaseFramework(); - } - - void assemblyInternalJoints(bool testAssemblySerialization) - { - createFramework(); - createTestAssets(true); // Create assets with internal joints - - TkFramework* fw = NvBlastTkFrameworkGet(); - - TestFamilyTracker tracker; - - TkGroupDesc gdesc; - gdesc.workerCount = m_taskman->getCpuDispatcher()->getWorkerCount(); - TkGroup* group = fw->createGroup(gdesc); - EXPECT_TRUE(group != nullptr); - - m_groupTM->setGroup(group); - - TkActorDesc adesc(testAssets[0]); - - TkActor* actor1 = fw->createActor(adesc); - EXPECT_TRUE(actor1 != nullptr); - tracker.insertActor(actor1); - - actor1->getFamily().addListener(tracker); - - TkFamily* family = &actor1->getFamily(); - - group->addActor(*actor1); - - CSParams cs2(2, 0.0f); - NvBlastExtProgramParams csParams2 = { &cs2, nullptr }; - actor1->damage(getCubeSlicerProgram(), &csParams2); - - EXPECT_EQ((size_t)0, tracker.joints.size()); - - m_groupTM->process(); - m_groupTM->wait(); - - if (testAssemblySerialization) - { - std::vector families; - families.push_back(family); - familySerialization(families, tracker); - family = families[0]; - std::vector actors(family->getActorCount()); - family->getActors(actors.data(), static_cast(actors.size())); - for (TkActor* actor : actors) - { - group->addActor(*actor); - } - } - - EXPECT_EQ((size_t)2, family->getActorCount()); - EXPECT_EQ((size_t)4, tracker.joints.size()); // 2) Create an actor with internal joints. Splitting the actor should cause joint create events to be dispatched - - std::vector actors(family->getActorCount()); - family->getActors(actors.data(), static_cast(actors.size())); - - for (TkJoint* joint : tracker.joints) - { - TkJointData jd = joint->getData(); - EXPECT_FALSE(actors.end() == std::find(actors.begin(), actors.end(), jd.actors[0])); - EXPECT_FALSE(actors.end() == std::find(actors.begin(), actors.end(), jd.actors[1])); - } - - NvBlastExtRadialDamageDesc radialDamage = getRadialDamageDesc(0, 0, 0); - NvBlastExtProgramParams radialParams = { &radialDamage, nullptr }; - for (TkActor* actor : actors) - { - actor->damage(getFalloffProgram(), &radialParams); - } - - m_groupTM->process(); - m_groupTM->wait(); - - if (testAssemblySerialization) - { - std::vector families; - families.push_back(family); - familySerialization(families, tracker); - family = families[0]; - } - - EXPECT_EQ((size_t)8, family->getActorCount()); - EXPECT_EQ((size_t)4, tracker.joints.size()); - - // 3) Joint update events should be fired when attached actors change - - actors.resize(family->getActorCount()); - family->getActors(actors.data(), static_cast(actors.size())); - - for (TkJoint* joint : tracker.joints) - { - TkJointData jd = joint->getData(); - EXPECT_FALSE(actors.end() == std::find(actors.begin(), actors.end(), jd.actors[0])); - EXPECT_FALSE(actors.end() == std::find(actors.begin(), actors.end(), jd.actors[1])); - } - - for (TkActor* actor : actors) - { - actor->release(); - } - - EXPECT_EQ((size_t)0, tracker.joints.size()); // 4) Joint delete events should be fired when at least one attached actor is deleted - - group->release(); - - releaseTestAssets(); - releaseFramework(); - } - - void assemblyCompositeWithInternalJoints(bool createNRFJoints, bool serializationTest) - { - createFramework(); - createTestAssets(true); // Create assets with internal joints - - TkFramework* fw = NvBlastTkFrameworkGet(); - - const TkType* familyType = fw->getType(TkTypeIndex::Family); - EXPECT_TRUE(familyType != nullptr); - - if (familyType == nullptr) - { - return; - } - - TestFamilyTracker tracker; - - std::vector families; - - // Create assembly - std::vector actors; - std::vector joints; - createAssembly(actors, joints, createNRFJoints); - tracker.joints.insert(joints.begin(), joints.end()); - - TkGroupDesc gdesc; - gdesc.workerCount = m_taskman->getCpuDispatcher()->getWorkerCount(); - TkGroup* group = fw->createGroup(gdesc); - EXPECT_TRUE(group != nullptr); - - m_groupTM->setGroup(group); - - for (size_t i = 0; i < actors.size(); ++i) - { - TkFamily& family = actors[i]->getFamily(); - families.push_back(&family); - family.addListener(tracker); - tracker.insertActor(actors[i]); - group->addActor(*actors[i]); - } - - if (serializationTest) - { - familySerialization(families, tracker); - recollectActors(families, actors); - for (auto actor : actors) - { - group->addActor(*actor); - } - } - - EXPECT_EQ((size_t)4, actors.size()); - - const size_t compJointCount = createNRFJoints ? (size_t)12 : (size_t)8; - - EXPECT_EQ(compJointCount, tracker.joints.size()); - - CSParams cs2(2, 0.0f); - NvBlastExtProgramParams csParams2 = { &cs2, nullptr }; - - size_t totalActorCount = 0; - for (uint32_t i = 0; i < 4; ++i) - { - actors[i]->damage(getCubeSlicerProgram(), &csParams2); - - m_groupTM->process(); - m_groupTM->wait(); - - if (serializationTest) - { - familySerialization(families, tracker); - for (size_t j = 0; j < families.size(); ++j) - { - TkFamily* family = families[j]; - std::vector a(family->getActorCount()); - family->getActors(a.data(), static_cast(a.size())); - for (auto actor : a) - { - group->addActor(*actor); - } - EXPECT_TRUE(j <= i || a.size() == 1); - if (j > i && a.size() == 1) - { - actors[j] = a[0]; - } - } - } - - EXPECT_EQ((size_t)2, families[i]->getActorCount()); - EXPECT_EQ((size_t)(compJointCount + 4 * (i + 1)), tracker.joints.size()); // Four joints created per actor - - totalActorCount += families[i]->getActorCount(); - } - - actors.resize(totalActorCount); - totalActorCount = 0; - for (int i = 0; i < 4; ++i) - { - families[i]->getActors(actors.data() + totalActorCount, families[i]->getActorCount()); - totalActorCount += families[i]->getActorCount(); - } - - for (TkJoint* joint : tracker.joints) - { - TkJointData jd = joint->getData(); - EXPECT_TRUE(jd.actors[0] == nullptr || actors.end() != std::find(actors.begin(), actors.end(), jd.actors[0])); - EXPECT_TRUE(jd.actors[1] == nullptr || actors.end() != std::find(actors.begin(), actors.end(), jd.actors[1])); - } - - NvBlastExtRadialDamageDesc radialDamage = getRadialDamageDesc(0, 0, 0); - NvBlastExtProgramParams radialParams = { &radialDamage, nullptr }; - for (TkActor* actor : actors) - { - actor->damage(getFalloffProgram(), &radialParams); - } - - m_groupTM->process(); - m_groupTM->wait(); - - totalActorCount = 0; - for (int i = 0; i < 4; ++i) - { - totalActorCount += families[i]->getActorCount(); - } - - if (serializationTest) - { - familySerialization(families, tracker); - } - - EXPECT_EQ((size_t)32, totalActorCount); - EXPECT_EQ(compJointCount + (size_t)16, tracker.joints.size()); - - actors.resize(totalActorCount); - totalActorCount = 0; - for (int i = 0; i < 4; ++i) - { - families[i]->getActors(actors.data() + totalActorCount, families[i]->getActorCount()); - totalActorCount += families[i]->getActorCount(); - } - - // 3) Joint update events should be fired when attached actors change - - for (TkActor* actor : actors) - { - actor->release(); - } - - EXPECT_EQ((size_t)0, tracker.joints.size()); // 4) Joint delete events should be fired when at least one attached actor is deleted - - group->release(); - - releaseTestAssets(); - releaseFramework(); - } - - void assemblyExternalJoints_MultiFamilyDamage(bool explicitJointRelease = true) - { - createFramework(); - - const NvBlastChunkDesc chunkDescs[3] = - { -// centroid volume parent idx flags ID - { { 0.0f, 0.0f, 0.0f }, 4.0f, UINT32_MAX, NvBlastChunkDesc::NoFlags, 0 }, - { { 0.0f,-1.0f, 0.0f }, 2.0f, 0, NvBlastChunkDesc::SupportFlag, 1 }, - { { 0.0f, 1.0f, 0.0f }, 2.0f, 0, NvBlastChunkDesc::SupportFlag, 2 } - }; - - const NvBlastBondDesc bondDesc = -// normal area centroid userData chunks - { { { 0.0f, 1.0f, 0.0f }, 1.0f, { 0.0f, 0.0f, 0.0f }, 0 }, { 1, 2 } }; - - TkFramework* framework = NvBlastTkFrameworkGet(); - - TestFamilyTracker tracker; - - TkAssetDesc desc; - desc.chunkCount = 3; - desc.chunkDescs = chunkDescs; - desc.bondCount = 1; - desc.bondDescs = &bondDesc; - desc.bondFlags = nullptr; - TkAsset* asset = framework->createAsset(desc); - EXPECT_TRUE(asset != nullptr); - - TkGroupDesc gdesc; - gdesc.workerCount = m_taskman->getCpuDispatcher()->getWorkerCount(); - TkGroup* group = framework->createGroup(gdesc); - EXPECT_TRUE(group != nullptr); - - m_groupTM->setGroup(group); - - TkActorDesc adesc(asset); - TkActor* actor1 = framework->createActor(adesc); - EXPECT_TRUE(actor1 != nullptr); - TkActor* actor2 = framework->createActor(adesc); - EXPECT_TRUE(actor2 != nullptr); - - group->addActor(*actor1); - group->addActor(*actor2); - - TkFamily* family1 = &actor1->getFamily(); - TkFamily* family2 = &actor2->getFamily(); - - family1->addListener(tracker); - family2->addListener(tracker); - tracker.insertActor(actor1); - tracker.insertActor(actor2); - - TkJointDesc jdesc; - jdesc.families[0] = family1; - jdesc.families[1] = family2; - jdesc.chunkIndices[0] = 2; - jdesc.chunkIndices[1] = 1; - jdesc.attachPositions[0] = PxVec3(0.0f, 1.0f, 0.0f); - jdesc.attachPositions[1] = PxVec3(0.0f, -1.0f, 0.0f); - TkJoint* joint = framework->createJoint(jdesc); - EXPECT_TRUE(joint != nullptr); - tracker.joints.insert(joint); - - NvBlastExtRadialDamageDesc radialDamage1 = getRadialDamageDesc(0, 1, 0, 2, 2); - NvBlastExtProgramParams radialParams1 = { &radialDamage1, nullptr }; - actor1->damage(getFalloffProgram(), &radialParams1); - NvBlastExtRadialDamageDesc radialDamage2 = getRadialDamageDesc(0, -1, 0, 2, 2); - NvBlastExtProgramParams radialParams2 = { &radialDamage2, nullptr }; - actor2->damage(getFalloffProgram(), &radialParams2); - - m_groupTM->process(); - m_groupTM->wait(); - - TkActor* actors1[2]; - TkActor* actors2[2]; - EXPECT_EQ(2, family1->getActors(actors1, 2)); - EXPECT_EQ(2, family2->getActors(actors2, 2)); - - const TkJointData jdata = joint->getData(); - EXPECT_TRUE(jdata.actors[0] != nullptr); - EXPECT_TRUE(jdata.actors[1] != nullptr); - EXPECT_TRUE(&jdata.actors[0]->getFamily() == family1); - EXPECT_TRUE(&jdata.actors[1]->getFamily() == family2); - - // Clean up - if (explicitJointRelease) - { - joint->release(); - family2->release(); - family1->release(); - asset->release(); - releaseFramework(); - } - else - { - EXPECT_EQ(1, tracker.joints.size()); - releaseFramework(); - // Commenting these out - but shouldn't we be sending delete events when we release the framework? -// EXPECT_EQ(0, tracker.joints.size()); -// EXPECT_EQ(0, tracker.actors.size()); - } - } - -protected: - // http://clang.llvm.org/compatibility.html#dep_lookup_bases - // http://stackoverflow.com/questions/6592512/templates-parent-class-member-variables-not-visible-in-inherited-class - - using TkBaseTest::testAssets; - using TkBaseTest::m_taskman; - using TkBaseTest::m_groupTM; - using TkBaseTest::createFramework; - using TkBaseTest::releaseFramework; - using TkBaseTest::createTestAssets; - using TkBaseTest::releaseTestAssets; - using TkBaseTest::getCubeSlicerProgram; - using TkBaseTest::getDefaultMaterial; - using TkBaseTest::getRadialDamageDesc; - using TkBaseTest::getFalloffProgram; -}; - - -typedef TkCompositeTest TkCompositeTestAllowWarnings; -typedef TkCompositeTest TkCompositeTestStrict; - - -/* -1) Create assembly, actors and joints should be created automatically -*/ - -TEST_F(TkCompositeTestStrict, AssemblyCreateAndRelease_NoNRFJoints_NoSerialization) -{ - assemblyCreateAndRelease(false, false); -} - -TEST_F(TkCompositeTestStrict, DISABLED_AssemblyCreateAndRelease_NoNRFJoints_AssemblySerialization) -{ - assemblyCreateAndRelease(false, true); -} - -TEST_F(TkCompositeTestStrict, AssemblyCreateAndRelease_WithNRFJoints_NoSerialization) -{ - assemblyCreateAndRelease(true, false); -} - -TEST_F(TkCompositeTestStrict, DISABLED_AssemblyCreateAndRelease_WithNRFJoints_AssemblySerialization) -{ - assemblyCreateAndRelease(true, true); -} - - -/** -2) Create an actor with internal joints. Splitting the actor should cause joint create events to be dispatched - -3) Joint update events should be fired when attached actors change - -4) Joint delete events should be fired when at least one attached actor is deleted -*/ - -TEST_F(TkCompositeTestStrict, AssemblyInternalJoints_NoSerialization) -{ - assemblyInternalJoints(false); -} - -TEST_F(TkCompositeTestStrict, DISABLED_AssemblyInternalJoints_AssemblySerialization) -{ - assemblyInternalJoints(true); -} - - -/** -5) Creating a composite from assets with internal joints should have expected behaviors (1-4) above -*/ - -TEST_F(TkCompositeTestStrict, AssemblyCompositeWithInternalJoints_NoNRFJoints_NoSerialization) -{ - assemblyCompositeWithInternalJoints(false, false); -} - -TEST_F(TkCompositeTestStrict, DISABLED_AssemblyCompositeWithInternalJoints_NoNRFJoints_AssemblySerialization) -{ - assemblyCompositeWithInternalJoints(false, true); -} - -TEST_F(TkCompositeTestStrict, AssemblyCompositeWithInternalJoints_WithNRFJoints_NoSerialization) -{ - assemblyCompositeWithInternalJoints(true, false); -} - -TEST_F(TkCompositeTestStrict, DISABLED_AssemblyCompositeWithInternalJoints_WithNRFJoints_AssemblySerialization) -{ - assemblyCompositeWithInternalJoints(true, true); -} - - -/* -More tests -*/ - -TEST_F(TkCompositeTestStrict, AssemblyExternalJoints_MultiFamilyDamage) -{ - assemblyExternalJoints_MultiFamilyDamage(true); -} - -TEST_F(TkCompositeTestStrict, AssemblyExternalJoints_MultiFamilyDamage_AutoJointRelease) -{ - assemblyExternalJoints_MultiFamilyDamage(false); -} +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. + + +#include "TkBaseTest.h" + +#include +#include +#include + +#include "PsMemoryBuffer.h" + +#include "NvBlastTime.h" + + +/* +Composite and joint tests: + +0) Test serialization of composites and assemblies + +1) Create assembly, actors and joints should be created automatically + +2) Create an actor with internal joints. Splitting the actor should cause joint create events to be dispatched + +3) Joint update events should be fired when attached actors change + +4) Joint delete events should be fired when at least one attached actor is deleted + +5) Creating a composite from assets with internal joints should have expected behaviors (1-4) above +*/ + + +struct Composite +{ + std::vector m_actorDescs; + std::vector m_relTMs; + std::vector m_jointDescs; +}; + + +template +class TkCompositeTest : public TkBaseTest +{ +public: + + // Composite/joint tests + void createAssembly(std::vector& actors, std::vector& joints, bool createNRFJoints) + { + TkFramework* fw = NvBlastTkFrameworkGet(); + + actors.resize(4, nullptr); + actors[0] = fw->createActor(TkActorDesc(testAssets[0])); + actors[1] = fw->createActor(TkActorDesc(testAssets[0])); + actors[2] = fw->createActor(TkActorDesc(testAssets[1])); + actors[3] = fw->createActor(TkActorDesc(testAssets[1])); + + std::vector families(4); + families[0] = &actors[0]->getFamily(); + families[1] = &actors[1]->getFamily(); + families[2] = &actors[2]->getFamily(); + families[3] = &actors[3]->getFamily(); + + EXPECT_FALSE(actors[0] == nullptr); + EXPECT_FALSE(actors[1] == nullptr); + EXPECT_FALSE(actors[2] == nullptr); + EXPECT_FALSE(actors[3] == nullptr); + + const TkJointDesc jointDescsNoNRF[8] = + { + // Actor indices, chunk indices, attach position in the composite frame + { { families[0], families[1] }, { 6, 5 }, { PxVec3(0.0f, -1.5f, 0.5f), PxVec3(0.0f, -1.5f, 0.5f) } }, + { { families[0], families[1] }, { 4, 3 }, { PxVec3(0.0f, -0.5f, -0.5f), PxVec3(0.0f, -0.5f, -0.5f) } }, + + { { families[0], families[2] }, { 8, 6 }, { PxVec3(-0.5f, 0.0f, 0.5f), PxVec3(-0.5f, 0.0f, 0.5f) } }, + { { families[0], families[2] }, { 3, 1 }, { PxVec3(-1.5f, 0.0f, -0.5f), PxVec3(-1.5f, 0.0f, -0.5f) } }, + + { { families[1], families[3] }, { 7, 5 }, { PxVec3(0.5f, 0.0f, 0.5f), PxVec3(0.5f, 0.0f, 0.5f) } }, + { { families[1], families[3] }, { 4, 2 }, { PxVec3(1.0f, 0.0f, -0.5f), PxVec3(1.0f, 0.0f, -0.5f) } }, + + { { families[2], families[3] }, { 8, 7 }, { PxVec3(0.0f, 1.5f, 0.5f), PxVec3(0.0f, 1.5f, 0.5f) } }, + { { families[2], families[3] }, { 2, 1 }, { PxVec3(0.0f, 0.5f, -0.5f), PxVec3(0.0f, 0.5f, -0.5f) } } + }; + + const TkJointDesc jointDescsWithNRF[12] = + { + // Actor indices, chunk indices, attach position in the composite frame + { { families[0], families[1] }, { 6, 5 }, { PxVec3(0.0f, -1.5f, 0.5f), PxVec3(0.0f, -1.5f, 0.5f) } }, + { { families[0], families[1] }, { 4, 3 }, { PxVec3(0.0f, -0.5f, -0.5f), PxVec3(0.0f, -0.5f, -0.5f) } }, + + { { families[0], nullptr }, { 8, 0xFFFFFFFF }, { PxVec3(-0.5f, 0.0f, 0.5f), PxVec3(-0.5f, 0.0f, 0.5f) } }, + { { families[0], nullptr }, { 3, 0xFFFFFFFF }, { PxVec3(-1.5f, 0.0f, -0.5f), PxVec3(-1.5f, 0.0f, -0.5f) } }, + + { { nullptr, families[2] }, { 0xFFFFFFFF, 6 }, { PxVec3(-0.5f, 0.0f, 0.5f), PxVec3(-0.5f, 0.0f, 0.5f) } }, + { { nullptr, families[2] }, { 0xFFFFFFFF, 1 }, { PxVec3(-1.5f, 0.0f, -0.5f), PxVec3(-1.5f, 0.0f, -0.5f) } }, + + { { families[1], nullptr }, { 7, 0xFFFFFFFF }, { PxVec3(0.5f, 0.0f, 0.5f), PxVec3(0.5f, 0.0f, 0.5f) } }, + { { families[1], nullptr }, { 4, 0xFFFFFFFF }, { PxVec3(1.0f, 0.0f, -0.5f), PxVec3(1.0f, 0.0f, -0.5f) } }, + + { { nullptr, families[3] }, { 0xFFFFFFFF, 5 }, { PxVec3(0.5f, 0.0f, 0.5f), PxVec3(0.5f, 0.0f, 0.5f) } }, + { { nullptr, families[3] }, { 0xFFFFFFFF, 2 }, { PxVec3(1.0f, 0.0f, -0.5f), PxVec3(1.0f, 0.0f, -0.5f) } }, + + { { families[2], families[3] }, { 8, 7 }, { PxVec3(0.0f, 1.5f, 0.5f), PxVec3(0.0f, 1.5f, 0.5f) } }, + { { families[2], families[3] }, { 2, 1 }, { PxVec3(0.0f, 0.5f, -0.5f), PxVec3(0.0f, 0.5f, -0.5f), } } + }; + + const TkJointDesc* jointDescs = createNRFJoints ? jointDescsWithNRF : jointDescsNoNRF; + const int jointCount = createNRFJoints ? 12 : 8; + + joints.resize(jointCount, nullptr); + for (int i = 0; i < jointCount; ++i) + { + joints[i] = fw->createJoint(jointDescs[i]); + EXPECT_FALSE(joints[i] == nullptr); + } + } + + void familySerialization(std::vector& families, TestFamilyTracker& tracker) + { +#if 1 + NV_UNUSED(families); + NV_UNUSED(tracker); +#else + TkFramework* fw = NvBlastTkFrameworkGet(); + + PsMemoryBuffer* membuf = PX_NEW(PsMemoryBuffer); + EXPECT_TRUE(membuf != nullptr); + if (membuf == nullptr) + { + return; + } + + std::vector oldFamilies = families; + + for (size_t familyNum = 0; familyNum < families.size(); ++familyNum) + { + GTEST_FATAL_FAILURE_("Serialization of families needs to be put into extensions."); +// families[familyNum]->serialize(*membuf); + } + + for (size_t familyNum = 0; familyNum < families.size(); ++familyNum) + { + TkFamily* f = families[familyNum]; + + std::vector actors(f->getActorCount()); + f->getActors(actors.data(), static_cast(actors.size())); + for (auto a : actors) + { + tracker.eraseActor(a); + } + + f->release(); + families[familyNum] = nullptr; + } + + for (size_t familyNum = 0; familyNum < families.size(); ++familyNum) + { + GTEST_FATAL_FAILURE_("Deserialization of families needs to be put into extensions."); +// TkFamily* f = reinterpret_cast(fw->deserialize(*membuf)); +// f->addListener(tracker); +// families[familyNum] = f; + } + + for (size_t familyNum = 0; familyNum < families.size(); ++familyNum) + { + TkFamily* f = families[familyNum]; + + std::vector actors(f->getActorCount()); + f->getActors(actors.data(), static_cast(actors.size())); + for (auto a : actors) + { + tracker.insertActor(a); + + std::vector joints(a->getJointCount()); + a->getJoints(joints.data(), (uint32_t)joints.size()); + + for (auto j : joints) + { + const TkJointData jd = j->getData(); + if (jd.actors[0] != jd.actors[1]) + { + tracker.joints.insert(j); + } + } + } + } + + membuf->release(); +#endif + } + + void recollectActors(std::vector& families, std::vector& actors) + { + uint32_t totalActorCount = 0; + for (auto family : families) + { + EXPECT_LE(family->getActorCount() + totalActorCount, actors.size()); + totalActorCount += family->getActors(actors.data() + totalActorCount, static_cast(actors.size()) - totalActorCount); + } + } + + void assemblyCreateAndRelease(bool createNRFJoints, bool serializationTest) + { + createFramework(); + createTestAssets(); + + TkFramework* fw = NvBlastTkFrameworkGet(); + + const TkType* familyType = fw->getType(TkTypeIndex::Family); + EXPECT_TRUE(familyType != nullptr); + + TestFamilyTracker tracker; + + std::vector families1; + std::vector families2; + + // Create one assembly + std::vector actors1; + std::vector joints1; + createAssembly(actors1, joints1, createNRFJoints); + tracker.joints.insert(joints1.begin(), joints1.end()); + + // Create another assembly + std::vector actors2; + std::vector joints2; + createAssembly(actors2, joints2, createNRFJoints); + tracker.joints.insert(joints2.begin(), joints2.end()); + + // Store families and fill group + for (size_t actorNum = 0; actorNum < actors1.size(); ++actorNum) + { + TkFamily& family = actors1[actorNum]->getFamily(); + families1.push_back(&family); + family.addListener(tracker); + } + for (size_t actorNum = 0; actorNum < actors2.size(); ++actorNum) + { + TkFamily& family = actors2[actorNum]->getFamily(); + families2.push_back(&family); + family.addListener(tracker); + } + + if (serializationTest) + { + familySerialization(families1, tracker); + recollectActors(families1, actors1); + familySerialization(families2, tracker); + recollectActors(families2, actors2); + } + + EXPECT_EQ(joints1.size() + joints2.size(), tracker.joints.size()); + + // Release 1st assembly's actors + for (size_t actorNum = 0; actorNum < actors1.size(); ++actorNum) + { + actors1[actorNum]->release(); + } + + if (serializationTest) + { + familySerialization(families2, tracker); + recollectActors(families2, actors2); + } + + EXPECT_EQ(joints2.size(), tracker.joints.size()); + + // Release 2nd assembly's actors + for (size_t actorNum = 0; actorNum < actors1.size(); ++actorNum) + { + actors2[actorNum]->release(); + } + + EXPECT_EQ(0, tracker.joints.size()); + + releaseTestAssets(); + releaseFramework(); + } + + void assemblyInternalJoints(bool testAssemblySerialization) + { + createFramework(); + createTestAssets(true); // Create assets with internal joints + + TkFramework* fw = NvBlastTkFrameworkGet(); + + TestFamilyTracker tracker; + + TkGroupDesc gdesc; + gdesc.workerCount = m_taskman->getCpuDispatcher()->getWorkerCount(); + TkGroup* group = fw->createGroup(gdesc); + EXPECT_TRUE(group != nullptr); + + m_groupTM->setGroup(group); + + TkActorDesc adesc(testAssets[0]); + + TkActor* actor1 = fw->createActor(adesc); + EXPECT_TRUE(actor1 != nullptr); + tracker.insertActor(actor1); + + actor1->getFamily().addListener(tracker); + + TkFamily* family = &actor1->getFamily(); + + group->addActor(*actor1); + + CSParams cs2(2, 0.0f); + NvBlastExtProgramParams csParams2 = { &cs2, nullptr }; + actor1->damage(getCubeSlicerProgram(), &csParams2); + + EXPECT_EQ((size_t)0, tracker.joints.size()); + + m_groupTM->process(); + m_groupTM->wait(); + + if (testAssemblySerialization) + { + std::vector families; + families.push_back(family); + familySerialization(families, tracker); + family = families[0]; + std::vector actors(family->getActorCount()); + family->getActors(actors.data(), static_cast(actors.size())); + for (TkActor* actor : actors) + { + group->addActor(*actor); + } + } + + EXPECT_EQ((size_t)2, family->getActorCount()); + EXPECT_EQ((size_t)4, tracker.joints.size()); // 2) Create an actor with internal joints. Splitting the actor should cause joint create events to be dispatched + + std::vector actors(family->getActorCount()); + family->getActors(actors.data(), static_cast(actors.size())); + + for (TkJoint* joint : tracker.joints) + { + TkJointData jd = joint->getData(); + EXPECT_FALSE(actors.end() == std::find(actors.begin(), actors.end(), jd.actors[0])); + EXPECT_FALSE(actors.end() == std::find(actors.begin(), actors.end(), jd.actors[1])); + } + + NvBlastExtRadialDamageDesc radialDamage = getRadialDamageDesc(0, 0, 0); + NvBlastExtProgramParams radialParams = { &radialDamage, nullptr }; + for (TkActor* actor : actors) + { + actor->damage(getFalloffProgram(), &radialParams); + } + + m_groupTM->process(); + m_groupTM->wait(); + + if (testAssemblySerialization) + { + std::vector families; + families.push_back(family); + familySerialization(families, tracker); + family = families[0]; + } + + EXPECT_EQ((size_t)8, family->getActorCount()); + EXPECT_EQ((size_t)4, tracker.joints.size()); + + // 3) Joint update events should be fired when attached actors change + + actors.resize(family->getActorCount()); + family->getActors(actors.data(), static_cast(actors.size())); + + for (TkJoint* joint : tracker.joints) + { + TkJointData jd = joint->getData(); + EXPECT_FALSE(actors.end() == std::find(actors.begin(), actors.end(), jd.actors[0])); + EXPECT_FALSE(actors.end() == std::find(actors.begin(), actors.end(), jd.actors[1])); + } + + for (TkActor* actor : actors) + { + actor->release(); + } + + EXPECT_EQ((size_t)0, tracker.joints.size()); // 4) Joint delete events should be fired when at least one attached actor is deleted + + group->release(); + + releaseTestAssets(); + releaseFramework(); + } + + void assemblyCompositeWithInternalJoints(bool createNRFJoints, bool serializationTest) + { + createFramework(); + createTestAssets(true); // Create assets with internal joints + + TkFramework* fw = NvBlastTkFrameworkGet(); + + const TkType* familyType = fw->getType(TkTypeIndex::Family); + EXPECT_TRUE(familyType != nullptr); + + if (familyType == nullptr) + { + return; + } + + TestFamilyTracker tracker; + + std::vector families; + + // Create assembly + std::vector actors; + std::vector joints; + createAssembly(actors, joints, createNRFJoints); + tracker.joints.insert(joints.begin(), joints.end()); + + TkGroupDesc gdesc; + gdesc.workerCount = m_taskman->getCpuDispatcher()->getWorkerCount(); + TkGroup* group = fw->createGroup(gdesc); + EXPECT_TRUE(group != nullptr); + + m_groupTM->setGroup(group); + + for (size_t i = 0; i < actors.size(); ++i) + { + TkFamily& family = actors[i]->getFamily(); + families.push_back(&family); + family.addListener(tracker); + tracker.insertActor(actors[i]); + group->addActor(*actors[i]); + } + + if (serializationTest) + { + familySerialization(families, tracker); + recollectActors(families, actors); + for (auto actor : actors) + { + group->addActor(*actor); + } + } + + EXPECT_EQ((size_t)4, actors.size()); + + const size_t compJointCount = createNRFJoints ? (size_t)12 : (size_t)8; + + EXPECT_EQ(compJointCount, tracker.joints.size()); + + CSParams cs2(2, 0.0f); + NvBlastExtProgramParams csParams2 = { &cs2, nullptr }; + + size_t totalActorCount = 0; + for (uint32_t i = 0; i < 4; ++i) + { + actors[i]->damage(getCubeSlicerProgram(), &csParams2); + + m_groupTM->process(); + m_groupTM->wait(); + + if (serializationTest) + { + familySerialization(families, tracker); + for (size_t j = 0; j < families.size(); ++j) + { + TkFamily* family = families[j]; + std::vector a(family->getActorCount()); + family->getActors(a.data(), static_cast(a.size())); + for (auto actor : a) + { + group->addActor(*actor); + } + EXPECT_TRUE(j <= i || a.size() == 1); + if (j > i && a.size() == 1) + { + actors[j] = a[0]; + } + } + } + + EXPECT_EQ((size_t)2, families[i]->getActorCount()); + EXPECT_EQ((size_t)(compJointCount + 4 * (i + 1)), tracker.joints.size()); // Four joints created per actor + + totalActorCount += families[i]->getActorCount(); + } + + actors.resize(totalActorCount); + totalActorCount = 0; + for (int i = 0; i < 4; ++i) + { + families[i]->getActors(actors.data() + totalActorCount, families[i]->getActorCount()); + totalActorCount += families[i]->getActorCount(); + } + + for (TkJoint* joint : tracker.joints) + { + TkJointData jd = joint->getData(); + EXPECT_TRUE(jd.actors[0] == nullptr || actors.end() != std::find(actors.begin(), actors.end(), jd.actors[0])); + EXPECT_TRUE(jd.actors[1] == nullptr || actors.end() != std::find(actors.begin(), actors.end(), jd.actors[1])); + } + + NvBlastExtRadialDamageDesc radialDamage = getRadialDamageDesc(0, 0, 0); + NvBlastExtProgramParams radialParams = { &radialDamage, nullptr }; + for (TkActor* actor : actors) + { + actor->damage(getFalloffProgram(), &radialParams); + } + + m_groupTM->process(); + m_groupTM->wait(); + + totalActorCount = 0; + for (int i = 0; i < 4; ++i) + { + totalActorCount += families[i]->getActorCount(); + } + + if (serializationTest) + { + familySerialization(families, tracker); + } + + EXPECT_EQ((size_t)32, totalActorCount); + EXPECT_EQ(compJointCount + (size_t)16, tracker.joints.size()); + + actors.resize(totalActorCount); + totalActorCount = 0; + for (int i = 0; i < 4; ++i) + { + families[i]->getActors(actors.data() + totalActorCount, families[i]->getActorCount()); + totalActorCount += families[i]->getActorCount(); + } + + // 3) Joint update events should be fired when attached actors change + + for (TkActor* actor : actors) + { + actor->release(); + } + + EXPECT_EQ((size_t)0, tracker.joints.size()); // 4) Joint delete events should be fired when at least one attached actor is deleted + + group->release(); + + releaseTestAssets(); + releaseFramework(); + } + + void assemblyExternalJoints_MultiFamilyDamage(bool explicitJointRelease = true) + { + createFramework(); + + const NvBlastChunkDesc chunkDescs[3] = + { +// centroid volume parent idx flags ID + { { 0.0f, 0.0f, 0.0f }, 4.0f, UINT32_MAX, NvBlastChunkDesc::NoFlags, 0 }, + { { 0.0f,-1.0f, 0.0f }, 2.0f, 0, NvBlastChunkDesc::SupportFlag, 1 }, + { { 0.0f, 1.0f, 0.0f }, 2.0f, 0, NvBlastChunkDesc::SupportFlag, 2 } + }; + + const NvBlastBondDesc bondDesc = +// normal area centroid userData chunks + { { { 0.0f, 1.0f, 0.0f }, 1.0f, { 0.0f, 0.0f, 0.0f }, 0 }, { 1, 2 } }; + + TkFramework* framework = NvBlastTkFrameworkGet(); + + TestFamilyTracker tracker; + + TkAssetDesc desc; + desc.chunkCount = 3; + desc.chunkDescs = chunkDescs; + desc.bondCount = 1; + desc.bondDescs = &bondDesc; + desc.bondFlags = nullptr; + TkAsset* asset = framework->createAsset(desc); + EXPECT_TRUE(asset != nullptr); + + TkGroupDesc gdesc; + gdesc.workerCount = m_taskman->getCpuDispatcher()->getWorkerCount(); + TkGroup* group = framework->createGroup(gdesc); + EXPECT_TRUE(group != nullptr); + + m_groupTM->setGroup(group); + + TkActorDesc adesc(asset); + TkActor* actor1 = framework->createActor(adesc); + EXPECT_TRUE(actor1 != nullptr); + TkActor* actor2 = framework->createActor(adesc); + EXPECT_TRUE(actor2 != nullptr); + + group->addActor(*actor1); + group->addActor(*actor2); + + TkFamily* family1 = &actor1->getFamily(); + TkFamily* family2 = &actor2->getFamily(); + + family1->addListener(tracker); + family2->addListener(tracker); + tracker.insertActor(actor1); + tracker.insertActor(actor2); + + TkJointDesc jdesc; + jdesc.families[0] = family1; + jdesc.families[1] = family2; + jdesc.chunkIndices[0] = 2; + jdesc.chunkIndices[1] = 1; + jdesc.attachPositions[0] = PxVec3(0.0f, 1.0f, 0.0f); + jdesc.attachPositions[1] = PxVec3(0.0f, -1.0f, 0.0f); + TkJoint* joint = framework->createJoint(jdesc); + EXPECT_TRUE(joint != nullptr); + tracker.joints.insert(joint); + + NvBlastExtRadialDamageDesc radialDamage1 = getRadialDamageDesc(0, 1, 0, 2, 2); + NvBlastExtProgramParams radialParams1 = { &radialDamage1, nullptr }; + actor1->damage(getFalloffProgram(), &radialParams1); + NvBlastExtRadialDamageDesc radialDamage2 = getRadialDamageDesc(0, -1, 0, 2, 2); + NvBlastExtProgramParams radialParams2 = { &radialDamage2, nullptr }; + actor2->damage(getFalloffProgram(), &radialParams2); + + m_groupTM->process(); + m_groupTM->wait(); + + TkActor* actors1[2]; + TkActor* actors2[2]; + EXPECT_EQ(2, family1->getActors(actors1, 2)); + EXPECT_EQ(2, family2->getActors(actors2, 2)); + + const TkJointData jdata = joint->getData(); + EXPECT_TRUE(jdata.actors[0] != nullptr); + EXPECT_TRUE(jdata.actors[1] != nullptr); + EXPECT_TRUE(&jdata.actors[0]->getFamily() == family1); + EXPECT_TRUE(&jdata.actors[1]->getFamily() == family2); + + // Clean up + if (explicitJointRelease) + { + joint->release(); + family2->release(); + family1->release(); + asset->release(); + releaseFramework(); + } + else + { + EXPECT_EQ(1, tracker.joints.size()); + releaseFramework(); + // Commenting these out - but shouldn't we be sending delete events when we release the framework? +// EXPECT_EQ(0, tracker.joints.size()); +// EXPECT_EQ(0, tracker.actors.size()); + } + } + +protected: + // http://clang.llvm.org/compatibility.html#dep_lookup_bases + // http://stackoverflow.com/questions/6592512/templates-parent-class-member-variables-not-visible-in-inherited-class + + using TkBaseTest::testAssets; + using TkBaseTest::m_taskman; + using TkBaseTest::m_groupTM; + using TkBaseTest::createFramework; + using TkBaseTest::releaseFramework; + using TkBaseTest::createTestAssets; + using TkBaseTest::releaseTestAssets; + using TkBaseTest::getCubeSlicerProgram; + using TkBaseTest::getDefaultMaterial; + using TkBaseTest::getRadialDamageDesc; + using TkBaseTest::getFalloffProgram; +}; + + +typedef TkCompositeTest TkCompositeTestAllowWarnings; +typedef TkCompositeTest TkCompositeTestStrict; + + +/* +1) Create assembly, actors and joints should be created automatically +*/ + +TEST_F(TkCompositeTestStrict, AssemblyCreateAndRelease_NoNRFJoints_NoSerialization) +{ + assemblyCreateAndRelease(false, false); +} + +TEST_F(TkCompositeTestStrict, DISABLED_AssemblyCreateAndRelease_NoNRFJoints_AssemblySerialization) +{ + assemblyCreateAndRelease(false, true); +} + +TEST_F(TkCompositeTestStrict, AssemblyCreateAndRelease_WithNRFJoints_NoSerialization) +{ + assemblyCreateAndRelease(true, false); +} + +TEST_F(TkCompositeTestStrict, DISABLED_AssemblyCreateAndRelease_WithNRFJoints_AssemblySerialization) +{ + assemblyCreateAndRelease(true, true); +} + + +/** +2) Create an actor with internal joints. Splitting the actor should cause joint create events to be dispatched + +3) Joint update events should be fired when attached actors change + +4) Joint delete events should be fired when at least one attached actor is deleted +*/ + +TEST_F(TkCompositeTestStrict, AssemblyInternalJoints_NoSerialization) +{ + assemblyInternalJoints(false); +} + +TEST_F(TkCompositeTestStrict, DISABLED_AssemblyInternalJoints_AssemblySerialization) +{ + assemblyInternalJoints(true); +} + + +/** +5) Creating a composite from assets with internal joints should have expected behaviors (1-4) above +*/ + +TEST_F(TkCompositeTestStrict, AssemblyCompositeWithInternalJoints_NoNRFJoints_NoSerialization) +{ + assemblyCompositeWithInternalJoints(false, false); +} + +TEST_F(TkCompositeTestStrict, DISABLED_AssemblyCompositeWithInternalJoints_NoNRFJoints_AssemblySerialization) +{ + assemblyCompositeWithInternalJoints(false, true); +} + +TEST_F(TkCompositeTestStrict, AssemblyCompositeWithInternalJoints_WithNRFJoints_NoSerialization) +{ + assemblyCompositeWithInternalJoints(true, false); +} + +TEST_F(TkCompositeTestStrict, DISABLED_AssemblyCompositeWithInternalJoints_WithNRFJoints_AssemblySerialization) +{ + assemblyCompositeWithInternalJoints(true, true); +} + + +/* +More tests +*/ + +TEST_F(TkCompositeTestStrict, AssemblyExternalJoints_MultiFamilyDamage) +{ + assemblyExternalJoints_MultiFamilyDamage(true); +} + +TEST_F(TkCompositeTestStrict, AssemblyExternalJoints_MultiFamilyDamage_AutoJointRelease) +{ + assemblyExternalJoints_MultiFamilyDamage(false); +} -- cgit v1.2.3