new stuff
This commit is contained in:
parent
8998bc3936
commit
64c8492e5c
6907 changed files with 3401899 additions and 0 deletions
57
assimp/test/unit/ImportExport/MDL/MDLHL1TestFiles.h
Normal file
57
assimp/test/unit/ImportExport/MDL/MDLHL1TestFiles.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file MDLHL1TestFiles.h
|
||||
* @brief Definitions for Half-Life 1 MDL loader tests.
|
||||
*/
|
||||
|
||||
#ifndef AI_MDLHL1TESTFILES_INCLUDED
|
||||
#define AI_MDLHL1TESTFILES_INCLUDED
|
||||
|
||||
#ifndef ASSIMP_TEST_MDL_HL1_MODELS_DIR
|
||||
#define ASSIMP_TEST_MDL_HL1_MODELS_DIR ASSIMP_TEST_MODELS_DIR"/MDL/MDL (HL1)/"
|
||||
#endif
|
||||
|
||||
#ifndef MDL_HL1_FILE_MAN
|
||||
#define MDL_HL1_FILE_MAN ASSIMP_TEST_MDL_HL1_MODELS_DIR "man.mdl"
|
||||
#endif
|
||||
|
||||
#endif // AI_MDLHL1TESTFILES_INCLUDED
|
||||
|
|
@ -0,0 +1,228 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file utMDLImporter_HL1_ImportSettings.cpp
|
||||
* @brief Half-Life 1 MDL loader import settings tests.
|
||||
*/
|
||||
|
||||
#include "AbstractImportExportBase.h"
|
||||
#include "AssetLib/MDL/HalfLife/HL1ImportDefinitions.h"
|
||||
#include "MDLHL1TestFiles.h"
|
||||
#include "UnitTestPCH.h"
|
||||
#include <assimp/postprocess.h>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
class utMDLImporter_HL1_ImportSettings : public ::testing::Test {
|
||||
|
||||
public:
|
||||
// Test various import settings scenarios.
|
||||
|
||||
void importSettings() {
|
||||
|
||||
/* Verify that animations are *NOT* imported when
|
||||
'Read animations' is disabled. */
|
||||
load_with_import_setting_bool(
|
||||
MDL_HL1_FILE_MAN,
|
||||
AI_CONFIG_IMPORT_MDL_HL1_READ_ANIMATIONS,
|
||||
false, // Set config value to false.
|
||||
[&](const aiScene *scene) {
|
||||
EXPECT_EQ(0u, scene->mNumAnimations);
|
||||
EXPECT_EQ(nullptr, scene->mRootNode->FindNode(AI_MDL_HL1_NODE_SEQUENCE_INFOS));
|
||||
EXPECT_EQ(nullptr, scene->mRootNode->FindNode(AI_MDL_HL1_NODE_SEQUENCE_GROUPS));
|
||||
EXPECT_EQ(nullptr, scene->mRootNode->FindNode(AI_MDL_HL1_NODE_SEQUENCE_TRANSITION_GRAPH));
|
||||
|
||||
expect_global_info_eq<int>(scene, { { 0, "NumSequences" },
|
||||
{ 0, "NumTransitionNodes" } });
|
||||
});
|
||||
|
||||
/* Verify that blend controllers info is *NOT* imported when
|
||||
'Read blend controllers' is disabled. */
|
||||
load_with_import_setting_bool(
|
||||
MDL_HL1_FILE_MAN,
|
||||
AI_CONFIG_IMPORT_MDL_HL1_READ_BLEND_CONTROLLERS,
|
||||
false, // Set config value to false.
|
||||
[&](const aiScene *scene) {
|
||||
EXPECT_NE(0u, scene->mNumAnimations);
|
||||
|
||||
const aiNode *sequence_infos = scene->mRootNode->FindNode(AI_MDL_HL1_NODE_SEQUENCE_INFOS);
|
||||
EXPECT_NE(nullptr, sequence_infos);
|
||||
|
||||
for (unsigned int i = 0; i < sequence_infos->mNumChildren; ++i)
|
||||
EXPECT_EQ(nullptr, sequence_infos->mChildren[i]->FindNode(AI_MDL_HL1_NODE_BLEND_CONTROLLERS));
|
||||
|
||||
expect_global_info_eq(scene, 0, "NumBlendControllers");
|
||||
});
|
||||
|
||||
/* Verify that animation events are *NOT* imported when
|
||||
'Read animation events' is disabled. */
|
||||
load_with_import_setting_bool(
|
||||
MDL_HL1_FILE_MAN,
|
||||
AI_CONFIG_IMPORT_MDL_HL1_READ_ANIMATION_EVENTS,
|
||||
false, // Set config value to false.
|
||||
[&](const aiScene *scene) {
|
||||
EXPECT_NE(0u, scene->mNumAnimations);
|
||||
|
||||
const aiNode *sequence_infos = scene->mRootNode->FindNode(AI_MDL_HL1_NODE_SEQUENCE_INFOS);
|
||||
EXPECT_NE(nullptr, sequence_infos);
|
||||
|
||||
for (unsigned int i = 0; i < sequence_infos->mNumChildren; ++i)
|
||||
EXPECT_EQ(nullptr, sequence_infos->mChildren[i]->FindNode(AI_MDL_HL1_NODE_ANIMATION_EVENTS));
|
||||
});
|
||||
|
||||
/* Verify that sequence transitions info is read when
|
||||
'Read sequence transitions' is enabled. */
|
||||
load_with_import_setting_bool(
|
||||
ASSIMP_TEST_MDL_HL1_MODELS_DIR "sequence_transitions.mdl",
|
||||
AI_CONFIG_IMPORT_MDL_HL1_READ_SEQUENCE_TRANSITIONS,
|
||||
true, // Set config value to true.
|
||||
[&](const aiScene *scene) {
|
||||
EXPECT_NE(nullptr, scene->mRootNode->FindNode(AI_MDL_HL1_NODE_SEQUENCE_TRANSITION_GRAPH));
|
||||
expect_global_info_eq(scene, 4, "NumTransitionNodes");
|
||||
});
|
||||
|
||||
/* Verify that sequence transitions info is *NOT* read when
|
||||
'Read sequence transitions' is disabled. */
|
||||
load_with_import_setting_bool(
|
||||
ASSIMP_TEST_MDL_HL1_MODELS_DIR "sequence_transitions.mdl",
|
||||
AI_CONFIG_IMPORT_MDL_HL1_READ_SEQUENCE_TRANSITIONS,
|
||||
false, // Set config value to false.
|
||||
[&](const aiScene *scene) {
|
||||
EXPECT_EQ(nullptr, scene->mRootNode->FindNode(AI_MDL_HL1_NODE_SEQUENCE_TRANSITION_GRAPH));
|
||||
expect_global_info_eq(scene, 0, "NumTransitionNodes");
|
||||
});
|
||||
|
||||
/* Verify that bone controllers info is *NOT* read when
|
||||
'Read bone controllers' is disabled. */
|
||||
load_with_import_setting_bool(
|
||||
MDL_HL1_FILE_MAN,
|
||||
AI_CONFIG_IMPORT_MDL_HL1_READ_BONE_CONTROLLERS,
|
||||
false, // Set config value to false.
|
||||
[&](const aiScene *scene) {
|
||||
EXPECT_EQ(nullptr, scene->mRootNode->FindNode(AI_MDL_HL1_NODE_BONE_CONTROLLERS));
|
||||
expect_global_info_eq(scene, 0, "NumBoneControllers");
|
||||
});
|
||||
|
||||
/* Verify that attachments info is *NOT* read when
|
||||
'Read attachments' is disabled. */
|
||||
load_with_import_setting_bool(
|
||||
MDL_HL1_FILE_MAN,
|
||||
AI_CONFIG_IMPORT_MDL_HL1_READ_ATTACHMENTS,
|
||||
false, // Set config value to false.
|
||||
[&](const aiScene *scene) {
|
||||
EXPECT_EQ(nullptr, scene->mRootNode->FindNode(AI_MDL_HL1_NODE_ATTACHMENTS));
|
||||
expect_global_info_eq(scene, 0, "NumAttachments");
|
||||
});
|
||||
|
||||
/* Verify that hitboxes info is *NOT* read when
|
||||
'Read hitboxes' is disabled. */
|
||||
load_with_import_setting_bool(
|
||||
MDL_HL1_FILE_MAN,
|
||||
AI_CONFIG_IMPORT_MDL_HL1_READ_HITBOXES,
|
||||
false, // Set config value to false.
|
||||
[&](const aiScene *scene) {
|
||||
EXPECT_EQ(nullptr, scene->mRootNode->FindNode(AI_MDL_HL1_NODE_HITBOXES));
|
||||
expect_global_info_eq(scene, 0, "NumHitboxes");
|
||||
});
|
||||
|
||||
/* Verify that misc global info is *NOT* read when
|
||||
'Read misc global info' is disabled. */
|
||||
load_with_import_setting_bool(
|
||||
MDL_HL1_FILE_MAN,
|
||||
AI_CONFIG_IMPORT_MDL_HL1_READ_MISC_GLOBAL_INFO,
|
||||
false, // Set config value to false.
|
||||
[&](const aiScene *scene) {
|
||||
aiNode *global_info = get_global_info(scene);
|
||||
EXPECT_NE(nullptr, global_info);
|
||||
aiVector3D temp;
|
||||
EXPECT_FALSE(global_info->mMetaData->Get("EyePosition", temp));
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
void load_with_import_setting_bool(
|
||||
const char *file_path,
|
||||
const char *setting_key,
|
||||
bool setting_value,
|
||||
std::function<void(const aiScene *)> &&func) {
|
||||
Assimp::Importer importer;
|
||||
importer.SetPropertyBool(setting_key, setting_value);
|
||||
const aiScene *scene = importer.ReadFile(file_path, aiProcess_ValidateDataStructure);
|
||||
ASSERT_NE(nullptr, scene);
|
||||
func(scene);
|
||||
}
|
||||
|
||||
inline static aiNode *get_global_info(const aiScene *scene) {
|
||||
return scene->mRootNode->FindNode(AI_MDL_HL1_NODE_GLOBAL_INFO);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void expect_global_info_eq(
|
||||
const aiScene *scene,
|
||||
T expected_value,
|
||||
const char *key_name) {
|
||||
aiNode *global_info = get_global_info(scene);
|
||||
EXPECT_NE(nullptr, global_info);
|
||||
T temp = 0;
|
||||
EXPECT_TRUE(global_info->mMetaData->Get(key_name, temp));
|
||||
EXPECT_EQ(expected_value, temp);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void expect_global_info_eq(const aiScene *scene,
|
||||
std::initializer_list<std::pair<T, const char *>> p_kv) {
|
||||
aiNode *global_info = get_global_info(scene);
|
||||
EXPECT_NE(nullptr, global_info);
|
||||
for (auto it = p_kv.begin(); it != p_kv.end(); ++it) {
|
||||
T temp = 0;
|
||||
EXPECT_TRUE(global_info->mMetaData->Get(it->second, temp));
|
||||
EXPECT_EQ(it->first, temp);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(utMDLImporter_HL1_ImportSettings, importSettings) {
|
||||
importSettings();
|
||||
}
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file utMDLImporter_HL1_Materials.cpp
|
||||
* @brief Half-Life 1 MDL loader materials tests.
|
||||
*/
|
||||
|
||||
#include "AbstractImportExportBase.h"
|
||||
#include "AssetLib/MDL/HalfLife/HL1ImportDefinitions.h"
|
||||
#include "MDLHL1TestFiles.h"
|
||||
#include "UnitTestPCH.h"
|
||||
#include <assimp/postprocess.h>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/Importer.hpp>
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
class utMDLImporter_HL1_Materials : public ::testing::Test {
|
||||
|
||||
public:
|
||||
/* Given an MDL model with a texture flagged as flatshade,
|
||||
verify that the imported model has a flat shading model. */
|
||||
void flatShadeTexture() {
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "chrome_sphere.mdl", aiProcess_ValidateDataStructure);
|
||||
ASSERT_NE(nullptr, scene);
|
||||
ASSERT_NE(nullptr, scene->mMaterials);
|
||||
|
||||
aiShadingMode shading_mode = aiShadingMode_Flat;
|
||||
scene->mMaterials[0]->Get(AI_MATKEY_SHADING_MODEL, shading_mode);
|
||||
EXPECT_EQ(aiShadingMode_Flat, shading_mode);
|
||||
}
|
||||
|
||||
/* Given an MDL model with a chrome texture, verify that
|
||||
the imported model has a chrome material. */
|
||||
void chromeTexture() {
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "chrome_sphere.mdl", aiProcess_ValidateDataStructure);
|
||||
ASSERT_NE(nullptr, scene);
|
||||
ASSERT_NE(nullptr, scene->mMaterials);
|
||||
|
||||
int chrome;
|
||||
scene->mMaterials[0]->Get(AI_MDL_HL1_MATKEY_CHROME(aiTextureType_DIFFUSE, 0), chrome);
|
||||
EXPECT_EQ(1, chrome);
|
||||
}
|
||||
|
||||
/* Given an MDL model with an additive texture, verify that
|
||||
the imported model has an additive material. */
|
||||
void additiveBlendTexture() {
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "blend_additive.mdl", aiProcess_ValidateDataStructure);
|
||||
ASSERT_NE(nullptr, scene);
|
||||
ASSERT_NE(nullptr, scene->mMaterials);
|
||||
|
||||
aiBlendMode blend_mode = aiBlendMode_Default;
|
||||
scene->mMaterials[0]->Get(AI_MATKEY_BLEND_FUNC, blend_mode);
|
||||
EXPECT_EQ(aiBlendMode_Additive, blend_mode);
|
||||
}
|
||||
|
||||
/* Given an MDL model with a color masked texture, verify that
|
||||
the imported model has a color masked material. Ensure too
|
||||
that the transparency color is the correct one. */
|
||||
void textureWithColorMask() {
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "alpha_test.mdl", aiProcess_ValidateDataStructure);
|
||||
ASSERT_NE(nullptr, scene);
|
||||
ASSERT_NE(nullptr, scene->mMaterials);
|
||||
|
||||
int texture_flags = 0;
|
||||
scene->mMaterials[0]->Get(AI_MATKEY_TEXFLAGS_DIFFUSE(0), texture_flags);
|
||||
EXPECT_EQ(aiTextureFlags_UseAlpha, texture_flags);
|
||||
|
||||
// The model has only one texture, a 256 color bitmap with
|
||||
// a palette. Pure blue is the last color in the palette,
|
||||
// and should be the transparency color.
|
||||
aiColor3D transparency_color = {};
|
||||
scene->mMaterials[0]->Get(AI_MATKEY_COLOR_TRANSPARENT, transparency_color);
|
||||
EXPECT_EQ(aiColor3D(0, 0, 255), transparency_color);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(utMDLImporter_HL1_Materials, flatShadeTexture) {
|
||||
flatShadeTexture();
|
||||
}
|
||||
|
||||
TEST_F(utMDLImporter_HL1_Materials, chromeTexture) {
|
||||
chromeTexture();
|
||||
}
|
||||
|
||||
TEST_F(utMDLImporter_HL1_Materials, additiveBlendTexture) {
|
||||
additiveBlendTexture();
|
||||
}
|
||||
|
||||
TEST_F(utMDLImporter_HL1_Materials, textureWithColorMask) {
|
||||
textureWithColorMask();
|
||||
}
|
||||
563
assimp/test/unit/ImportExport/MDL/utMDLImporter_HL1_Nodes.cpp
Normal file
563
assimp/test/unit/ImportExport/MDL/utMDLImporter_HL1_Nodes.cpp
Normal file
|
|
@ -0,0 +1,563 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file utMDLImporter_HL1_Nodes.cpp
|
||||
* @brief Half-Life 1 MDL loader nodes tests.
|
||||
*/
|
||||
|
||||
#include "AbstractImportExportBase.h"
|
||||
#include "AssetLib/MDL/HalfLife/HL1ImportDefinitions.h"
|
||||
#include "MDLHL1TestFiles.h"
|
||||
#include "UnitTestPCH.h"
|
||||
#include <assimp/postprocess.h>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/Importer.hpp>
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
class utMDLImporter_HL1_Nodes : public ::testing::Test {
|
||||
|
||||
/**
|
||||
* @note Represents a flattened node hierarchy where each item is a pair
|
||||
* containing the node level and it's name.
|
||||
*/
|
||||
using Hierarchy = std::vector<std::pair<unsigned int, std::string>>;
|
||||
|
||||
/**
|
||||
* @note A vector of strings. Used for symplifying syntax.
|
||||
*/
|
||||
using StringVector = std::vector<std::string>;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @note The following tests require a basic understanding
|
||||
* of the SMD format. For more information about SMD format,
|
||||
* please refer to the SMD importer or go to VDC
|
||||
* (Valve Developer Community).
|
||||
*/
|
||||
|
||||
// Given a model, verify that the bones nodes hierarchy is correctly formed.
|
||||
void checkBoneHierarchy() {
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "multiple_roots.mdl", aiProcess_ValidateDataStructure);
|
||||
ASSERT_NE(nullptr, scene);
|
||||
ASSERT_NE(nullptr, scene->mRootNode);
|
||||
|
||||
// First, check that "<MDL_root>" and "<MDL_bones>" are linked.
|
||||
const aiNode* node_MDL_root = scene->mRootNode->FindNode(AI_MDL_HL1_NODE_ROOT);
|
||||
ASSERT_NE(nullptr, node_MDL_root);
|
||||
|
||||
const aiNode *node_MDL_bones = scene->mRootNode->FindNode(AI_MDL_HL1_NODE_BONES);
|
||||
ASSERT_NE(nullptr, node_MDL_bones);
|
||||
ASSERT_NE(nullptr, node_MDL_bones->mParent);
|
||||
ASSERT_EQ(node_MDL_root, node_MDL_bones->mParent);
|
||||
|
||||
// Second, verify "<MDL_bones>" hierarchy.
|
||||
const Hierarchy expected_hierarchy = {
|
||||
{ 0, AI_MDL_HL1_NODE_BONES },
|
||||
{ 1, "root1_bone1" },
|
||||
{ 2, "root1_bone2" },
|
||||
{ 3, "root1_bone4" },
|
||||
{ 3, "root1_bone5" },
|
||||
{ 2, "root1_bone3" },
|
||||
{ 3, "root1_bone6" },
|
||||
{ 1, "root2_bone1" },
|
||||
{ 2, "root2_bone2" },
|
||||
{ 2, "root2_bone3" },
|
||||
{ 3, "root2_bone5" },
|
||||
{ 2, "root2_bone4" },
|
||||
{ 3, "root2_bone6" },
|
||||
{ 1, "root3_bone1" },
|
||||
{ 2, "root3_bone2" },
|
||||
{ 2, "root3_bone3" },
|
||||
{ 2, "root3_bone4" },
|
||||
{ 3, "root3_bone5" },
|
||||
{ 4, "root3_bone6" },
|
||||
{ 4, "root3_bone7" },
|
||||
};
|
||||
|
||||
Hierarchy actual_hierarchy;
|
||||
flatten_hierarchy(node_MDL_bones, actual_hierarchy);
|
||||
ASSERT_EQ(expected_hierarchy, actual_hierarchy);
|
||||
}
|
||||
|
||||
/* Given a model with bones that have empty names,
|
||||
verify that all the bones of the imported model
|
||||
have unique and no empty names.
|
||||
|
||||
"" <----+---- empty names
|
||||
"" <----+
|
||||
"" <----+
|
||||
"Bone_3" |
|
||||
"" <----+
|
||||
"Bone_2" |
|
||||
"Bone_5" |
|
||||
"" <----+
|
||||
"" <----+
|
||||
*/
|
||||
void emptyBonesNames() {
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "unnamed_bones.mdl", aiProcess_ValidateDataStructure);
|
||||
ASSERT_NE(nullptr, scene);
|
||||
|
||||
const StringVector expected_bones_names = {
|
||||
"Bone",
|
||||
"Bone_0",
|
||||
"Bone_1",
|
||||
"Bone_3",
|
||||
"Bone_4",
|
||||
"Bone_2",
|
||||
"Bone_5",
|
||||
"Bone_6",
|
||||
"Bone_7"
|
||||
};
|
||||
|
||||
StringVector actual_bones_names;
|
||||
get_node_children_names(scene->mRootNode->FindNode(AI_MDL_HL1_NODE_BONES), actual_bones_names);
|
||||
ASSERT_EQ(expected_bones_names, actual_bones_names);
|
||||
}
|
||||
|
||||
/* Given a model with bodyparts that have empty names,
|
||||
verify that the imported model contains bodyparts with
|
||||
unique and no empty names.
|
||||
|
||||
$body "" <----+---- empty names
|
||||
$body "Bodypart_1" |
|
||||
$body "Bodypart_5" |
|
||||
$body "Bodypart_6" |
|
||||
$body "" <----+
|
||||
$body "Bodypart_2" |
|
||||
$body "" <----+
|
||||
$body "Bodypart_3" |
|
||||
$body "" <----+
|
||||
*/
|
||||
void emptyBodypartsNames() {
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "unnamed_bodyparts.mdl", aiProcess_ValidateDataStructure);
|
||||
ASSERT_NE(nullptr, scene);
|
||||
|
||||
const StringVector expected_bodyparts_names = {
|
||||
"Bodypart",
|
||||
"Bodypart_1",
|
||||
"Bodypart_5",
|
||||
"Bodypart_6",
|
||||
"Bodypart_0",
|
||||
"Bodypart_2",
|
||||
"Bodypart_4",
|
||||
"Bodypart_3",
|
||||
"Bodypart_7"
|
||||
};
|
||||
|
||||
StringVector actual_bodyparts_names;
|
||||
// Get the bodyparts names "without" the submodels.
|
||||
get_node_children_names(scene->mRootNode->FindNode(AI_MDL_HL1_NODE_BODYPARTS), actual_bodyparts_names, 0);
|
||||
ASSERT_EQ(expected_bodyparts_names, actual_bodyparts_names);
|
||||
}
|
||||
|
||||
/* Given a model with bodyparts that have duplicate names,
|
||||
verify that the imported model contains bodyparts with
|
||||
unique and no duplicate names.
|
||||
|
||||
$body "Bodypart" <-----+
|
||||
$body "Bodypart_1" <--+ |
|
||||
$body "Bodypart_2" | |
|
||||
$body "Bodypart1" | |
|
||||
$body "Bodypart" ---|--+
|
||||
$body "Bodypart_1" ---+ |
|
||||
$body "Bodypart2" |
|
||||
$body "Bodypart" ------+
|
||||
$body "Bodypart_4"
|
||||
*/
|
||||
void duplicateBodypartsNames() {
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "duplicate_bodyparts.mdl", aiProcess_ValidateDataStructure);
|
||||
ASSERT_NE(nullptr, scene);
|
||||
|
||||
const StringVector expected_bodyparts_names = {
|
||||
"Bodypart",
|
||||
"Bodypart_1",
|
||||
"Bodypart_2",
|
||||
"Bodypart1",
|
||||
"Bodypart_0",
|
||||
"Bodypart_1_0",
|
||||
"Bodypart2",
|
||||
"Bodypart_3",
|
||||
"Bodypart_4"
|
||||
};
|
||||
|
||||
StringVector actual_bodyparts_names;
|
||||
// Get the bodyparts names "without" the submodels.
|
||||
get_node_children_names(scene->mRootNode->FindNode(AI_MDL_HL1_NODE_BODYPARTS), actual_bodyparts_names, 0);
|
||||
ASSERT_EQ(expected_bodyparts_names, actual_bodyparts_names);
|
||||
}
|
||||
|
||||
/* Given a model with several bodyparts that contains multiple
|
||||
sub models with the same file name, verify for each bodypart
|
||||
sub model of the imported model that they have a unique name.
|
||||
|
||||
$bodygroup "first_bodypart"
|
||||
{
|
||||
studio "triangle" <------+ duplicate file names.
|
||||
studio "triangle" -------+
|
||||
} |
|
||||
|
|
||||
$bodygroup "second_bodypart" |
|
||||
{ |
|
||||
studio "triangle" -------+ same as first bodypart, but with same file.
|
||||
studio "triangle" -------+
|
||||
}
|
||||
|
||||
$bodygroup "last_bodypart"
|
||||
{
|
||||
studio "triangle2" <------+ duplicate names.
|
||||
studio "triangle2" -------+
|
||||
}
|
||||
*/
|
||||
void duplicateSubModelsNames() {
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "duplicate_submodels.mdl", aiProcess_ValidateDataStructure);
|
||||
ASSERT_NE(nullptr, scene);
|
||||
|
||||
const std::vector<StringVector> expected_bodypart_sub_models_names = {
|
||||
{
|
||||
"triangle",
|
||||
"triangle_0",
|
||||
},
|
||||
{
|
||||
"triangle_1",
|
||||
"triangle_2",
|
||||
},
|
||||
{
|
||||
"triangle2",
|
||||
"triangle2_0",
|
||||
}
|
||||
};
|
||||
|
||||
const aiNode *bodyparts_node = scene->mRootNode->FindNode(AI_MDL_HL1_NODE_BODYPARTS);
|
||||
ASSERT_NE(nullptr, bodyparts_node);
|
||||
EXPECT_EQ(3u, bodyparts_node->mNumChildren);
|
||||
|
||||
StringVector actual_submodels_names;
|
||||
for (unsigned int i = 0; i < bodyparts_node->mNumChildren; ++i)
|
||||
{
|
||||
actual_submodels_names.clear();
|
||||
get_node_children_names(bodyparts_node->mChildren[i], actual_submodels_names);
|
||||
ASSERT_EQ(expected_bodypart_sub_models_names[i], actual_submodels_names);
|
||||
}
|
||||
}
|
||||
|
||||
/* Given a model with sequences that have duplicate names, verify
|
||||
that each sequence from the imported model has a unique
|
||||
name.
|
||||
|
||||
$sequence "idle_1" <-------+
|
||||
$sequence "idle" <----+ |
|
||||
$sequence "idle_2" | |
|
||||
$sequence "idle" -----+ |
|
||||
$sequence "idle_0" | |
|
||||
$sequence "idle_1" -----|--+
|
||||
$sequence "idle_3" |
|
||||
$sequence "idle" -----+
|
||||
$sequence "idle_7"
|
||||
*/
|
||||
void duplicateSequenceNames() {
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "duplicate_sequences.mdl", aiProcess_ValidateDataStructure);
|
||||
ASSERT_NE(nullptr, scene);
|
||||
|
||||
const StringVector expected_sequence_names = {
|
||||
"idle_1",
|
||||
"idle",
|
||||
"idle_2",
|
||||
"idle_4",
|
||||
"idle_0",
|
||||
"idle_1_0",
|
||||
"idle_3",
|
||||
"idle_5",
|
||||
"idle_7"
|
||||
};
|
||||
|
||||
StringVector actual_sequence_names;
|
||||
get_node_children_names(scene->mRootNode->FindNode(AI_MDL_HL1_NODE_SEQUENCE_INFOS), actual_sequence_names);
|
||||
ASSERT_EQ(expected_sequence_names, actual_sequence_names);
|
||||
}
|
||||
|
||||
/* Given a model with sequences that have empty names, verify
|
||||
that each sequence from the imported model has a unique
|
||||
name.
|
||||
|
||||
$sequence "" <----+---- empty names
|
||||
$sequence "Sequence_1" |
|
||||
$sequence "" <----+
|
||||
$sequence "Sequence_4" |
|
||||
$sequence "" <----+
|
||||
$sequence "Sequence_8" |
|
||||
$sequence "" <----+
|
||||
$sequence "Sequence_2" |
|
||||
$sequence "" <----+
|
||||
*/
|
||||
void emptySequenceNames() {
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "unnamed_sequences.mdl", aiProcess_ValidateDataStructure);
|
||||
ASSERT_NE(nullptr, scene);
|
||||
|
||||
const StringVector expected_sequence_names = {
|
||||
"Sequence",
|
||||
"Sequence_1",
|
||||
"Sequence_0",
|
||||
"Sequence_4",
|
||||
"Sequence_3",
|
||||
"Sequence_8",
|
||||
"Sequence_5",
|
||||
"Sequence_2",
|
||||
"Sequence_6"
|
||||
};
|
||||
|
||||
StringVector actual_sequence_names;
|
||||
get_node_children_names(scene->mRootNode->FindNode(AI_MDL_HL1_NODE_SEQUENCE_INFOS), actual_sequence_names);
|
||||
ASSERT_EQ(expected_sequence_names, actual_sequence_names);
|
||||
}
|
||||
|
||||
/* Given a model with sequence groups that have duplicate names,
|
||||
verify that each sequence group from the imported model has
|
||||
a unique name.
|
||||
|
||||
"default"
|
||||
$sequencegroup "SequenceGroup" <----+
|
||||
$sequencegroup "SequenceGroup_1" |
|
||||
$sequencegroup "SequenceGroup_5" <----|--+
|
||||
$sequencegroup "SequenceGroup" -----+ |
|
||||
$sequencegroup "SequenceGroup_0" | |
|
||||
$sequencegroup "SequenceGroup" -----+ |
|
||||
$sequencegroup "SequenceGroup_5" --------+
|
||||
$sequencegroup "SequenceGroup_6"
|
||||
$sequencegroup "SequenceGroup_2"
|
||||
*/
|
||||
void duplicateSequenceGroupNames() {
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "duplicate_sequence_groups/duplicate_sequence_groups.mdl", aiProcess_ValidateDataStructure);
|
||||
ASSERT_NE(nullptr, scene);
|
||||
|
||||
const StringVector expected_sequence_names = {
|
||||
"default",
|
||||
"SequenceGroup",
|
||||
"SequenceGroup_1",
|
||||
"SequenceGroup_5",
|
||||
"SequenceGroup_3",
|
||||
"SequenceGroup_0",
|
||||
"SequenceGroup_4",
|
||||
"SequenceGroup_5_0",
|
||||
"SequenceGroup_6",
|
||||
"SequenceGroup_2"
|
||||
};
|
||||
|
||||
StringVector actual_sequence_names;
|
||||
get_node_children_names(scene->mRootNode->FindNode(AI_MDL_HL1_NODE_SEQUENCE_GROUPS), actual_sequence_names);
|
||||
ASSERT_EQ(expected_sequence_names, actual_sequence_names);
|
||||
}
|
||||
|
||||
/* Given a model with sequence groups that have empty names,
|
||||
verify that each sequence group from the imported model has
|
||||
a unique name.
|
||||
|
||||
"default"
|
||||
$sequencegroup "" <----+---- empty names
|
||||
$sequencegroup "SequenceGroup_2" |
|
||||
$sequencegroup "SequenceGroup_6" |
|
||||
$sequencegroup "" <----+
|
||||
$sequencegroup "" <----+
|
||||
$sequencegroup "SequenceGroup_1" |
|
||||
$sequencegroup "SequenceGroup_5" |
|
||||
$sequencegroup "" <----+
|
||||
$sequencegroup "SequenceGroup_4"
|
||||
*/
|
||||
void emptySequenceGroupNames() {
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "unnamed_sequence_groups/unnamed_sequence_groups.mdl", aiProcess_ValidateDataStructure);
|
||||
ASSERT_NE(nullptr, scene);
|
||||
|
||||
const StringVector expected_sequence_names = {
|
||||
"default",
|
||||
"SequenceGroup",
|
||||
"SequenceGroup_2",
|
||||
"SequenceGroup_6",
|
||||
"SequenceGroup_0",
|
||||
"SequenceGroup_3",
|
||||
"SequenceGroup_1",
|
||||
"SequenceGroup_5",
|
||||
"SequenceGroup_7",
|
||||
"SequenceGroup_4"
|
||||
};
|
||||
|
||||
StringVector actual_sequence_names;
|
||||
get_node_children_names(scene->mRootNode->FindNode(AI_MDL_HL1_NODE_SEQUENCE_GROUPS), actual_sequence_names);
|
||||
ASSERT_EQ(expected_sequence_names, actual_sequence_names);
|
||||
}
|
||||
|
||||
/* Verify that mOffsetMatrix applies the correct
|
||||
inverse bind pose transform. */
|
||||
void offsetMatrixUnappliesTransformations() {
|
||||
|
||||
const float TOLERANCE = 0.01f;
|
||||
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(MDL_HL1_FILE_MAN, aiProcess_ValidateDataStructure);
|
||||
ASSERT_NE(nullptr, scene);
|
||||
|
||||
aiNode *scene_bones_node = scene->mRootNode->FindNode(AI_MDL_HL1_NODE_BONES);
|
||||
|
||||
const aiMatrix4x4 identity_matrix;
|
||||
|
||||
for (unsigned int i = 0; i < scene->mNumMeshes; ++i) {
|
||||
aiMesh *scene_mesh = scene->mMeshes[i];
|
||||
for (unsigned int j = 0; j < scene_mesh->mNumBones; ++j) {
|
||||
aiBone *scene_mesh_bone = scene_mesh->mBones[j];
|
||||
|
||||
// Store local node transforms.
|
||||
aiNode *n = scene_bones_node->FindNode(scene_mesh_bone->mName);
|
||||
std::vector<aiMatrix4x4> bone_matrices = { n->mTransformation };
|
||||
while (n->mParent != scene->mRootNode) {
|
||||
n = n->mParent;
|
||||
bone_matrices.push_back(n->mTransformation);
|
||||
}
|
||||
|
||||
// Compute absolute node transform.
|
||||
aiMatrix4x4 transform;
|
||||
for (auto it = bone_matrices.rbegin(); it != bone_matrices.rend(); ++it)
|
||||
transform *= *it;
|
||||
|
||||
// Unapply the transformation using the offset matrix.
|
||||
aiMatrix4x4 unapplied_transform = scene_mesh_bone->mOffsetMatrix * transform;
|
||||
|
||||
// Ensure that we have, approximately, the identity matrix.
|
||||
expect_equal_matrices(identity_matrix, unapplied_transform, TOLERANCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void expect_equal_matrices(const aiMatrix4x4 &expected, const aiMatrix4x4 &actual, float abs_error) {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int j = 0; j < 4; ++j)
|
||||
EXPECT_NEAR(expected[i][j], actual[i][j], abs_error);
|
||||
}
|
||||
}
|
||||
|
||||
/** Get a flattened representation of a node's hierarchy.
|
||||
* \param[in] node The node.
|
||||
* \param[out] hierarchy The flattened node's hierarchy.
|
||||
*/
|
||||
void flatten_hierarchy(const aiNode *node, Hierarchy &hierarchy)
|
||||
{
|
||||
flatten_hierarchy_impl(node, hierarchy, 0);
|
||||
}
|
||||
|
||||
void flatten_hierarchy_impl(const aiNode *node, Hierarchy &hierarchy, unsigned int level)
|
||||
{
|
||||
hierarchy.push_back({ level, node->mName.C_Str() });
|
||||
for (size_t i = 0; i < node->mNumChildren; ++i)
|
||||
{
|
||||
flatten_hierarchy_impl(node->mChildren[i], hierarchy, level + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/** Get all node's children names beneath max_level.
|
||||
* \param[in] node The parent node from which to get all children names.
|
||||
* \param[out] names The list of children names.
|
||||
* \param[in] max_level If set to -1, all children names will be collected.
|
||||
*/
|
||||
void get_node_children_names(const aiNode *node, StringVector &names, const int max_level = -1)
|
||||
{
|
||||
get_node_children_names_impl(node, names, 0, max_level);
|
||||
}
|
||||
|
||||
void get_node_children_names_impl(const aiNode *node, StringVector &names, int level, const int max_level = -1)
|
||||
{
|
||||
for (size_t i = 0; i < node->mNumChildren; ++i)
|
||||
{
|
||||
names.push_back(node->mChildren[i]->mName.C_Str());
|
||||
if (max_level == -1 || level < max_level)
|
||||
{
|
||||
get_node_children_names_impl(node->mChildren[i], names, level + 1, max_level);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(utMDLImporter_HL1_Nodes, checkBoneHierarchy) {
|
||||
checkBoneHierarchy();
|
||||
}
|
||||
|
||||
TEST_F(utMDLImporter_HL1_Nodes, emptyBonesNames) {
|
||||
emptyBonesNames();
|
||||
}
|
||||
|
||||
TEST_F(utMDLImporter_HL1_Nodes, emptyBodypartsNames) {
|
||||
emptyBodypartsNames();
|
||||
}
|
||||
|
||||
TEST_F(utMDLImporter_HL1_Nodes, duplicateBodypartsNames) {
|
||||
duplicateBodypartsNames();
|
||||
}
|
||||
|
||||
TEST_F(utMDLImporter_HL1_Nodes, duplicateSubModelsNames) {
|
||||
duplicateSubModelsNames();
|
||||
}
|
||||
|
||||
TEST_F(utMDLImporter_HL1_Nodes, emptySequenceNames) {
|
||||
emptySequenceNames();
|
||||
}
|
||||
|
||||
TEST_F(utMDLImporter_HL1_Nodes, duplicateSequenceNames) {
|
||||
duplicateSequenceNames();
|
||||
}
|
||||
|
||||
TEST_F(utMDLImporter_HL1_Nodes, emptySequenceGroupNames) {
|
||||
emptySequenceGroupNames();
|
||||
}
|
||||
|
||||
TEST_F(utMDLImporter_HL1_Nodes, duplicateSequenceGroupNames) {
|
||||
duplicateSequenceGroupNames();
|
||||
}
|
||||
|
||||
TEST_F(utMDLImporter_HL1_Nodes, offsetMatrixUnappliesTransformations) {
|
||||
offsetMatrixUnappliesTransformations();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue