mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-17 10:21:11 +00:00
Merge pull request #1864 from elsid/nifbullet_tests
Add unit tests for BulletNifLoader
This commit is contained in:
commit
953e3a4eba
@ -24,8 +24,6 @@ addons:
|
|||||||
packages: [
|
packages: [
|
||||||
# Dev
|
# Dev
|
||||||
cmake, clang-3.6, libunshield-dev, libtinyxml-dev,
|
cmake, clang-3.6, libunshield-dev, libtinyxml-dev,
|
||||||
# Tests
|
|
||||||
libgtest-dev, google-mock,
|
|
||||||
# Boost
|
# Boost
|
||||||
libboost-filesystem-dev, libboost-program-options-dev, libboost-system-dev,
|
libboost-filesystem-dev, libboost-program-options-dev, libboost-system-dev,
|
||||||
# FFmpeg
|
# FFmpeg
|
||||||
|
@ -1,11 +1,3 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
sudo ln -s /usr/bin/clang-3.6 /usr/local/bin/clang
|
sudo ln -s /usr/bin/clang-3.6 /usr/local/bin/clang
|
||||||
sudo ln -s /usr/bin/clang++-3.6 /usr/local/bin/clang++
|
sudo ln -s /usr/bin/clang++-3.6 /usr/local/bin/clang++
|
||||||
|
|
||||||
# build libgtest & libgtest_main
|
|
||||||
sudo mkdir /usr/src/gtest/build
|
|
||||||
cd /usr/src/gtest/build
|
|
||||||
sudo cmake .. -DBUILD_SHARED_LIBS=1
|
|
||||||
sudo make -j4
|
|
||||||
sudo ln -s /usr/src/gtest/build/libgtest.so /usr/lib/libgtest.so
|
|
||||||
sudo ln -s /usr/src/gtest/build/libgtest_main.so /usr/lib/libgtest_main.so
|
|
||||||
|
@ -1,8 +1,21 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh -e
|
||||||
|
|
||||||
free -m
|
free -m
|
||||||
|
|
||||||
|
env GENERATOR='Unix Makefiles' CONFIGURATION=Release CI/build_googletest.sh
|
||||||
|
GOOGLETEST_DIR="$(pwd)/googletest/build"
|
||||||
|
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
export CODE_COVERAGE=1
|
export CODE_COVERAGE=1
|
||||||
if [ "${CC}" = "clang" ]; then export CODE_COVERAGE=0; fi
|
if [ "${CC}" = "clang" ]; then export CODE_COVERAGE=0; fi
|
||||||
${ANALYZE}cmake .. -DBUILD_WITH_CODE_COVERAGE=${CODE_COVERAGE} -DBUILD_UNITTESTS=1 -DCMAKE_INSTALL_PREFIX=/usr -DBINDIR=/usr/games -DCMAKE_BUILD_TYPE="None" -DUSE_SYSTEM_TINYXML=TRUE
|
${ANALYZE}cmake \
|
||||||
|
-DBUILD_WITH_CODE_COVERAGE=${CODE_COVERAGE} \
|
||||||
|
-DBUILD_UNITTESTS=1 \
|
||||||
|
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||||
|
-DBINDIR=/usr/games \
|
||||||
|
-DCMAKE_BUILD_TYPE="None" \
|
||||||
|
-DUSE_SYSTEM_TINYXML=TRUE \
|
||||||
|
-DGTEST_ROOT="${GOOGLETEST_DIR}" \
|
||||||
|
-DGMOCK_ROOT="${GOOGLETEST_DIR}" \
|
||||||
|
..
|
||||||
|
13
CI/build_googletest.sh
Executable file
13
CI/build_googletest.sh
Executable file
@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
git clone https://github.com/google/googletest.git
|
||||||
|
cd googletest
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake \
|
||||||
|
-D CMAKE_BUILD_TYPE="${CONFIGURATION}" \
|
||||||
|
-D CMAKE_INSTALL_PREFIX=. \
|
||||||
|
-G "${GENERATOR}" \
|
||||||
|
..
|
||||||
|
cmake --build . --config "${CONFIGURATION}"
|
||||||
|
cmake --build . --target install --config "${CONFIGURATION}"
|
@ -1,7 +1,9 @@
|
|||||||
find_package(GTest REQUIRED)
|
find_package(GTest REQUIRED)
|
||||||
|
find_package(GMock REQUIRED)
|
||||||
|
|
||||||
if (GTEST_FOUND)
|
if (GTEST_FOUND AND GMOCK_FOUND)
|
||||||
include_directories(SYSTEM ${GTEST_INCLUDE_DIRS})
|
include_directories(SYSTEM ${GTEST_INCLUDE_DIRS})
|
||||||
|
include_directories(SYSTEM ${GMOCK_INCLUDE_DIRS})
|
||||||
|
|
||||||
file(GLOB UNITTEST_SRC_FILES
|
file(GLOB UNITTEST_SRC_FILES
|
||||||
../openmw/mwworld/store.cpp
|
../openmw/mwworld/store.cpp
|
||||||
@ -13,17 +15,22 @@ if (GTEST_FOUND)
|
|||||||
esm/test_fixed_string.cpp
|
esm/test_fixed_string.cpp
|
||||||
|
|
||||||
misc/test_stringops.cpp
|
misc/test_stringops.cpp
|
||||||
|
|
||||||
|
nifloader/testbulletnifloader.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
source_group(apps\\openmw_test_suite FILES openmw_test_suite.cpp ${UNITTEST_SRC_FILES})
|
source_group(apps\\openmw_test_suite FILES openmw_test_suite.cpp ${UNITTEST_SRC_FILES})
|
||||||
|
|
||||||
openmw_add_executable(openmw_test_suite openmw_test_suite.cpp ${UNITTEST_SRC_FILES})
|
openmw_add_executable(openmw_test_suite openmw_test_suite.cpp ${UNITTEST_SRC_FILES})
|
||||||
|
|
||||||
target_link_libraries(openmw_test_suite ${GTEST_BOTH_LIBRARIES} components)
|
target_link_libraries(openmw_test_suite ${GMOCK_LIBRARIES} components)
|
||||||
# Fix for not visible pthreads functions for linker with glibc 2.15
|
# Fix for not visible pthreads functions for linker with glibc 2.15
|
||||||
if (UNIX AND NOT APPLE)
|
if (UNIX AND NOT APPLE)
|
||||||
target_link_libraries(openmw_test_suite ${CMAKE_THREAD_LIBS_INIT})
|
target_link_libraries(openmw_test_suite ${CMAKE_THREAD_LIBS_INIT})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (BUILD_WITH_CODE_COVERAGE)
|
||||||
|
add_definitions(--coverage)
|
||||||
|
target_link_libraries(openmw_test_suite gcov)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
951
apps/openmw_test_suite/nifloader/testbulletnifloader.cpp
Normal file
951
apps/openmw_test_suite/nifloader/testbulletnifloader.cpp
Normal file
@ -0,0 +1,951 @@
|
|||||||
|
#include <components/nifbullet/bulletnifloader.hpp>
|
||||||
|
#include <components/bullethelpers/processtrianglecallback.hpp>
|
||||||
|
#include <components/nif/node.hpp>
|
||||||
|
|
||||||
|
#include <BulletCollision/CollisionShapes/btBoxShape.h>
|
||||||
|
#include <BulletCollision/CollisionShapes/btCompoundShape.h>
|
||||||
|
#include <BulletCollision/CollisionShapes/btTriangleMesh.h>
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <gmock/gmock.h>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
bool compareObjects(const T* lhs, const T* rhs)
|
||||||
|
{
|
||||||
|
return (!lhs && !rhs) || (lhs && rhs && *lhs == *rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<btVector3> getTriangles(const btBvhTriangleMeshShape& shape)
|
||||||
|
{
|
||||||
|
std::vector<btVector3> result;
|
||||||
|
auto callback = BulletHelpers::makeProcessTriangleCallback([&] (btVector3* triangle, int, int) {
|
||||||
|
for (std::size_t i = 0; i < 3; ++i)
|
||||||
|
result.push_back(triangle[i]);
|
||||||
|
});
|
||||||
|
btVector3 aabbMin;
|
||||||
|
btVector3 aabbMax;
|
||||||
|
shape.getAabb(btTransform::getIdentity(), aabbMin, aabbMax);
|
||||||
|
shape.processAllTriangles(&callback, aabbMin, aabbMax);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::ostream& operator <<(std::ostream& stream, const btVector3& value)
|
||||||
|
{
|
||||||
|
return stream << "btVector3 {"
|
||||||
|
<< std::setprecision(std::numeric_limits<float>::max_exponent10) << value.getX() << ", "
|
||||||
|
<< std::setprecision(std::numeric_limits<float>::max_exponent10) << value.getY() << ", "
|
||||||
|
<< std::setprecision(std::numeric_limits<float>::max_exponent10) << value.getZ() << "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::ostream& operator <<(std::ostream& stream, const btMatrix3x3& value)
|
||||||
|
{
|
||||||
|
stream << "btMatrix3x3 {";
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
stream << value.getRow(i) << ", ";
|
||||||
|
return stream << "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::ostream& operator <<(std::ostream& stream, const btTransform& value)
|
||||||
|
{
|
||||||
|
return stream << "btTransform {" << value.getBasis() << ", " << value.getOrigin() << "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::ostream& operator <<(std::ostream& stream, const btCollisionShape* value);
|
||||||
|
|
||||||
|
static std::ostream& operator <<(std::ostream& stream, const btCompoundShape& value)
|
||||||
|
{
|
||||||
|
stream << "btCompoundShape {" << value.getLocalScaling() << ", ";
|
||||||
|
stream << "{";
|
||||||
|
for (int i = 0; i < value.getNumChildShapes(); ++i)
|
||||||
|
stream << value.getChildShape(i) << ", ";
|
||||||
|
stream << "},";
|
||||||
|
stream << "{";
|
||||||
|
for (int i = 0; i < value.getNumChildShapes(); ++i)
|
||||||
|
stream << value.getChildTransform(i) << ", ";
|
||||||
|
stream << "}";
|
||||||
|
return stream << "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::ostream& operator <<(std::ostream& stream, const btBoxShape& value)
|
||||||
|
{
|
||||||
|
return stream << "btBoxShape {" << value.getLocalScaling() << ", " << value.getHalfExtentsWithoutMargin() << "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Resource
|
||||||
|
{
|
||||||
|
|
||||||
|
static std::ostream& operator <<(std::ostream& stream, const TriangleMeshShape& value)
|
||||||
|
{
|
||||||
|
stream << "Resource::TriangleMeshShape {" << value.getLocalScaling() << ", "
|
||||||
|
<< value.usesQuantizedAabbCompression() << ", " << value.getOwnsBvh() << ", {";
|
||||||
|
auto callback = BulletHelpers::makeProcessTriangleCallback([&] (btVector3* triangle, int, int) {
|
||||||
|
for (std::size_t i = 0; i < 3; ++i)
|
||||||
|
stream << triangle[i] << ", ";
|
||||||
|
});
|
||||||
|
btVector3 aabbMin;
|
||||||
|
btVector3 aabbMax;
|
||||||
|
value.getAabb(btTransform::getIdentity(), aabbMin, aabbMax);
|
||||||
|
value.processAllTriangles(&callback, aabbMin, aabbMax);
|
||||||
|
return stream << "}}";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::ostream& operator <<(std::ostream& stream, const btCollisionShape& value)
|
||||||
|
{
|
||||||
|
switch (value.getShapeType())
|
||||||
|
{
|
||||||
|
case COMPOUND_SHAPE_PROXYTYPE:
|
||||||
|
return stream << static_cast<const btCompoundShape&>(value);
|
||||||
|
case BOX_SHAPE_PROXYTYPE:
|
||||||
|
return stream << static_cast<const btBoxShape&>(value);
|
||||||
|
case TRIANGLE_MESH_SHAPE_PROXYTYPE:
|
||||||
|
if (const auto casted = dynamic_cast<const Resource::TriangleMeshShape*>(&value))
|
||||||
|
return stream << *casted;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return stream << "btCollisionShape {" << value.getShapeType() << "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::ostream& operator <<(std::ostream& stream, const btCollisionShape* value)
|
||||||
|
{
|
||||||
|
return value ? stream << "&" << *value : stream << "nullptr";
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace osg
|
||||||
|
{
|
||||||
|
static std::ostream& operator <<(std::ostream& stream, const Vec3f& value)
|
||||||
|
{
|
||||||
|
return stream << "osg::Vec3f {"
|
||||||
|
<< value.x() << ", "
|
||||||
|
<< value.y() << ", "
|
||||||
|
<< value.z() << "}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
static std::ostream& operator <<(std::ostream& stream, const map<int, int>& value)
|
||||||
|
{
|
||||||
|
stream << "std::map<int, int> {";
|
||||||
|
for (const auto& v : value)
|
||||||
|
stream << "{" << v.first << ", " << v.second << "},";
|
||||||
|
return stream << "}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Resource
|
||||||
|
{
|
||||||
|
static bool operator ==(const Resource::BulletShape& lhs, const Resource::BulletShape& rhs)
|
||||||
|
{
|
||||||
|
return compareObjects(lhs.mCollisionShape, rhs.mCollisionShape)
|
||||||
|
&& lhs.mCollisionBoxHalfExtents == rhs.mCollisionBoxHalfExtents
|
||||||
|
&& lhs.mCollisionBoxTranslate == rhs.mCollisionBoxTranslate
|
||||||
|
&& lhs.mAnimatedShapes == rhs.mAnimatedShapes;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::ostream& operator <<(std::ostream& stream, const Resource::BulletShape& value)
|
||||||
|
{
|
||||||
|
return stream << "Resource::BulletShape {"
|
||||||
|
<< value.mCollisionShape << ", "
|
||||||
|
<< value.mCollisionBoxHalfExtents << ", "
|
||||||
|
<< value.mAnimatedShapes
|
||||||
|
<< "}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool operator ==(const btCollisionShape& lhs, const btCollisionShape& rhs);
|
||||||
|
|
||||||
|
static bool operator ==(const btCompoundShape& lhs, const btCompoundShape& rhs)
|
||||||
|
{
|
||||||
|
if (lhs.getNumChildShapes() != rhs.getNumChildShapes() || lhs.getLocalScaling() != rhs.getLocalScaling())
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < lhs.getNumChildShapes(); ++i)
|
||||||
|
{
|
||||||
|
if (!compareObjects(lhs.getChildShape(i), rhs.getChildShape(i))
|
||||||
|
|| !(lhs.getChildTransform(i) == rhs.getChildTransform(i)))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool operator ==(const btBoxShape& lhs, const btBoxShape& rhs)
|
||||||
|
{
|
||||||
|
return lhs.getLocalScaling() == rhs.getLocalScaling()
|
||||||
|
&& lhs.getHalfExtentsWithoutMargin() == rhs.getHalfExtentsWithoutMargin();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool operator ==(const btBvhTriangleMeshShape& lhs, const btBvhTriangleMeshShape& rhs)
|
||||||
|
{
|
||||||
|
return lhs.getLocalScaling() == rhs.getLocalScaling()
|
||||||
|
&& lhs.usesQuantizedAabbCompression() == rhs.usesQuantizedAabbCompression()
|
||||||
|
&& lhs.getOwnsBvh() == rhs.getOwnsBvh()
|
||||||
|
&& getTriangles(lhs) == getTriangles(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool operator ==(const btCollisionShape& lhs, const btCollisionShape& rhs)
|
||||||
|
{
|
||||||
|
if (lhs.getShapeType() != rhs.getShapeType())
|
||||||
|
return false;
|
||||||
|
switch (lhs.getShapeType())
|
||||||
|
{
|
||||||
|
case COMPOUND_SHAPE_PROXYTYPE:
|
||||||
|
return static_cast<const btCompoundShape&>(lhs) == static_cast<const btCompoundShape&>(rhs);
|
||||||
|
case BOX_SHAPE_PROXYTYPE:
|
||||||
|
return static_cast<const btBoxShape&>(lhs) == static_cast<const btBoxShape&>(rhs);
|
||||||
|
case TRIANGLE_MESH_SHAPE_PROXYTYPE:
|
||||||
|
if (const auto lhsCasted = dynamic_cast<const Resource::TriangleMeshShape*>(&lhs))
|
||||||
|
if (const auto rhsCasted = dynamic_cast<const Resource::TriangleMeshShape*>(&rhs))
|
||||||
|
return *lhsCasted == *rhsCasted;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
using namespace testing;
|
||||||
|
using NifBullet::BulletNifLoader;
|
||||||
|
|
||||||
|
void init(Nif::Transformation& value)
|
||||||
|
{
|
||||||
|
value = Nif::Transformation::getIdentity();
|
||||||
|
}
|
||||||
|
|
||||||
|
void init(Nif::Extra& value)
|
||||||
|
{
|
||||||
|
value.extra = Nif::ExtraPtr(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init(Nif::Controlled& value)
|
||||||
|
{
|
||||||
|
init(static_cast<Nif::Extra&>(value));
|
||||||
|
value.controller = Nif::ControllerPtr(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init(Nif::Named& value)
|
||||||
|
{
|
||||||
|
init(static_cast<Nif::Controlled&>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void init(Nif::Node& value)
|
||||||
|
{
|
||||||
|
init(static_cast<Nif::Named&>(value));
|
||||||
|
value.flags = 0;
|
||||||
|
init(value.trafo);
|
||||||
|
value.hasBounds = false;
|
||||||
|
value.parent = nullptr;
|
||||||
|
value.isBone = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init(Nif::NiTriShape& value)
|
||||||
|
{
|
||||||
|
init(static_cast<Nif::Node&>(value));
|
||||||
|
value.recType = Nif::RC_NiTriShape;
|
||||||
|
value.data = Nif::NiTriShapeDataPtr(nullptr);
|
||||||
|
value.skin = Nif::NiSkinInstancePtr(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init(Nif::NiSkinInstance& value)
|
||||||
|
{
|
||||||
|
value.data = Nif::NiSkinDataPtr(nullptr);
|
||||||
|
value.root = Nif::NodePtr(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init(Nif::Controller& value)
|
||||||
|
{
|
||||||
|
value.next = Nif::ControllerPtr(nullptr);
|
||||||
|
value.flags = 0;
|
||||||
|
value.frequency = 0;
|
||||||
|
value.phase = 0;
|
||||||
|
value.timeStart = 0;
|
||||||
|
value.timeStop = 0;
|
||||||
|
value.target = Nif::ControlledPtr(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy(const btTransform& src, Nif::Transformation& dst) {
|
||||||
|
dst.pos = osg::Vec3f(src.getOrigin().x(), src.getOrigin().y(), src.getOrigin().z());
|
||||||
|
for (int row = 0; row < 3; ++row)
|
||||||
|
for (int column = 0; column < 3; ++column)
|
||||||
|
dst.rotation.mValues[column][row] = src.getBasis().getRow(row)[column];
|
||||||
|
}
|
||||||
|
|
||||||
|
struct NifFileMock : Nif::File
|
||||||
|
{
|
||||||
|
MOCK_CONST_METHOD1(fail, void (const std::string&));
|
||||||
|
MOCK_CONST_METHOD1(warn, void (const std::string&));
|
||||||
|
MOCK_CONST_METHOD1(getRecord, Nif::Record* (std::size_t));
|
||||||
|
MOCK_CONST_METHOD0(numRecords, std::size_t ());
|
||||||
|
MOCK_CONST_METHOD1(getRoot, Nif::Record* (std::size_t));
|
||||||
|
MOCK_CONST_METHOD0(numRoots, std::size_t ());
|
||||||
|
MOCK_METHOD1(setUseSkinning, void (bool));
|
||||||
|
MOCK_CONST_METHOD0(getUseSkinning, bool ());
|
||||||
|
MOCK_CONST_METHOD0(getFilename, std::string ());
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RecordMock : Nif::Record
|
||||||
|
{
|
||||||
|
MOCK_METHOD1(read, void (Nif::NIFStream *nif));
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TestBulletNifLoader : Test
|
||||||
|
{
|
||||||
|
BulletNifLoader mLoader;
|
||||||
|
const StrictMock<const NifFileMock> mNifFile;
|
||||||
|
Nif::Node mNode;
|
||||||
|
Nif::Node mNode2;
|
||||||
|
Nif::NiNode mNiNode;
|
||||||
|
Nif::NiNode mNiNode2;
|
||||||
|
Nif::NiNode mNiNode3;
|
||||||
|
Nif::NiTriShapeData mNiTriShapeData;
|
||||||
|
Nif::NiTriShape mNiTriShape;
|
||||||
|
Nif::NiTriShapeData mNiTriShapeData2;
|
||||||
|
Nif::NiTriShape mNiTriShape2;
|
||||||
|
Nif::NiSkinInstance mNiSkinInstance;
|
||||||
|
Nif::NiStringExtraData mNiStringExtraData;
|
||||||
|
Nif::NiStringExtraData mNiStringExtraData2;
|
||||||
|
Nif::Controller mController;
|
||||||
|
btTransform mTransform {btMatrix3x3(btQuaternion(btVector3(1, 0, 0), 0.5f)), btVector3(1, 2, 3)};
|
||||||
|
btTransform mResultTransform {
|
||||||
|
btMatrix3x3(
|
||||||
|
1, 0, 0,
|
||||||
|
0, 0.82417738437652587890625, 0.56633174419403076171875,
|
||||||
|
0, -0.56633174419403076171875, 0.82417738437652587890625
|
||||||
|
),
|
||||||
|
btVector3(1, 2, 3)
|
||||||
|
};
|
||||||
|
btTransform mResultTransform2 {
|
||||||
|
btMatrix3x3(
|
||||||
|
1, 0, 0,
|
||||||
|
0, 0.7951543331146240234375, 0.606407105922698974609375,
|
||||||
|
0, -0.606407105922698974609375, 0.7951543331146240234375
|
||||||
|
),
|
||||||
|
btVector3(4, 8, 12)
|
||||||
|
};
|
||||||
|
|
||||||
|
TestBulletNifLoader()
|
||||||
|
{
|
||||||
|
init(mNode);
|
||||||
|
init(mNode2);
|
||||||
|
init(mNiNode);
|
||||||
|
init(mNiNode2);
|
||||||
|
init(mNiNode3);
|
||||||
|
init(mNiTriShape);
|
||||||
|
init(mNiTriShape2);
|
||||||
|
init(mNiSkinInstance);
|
||||||
|
init(mNiStringExtraData);
|
||||||
|
init(mNiStringExtraData2);
|
||||||
|
init(mController);
|
||||||
|
|
||||||
|
mNiTriShapeData.vertices = {osg::Vec3f(0, 0, 0), osg::Vec3f(1, 0, 0), osg::Vec3f(1, 1, 0)};
|
||||||
|
mNiTriShapeData.triangles = {0, 1, 2};
|
||||||
|
mNiTriShape.data = Nif::NiTriShapeDataPtr(&mNiTriShapeData);
|
||||||
|
|
||||||
|
mNiTriShapeData2.vertices = {osg::Vec3f(0, 0, 1), osg::Vec3f(1, 0, 1), osg::Vec3f(1, 1, 1)};
|
||||||
|
mNiTriShapeData2.triangles = {0, 1, 2};
|
||||||
|
mNiTriShape2.data = Nif::NiTriShapeDataPtr(&mNiTriShapeData2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_zero_num_roots_should_return_default)
|
||||||
|
{
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(0));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_root_not_nif_node_should_return_default)
|
||||||
|
{
|
||||||
|
StrictMock<RecordMock> record;
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&record));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_default_root_nif_node_should_return_default)
|
||||||
|
{
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNode));
|
||||||
|
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif"));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_default_root_collision_node_nif_node_should_return_default)
|
||||||
|
{
|
||||||
|
mNode.recType = Nif::RC_RootCollisionNode;
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNode));
|
||||||
|
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif"));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_default_root_nif_node_and_filename_starting_with_x_should_return_default)
|
||||||
|
{
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNode));
|
||||||
|
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("xtest.nif"));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_root_nif_node_with_bounding_box_should_return_shape_with_compound_shape_and_box_inside)
|
||||||
|
{
|
||||||
|
mNode.hasBounds = true;
|
||||||
|
mNode.flags |= Nif::NiNode::Flag_BBoxCollision;
|
||||||
|
mNode.boundXYZ = osg::Vec3f(1, 2, 3);
|
||||||
|
mNode.boundPos = osg::Vec3f(-1, -2, -3);
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNode));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
expected.mCollisionBoxHalfExtents = osg::Vec3f(1, 2, 3);
|
||||||
|
expected.mCollisionBoxTranslate = osg::Vec3f(-1, -2, -3);
|
||||||
|
std::unique_ptr<btBoxShape> box(new btBoxShape(btVector3(1, 2, 3)));
|
||||||
|
std::unique_ptr<btCompoundShape> shape(new btCompoundShape);
|
||||||
|
shape->addChildShape(btTransform(btMatrix3x3::getIdentity(), btVector3(-1, -2, -3)), box.release());
|
||||||
|
expected.mCollisionShape = shape.release();
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_child_nif_node_with_bounding_box)
|
||||||
|
{
|
||||||
|
mNode.hasBounds = true;
|
||||||
|
mNode.flags |= Nif::NiNode::Flag_BBoxCollision;
|
||||||
|
mNode.boundXYZ = osg::Vec3f(1, 2, 3);
|
||||||
|
mNode.boundPos = osg::Vec3f(-1, -2, -3);
|
||||||
|
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNode)}));
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
expected.mCollisionBoxHalfExtents = osg::Vec3f(1, 2, 3);
|
||||||
|
expected.mCollisionBoxTranslate = osg::Vec3f(-1, -2, -3);
|
||||||
|
std::unique_ptr<btBoxShape> box(new btBoxShape(btVector3(1, 2, 3)));
|
||||||
|
std::unique_ptr<btCompoundShape> shape(new btCompoundShape);
|
||||||
|
shape->addChildShape(btTransform(btMatrix3x3::getIdentity(), btVector3(-1, -2, -3)), box.release());
|
||||||
|
expected.mCollisionShape = shape.release();
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_root_and_child_nif_node_with_bounding_box_but_root_without_flag_should_use_child_bounds)
|
||||||
|
{
|
||||||
|
mNode.hasBounds = true;
|
||||||
|
mNode.flags |= Nif::NiNode::Flag_BBoxCollision;
|
||||||
|
mNode.boundXYZ = osg::Vec3f(1, 2, 3);
|
||||||
|
mNode.boundPos = osg::Vec3f(-1, -2, -3);
|
||||||
|
|
||||||
|
mNiNode.hasBounds = true;
|
||||||
|
mNiNode.boundXYZ = osg::Vec3f(4, 5, 6);
|
||||||
|
mNiNode.boundPos = osg::Vec3f(-4, -5, -6);
|
||||||
|
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNode)}));
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
expected.mCollisionBoxHalfExtents = osg::Vec3f(1, 2, 3);
|
||||||
|
expected.mCollisionBoxTranslate = osg::Vec3f(-1, -2, -3);
|
||||||
|
std::unique_ptr<btBoxShape> box(new btBoxShape(btVector3(1, 2, 3)));
|
||||||
|
std::unique_ptr<btCompoundShape> shape(new btCompoundShape);
|
||||||
|
shape->addChildShape(btTransform(btMatrix3x3::getIdentity(), btVector3(-1, -2, -3)), box.release());
|
||||||
|
expected.mCollisionShape = shape.release();
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_root_and_two_children_where_both_with_bounds_but_only_first_with_flag_should_use_first_bounds)
|
||||||
|
{
|
||||||
|
mNode.hasBounds = true;
|
||||||
|
mNode.flags |= Nif::NiNode::Flag_BBoxCollision;
|
||||||
|
mNode.boundXYZ = osg::Vec3f(1, 2, 3);
|
||||||
|
mNode.boundPos = osg::Vec3f(-1, -2, -3);
|
||||||
|
|
||||||
|
mNode2.hasBounds = true;
|
||||||
|
mNode2.boundXYZ = osg::Vec3f(4, 5, 6);
|
||||||
|
mNode2.boundPos = osg::Vec3f(-4, -5, -6);
|
||||||
|
|
||||||
|
mNiNode.hasBounds = true;
|
||||||
|
mNiNode.boundXYZ = osg::Vec3f(7, 8, 9);
|
||||||
|
mNiNode.boundPos = osg::Vec3f(-7, -8, -9);
|
||||||
|
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNode), Nif::NodePtr(&mNode2)}));
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
expected.mCollisionBoxHalfExtents = osg::Vec3f(1, 2, 3);
|
||||||
|
expected.mCollisionBoxTranslate = osg::Vec3f(-1, -2, -3);
|
||||||
|
std::unique_ptr<btBoxShape> box(new btBoxShape(btVector3(1, 2, 3)));
|
||||||
|
std::unique_ptr<btCompoundShape> shape(new btCompoundShape);
|
||||||
|
shape->addChildShape(btTransform(btMatrix3x3::getIdentity(), btVector3(-1, -2, -3)), box.release());
|
||||||
|
expected.mCollisionShape = shape.release();
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_root_and_two_children_where_both_with_bounds_but_only_second_with_flag_should_use_second_bounds)
|
||||||
|
{
|
||||||
|
mNode.hasBounds = true;
|
||||||
|
mNode.boundXYZ = osg::Vec3f(1, 2, 3);
|
||||||
|
mNode.boundPos = osg::Vec3f(-1, -2, -3);
|
||||||
|
|
||||||
|
mNode2.hasBounds = true;
|
||||||
|
mNode2.flags |= Nif::NiNode::Flag_BBoxCollision;
|
||||||
|
mNode2.boundXYZ = osg::Vec3f(4, 5, 6);
|
||||||
|
mNode2.boundPos = osg::Vec3f(-4, -5, -6);
|
||||||
|
|
||||||
|
mNiNode.hasBounds = true;
|
||||||
|
mNiNode.boundXYZ = osg::Vec3f(7, 8, 9);
|
||||||
|
mNiNode.boundPos = osg::Vec3f(-7, -8, -9);
|
||||||
|
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNode), Nif::NodePtr(&mNode2)}));
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
expected.mCollisionBoxHalfExtents = osg::Vec3f(4, 5, 6);
|
||||||
|
expected.mCollisionBoxTranslate = osg::Vec3f(-4, -5, -6);
|
||||||
|
std::unique_ptr<btBoxShape> box(new btBoxShape(btVector3(4, 5, 6)));
|
||||||
|
std::unique_ptr<btCompoundShape> shape(new btCompoundShape);
|
||||||
|
shape->addChildShape(btTransform(btMatrix3x3::getIdentity(), btVector3(-4, -5, -6)), box.release());
|
||||||
|
expected.mCollisionShape = shape.release();
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_root_nif_node_with_bounds_but_without_flag_should_return_shape_with_bounds_but_with_null_collision_shape)
|
||||||
|
{
|
||||||
|
mNode.hasBounds = true;
|
||||||
|
mNode.boundXYZ = osg::Vec3f(1, 2, 3);
|
||||||
|
mNode.boundPos = osg::Vec3f(-1, -2, -3);
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNode));
|
||||||
|
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif"));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
expected.mCollisionBoxHalfExtents = osg::Vec3f(1, 2, 3);
|
||||||
|
expected.mCollisionBoxTranslate = osg::Vec3f(-1, -2, -3);
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_tri_shape_root_node_should_return_shape_with_triangle_mesh_shape)
|
||||||
|
{
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiTriShape));
|
||||||
|
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif"));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
|
||||||
|
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
expected.mCollisionShape = new Resource::TriangleMeshShape(triangles.release(), true);
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_tri_shape_root_node_with_bounds_should_return_shape_with_bounds_but_with_null_collision_shape)
|
||||||
|
{
|
||||||
|
mNiTriShape.hasBounds = true;
|
||||||
|
mNiTriShape.boundXYZ = osg::Vec3f(1, 2, 3);
|
||||||
|
mNiTriShape.boundPos = osg::Vec3f(-1, -2, -3);
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiTriShape));
|
||||||
|
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif"));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
expected.mCollisionBoxHalfExtents = osg::Vec3f(1, 2, 3);
|
||||||
|
expected.mCollisionBoxTranslate = osg::Vec3f(-1, -2, -3);
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_tri_shape_child_node_should_return_shape_with_triangle_mesh_shape)
|
||||||
|
{
|
||||||
|
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNiTriShape)}));
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode));
|
||||||
|
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif"));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
|
||||||
|
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
expected.mCollisionShape = new Resource::TriangleMeshShape(triangles.release(), true);
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_nested_tri_shape_child_should_return_shape_with_triangle_mesh_shape)
|
||||||
|
{
|
||||||
|
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNiNode2)}));
|
||||||
|
mNiNode2.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNiTriShape)}));
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode));
|
||||||
|
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif"));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
|
||||||
|
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
expected.mCollisionShape = new Resource::TriangleMeshShape(triangles.release(), true);
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_two_tri_shape_children_should_return_shape_with_triangle_mesh_shape_with_all_meshes)
|
||||||
|
{
|
||||||
|
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({
|
||||||
|
Nif::NodePtr(&mNiTriShape),
|
||||||
|
Nif::NodePtr(&mNiTriShape2)
|
||||||
|
}));
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode));
|
||||||
|
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif"));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
|
||||||
|
triangles->addTriangle(btVector3(0, 0, 1), btVector3(1, 0, 1), btVector3(1, 1, 1));
|
||||||
|
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
expected.mCollisionShape = new Resource::TriangleMeshShape(triangles.release(), true);
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_tri_shape_child_node_and_filename_starting_with_x_and_not_empty_skin_should_return_shape_with_triangle_mesh_shape)
|
||||||
|
{
|
||||||
|
mNiTriShape.skin = Nif::NiSkinInstancePtr(&mNiSkinInstance);
|
||||||
|
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNiTriShape)}));
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode));
|
||||||
|
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("xtest.nif"));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
|
||||||
|
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
expected.mCollisionShape = new Resource::TriangleMeshShape(triangles.release(), true);
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_tri_shape_root_node_and_filename_starting_with_x_should_return_shape_with_compound_shape)
|
||||||
|
{
|
||||||
|
copy(mTransform, mNiTriShape.trafo);
|
||||||
|
mNiTriShape.trafo.scale = 3;
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiTriShape));
|
||||||
|
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("xtest.nif"));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
|
||||||
|
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
|
||||||
|
std::unique_ptr<Resource::TriangleMeshShape> mesh(new Resource::TriangleMeshShape(triangles.release(), true));
|
||||||
|
mesh->setLocalScaling(btVector3(3, 3, 3));
|
||||||
|
std::unique_ptr<btCompoundShape> shape(new btCompoundShape);
|
||||||
|
shape->addChildShape(mResultTransform, mesh.release());
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
expected.mCollisionShape = shape.release();
|
||||||
|
expected.mAnimatedShapes = {{-1, 0}};
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_tri_shape_child_node_and_filename_starting_with_x_should_return_shape_with_compound_shape)
|
||||||
|
{
|
||||||
|
copy(mTransform, mNiTriShape.trafo);
|
||||||
|
mNiTriShape.trafo.scale = 3;
|
||||||
|
mNiTriShape.parent = &mNiNode;
|
||||||
|
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNiTriShape)}));
|
||||||
|
mNiNode.trafo.scale = 4;
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode));
|
||||||
|
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("xtest.nif"));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
|
||||||
|
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
|
||||||
|
std::unique_ptr<Resource::TriangleMeshShape> mesh(new Resource::TriangleMeshShape(triangles.release(), true));
|
||||||
|
mesh->setLocalScaling(btVector3(12, 12, 12));
|
||||||
|
std::unique_ptr<btCompoundShape> shape(new btCompoundShape);
|
||||||
|
shape->addChildShape(mResultTransform2, mesh.release());
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
expected.mCollisionShape = shape.release();
|
||||||
|
expected.mAnimatedShapes = {{-1, 0}};
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_two_tri_shape_children_nodes_and_filename_starting_with_x_should_return_shape_with_compound_shape)
|
||||||
|
{
|
||||||
|
copy(mTransform, mNiTriShape.trafo);
|
||||||
|
mNiTriShape.trafo.scale = 3;
|
||||||
|
|
||||||
|
copy(mTransform, mNiTriShape2.trafo);
|
||||||
|
mNiTriShape2.trafo.scale = 3;
|
||||||
|
|
||||||
|
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({
|
||||||
|
Nif::NodePtr(&mNiTriShape),
|
||||||
|
Nif::NodePtr(&mNiTriShape2),
|
||||||
|
}));
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode));
|
||||||
|
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("xtest.nif"));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
|
||||||
|
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
|
||||||
|
std::unique_ptr<Resource::TriangleMeshShape> mesh(new Resource::TriangleMeshShape(triangles.release(), true));
|
||||||
|
mesh->setLocalScaling(btVector3(3, 3, 3));
|
||||||
|
|
||||||
|
std::unique_ptr<btTriangleMesh> triangles2(new btTriangleMesh(false));
|
||||||
|
triangles2->addTriangle(btVector3(0, 0, 1), btVector3(1, 0, 1), btVector3(1, 1, 1));
|
||||||
|
std::unique_ptr<Resource::TriangleMeshShape> mesh2(new Resource::TriangleMeshShape(triangles2.release(), true));
|
||||||
|
mesh2->setLocalScaling(btVector3(3, 3, 3));
|
||||||
|
|
||||||
|
std::unique_ptr<btCompoundShape> shape(new btCompoundShape);
|
||||||
|
shape->addChildShape(mResultTransform, mesh.release());
|
||||||
|
shape->addChildShape(mResultTransform, mesh2.release());
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
expected.mCollisionShape = shape.release();
|
||||||
|
expected.mAnimatedShapes = {{-1, 0}};
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_tri_shape_child_node_with_controller_should_return_shape_with_compound_shape)
|
||||||
|
{
|
||||||
|
mController.recType = Nif::RC_NiKeyframeController;
|
||||||
|
mController.flags |= Nif::NiNode::ControllerFlag_Active;
|
||||||
|
copy(mTransform, mNiTriShape.trafo);
|
||||||
|
mNiTriShape.trafo.scale = 3;
|
||||||
|
mNiTriShape.parent = &mNiNode;
|
||||||
|
mNiTriShape.controller = Nif::ControllerPtr(&mController);
|
||||||
|
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNiTriShape)}));
|
||||||
|
mNiNode.trafo.scale = 4;
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode));
|
||||||
|
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif"));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
|
||||||
|
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
|
||||||
|
std::unique_ptr<Resource::TriangleMeshShape> mesh(new Resource::TriangleMeshShape(triangles.release(), true));
|
||||||
|
mesh->setLocalScaling(btVector3(12, 12, 12));
|
||||||
|
std::unique_ptr<btCompoundShape> shape(new btCompoundShape);
|
||||||
|
shape->addChildShape(mResultTransform2, mesh.release());
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
expected.mCollisionShape = shape.release();
|
||||||
|
expected.mAnimatedShapes = {{-1, 0}};
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_two_tri_shape_children_nodes_where_one_with_controller_should_return_shape_with_compound_shape)
|
||||||
|
{
|
||||||
|
mController.recType = Nif::RC_NiKeyframeController;
|
||||||
|
mController.flags |= Nif::NiNode::ControllerFlag_Active;
|
||||||
|
copy(mTransform, mNiTriShape.trafo);
|
||||||
|
mNiTriShape.trafo.scale = 3;
|
||||||
|
copy(mTransform, mNiTriShape2.trafo);
|
||||||
|
mNiTriShape2.trafo.scale = 3;
|
||||||
|
mNiTriShape2.parent = &mNiNode;
|
||||||
|
mNiTriShape2.controller = Nif::ControllerPtr(&mController);
|
||||||
|
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({
|
||||||
|
Nif::NodePtr(&mNiTriShape),
|
||||||
|
Nif::NodePtr(&mNiTriShape2),
|
||||||
|
}));
|
||||||
|
mNiNode.trafo.scale = 4;
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode));
|
||||||
|
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif"));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
|
||||||
|
triangles->addTriangle(btVector3(1, 2, 3), btVector3(4, 2, 3), btVector3(4, 4.632747650146484375, 1.56172335147857666015625));
|
||||||
|
std::unique_ptr<Resource::TriangleMeshShape> mesh(new Resource::TriangleMeshShape(triangles.release(), true));
|
||||||
|
mesh->setLocalScaling(btVector3(1, 1, 1));
|
||||||
|
|
||||||
|
std::unique_ptr<btTriangleMesh> triangles2(new btTriangleMesh(false));
|
||||||
|
triangles2->addTriangle(btVector3(0, 0, 1), btVector3(1, 0, 1), btVector3(1, 1, 1));
|
||||||
|
std::unique_ptr<Resource::TriangleMeshShape> mesh2(new Resource::TriangleMeshShape(triangles2.release(), true));
|
||||||
|
mesh2->setLocalScaling(btVector3(12, 12, 12));
|
||||||
|
|
||||||
|
std::unique_ptr<btCompoundShape> shape(new btCompoundShape);
|
||||||
|
shape->addChildShape(mResultTransform2, mesh2.release());
|
||||||
|
shape->addChildShape(btTransform::getIdentity(), mesh.release());
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
expected.mCollisionShape = shape.release();
|
||||||
|
expected.mAnimatedShapes = {{-1, 0}};
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_root_avoid_node_and_tri_shape_child_node_should_return_shape_with_null_collision_shape)
|
||||||
|
{
|
||||||
|
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNiTriShape)}));
|
||||||
|
mNiNode.recType = Nif::RC_AvoidNode;
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode));
|
||||||
|
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif"));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_tri_shape_child_node_with_empty_data_should_return_shape_with_null_collision_shape)
|
||||||
|
{
|
||||||
|
mNiTriShape.data = Nif::NiTriShapeDataPtr(nullptr);
|
||||||
|
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNiTriShape)}));
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode));
|
||||||
|
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif"));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_tri_shape_child_node_with_empty_data_triangles_should_return_shape_with_null_collision_shape)
|
||||||
|
{
|
||||||
|
mNiTriShape.data->triangles.clear();
|
||||||
|
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNiTriShape)}));
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode));
|
||||||
|
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif"));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_tri_shape_child_node_with_extra_data_string_starting_with_nc_should_return_shape_with_null_collision_shape)
|
||||||
|
{
|
||||||
|
mNiStringExtraData.string = "NC___";
|
||||||
|
mNiStringExtraData.recType = Nif::RC_NiStringExtraData;
|
||||||
|
mNiTriShape.extra = Nif::ExtraPtr(&mNiStringExtraData);
|
||||||
|
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNiTriShape)}));
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode));
|
||||||
|
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif"));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_tri_shape_child_node_with_not_first_extra_data_string_starting_with_nc_should_return_shape_with_null_collision_shape)
|
||||||
|
{
|
||||||
|
mNiStringExtraData.extra = Nif::ExtraPtr(&mNiStringExtraData2);
|
||||||
|
mNiStringExtraData2.string = "NC___";
|
||||||
|
mNiStringExtraData2.recType = Nif::RC_NiStringExtraData;
|
||||||
|
mNiTriShape.extra = Nif::ExtraPtr(&mNiStringExtraData);
|
||||||
|
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNiTriShape)}));
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode));
|
||||||
|
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif"));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_tri_shape_child_node_with_extra_data_string_mrk_should_return_shape_with_null_collision_shape)
|
||||||
|
{
|
||||||
|
mNiStringExtraData.string = "MRK";
|
||||||
|
mNiStringExtraData.recType = Nif::RC_NiStringExtraData;
|
||||||
|
mNiTriShape.extra = Nif::ExtraPtr(&mNiStringExtraData);
|
||||||
|
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNiTriShape)}));
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode));
|
||||||
|
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif"));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestBulletNifLoader, for_tri_shape_child_node_with_extra_data_string_mrk_and_other_collision_node_should_return_shape_with_triangle_mesh_shape_with_all_meshes)
|
||||||
|
{
|
||||||
|
mNiStringExtraData.string = "MRK";
|
||||||
|
mNiStringExtraData.recType = Nif::RC_NiStringExtraData;
|
||||||
|
mNiTriShape.extra = Nif::ExtraPtr(&mNiStringExtraData);
|
||||||
|
mNiNode3.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNiTriShape)}));
|
||||||
|
mNiNode3.recType = Nif::RC_RootCollisionNode;
|
||||||
|
mNiNode2.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(nullptr), Nif::NodePtr(&mNiNode3)}));
|
||||||
|
mNiNode2.recType = Nif::RC_NiNode;
|
||||||
|
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNiNode2)}));
|
||||||
|
mNiNode.recType = Nif::RC_NiNode;
|
||||||
|
|
||||||
|
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1));
|
||||||
|
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode));
|
||||||
|
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif"));
|
||||||
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
|
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
|
||||||
|
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
|
||||||
|
Resource::BulletShape expected;
|
||||||
|
expected.mCollisionShape = new Resource::TriangleMeshShape(triangles.release(), true);
|
||||||
|
|
||||||
|
EXPECT_EQ(*result, expected);
|
||||||
|
}
|
||||||
|
}
|
515
cmake/FindGMock.cmake
Normal file
515
cmake/FindGMock.cmake
Normal file
@ -0,0 +1,515 @@
|
|||||||
|
# Get the Google C++ Mocking Framework.
|
||||||
|
# (This file is almost an copy of the original FindGTest.cmake file,
|
||||||
|
# altered to download and compile GMock and GTest if not found
|
||||||
|
# in GMOCK_ROOT or GTEST_ROOT respectively,
|
||||||
|
# feel free to use it as it is or modify it for your own needs.)
|
||||||
|
#
|
||||||
|
# Defines the following variables:
|
||||||
|
#
|
||||||
|
# GMOCK_FOUND - Found or got the Google Mocking framework
|
||||||
|
# GTEST_FOUND - Found or got the Google Testing framework
|
||||||
|
# GMOCK_INCLUDE_DIRS - GMock include directory
|
||||||
|
# GTEST_INCLUDE_DIRS - GTest include direcotry
|
||||||
|
#
|
||||||
|
# Also defines the library variables below as normal variables
|
||||||
|
#
|
||||||
|
# GMOCK_BOTH_LIBRARIES - Both libgmock & libgmock_main
|
||||||
|
# GMOCK_LIBRARIES - libgmock
|
||||||
|
# GMOCK_MAIN_LIBRARIES - libgmock-main
|
||||||
|
#
|
||||||
|
# GTEST_BOTH_LIBRARIES - Both libgtest & libgtest_main
|
||||||
|
# GTEST_LIBRARIES - libgtest
|
||||||
|
# GTEST_MAIN_LIBRARIES - libgtest_main
|
||||||
|
#
|
||||||
|
# Accepts the following variables as input:
|
||||||
|
#
|
||||||
|
# GMOCK_ROOT - The root directory of the gmock install prefix
|
||||||
|
# GTEST_ROOT - The root directory of the gtest install prefix
|
||||||
|
# GMOCK_SRC_DIR -The directory of the gmock sources
|
||||||
|
# GMOCK_VER - The version of the gmock sources to be downloaded
|
||||||
|
#
|
||||||
|
#-----------------------
|
||||||
|
# Example Usage:
|
||||||
|
#
|
||||||
|
# set(GMOCK_ROOT "~/gmock")
|
||||||
|
# find_package(GMock REQUIRED)
|
||||||
|
# include_directories(${GMOCK_INCLUDE_DIRS})
|
||||||
|
#
|
||||||
|
# add_executable(foo foo.cc)
|
||||||
|
# target_link_libraries(foo ${GMOCK_BOTH_LIBRARIES})
|
||||||
|
#
|
||||||
|
#=============================================================================
|
||||||
|
# Copyright (c) 2016 Michel Estermann
|
||||||
|
# Copyright (c) 2016 Kamil Strzempowicz
|
||||||
|
# Copyright (c) 2011 Matej Svec
|
||||||
|
#
|
||||||
|
# CMake - Cross Platform Makefile Generator
|
||||||
|
# Copyright 2000-2016 Kitware, Inc.
|
||||||
|
# Copyright 2000-2011 Insight Software Consortium
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use 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 names of Kitware, Inc., the Insight Software Consortium,
|
||||||
|
# nor the names of their contributors may be used to endorse or promote
|
||||||
|
# products derived from this software without specific prior written
|
||||||
|
# permission.
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
# HOLDER 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.
|
||||||
|
#
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# The above copyright and license notice applies to distributions of
|
||||||
|
# CMake in source and binary form. Some source files contain additional
|
||||||
|
# notices of original copyright by their contributors; see each source
|
||||||
|
# for details. Third-party software packages supplied with CMake under
|
||||||
|
# compatible licenses provide their own copyright notices documented in
|
||||||
|
# corresponding subdirectories.
|
||||||
|
#
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# CMake was initially developed by Kitware with the following sponsorship:
|
||||||
|
#
|
||||||
|
# * National Library of Medicine at the National Institutes of Health
|
||||||
|
# as part of the Insight Segmentation and Registration Toolkit (ITK).
|
||||||
|
#
|
||||||
|
# * US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel
|
||||||
|
# Visualization Initiative.
|
||||||
|
#
|
||||||
|
# * National Alliance for Medical Image Computing (NAMIC) is funded by the
|
||||||
|
# National Institutes of Health through the NIH Roadmap for Medical Research,
|
||||||
|
# Grant U54 EB005149.
|
||||||
|
#
|
||||||
|
# * Kitware, Inc.
|
||||||
|
#=============================================================================
|
||||||
|
# Thanks to Daniel Blezek <blezek@gmail.com> for the GTEST_ADD_TESTS code
|
||||||
|
|
||||||
|
function(gtest_add_tests executable extra_args)
|
||||||
|
if(NOT ARGN)
|
||||||
|
message(FATAL_ERROR "Missing ARGN: Read the documentation for GTEST_ADD_TESTS")
|
||||||
|
endif()
|
||||||
|
if(ARGN STREQUAL "AUTO")
|
||||||
|
# obtain sources used for building that executable
|
||||||
|
get_property(ARGN TARGET ${executable} PROPERTY SOURCES)
|
||||||
|
endif()
|
||||||
|
set(gtest_case_name_regex ".*\\( *([A-Za-z_0-9]+) *, *([A-Za-z_0-9]+) *\\).*")
|
||||||
|
set(gtest_test_type_regex "(TYPED_TEST|TEST_?[FP]?)")
|
||||||
|
foreach(source ${ARGN})
|
||||||
|
file(READ "${source}" contents)
|
||||||
|
string(REGEX MATCHALL "${gtest_test_type_regex} *\\(([A-Za-z_0-9 ,]+)\\)" found_tests ${contents})
|
||||||
|
foreach(hit ${found_tests})
|
||||||
|
string(REGEX MATCH "${gtest_test_type_regex}" test_type ${hit})
|
||||||
|
|
||||||
|
# Parameterized tests have a different signature for the filter
|
||||||
|
if("x${test_type}" STREQUAL "xTEST_P")
|
||||||
|
string(REGEX REPLACE ${gtest_case_name_regex} "*/\\1.\\2/*" test_name ${hit})
|
||||||
|
elseif("x${test_type}" STREQUAL "xTEST_F" OR "x${test_type}" STREQUAL "xTEST")
|
||||||
|
string(REGEX REPLACE ${gtest_case_name_regex} "\\1.\\2" test_name ${hit})
|
||||||
|
elseif("x${test_type}" STREQUAL "xTYPED_TEST")
|
||||||
|
string(REGEX REPLACE ${gtest_case_name_regex} "\\1/*.\\2" test_name ${hit})
|
||||||
|
else()
|
||||||
|
message(WARNING "Could not parse GTest ${hit} for adding to CTest.")
|
||||||
|
continue()
|
||||||
|
endif()
|
||||||
|
add_test(NAME ${test_name} COMMAND ${executable} --gtest_filter=${test_name} ${extra_args})
|
||||||
|
endforeach()
|
||||||
|
endforeach()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(_append_debugs _endvar _library)
|
||||||
|
if(${_library} AND ${_library}_DEBUG)
|
||||||
|
set(_output optimized ${${_library}} debug ${${_library}_DEBUG})
|
||||||
|
else()
|
||||||
|
set(_output ${${_library}})
|
||||||
|
endif()
|
||||||
|
set(${_endvar} ${_output} PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(_gmock_find_library _name)
|
||||||
|
find_library(${_name}
|
||||||
|
NAMES ${ARGN}
|
||||||
|
HINTS
|
||||||
|
ENV GMOCK_ROOT
|
||||||
|
${GMOCK_ROOT}
|
||||||
|
PATH_SUFFIXES ${_gmock_libpath_suffixes}
|
||||||
|
)
|
||||||
|
mark_as_advanced(${_name})
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(_gtest_find_library _name)
|
||||||
|
find_library(${_name}
|
||||||
|
NAMES ${ARGN}
|
||||||
|
HINTS
|
||||||
|
ENV GTEST_ROOT
|
||||||
|
${GTEST_ROOT}
|
||||||
|
PATH_SUFFIXES ${_gtest_libpath_suffixes}
|
||||||
|
)
|
||||||
|
mark_as_advanced(${_name})
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
if(NOT DEFINED GMOCK_MSVC_SEARCH)
|
||||||
|
set(GMOCK_MSVC_SEARCH MD)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(_gmock_libpath_suffixes lib)
|
||||||
|
set(_gtest_libpath_suffixes lib)
|
||||||
|
if(MSVC)
|
||||||
|
if(GMOCK_MSVC_SEARCH STREQUAL "MD")
|
||||||
|
list(APPEND _gmock_libpath_suffixes
|
||||||
|
msvc/gmock-md/Debug
|
||||||
|
msvc/gmock-md/Release)
|
||||||
|
list(APPEND _gtest_libpath_suffixes
|
||||||
|
msvc/gtest-md/Debug
|
||||||
|
msvc/gtest-md/Release)
|
||||||
|
elseif(GMOCK_MSVC_SEARCH STREQUAL "MT")
|
||||||
|
list(APPEND _gmock_libpath_suffixes
|
||||||
|
msvc/gmock/Debug
|
||||||
|
msvc/gmock/Release)
|
||||||
|
list(APPEND _gtest_libpath_suffixes
|
||||||
|
msvc/gtest/Debug
|
||||||
|
msvc/gtest/Release)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_path(GMOCK_INCLUDE_DIR gmock/gmock.h
|
||||||
|
HINTS
|
||||||
|
$ENV{GMOCK_ROOT}/include
|
||||||
|
${GMOCK_ROOT}/include
|
||||||
|
)
|
||||||
|
mark_as_advanced(GMOCK_INCLUDE_DIR)
|
||||||
|
|
||||||
|
find_path(GTEST_INCLUDE_DIR gtest/gtest.h
|
||||||
|
HINTS
|
||||||
|
$ENV{GTEST_ROOT}/include
|
||||||
|
${GTEST_ROOT}/include
|
||||||
|
)
|
||||||
|
mark_as_advanced(GTEST_INCLUDE_DIR)
|
||||||
|
|
||||||
|
if(MSVC AND GMOCK_MSVC_SEARCH STREQUAL "MD")
|
||||||
|
# The provided /MD project files for Google Mock add -md suffixes to the
|
||||||
|
# library names.
|
||||||
|
_gmock_find_library(GMOCK_LIBRARY gmock-md gmock)
|
||||||
|
_gmock_find_library(GMOCK_LIBRARY_DEBUG gmock-mdd gmockd)
|
||||||
|
_gmock_find_library(GMOCK_MAIN_LIBRARY gmock_main-md gmock_main)
|
||||||
|
_gmock_find_library(GMOCK_MAIN_LIBRARY_DEBUG gmock_main-mdd gmock_maind)
|
||||||
|
|
||||||
|
_gtest_find_library(GTEST_LIBRARY gtest-md gtest)
|
||||||
|
_gtest_find_library(GTEST_LIBRARY_DEBUG gtest-mdd gtestd)
|
||||||
|
_gtest_find_library(GTEST_MAIN_LIBRARY gtest_main-md gtest_main)
|
||||||
|
_gtest_find_library(GTEST_MAIN_LIBRARY_DEBUG gtest_main-mdd gtest_maind)
|
||||||
|
else()
|
||||||
|
_gmock_find_library(GMOCK_LIBRARY gmock)
|
||||||
|
_gmock_find_library(GMOCK_LIBRARY_DEBUG gmockd)
|
||||||
|
_gmock_find_library(GMOCK_MAIN_LIBRARY gmock_main)
|
||||||
|
_gmock_find_library(GMOCK_MAIN_LIBRARY_DEBUG gmock_maind)
|
||||||
|
|
||||||
|
_gtest_find_library(GTEST_LIBRARY gtest)
|
||||||
|
_gtest_find_library(GTEST_LIBRARY_DEBUG gtestd)
|
||||||
|
_gtest_find_library(GTEST_MAIN_LIBRARY gtest_main)
|
||||||
|
_gtest_find_library(GTEST_MAIN_LIBRARY_DEBUG gtest_maind)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT TARGET GTest::GTest)
|
||||||
|
add_library(GTest::GTest UNKNOWN IMPORTED)
|
||||||
|
endif()
|
||||||
|
if(NOT TARGET GTest::Main)
|
||||||
|
add_library(GTest::Main UNKNOWN IMPORTED)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT TARGET GMock::GMock)
|
||||||
|
add_library(GMock::GMock UNKNOWN IMPORTED)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT TARGET GMock::Main)
|
||||||
|
add_library(GMock::Main UNKNOWN IMPORTED)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(GMOCK_LIBRARY_EXISTS OFF)
|
||||||
|
set(GTEST_LIBRARY_EXISTS OFF)
|
||||||
|
|
||||||
|
if(EXISTS "${GMOCK_LIBRARY}" OR EXISTS "${GMOCK_LIBRARY_DEBUG}" AND GMOCK_INCLUDE_DIR)
|
||||||
|
set(GMOCK_LIBRARY_EXISTS ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(EXISTS "${GTEST_LIBRARY}" OR EXISTS "${GTEST_LIBRARY_DEBUG}" AND GTEST_INCLUDE_DIR)
|
||||||
|
set(GTEST_LIBRARY_EXISTS ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT (${GMOCK_LIBRARY_EXISTS} AND ${GTEST_LIBRARY_EXISTS}))
|
||||||
|
|
||||||
|
include(ExternalProject)
|
||||||
|
|
||||||
|
if(GTEST_USE_STATIC_LIBS)
|
||||||
|
set(GTEST_CMAKE_ARGS -Dgtest_force_shared_crt:BOOL=ON -DBUILD_SHARED_LIBS=OFF)
|
||||||
|
if(BUILD_SHARED_LIBS)
|
||||||
|
list(APPEND GTEST_CMAKE_ARGS
|
||||||
|
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
|
||||||
|
-Dgtest_hide_internal_symbols=ON
|
||||||
|
-DCMAKE_CXX_VISIBILITY_PRESET=hidden
|
||||||
|
-DCMAKE_VISIBILITY_INLINES_HIDDEN=ON
|
||||||
|
-DCMAKE_POLICY_DEFAULT_CMP0063=NEW
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
set(GTEST_LIBRARY_PREFIX ${CMAKE_STATIC_LIBRARY_PREFIX})
|
||||||
|
else()
|
||||||
|
set(GTEST_CMAKE_ARGS -DBUILD_SHARED_LIBS=ON)
|
||||||
|
set(GTEST_LIBRARY_PREFIX ${CMAKE_SHARED_LIBRARY_PREFIX})
|
||||||
|
endif()
|
||||||
|
if(WIN32)
|
||||||
|
list(APPEND GTEST_CMAKE_ARGS -Dgtest_disable_pthreads=ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if("${GMOCK_SRC_DIR}" STREQUAL "")
|
||||||
|
message(STATUS "Downloading GMock / GTest version ${GMOCK_VER} from git")
|
||||||
|
if("${GMOCK_VER}" STREQUAL "1.6.0" OR "${GMOCK_VER}" STREQUAL "1.7.0")
|
||||||
|
set(GTEST_BIN_DIR "${GMOCK_ROOT}/src/gtest-build")
|
||||||
|
set(GTEST_LIBRARY "${GTEST_BIN_DIR}/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||||
|
set(GTEST_MAIN_LIBRARY "${GTEST_BIN_DIR}/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gtest_main${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||||
|
mark_as_advanced(GTEST_LIBRARY)
|
||||||
|
mark_as_advanced(GTEST_MAIN_LIBRARY)
|
||||||
|
|
||||||
|
externalproject_add(
|
||||||
|
gtest
|
||||||
|
GIT_REPOSITORY "https://github.com/google/googletest.git"
|
||||||
|
GIT_TAG "release-${GMOCK_VER}"
|
||||||
|
PREFIX ${GMOCK_ROOT}
|
||||||
|
INSTALL_COMMAND ""
|
||||||
|
LOG_DOWNLOAD ON
|
||||||
|
LOG_CONFIGURE ON
|
||||||
|
LOG_BUILD ON
|
||||||
|
CMAKE_ARGS
|
||||||
|
${GTEST_CMAKE_ARGS}
|
||||||
|
BINARY_DIR ${GTEST_BIN_DIR}
|
||||||
|
BUILD_BYPRODUCTS
|
||||||
|
"${GTEST_LIBRARY}"
|
||||||
|
"${GTEST_MAIN_LIBRARY}"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(GMOCK_BIN_DIR "${GMOCK_ROOT}/src/gmock-build")
|
||||||
|
set(GMOCK_LIBRARY "${GMOCK_BIN_DIR}/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gmock${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||||
|
set(GMOCK_MAIN_LIBRARY "${GMOCK_BIN_DIR}/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gmock_main${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||||
|
mark_as_advanced(GMOCK_LIBRARY)
|
||||||
|
mark_as_advanced(GMOCK_MAIN_LIBRARY)
|
||||||
|
|
||||||
|
externalproject_add(
|
||||||
|
gmock
|
||||||
|
GIT_REPOSITORY "https://github.com/google/googlemock.git"
|
||||||
|
GIT_TAG "release-${GMOCK_VER}"
|
||||||
|
PREFIX ${GMOCK_ROOT}
|
||||||
|
INSTALL_COMMAND ""
|
||||||
|
LOG_DOWNLOAD ON
|
||||||
|
LOG_CONFIGURE ON
|
||||||
|
LOG_BUILD ON
|
||||||
|
CMAKE_ARGS
|
||||||
|
${GTEST_CMAKE_ARGS}
|
||||||
|
BINARY_DIR ${GMOCK_BIN_DIR}
|
||||||
|
BUILD_BYPRODUCTS
|
||||||
|
"${GMOCK_LIBRARY}"
|
||||||
|
"${GMOCK_MAIN_LIBRARY}"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_dependencies(gmock gtest)
|
||||||
|
|
||||||
|
add_dependencies(GTest::GTest gtest)
|
||||||
|
add_dependencies(GTest::Main gtest)
|
||||||
|
add_dependencies(GMock::GMock gmock)
|
||||||
|
add_dependencies(GMock::Main gmock)
|
||||||
|
|
||||||
|
externalproject_get_property(gtest source_dir)
|
||||||
|
set(GTEST_INCLUDE_DIR "${source_dir}/include")
|
||||||
|
mark_as_advanced(GTEST_INCLUDE_DIR)
|
||||||
|
externalproject_get_property(gmock source_dir)
|
||||||
|
set(GMOCK_INCLUDE_DIR "${source_dir}/include")
|
||||||
|
mark_as_advanced(GMOCK_INCLUDE_DIR)
|
||||||
|
else() #1.8.0
|
||||||
|
set(GMOCK_BIN_DIR "${GMOCK_ROOT}/src/gmock-build")
|
||||||
|
set(GTEST_LIBRARY "${GMOCK_BIN_DIR}/googlemock/gtest/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||||
|
set(GTEST_MAIN_LIBRARY "${GMOCK_BIN_DIR}/googlemock/gtest/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gtest_main${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||||
|
set(GMOCK_LIBRARY "${GMOCK_BIN_DIR}/googlemock/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gmock${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||||
|
set(GMOCK_MAIN_LIBRARY "${GMOCK_BIN_DIR}/googlemock/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gmock_main${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||||
|
mark_as_advanced(GTEST_LIBRARY)
|
||||||
|
mark_as_advanced(GTEST_MAIN_LIBRARY)
|
||||||
|
mark_as_advanced(GMOCK_LIBRARY)
|
||||||
|
mark_as_advanced(GMOCK_MAIN_LIBRARY)
|
||||||
|
|
||||||
|
externalproject_add(
|
||||||
|
gmock
|
||||||
|
GIT_REPOSITORY "https://github.com/google/googletest.git"
|
||||||
|
GIT_TAG "release-${GMOCK_VER}"
|
||||||
|
PREFIX ${GMOCK_ROOT}
|
||||||
|
INSTALL_COMMAND ""
|
||||||
|
LOG_DOWNLOAD ON
|
||||||
|
LOG_CONFIGURE ON
|
||||||
|
LOG_BUILD ON
|
||||||
|
CMAKE_ARGS
|
||||||
|
${GTEST_CMAKE_ARGS}
|
||||||
|
BINARY_DIR "${GMOCK_BIN_DIR}"
|
||||||
|
BUILD_BYPRODUCTS
|
||||||
|
"${GTEST_LIBRARY}"
|
||||||
|
"${GTEST_MAIN_LIBRARY}"
|
||||||
|
"${GMOCK_LIBRARY}"
|
||||||
|
"${GMOCK_MAIN_LIBRARY}"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_dependencies(GTest::GTest gmock)
|
||||||
|
add_dependencies(GTest::Main gmock)
|
||||||
|
add_dependencies(GMock::GMock gmock)
|
||||||
|
add_dependencies(GMock::Main gmock)
|
||||||
|
|
||||||
|
externalproject_get_property(gmock source_dir)
|
||||||
|
set(GTEST_INCLUDE_DIR "${source_dir}/googletest/include")
|
||||||
|
set(GMOCK_INCLUDE_DIR "${source_dir}/googlemock/include")
|
||||||
|
mark_as_advanced(GMOCK_INCLUDE_DIR)
|
||||||
|
mark_as_advanced(GTEST_INCLUDE_DIR)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Prevent CMake from complaining about these directories missing when the libgtest/libgmock targets get used as dependencies
|
||||||
|
file(MAKE_DIRECTORY ${GTEST_INCLUDE_DIR} ${GMOCK_INCLUDE_DIR})
|
||||||
|
else()
|
||||||
|
message(STATUS "Building Gmock / Gtest from dir ${GMOCK_SRC_DIR}")
|
||||||
|
|
||||||
|
set(GMOCK_BIN_DIR "${GMOCK_ROOT}/src/gmock-build")
|
||||||
|
set(GTEST_LIBRARY "${GMOCK_BIN_DIR}/gtest/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||||
|
set(GTEST_MAIN_LIBRARY "${GMOCK_BIN_DIR}/gtest/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gtest_main${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||||
|
set(GMOCK_LIBRARY "${GMOCK_BIN_DIR}/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gmock${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||||
|
set(GMOCK_MAIN_LIBRARY "${GMOCK_BIN_DIR}/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gmock_main${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||||
|
mark_as_advanced(GTEST_LIBRARY)
|
||||||
|
mark_as_advanced(GTEST_MAIN_LIBRARY)
|
||||||
|
mark_as_advanced(GMOCK_LIBRARY)
|
||||||
|
mark_as_advanced(GMOCK_MAIN_LIBRARY)
|
||||||
|
|
||||||
|
if(EXISTS "${GMOCK_SRC_DIR}/gtest/include/gtest/gtest.h")
|
||||||
|
set(GTEST_INCLUDE_DIR "${GMOCK_SRC_DIR}/gtest/include")
|
||||||
|
mark_as_advanced(GTEST_INCLUDE_DIR)
|
||||||
|
endif()
|
||||||
|
if(EXISTS "${GMOCK_SRC_DIR}/include/gmock/gmock.h")
|
||||||
|
set(GMOCK_INCLUDE_DIR "${GMOCK_SRC_DIR}/include")
|
||||||
|
mark_as_advanced(GMOCK_INCLUDE_DIR)
|
||||||
|
elseif(EXISTS "${GMOCK_SRC_DIR}/../../include/gmock/gmock.h")
|
||||||
|
set(GMOCK_INCLUDE_DIR "${GMOCK_SRC_DIR}/../../include")
|
||||||
|
if(IS_ABSOLUTE "${GMOCK_INCLUDE_DIR}")
|
||||||
|
get_filename_component(GMOCK_INCLUDE_DIR "${GMOCK_INCLUDE_DIR}" ABSOLUTE)
|
||||||
|
endif()
|
||||||
|
mark_as_advanced(GMOCK_INCLUDE_DIR)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
externalproject_add(
|
||||||
|
gmock
|
||||||
|
SOURCE_DIR ${GMOCK_SRC_DIR}
|
||||||
|
PREFIX ${GMOCK_ROOT}
|
||||||
|
INSTALL_COMMAND ""
|
||||||
|
LOG_DOWNLOAD ON
|
||||||
|
LOG_CONFIGURE ON
|
||||||
|
LOG_BUILD ON
|
||||||
|
CMAKE_ARGS
|
||||||
|
${GTEST_CMAKE_ARGS}
|
||||||
|
BINARY_DIR "${GMOCK_BIN_DIR}"
|
||||||
|
BUILD_BYPRODUCTS
|
||||||
|
"${GTEST_LIBRARY}"
|
||||||
|
"${GTEST_MAIN_LIBRARY}"
|
||||||
|
"${GMOCK_LIBRARY}"
|
||||||
|
"${GMOCK_MAIN_LIBRARY}"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_dependencies(GTest::GTest gmock)
|
||||||
|
add_dependencies(GTest::Main gmock)
|
||||||
|
add_dependencies(GMock::GMock gmock)
|
||||||
|
add_dependencies(GMock::Main gmock)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(GTest DEFAULT_MSG GTEST_LIBRARY GTEST_INCLUDE_DIR GTEST_MAIN_LIBRARY)
|
||||||
|
find_package_handle_standard_args(GMock DEFAULT_MSG GMOCK_LIBRARY GMOCK_INCLUDE_DIR GMOCK_MAIN_LIBRARY)
|
||||||
|
|
||||||
|
include(CMakeFindDependencyMacro)
|
||||||
|
find_dependency(Threads)
|
||||||
|
|
||||||
|
set_target_properties(GTest::GTest PROPERTIES
|
||||||
|
INTERFACE_LINK_LIBRARIES "Threads::Threads"
|
||||||
|
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
|
||||||
|
IMPORTED_LOCATION "${GTEST_LIBRARY}"
|
||||||
|
)
|
||||||
|
|
||||||
|
if(GTEST_INCLUDE_DIR)
|
||||||
|
set_target_properties(GTest::GTest PROPERTIES
|
||||||
|
INTERFACE_INCLUDE_DIRECTORIES "${GTEST_INCLUDE_DIR}"
|
||||||
|
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${GTEST_INCLUDE_DIR}"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set_target_properties(GTest::Main PROPERTIES
|
||||||
|
INTERFACE_LINK_LIBRARIES "GTest::GTest"
|
||||||
|
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
|
||||||
|
IMPORTED_LOCATION "${GTEST_MAIN_LIBRARY}")
|
||||||
|
|
||||||
|
set_target_properties(GMock::GMock PROPERTIES
|
||||||
|
INTERFACE_LINK_LIBRARIES "Threads::Threads"
|
||||||
|
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
|
||||||
|
IMPORTED_LOCATION "${GMOCK_LIBRARY}")
|
||||||
|
|
||||||
|
if(GMOCK_INCLUDE_DIR)
|
||||||
|
set_target_properties(GMock::GMock PROPERTIES
|
||||||
|
INTERFACE_INCLUDE_DIRECTORIES "${GMOCK_INCLUDE_DIR}"
|
||||||
|
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${GMOCK_INCLUDE_DIR}"
|
||||||
|
)
|
||||||
|
if(GMOCK_VER VERSION_LESS "1.7")
|
||||||
|
# GMock 1.6 still has GTest as an external link-time dependency,
|
||||||
|
# so just specify it on the link interface.
|
||||||
|
set_property(TARGET GMock::GMock APPEND PROPERTY
|
||||||
|
INTERFACE_LINK_LIBRARIES GTest::GTest)
|
||||||
|
elseif(GTEST_INCLUDE_DIR)
|
||||||
|
# GMock 1.7 and beyond doesn't have it as a link-time dependency anymore,
|
||||||
|
# so merge it's compile-time interface (include dirs) with ours.
|
||||||
|
set_property(TARGET GMock::GMock APPEND PROPERTY
|
||||||
|
INTERFACE_INCLUDE_DIRECTORIES "${GTEST_INCLUDE_DIR}")
|
||||||
|
set_property(TARGET GMock::GMock APPEND PROPERTY
|
||||||
|
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${GTEST_INCLUDE_DIR}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set_target_properties(GMock::Main PROPERTIES
|
||||||
|
INTERFACE_LINK_LIBRARIES "GMock::GMock"
|
||||||
|
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
|
||||||
|
IMPORTED_LOCATION "${GMOCK_MAIN_LIBRARY}")
|
||||||
|
|
||||||
|
if(GTEST_FOUND)
|
||||||
|
set(GTEST_INCLUDE_DIRS ${GTEST_INCLUDE_DIR})
|
||||||
|
set(GTEST_LIBRARIES GTest::GTest)
|
||||||
|
set(GTEST_MAIN_LIBRARIES GTest::Main)
|
||||||
|
set(GTEST_BOTH_LIBRARIES ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES})
|
||||||
|
if(VERBOSE)
|
||||||
|
message(STATUS "GTest includes: ${GTEST_INCLUDE_DIRS}")
|
||||||
|
message(STATUS "GTest libs: ${GTEST_BOTH_LIBRARIES}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(GMOCK_FOUND)
|
||||||
|
set(GMOCK_INCLUDE_DIRS ${GMOCK_INCLUDE_DIR})
|
||||||
|
set(GMOCK_LIBRARIES GMock::GMock)
|
||||||
|
set(GMOCK_MAIN_LIBRARIES GMock::Main)
|
||||||
|
set(GMOCK_BOTH_LIBRARIES ${GMOCK_LIBRARIES} ${GMOCK_MAIN_LIBRARIES})
|
||||||
|
if(VERBOSE)
|
||||||
|
message(STATUS "GMock includes: ${GMOCK_INCLUDE_DIRS}")
|
||||||
|
message(STATUS "GMock libs: ${GMOCK_BOTH_LIBRARIES}")
|
||||||
|
endif()
|
||||||
|
endif()
|
@ -242,6 +242,11 @@ if (UNIX AND NOT APPLE)
|
|||||||
target_link_libraries(components ${CMAKE_THREAD_LIBS_INIT})
|
target_link_libraries(components ${CMAKE_THREAD_LIBS_INIT})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (BUILD_WITH_CODE_COVERAGE)
|
||||||
|
add_definitions(--coverage)
|
||||||
|
target_link_libraries(components gcov)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
# Make the variable accessible for other subdirectories
|
# Make the variable accessible for other subdirectories
|
||||||
set(COMPONENT_FILES ${COMPONENT_FILES} PARENT_SCOPE)
|
set(COMPONENT_FILES ${COMPONENT_FILES} PARENT_SCOPE)
|
||||||
|
34
components/bullethelpers/processtrianglecallback.hpp
Normal file
34
components/bullethelpers/processtrianglecallback.hpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#ifndef OPENMW_COMPONENTS_BULLETHELPERS_PROCESSTRIANGLECALLBACK_H
|
||||||
|
#define OPENMW_COMPONENTS_BULLETHELPERS_PROCESSTRIANGLECALLBACK_H
|
||||||
|
|
||||||
|
#include <BulletCollision/CollisionShapes/btTriangleCallback.h>
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace BulletHelpers
|
||||||
|
{
|
||||||
|
template <class Impl>
|
||||||
|
class ProcessTriangleCallback : public btTriangleCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ProcessTriangleCallback(Impl impl)
|
||||||
|
: mImpl(std::move(impl))
|
||||||
|
{}
|
||||||
|
|
||||||
|
void processTriangle(btVector3* triangle, int partId, int triangleIndex) override final
|
||||||
|
{
|
||||||
|
return mImpl(triangle, partId, triangleIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Impl mImpl;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Impl>
|
||||||
|
ProcessTriangleCallback<typename std::decay<Impl>::type> makeProcessTriangleCallback(Impl&& impl)
|
||||||
|
{
|
||||||
|
return ProcessTriangleCallback<typename std::decay<Impl>::type>(std::forward<Impl>(impl));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -14,7 +14,30 @@
|
|||||||
namespace Nif
|
namespace Nif
|
||||||
{
|
{
|
||||||
|
|
||||||
class NIFFile
|
struct File
|
||||||
|
{
|
||||||
|
virtual ~File() = default;
|
||||||
|
|
||||||
|
virtual void fail(const std::string &msg) const = 0;
|
||||||
|
|
||||||
|
virtual void warn(const std::string &msg) const = 0;
|
||||||
|
|
||||||
|
virtual Record *getRecord(size_t index) const = 0;
|
||||||
|
|
||||||
|
virtual size_t numRecords() const = 0;
|
||||||
|
|
||||||
|
virtual Record *getRoot(size_t index = 0) const = 0;
|
||||||
|
|
||||||
|
virtual size_t numRoots() const = 0;
|
||||||
|
|
||||||
|
virtual void setUseSkinning(bool skinning) = 0;
|
||||||
|
|
||||||
|
virtual bool getUseSkinning() const = 0;
|
||||||
|
|
||||||
|
virtual std::string getFilename() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NIFFile final : public File
|
||||||
{
|
{
|
||||||
enum NIFVersion {
|
enum NIFVersion {
|
||||||
VER_MW = 0x04000002 // Morrowind NIFs
|
VER_MW = 0x04000002 // Morrowind NIFs
|
||||||
@ -48,14 +71,14 @@ class NIFFile
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/// Used if file parsing fails
|
/// Used if file parsing fails
|
||||||
void fail(const std::string &msg) const
|
void fail(const std::string &msg) const override
|
||||||
{
|
{
|
||||||
std::string err = " NIFFile Error: " + msg;
|
std::string err = " NIFFile Error: " + msg;
|
||||||
err += "\nFile: " + filename;
|
err += "\nFile: " + filename;
|
||||||
throw std::runtime_error(err);
|
throw std::runtime_error(err);
|
||||||
}
|
}
|
||||||
/// Used when something goes wrong, but not catastrophically so
|
/// Used when something goes wrong, but not catastrophically so
|
||||||
void warn(const std::string &msg) const
|
void warn(const std::string &msg) const override
|
||||||
{
|
{
|
||||||
std::cerr << " NIFFile Warning: " << msg <<std::endl
|
std::cerr << " NIFFile Warning: " << msg <<std::endl
|
||||||
<< "File: " << filename <<std::endl;
|
<< "File: " << filename <<std::endl;
|
||||||
@ -66,31 +89,31 @@ public:
|
|||||||
~NIFFile();
|
~NIFFile();
|
||||||
|
|
||||||
/// Get a given record
|
/// Get a given record
|
||||||
Record *getRecord(size_t index) const
|
Record *getRecord(size_t index) const override
|
||||||
{
|
{
|
||||||
Record *res = records.at(index);
|
Record *res = records.at(index);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
/// Number of records
|
/// Number of records
|
||||||
size_t numRecords() const { return records.size(); }
|
size_t numRecords() const override { return records.size(); }
|
||||||
|
|
||||||
/// Get a given root
|
/// Get a given root
|
||||||
Record *getRoot(size_t index=0) const
|
Record *getRoot(size_t index=0) const override
|
||||||
{
|
{
|
||||||
Record *res = roots.at(index);
|
Record *res = roots.at(index);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
/// Number of roots
|
/// Number of roots
|
||||||
size_t numRoots() const { return roots.size(); }
|
size_t numRoots() const override { return roots.size(); }
|
||||||
|
|
||||||
/// Set whether there is skinning contained in this NIF file.
|
/// Set whether there is skinning contained in this NIF file.
|
||||||
/// @note This is just a hint for users of the NIF file and has no effect on the loading procedure.
|
/// @note This is just a hint for users of the NIF file and has no effect on the loading procedure.
|
||||||
void setUseSkinning(bool skinning);
|
void setUseSkinning(bool skinning) override;
|
||||||
|
|
||||||
bool getUseSkinning() const;
|
bool getUseSkinning() const override;
|
||||||
|
|
||||||
/// Get the name of the file
|
/// Get the name of the file
|
||||||
std::string getFilename() const { return filename; }
|
std::string getFilename() const override { return filename; }
|
||||||
};
|
};
|
||||||
typedef std::shared_ptr<const Nif::NIFFile> NIFFilePtr;
|
typedef std::shared_ptr<const Nif::NIFFile> NIFFilePtr;
|
||||||
|
|
||||||
|
@ -23,6 +23,8 @@ class RecordPtrT
|
|||||||
public:
|
public:
|
||||||
RecordPtrT() : index(-2) {}
|
RecordPtrT() : index(-2) {}
|
||||||
|
|
||||||
|
RecordPtrT(X* ptr) : ptr(ptr) {}
|
||||||
|
|
||||||
/// Read the index from the nif
|
/// Read the index from the nif
|
||||||
void read(NIFStream *nif)
|
void read(NIFStream *nif)
|
||||||
{
|
{
|
||||||
@ -87,6 +89,12 @@ class RecordListT
|
|||||||
std::vector<Ptr> list;
|
std::vector<Ptr> list;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
RecordListT() = default;
|
||||||
|
|
||||||
|
RecordListT(std::vector<Ptr> list)
|
||||||
|
: list(std::move(list))
|
||||||
|
{}
|
||||||
|
|
||||||
void read(NIFStream *nif)
|
void read(NIFStream *nif)
|
||||||
{
|
{
|
||||||
int len = nif->getInt();
|
int len = nif->getInt();
|
||||||
|
@ -47,8 +47,8 @@ namespace NifBullet
|
|||||||
{
|
{
|
||||||
|
|
||||||
BulletNifLoader::BulletNifLoader()
|
BulletNifLoader::BulletNifLoader()
|
||||||
: mCompoundShape(NULL)
|
: mCompoundShape()
|
||||||
, mStaticMesh(NULL)
|
, mStaticMesh()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,20 +56,20 @@ BulletNifLoader::~BulletNifLoader()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::ref_ptr<Resource::BulletShape> BulletNifLoader::load(const Nif::NIFFilePtr& nif)
|
osg::ref_ptr<Resource::BulletShape> BulletNifLoader::load(const Nif::File& nif)
|
||||||
{
|
{
|
||||||
mShape = new Resource::BulletShape;
|
mShape = new Resource::BulletShape;
|
||||||
|
|
||||||
mCompoundShape = NULL;
|
mCompoundShape = NULL;
|
||||||
mStaticMesh = NULL;
|
mStaticMesh = NULL;
|
||||||
|
|
||||||
if (nif->numRoots() < 1)
|
if (nif.numRoots() < 1)
|
||||||
{
|
{
|
||||||
warn("Found no root nodes in NIF.");
|
warn("Found no root nodes in NIF.");
|
||||||
return mShape;
|
return mShape;
|
||||||
}
|
}
|
||||||
|
|
||||||
Nif::Record *r = nif->getRoot(0);
|
Nif::Record *r = nif.getRoot(0);
|
||||||
assert(r != NULL);
|
assert(r != NULL);
|
||||||
|
|
||||||
Nif::Node *node = dynamic_cast<Nif::Node*>(r);
|
Nif::Node *node = dynamic_cast<Nif::Node*>(r);
|
||||||
@ -84,10 +84,11 @@ osg::ref_ptr<Resource::BulletShape> BulletNifLoader::load(const Nif::NIFFilePtr&
|
|||||||
{
|
{
|
||||||
std::unique_ptr<btCompoundShape> compound (new btCompoundShape);
|
std::unique_ptr<btCompoundShape> compound (new btCompoundShape);
|
||||||
|
|
||||||
btBoxShape* boxShape = new btBoxShape(getbtVector(mShape->mCollisionBoxHalfExtents));
|
std::unique_ptr<btBoxShape> boxShape(new btBoxShape(getbtVector(mShape->mCollisionBoxHalfExtents)));
|
||||||
btTransform transform = btTransform::getIdentity();
|
btTransform transform = btTransform::getIdentity();
|
||||||
transform.setOrigin(getbtVector(mShape->mCollisionBoxTranslate));
|
transform.setOrigin(getbtVector(mShape->mCollisionBoxTranslate));
|
||||||
compound->addChildShape(transform, boxShape);
|
compound->addChildShape(transform, boxShape.get());
|
||||||
|
boxShape.release();
|
||||||
|
|
||||||
mShape->mCollisionShape = compound.release();
|
mShape->mCollisionShape = compound.release();
|
||||||
return mShape;
|
return mShape;
|
||||||
@ -96,27 +97,32 @@ osg::ref_ptr<Resource::BulletShape> BulletNifLoader::load(const Nif::NIFFilePtr&
|
|||||||
{
|
{
|
||||||
// files with the name convention xmodel.nif usually have keyframes stored in a separate file xmodel.kf (see Animation::addAnimSource).
|
// files with the name convention xmodel.nif usually have keyframes stored in a separate file xmodel.kf (see Animation::addAnimSource).
|
||||||
// assume all nodes in the file will be animated
|
// assume all nodes in the file will be animated
|
||||||
const bool isAnimated = pathFileNameStartsWithX(nif->getFilename());
|
const auto filename = nif.getFilename();
|
||||||
|
const bool isAnimated = pathFileNameStartsWithX(filename);
|
||||||
|
|
||||||
// If the mesh has RootCollisionNode, attached to actual root node, use it as collision mesh
|
// If the mesh has RootCollisionNode, attached to actual root node, use it as collision mesh
|
||||||
const Nif::Node* rootCollisionNode = getCollisionNode(node);
|
const Nif::Node* rootCollisionNode = getCollisionNode(node);
|
||||||
if (rootCollisionNode)
|
if (rootCollisionNode)
|
||||||
handleNode(nif->getFilename(), rootCollisionNode, 0, false, isAnimated, false);
|
handleNode(filename, rootCollisionNode, 0, false, isAnimated, false);
|
||||||
else
|
else
|
||||||
handleNode(nif->getFilename(), node, 0, true, isAnimated, true);
|
handleNode(filename, node, 0, true, isAnimated, true);
|
||||||
|
|
||||||
if (mCompoundShape)
|
if (mCompoundShape)
|
||||||
{
|
{
|
||||||
mShape->mCollisionShape = mCompoundShape;
|
|
||||||
if (mStaticMesh)
|
if (mStaticMesh)
|
||||||
{
|
{
|
||||||
btTransform trans;
|
btTransform trans;
|
||||||
trans.setIdentity();
|
trans.setIdentity();
|
||||||
mCompoundShape->addChildShape(trans, new Resource::TriangleMeshShape(mStaticMesh,true));
|
mCompoundShape->addChildShape(trans, new Resource::TriangleMeshShape(mStaticMesh.get(), true));
|
||||||
|
mStaticMesh.release();
|
||||||
}
|
}
|
||||||
|
mShape->mCollisionShape = mCompoundShape.release();
|
||||||
}
|
}
|
||||||
else if (mStaticMesh)
|
else if (mStaticMesh)
|
||||||
mShape->mCollisionShape = new Resource::TriangleMeshShape(mStaticMesh,true);
|
{
|
||||||
|
mShape->mCollisionShape = new Resource::TriangleMeshShape(mStaticMesh.get(), true);
|
||||||
|
mStaticMesh.release();
|
||||||
|
}
|
||||||
|
|
||||||
return mShape;
|
return mShape;
|
||||||
}
|
}
|
||||||
@ -276,9 +282,9 @@ void BulletNifLoader::handleNiTriShape(const Nif::NiTriShape *shape, int flags,
|
|||||||
if (isAnimated)
|
if (isAnimated)
|
||||||
{
|
{
|
||||||
if (!mCompoundShape)
|
if (!mCompoundShape)
|
||||||
mCompoundShape = new btCompoundShape();
|
mCompoundShape.reset(new btCompoundShape);
|
||||||
|
|
||||||
btTriangleMesh* childMesh = new btTriangleMesh();
|
std::unique_ptr<btTriangleMesh> childMesh(new btTriangleMesh);
|
||||||
|
|
||||||
const Nif::NiTriShapeData *data = shape->data.getPtr();
|
const Nif::NiTriShapeData *data = shape->data.getPtr();
|
||||||
|
|
||||||
@ -296,7 +302,8 @@ void BulletNifLoader::handleNiTriShape(const Nif::NiTriShape *shape, int flags,
|
|||||||
childMesh->addTriangle(getbtVector(b1), getbtVector(b2), getbtVector(b3));
|
childMesh->addTriangle(getbtVector(b1), getbtVector(b2), getbtVector(b3));
|
||||||
}
|
}
|
||||||
|
|
||||||
Resource::TriangleMeshShape* childShape = new Resource::TriangleMeshShape(childMesh,true);
|
std::unique_ptr<Resource::TriangleMeshShape> childShape(new Resource::TriangleMeshShape(childMesh.get(), true));
|
||||||
|
childMesh.release();
|
||||||
|
|
||||||
float scale = shape->trafo.scale;
|
float scale = shape->trafo.scale;
|
||||||
const Nif::Node* parent = shape;
|
const Nif::Node* parent = shape;
|
||||||
@ -313,12 +320,13 @@ void BulletNifLoader::handleNiTriShape(const Nif::NiTriShape *shape, int flags,
|
|||||||
|
|
||||||
mShape->mAnimatedShapes.insert(std::make_pair(shape->recIndex, mCompoundShape->getNumChildShapes()));
|
mShape->mAnimatedShapes.insert(std::make_pair(shape->recIndex, mCompoundShape->getNumChildShapes()));
|
||||||
|
|
||||||
mCompoundShape->addChildShape(trans, childShape);
|
mCompoundShape->addChildShape(trans, childShape.get());
|
||||||
|
childShape.release();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!mStaticMesh)
|
if (!mStaticMesh)
|
||||||
mStaticMesh = new btTriangleMesh(false);
|
mStaticMesh.reset(new btTriangleMesh(false));
|
||||||
|
|
||||||
// Static shape, just transform all vertices into position
|
// Static shape, just transform all vertices into position
|
||||||
const Nif::NiTriShapeData *data = shape->data.getPtr();
|
const Nif::NiTriShapeData *data = shape->data.getPtr();
|
||||||
|
@ -50,7 +50,7 @@ public:
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::ref_ptr<Resource::BulletShape> load(const Nif::NIFFilePtr& file);
|
osg::ref_ptr<Resource::BulletShape> load(const Nif::File& file);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool findBoundingBox(const Nif::Node* node, int flags = 0);
|
bool findBoundingBox(const Nif::Node* node, int flags = 0);
|
||||||
@ -61,9 +61,9 @@ private:
|
|||||||
|
|
||||||
void handleNiTriShape(const Nif::NiTriShape *shape, int flags, const osg::Matrixf& transform, bool isAnimated);
|
void handleNiTriShape(const Nif::NiTriShape *shape, int flags, const osg::Matrixf& transform, bool isAnimated);
|
||||||
|
|
||||||
btCompoundShape* mCompoundShape;
|
std::unique_ptr<btCompoundShape> mCompoundShape;
|
||||||
|
|
||||||
btTriangleMesh* mStaticMesh;
|
std::unique_ptr<btTriangleMesh> mStaticMesh;
|
||||||
|
|
||||||
osg::ref_ptr<Resource::BulletShape> mShape;
|
osg::ref_ptr<Resource::BulletShape> mShape;
|
||||||
};
|
};
|
||||||
|
@ -127,7 +127,7 @@ osg::ref_ptr<const BulletShape> BulletShapeManager::getShape(const std::string &
|
|||||||
if (ext == "nif")
|
if (ext == "nif")
|
||||||
{
|
{
|
||||||
NifBullet::BulletNifLoader loader;
|
NifBullet::BulletNifLoader loader;
|
||||||
shape = loader.load(mNifFileManager->get(normalized));
|
shape = loader.load(*mNifFileManager->get(normalized));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user