| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370 |
- // Copyright (c) Amer Koleci and Contributors.
- // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
- #include <gtest/gtest.h>
- #include "joltc.h"
- namespace BroadPhaseLayers {
- static constexpr JPH_BroadPhaseLayer NON_MOVING = 0;
- static constexpr JPH_BroadPhaseLayer MOVING = 1;
- static constexpr uint32_t NUM_LAYERS = 2;
- }
- namespace ObjectLayers {
- static constexpr JPH_ObjectLayer NON_MOVING = 0;
- static constexpr JPH_ObjectLayer MOVING = 1;
- static constexpr uint32_t NUM_LAYERS = 2;
- }
- class SkeletonTest : public ::testing::Test {
- protected:
- JPH_PhysicsSystem* physicsSystem = nullptr;
- JPH_BroadPhaseLayerInterface* bpLayer = nullptr;
- JPH_ObjectLayerPairFilter* objPairFilter = nullptr;
- JPH_ObjectVsBroadPhaseLayerFilter* objVsBpFilter = nullptr;
- void SetUp() override {
- ASSERT_TRUE(JPH_Init());
- bpLayer = JPH_BroadPhaseLayerInterfaceTable_Create(ObjectLayers::NUM_LAYERS, BroadPhaseLayers::NUM_LAYERS);
- JPH_BroadPhaseLayerInterfaceTable_MapObjectToBroadPhaseLayer(bpLayer, ObjectLayers::NON_MOVING, BroadPhaseLayers::NON_MOVING);
- JPH_BroadPhaseLayerInterfaceTable_MapObjectToBroadPhaseLayer(bpLayer, ObjectLayers::MOVING, BroadPhaseLayers::MOVING);
- objPairFilter = JPH_ObjectLayerPairFilterTable_Create(ObjectLayers::NUM_LAYERS);
- JPH_ObjectLayerPairFilterTable_EnableCollision(objPairFilter, ObjectLayers::NON_MOVING, ObjectLayers::MOVING);
- JPH_ObjectLayerPairFilterTable_EnableCollision(objPairFilter, ObjectLayers::MOVING, ObjectLayers::MOVING);
- objVsBpFilter = JPH_ObjectVsBroadPhaseLayerFilterTable_Create(
- bpLayer, BroadPhaseLayers::NUM_LAYERS,
- objPairFilter, ObjectLayers::NUM_LAYERS);
- JPH_PhysicsSystemSettings settings = {};
- settings.maxBodies = 1024;
- settings.maxBodyPairs = 1024;
- settings.maxContactConstraints = 1024;
- settings.broadPhaseLayerInterface = bpLayer;
- settings.objectVsBroadPhaseLayerFilter = objVsBpFilter;
- settings.objectLayerPairFilter = objPairFilter;
- physicsSystem = JPH_PhysicsSystem_Create(&settings);
- }
- void TearDown() override {
- if (physicsSystem) JPH_PhysicsSystem_Destroy(physicsSystem);
- JPH_Shutdown();
- }
- };
- // ============================================================================
- // Skeleton Tests
- // ============================================================================
- TEST_F(SkeletonTest, Skeleton_Create) {
- JPH_Skeleton* skeleton = JPH_Skeleton_Create();
- ASSERT_NE(skeleton, nullptr);
- EXPECT_EQ(JPH_Skeleton_GetJointCount(skeleton), 0);
- JPH_Skeleton_Destroy(skeleton);
- }
- TEST_F(SkeletonTest, Skeleton_AddJoint) {
- JPH_Skeleton* skeleton = JPH_Skeleton_Create();
- uint32_t rootIndex = JPH_Skeleton_AddJoint(skeleton, "root");
- EXPECT_EQ(rootIndex, 0u);
- EXPECT_EQ(JPH_Skeleton_GetJointCount(skeleton), 1);
- uint32_t childIndex = JPH_Skeleton_AddJoint2(skeleton, "child", 0);
- EXPECT_EQ(childIndex, 1u);
- EXPECT_EQ(JPH_Skeleton_GetJointCount(skeleton), 2);
- JPH_Skeleton_Destroy(skeleton);
- }
- TEST_F(SkeletonTest, Skeleton_AddJointByName) {
- JPH_Skeleton* skeleton = JPH_Skeleton_Create();
- JPH_Skeleton_AddJoint(skeleton, "root");
- uint32_t childIndex = JPH_Skeleton_AddJoint3(skeleton, "child", "root");
- EXPECT_EQ(childIndex, 1u);
- JPH_Skeleton_Destroy(skeleton);
- }
- TEST_F(SkeletonTest, Skeleton_GetJoint) {
- JPH_Skeleton* skeleton = JPH_Skeleton_Create();
- JPH_Skeleton_AddJoint(skeleton, "root");
- JPH_Skeleton_AddJoint2(skeleton, "spine", 0);
- JPH_SkeletonJoint joint;
- JPH_Skeleton_GetJoint(skeleton, 0, &joint);
- EXPECT_STREQ(joint.name, "root");
- EXPECT_EQ(joint.parentJointIndex, -1);
- JPH_Skeleton_GetJoint(skeleton, 1, &joint);
- EXPECT_STREQ(joint.name, "spine");
- EXPECT_EQ(joint.parentJointIndex, 0);
- JPH_Skeleton_Destroy(skeleton);
- }
- TEST_F(SkeletonTest, Skeleton_GetJointIndex) {
- JPH_Skeleton* skeleton = JPH_Skeleton_Create();
- JPH_Skeleton_AddJoint(skeleton, "root");
- JPH_Skeleton_AddJoint2(skeleton, "spine", 0);
- JPH_Skeleton_AddJoint2(skeleton, "head", 1);
- EXPECT_EQ(JPH_Skeleton_GetJointIndex(skeleton, "root"), 0);
- EXPECT_EQ(JPH_Skeleton_GetJointIndex(skeleton, "spine"), 1);
- EXPECT_EQ(JPH_Skeleton_GetJointIndex(skeleton, "head"), 2);
- EXPECT_EQ(JPH_Skeleton_GetJointIndex(skeleton, "nonexistent"), -1);
- JPH_Skeleton_Destroy(skeleton);
- }
- TEST_F(SkeletonTest, Skeleton_JointsCorrectlyOrdered) {
- JPH_Skeleton* skeleton = JPH_Skeleton_Create();
- JPH_Skeleton_AddJoint(skeleton, "root");
- JPH_Skeleton_AddJoint2(skeleton, "child", 0);
- EXPECT_TRUE(JPH_Skeleton_AreJointsCorrectlyOrdered(skeleton));
- JPH_Skeleton_Destroy(skeleton);
- }
- // ============================================================================
- // SkeletonPose Tests
- // ============================================================================
- TEST_F(SkeletonTest, SkeletonPose_Create) {
- JPH_SkeletonPose* pose = JPH_SkeletonPose_Create();
- ASSERT_NE(pose, nullptr);
- JPH_SkeletonPose_Destroy(pose);
- }
- TEST_F(SkeletonTest, SkeletonPose_SetSkeleton) {
- JPH_Skeleton* skeleton = JPH_Skeleton_Create();
- JPH_Skeleton_AddJoint(skeleton, "root");
- JPH_Skeleton_AddJoint2(skeleton, "child", 0);
- JPH_SkeletonPose* pose = JPH_SkeletonPose_Create();
- JPH_SkeletonPose_SetSkeleton(pose, skeleton);
- const JPH_Skeleton* retrievedSkeleton = JPH_SkeletonPose_GetSkeleton(pose);
- EXPECT_EQ(retrievedSkeleton, skeleton);
- EXPECT_EQ(JPH_SkeletonPose_GetJointCount(pose), 2);
- JPH_SkeletonPose_Destroy(pose);
- JPH_Skeleton_Destroy(skeleton);
- }
- TEST_F(SkeletonTest, SkeletonPose_RootOffset) {
- JPH_SkeletonPose* pose = JPH_SkeletonPose_Create();
- JPH_RVec3 offset = {1.0f, 2.0f, 3.0f};
- JPH_SkeletonPose_SetRootOffset(pose, &offset);
- JPH_RVec3 result;
- JPH_SkeletonPose_GetRootOffset(pose, &result);
- EXPECT_FLOAT_EQ(result.x, 1.0f);
- EXPECT_FLOAT_EQ(result.y, 2.0f);
- EXPECT_FLOAT_EQ(result.z, 3.0f);
- JPH_SkeletonPose_Destroy(pose);
- }
- TEST_F(SkeletonTest, SkeletonPose_JointState) {
- JPH_Skeleton* skeleton = JPH_Skeleton_Create();
- JPH_Skeleton_AddJoint(skeleton, "root");
- JPH_SkeletonPose* pose = JPH_SkeletonPose_Create();
- JPH_SkeletonPose_SetSkeleton(pose, skeleton);
- JPH_Vec3 translation = {1.0f, 2.0f, 3.0f};
- JPH_Quat rotation = {0.0f, 0.0f, 0.0f, 1.0f};
- JPH_SkeletonPose_SetJointState(pose, 0, &translation, &rotation);
- JPH_Vec3 outTranslation;
- JPH_Quat outRotation;
- JPH_SkeletonPose_GetJointState(pose, 0, &outTranslation, &outRotation);
- EXPECT_FLOAT_EQ(outTranslation.x, 1.0f);
- EXPECT_FLOAT_EQ(outTranslation.y, 2.0f);
- EXPECT_FLOAT_EQ(outTranslation.z, 3.0f);
- EXPECT_FLOAT_EQ(outRotation.w, 1.0f);
- JPH_SkeletonPose_Destroy(pose);
- JPH_Skeleton_Destroy(skeleton);
- }
- // ============================================================================
- // RagdollSettings Tests
- // ============================================================================
- TEST_F(SkeletonTest, RagdollSettings_Create) {
- JPH_RagdollSettings* settings = JPH_RagdollSettings_Create();
- ASSERT_NE(settings, nullptr);
- JPH_RagdollSettings_Destroy(settings);
- }
- TEST_F(SkeletonTest, RagdollSettings_SetSkeleton) {
- JPH_Skeleton* skeleton = JPH_Skeleton_Create();
- JPH_Skeleton_AddJoint(skeleton, "root");
- JPH_RagdollSettings* settings = JPH_RagdollSettings_Create();
- JPH_RagdollSettings_SetSkeleton(settings, skeleton);
- const JPH_Skeleton* retrievedSkeleton = JPH_RagdollSettings_GetSkeleton(settings);
- EXPECT_EQ(retrievedSkeleton, skeleton);
- JPH_RagdollSettings_Destroy(settings);
- JPH_Skeleton_Destroy(skeleton);
- }
- TEST_F(SkeletonTest, RagdollSettings_Parts) {
- JPH_RagdollSettings* settings = JPH_RagdollSettings_Create();
- JPH_RagdollSettings_ResizeParts(settings, 3);
- EXPECT_EQ(JPH_RagdollSettings_GetPartCount(settings), 3);
- // Set part properties
- JPH_SphereShape* shape = JPH_SphereShape_Create(0.5f);
- JPH_RVec3 position = {0.0f, 1.0f, 0.0f};
- JPH_Quat rotation = {0.0f, 0.0f, 0.0f, 1.0f};
- JPH_RagdollSettings_SetPartShape(settings, 0, (JPH_Shape*)shape);
- JPH_RagdollSettings_SetPartPosition(settings, 0, &position);
- JPH_RagdollSettings_SetPartRotation(settings, 0, &rotation);
- JPH_RagdollSettings_SetPartMotionType(settings, 0, JPH_MotionType_Dynamic);
- JPH_RagdollSettings_SetPartObjectLayer(settings, 0, ObjectLayers::MOVING);
- JPH_RagdollSettings_Destroy(settings);
- JPH_Shape_Destroy((JPH_Shape*)shape);
- }
- // ============================================================================
- // Ragdoll Tests
- // ============================================================================
- TEST_F(SkeletonTest, Ragdoll_CreateSimple) {
- // Create skeleton
- JPH_Skeleton* skeleton = JPH_Skeleton_Create();
- JPH_Skeleton_AddJoint(skeleton, "root");
- // Create ragdoll settings
- JPH_RagdollSettings* settings = JPH_RagdollSettings_Create();
- JPH_RagdollSettings_SetSkeleton(settings, skeleton);
- JPH_RagdollSettings_ResizeParts(settings, 1);
- // Set up part
- JPH_SphereShape* shape = JPH_SphereShape_Create(0.5f);
- JPH_RVec3 position = {0.0f, 1.0f, 0.0f};
- JPH_Quat rotation = {0.0f, 0.0f, 0.0f, 1.0f};
- JPH_RagdollSettings_SetPartShape(settings, 0, (JPH_Shape*)shape);
- JPH_RagdollSettings_SetPartPosition(settings, 0, &position);
- JPH_RagdollSettings_SetPartRotation(settings, 0, &rotation);
- JPH_RagdollSettings_SetPartMotionType(settings, 0, JPH_MotionType_Dynamic);
- JPH_RagdollSettings_SetPartObjectLayer(settings, 0, ObjectLayers::MOVING);
- // Create ragdoll
- JPH_Ragdoll* ragdoll = JPH_RagdollSettings_CreateRagdoll(settings, physicsSystem, 0, 0);
- ASSERT_NE(ragdoll, nullptr);
- EXPECT_EQ(JPH_Ragdoll_GetBodyCount(ragdoll), 1);
- JPH_BodyID bodyId = JPH_Ragdoll_GetBodyID(ragdoll, 0);
- EXPECT_NE(bodyId, 0xFFFFFFFF);
- JPH_Ragdoll_Destroy(ragdoll);
- JPH_RagdollSettings_Destroy(settings);
- JPH_Shape_Destroy((JPH_Shape*)shape);
- JPH_Skeleton_Destroy(skeleton);
- }
- TEST_F(SkeletonTest, Ragdoll_AddRemoveFromPhysicsSystem) {
- // Create skeleton
- JPH_Skeleton* skeleton = JPH_Skeleton_Create();
- JPH_Skeleton_AddJoint(skeleton, "root");
- // Create ragdoll settings
- JPH_RagdollSettings* settings = JPH_RagdollSettings_Create();
- JPH_RagdollSettings_SetSkeleton(settings, skeleton);
- JPH_RagdollSettings_ResizeParts(settings, 1);
- JPH_SphereShape* shape = JPH_SphereShape_Create(0.5f);
- JPH_RVec3 position = {0.0f, 1.0f, 0.0f};
- JPH_Quat rotation = {0.0f, 0.0f, 0.0f, 1.0f};
- JPH_RagdollSettings_SetPartShape(settings, 0, (JPH_Shape*)shape);
- JPH_RagdollSettings_SetPartPosition(settings, 0, &position);
- JPH_RagdollSettings_SetPartRotation(settings, 0, &rotation);
- JPH_RagdollSettings_SetPartMotionType(settings, 0, JPH_MotionType_Dynamic);
- JPH_RagdollSettings_SetPartObjectLayer(settings, 0, ObjectLayers::MOVING);
- JPH_Ragdoll* ragdoll = JPH_RagdollSettings_CreateRagdoll(settings, physicsSystem, 0, 0);
- // Add to physics system
- JPH_Ragdoll_AddToPhysicsSystem(ragdoll, JPH_Activation_Activate, true);
- EXPECT_TRUE(JPH_Ragdoll_IsActive(ragdoll, true));
- // Remove from physics system
- JPH_Ragdoll_RemoveFromPhysicsSystem(ragdoll, true);
- JPH_Ragdoll_Destroy(ragdoll);
- JPH_RagdollSettings_Destroy(settings);
- JPH_Shape_Destroy((JPH_Shape*)shape);
- JPH_Skeleton_Destroy(skeleton);
- }
- TEST_F(SkeletonTest, Ragdoll_GetRootTransform) {
- JPH_Skeleton* skeleton = JPH_Skeleton_Create();
- JPH_Skeleton_AddJoint(skeleton, "root");
- JPH_RagdollSettings* settings = JPH_RagdollSettings_Create();
- JPH_RagdollSettings_SetSkeleton(settings, skeleton);
- JPH_RagdollSettings_ResizeParts(settings, 1);
- JPH_SphereShape* shape = JPH_SphereShape_Create(0.5f);
- JPH_RVec3 position = {1.0f, 2.0f, 3.0f};
- JPH_Quat rotation = {0.0f, 0.0f, 0.0f, 1.0f};
- JPH_RagdollSettings_SetPartShape(settings, 0, (JPH_Shape*)shape);
- JPH_RagdollSettings_SetPartPosition(settings, 0, &position);
- JPH_RagdollSettings_SetPartRotation(settings, 0, &rotation);
- JPH_RagdollSettings_SetPartMotionType(settings, 0, JPH_MotionType_Dynamic);
- JPH_RagdollSettings_SetPartObjectLayer(settings, 0, ObjectLayers::MOVING);
- JPH_Ragdoll* ragdoll = JPH_RagdollSettings_CreateRagdoll(settings, physicsSystem, 0, 0);
- JPH_Ragdoll_AddToPhysicsSystem(ragdoll, JPH_Activation_Activate, true);
- JPH_RVec3 outPosition;
- JPH_Quat outRotation;
- JPH_Ragdoll_GetRootTransform(ragdoll, &outPosition, &outRotation, true);
- EXPECT_FLOAT_EQ(outPosition.x, 1.0f);
- EXPECT_FLOAT_EQ(outPosition.y, 2.0f);
- EXPECT_FLOAT_EQ(outPosition.z, 3.0f);
- JPH_Ragdoll_RemoveFromPhysicsSystem(ragdoll, true);
- JPH_Ragdoll_Destroy(ragdoll);
- JPH_RagdollSettings_Destroy(settings);
- JPH_Shape_Destroy((JPH_Shape*)shape);
- JPH_Skeleton_Destroy(skeleton);
- }
- // ============================================================================
- // SkeletonMapper Tests
- // ============================================================================
- TEST_F(SkeletonTest, SkeletonMapper_Create) {
- JPH_SkeletonMapper* mapper = JPH_SkeletonMapper_Create();
- ASSERT_NE(mapper, nullptr);
- JPH_SkeletonMapper_Destroy(mapper);
- }
|