[DEV] correct test unit
This commit is contained in:
parent
7ead46281c
commit
07611ca29f
File diff suppressed because it is too large
Load Diff
@ -44,117 +44,246 @@ namespace ephysics {
|
||||
float m_sleepAngularVelocity; //!< Sleep angular velocity threshold
|
||||
float m_timeBeforeSleep; //!< Time (in seconds) before a body is put to sleep if its velocity becomes smaller than the sleep velocity.
|
||||
/// Private copy-constructor
|
||||
DynamicsWorld(const DynamicsWorld& world);
|
||||
DynamicsWorld(const DynamicsWorld& world) = delete;
|
||||
/// Private assignment operator
|
||||
DynamicsWorld& operator=(const DynamicsWorld& world);
|
||||
/// Integrate the positions and orientations of rigid bodies.
|
||||
void int32_tegrateRigidBodiesPositions();
|
||||
/// Update the AABBs of the bodies
|
||||
void updateRigidBodiesAABB();
|
||||
/// Reset the external force and torque applied to the bodies
|
||||
DynamicsWorld& operator=(const DynamicsWorld& world) = delete;
|
||||
/**
|
||||
* @brief Integrate position and orientation of the rigid bodies.
|
||||
* The positions and orientations of the bodies are int32_tegrated using
|
||||
* the sympletic Euler time stepping scheme.
|
||||
*/
|
||||
void integrateRigidBodiesPositions();
|
||||
/**
|
||||
* @brief Reset the external force and torque applied to the bodies
|
||||
*/
|
||||
void resetBodiesForceAndTorque();
|
||||
/// Update the position and orientation of a body
|
||||
void updatePositionAndOrientationOfBody(RigidBody* _body, vec3 _newLinVelocity, vec3 _newAngVelocity);
|
||||
/// Compute and set the int32_terpolation factor to all bodies
|
||||
void setInterpolationFactorToAllBodies();
|
||||
/// Initialize the bodies velocities arrays for the next simulation step.
|
||||
/**
|
||||
* @brief Initialize the bodies velocities arrays for the next simulation step.
|
||||
*/
|
||||
void initVelocityArrays();
|
||||
/// Integrate the velocities of rigid bodies.
|
||||
void int32_tegrateRigidBodiesVelocities();
|
||||
/// Solve the contacts and constraints
|
||||
/**
|
||||
* @brief Integrate the velocities of rigid bodies.
|
||||
* This method only set the temporary velocities but does not update
|
||||
* the actual velocitiy of the bodies. The velocities updated in this method
|
||||
* might violate the constraints and will be corrected in the constraint and
|
||||
* contact solver.
|
||||
*/
|
||||
void integrateRigidBodiesVelocities();
|
||||
/**
|
||||
* @brief Solve the contacts and constraints
|
||||
*/
|
||||
void solveContactsAndConstraints();
|
||||
/// Solve the position error correction of the constraints
|
||||
/**
|
||||
* @brief Solve the position error correction of the constraints
|
||||
*/
|
||||
void solvePositionCorrection();
|
||||
/// Cleanup the constrained velocities array at each step
|
||||
void cleanupConstrainedVelocitiesArray();
|
||||
/// Compute the islands of awake bodies.
|
||||
/**
|
||||
* @brief Compute the islands of awake bodies.
|
||||
* An island is an isolated group of rigid bodies that have constraints (joints or contacts)
|
||||
* between each other. This method computes the islands at each time step as follows: For each
|
||||
* awake rigid body, we run a Depth First Search (DFS) through the constraint graph of that body
|
||||
* (graph where nodes are the bodies and where the edges are the constraints between the bodies) to
|
||||
* find all the bodies that are connected with it (the bodies that share joints or contacts with
|
||||
* it). Then, we create an island with this group of connected bodies.
|
||||
*/
|
||||
void computeIslands();
|
||||
/// Update the postion/orientation of the bodies
|
||||
/**
|
||||
* @brief Update the postion/orientation of the bodies
|
||||
*/
|
||||
void updateBodiesState();
|
||||
/// Put bodies to sleep if needed.
|
||||
/**
|
||||
* @brief Put bodies to sleep if needed.
|
||||
* For each island, if all the bodies have been almost still for a long enough period of
|
||||
* time, we put all the bodies of the island to sleep.
|
||||
*/
|
||||
void updateSleepingBodies();
|
||||
/// Add the joint to the list of joints of the two bodies involved in the joint
|
||||
void addJointToBody(Joint* joint);
|
||||
/**
|
||||
* @brief Add the joint to the list of joints of the two bodies involved in the joint
|
||||
* @param[in,out] _joint Joint to add at the body.
|
||||
*/
|
||||
void addJointToBody(Joint* _joint);
|
||||
public :
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param gravity Gravity vector in the world (in meters per second squared)
|
||||
*/
|
||||
DynamicsWorld(const vec3& m_gravity);
|
||||
/// Destructor
|
||||
DynamicsWorld(const vec3& _gravity);
|
||||
/**
|
||||
* @brief Vitualize the Destructor
|
||||
*/
|
||||
virtual ~DynamicsWorld();
|
||||
/// Update the physics simulation
|
||||
void update(float timeStep);
|
||||
/// Get the number of iterations for the velocity constraint solver
|
||||
/**
|
||||
* @brief Update the physics simulation
|
||||
* @param timeStep The amount of time to step the simulation by (in seconds)
|
||||
*/
|
||||
void update(float _timeStep);
|
||||
/**
|
||||
* @brief Get the number of iterations for the velocity constraint solver
|
||||
* @return Number if iteration.
|
||||
*/
|
||||
uint32_t getNbIterationsVelocitySolver() const;
|
||||
/// Set the number of iterations for the velocity constraint solver
|
||||
void setNbIterationsVelocitySolver(uint32_t nbIterations);
|
||||
/// Get the number of iterations for the position constraint solver
|
||||
/**
|
||||
* @brief Set the number of iterations for the velocity constraint solver
|
||||
* @param[in] _nbIterations Number of iterations for the velocity solver
|
||||
*/
|
||||
void setNbIterationsVelocitySolver(uint32_t _nbIterations);
|
||||
/**
|
||||
* @brief Get the number of iterations for the position constraint solver
|
||||
*/
|
||||
uint32_t getNbIterationsPositionSolver() const;
|
||||
/// Set the number of iterations for the position constraint solver
|
||||
void setNbIterationsPositionSolver(uint32_t nbIterations);
|
||||
/// Set the position correction technique used for contacts
|
||||
void setContactsPositionCorrectionTechnique(ContactsPositionCorrectionTechnique technique);
|
||||
/// Set the position correction technique used for joints
|
||||
void setJointsPositionCorrectionTechnique(JointsPositionCorrectionTechnique technique);
|
||||
/// Activate or deactivate the solving of friction constraints at the center of
|
||||
/// the contact manifold instead of solving them at each contact point
|
||||
void setIsSolveFrictionAtContactManifoldCenterActive(bool isActive);
|
||||
/// Create a rigid body int32_to the physics world.
|
||||
RigidBody* createRigidBody(const etk::Transform3D& transform);
|
||||
/// Destroy a rigid body and all the joints which it belongs
|
||||
void destroyRigidBody(RigidBody* rigidBody);
|
||||
/// Create a joint between two bodies in the world and return a pointer to the new joint
|
||||
Joint* createJoint(const JointInfo& jointInfo);
|
||||
/// Destroy a joint
|
||||
void destroyJoint(Joint* joint);
|
||||
/// Return the gravity vector of the world
|
||||
/**
|
||||
* @brief Set the number of iterations for the position constraint solver
|
||||
* @param[in] _nbIterations Number of iterations for the position solver
|
||||
*/
|
||||
void setNbIterationsPositionSolver(uint32_t _nbIterations);
|
||||
/**
|
||||
* @brief Set the position correction technique used for contacts
|
||||
* @param[in] _technique Technique used for the position correction (Baumgarte or Split Impulses)
|
||||
*/
|
||||
void setContactsPositionCorrectionTechnique(ContactsPositionCorrectionTechnique _technique);
|
||||
/**
|
||||
* @brief Set the position correction technique used for joints
|
||||
* @param[in] _technique Technique used for the joins position correction (Baumgarte or Non Linear Gauss Seidel)
|
||||
*/
|
||||
void setJointsPositionCorrectionTechnique(JointsPositionCorrectionTechnique _technique);
|
||||
/**
|
||||
* @brief Activate or deactivate the solving of friction constraints at the center of the contact
|
||||
* manifold instead of solving them at each contact point
|
||||
* @param[in] _isActive True if you want the friction to be solved at the center of
|
||||
* the contact manifold and false otherwise
|
||||
*/
|
||||
void setIsSolveFrictionAtContactManifoldCenterActive(bool _isActive);
|
||||
/**
|
||||
* @brief Create a rigid body int32_to the physics world
|
||||
* @param[in] _transform etk::Transform3Dation from body local-space to world-space
|
||||
* @return A pointer to the body that has been created in the world
|
||||
*/
|
||||
RigidBody* createRigidBody(const etk::Transform3D& _transform);
|
||||
/**
|
||||
* @brief Destroy a rigid body and all the joints which it belongs
|
||||
* @param[in,out] _rigidBody Pointer to the body you want to destroy
|
||||
*/
|
||||
void destroyRigidBody(RigidBody* _rigidBody);
|
||||
/**
|
||||
* @brief Create a joint between two bodies in the world and return a pointer to the new joint
|
||||
* @param[in] _jointInfo The information that is necessary to create the joint
|
||||
* @return A pointer to the joint that has been created in the world
|
||||
*/
|
||||
Joint* createJoint(const JointInfo& _jointInfo);
|
||||
/**
|
||||
* @brief Destroy a joint
|
||||
* @param[in,out] _joint Pointer to the joint you want to destroy
|
||||
*/
|
||||
void destroyJoint(Joint* _joint);
|
||||
/**
|
||||
* @brief Get the gravity vector of the world
|
||||
* @return The current gravity vector (in meter per seconds squared)
|
||||
*/
|
||||
vec3 getGravity() const;
|
||||
/// Set the gravity vector of the world
|
||||
void setGravity(vec3& gravity);
|
||||
/// Return if the gravity is on
|
||||
/**
|
||||
* @brief Set the gravity vector of the world
|
||||
* @param[in] _gravity The gravity vector (in meter per seconds squared)
|
||||
*/
|
||||
void setGravity(vec3& _gravity);
|
||||
/**
|
||||
* @brief Get if the gravity is enaled
|
||||
* @return True if the gravity is enabled in the world
|
||||
*/
|
||||
bool isGravityEnabled() const;
|
||||
/// Enable/Disable the gravity
|
||||
void setIsGratityEnabled(bool isGravityEnabled);
|
||||
/// Return the number of rigid bodies in the world
|
||||
/**
|
||||
* @brief Enable/Disable the gravity
|
||||
* @param[in] _isGravityEnabled True if you want to enable the gravity in the world
|
||||
* and false otherwise
|
||||
*/
|
||||
void setIsGratityEnabled(bool _isGravityEnabled);
|
||||
/**
|
||||
* @brief Get the number of rigid bodies in the world
|
||||
* @return Number of rigid bodies in the world
|
||||
*/
|
||||
uint32_t getNbRigidBodies() const;
|
||||
/// Return the number of joints in the world
|
||||
/**
|
||||
* @brief Get the number of all joints
|
||||
* @return Number of joints in the world
|
||||
*/
|
||||
uint32_t getNbJoints() const;
|
||||
/// Return an iterator to the beginning of the rigid bodies of the physics world
|
||||
/**
|
||||
* @brief Get an iterator to the beginning of the bodies of the physics world
|
||||
* @return Starting iterator of the set of rigid bodies
|
||||
*/
|
||||
etk::Set<RigidBody*>::Iterator getRigidBodiesBeginIterator();
|
||||
/// Return an iterator to the end of the rigid bodies of the physics world
|
||||
/**
|
||||
* @brief Get an iterator to the end of the bodies of the physics world
|
||||
* @return Ending iterator of the set of rigid bodies
|
||||
*/
|
||||
etk::Set<RigidBody*>::Iterator getRigidBodiesEndIterator();
|
||||
/// Return true if the sleeping technique is enabled
|
||||
/**
|
||||
* @brief Get if the sleeping technique is enabled
|
||||
* @return True if the sleeping technique is enabled and false otherwise
|
||||
*/
|
||||
bool isSleepingEnabled() const;
|
||||
/// Enable/Disable the sleeping technique
|
||||
void enableSleeping(bool isSleepingEnabled);
|
||||
/// Return the current sleep linear velocity
|
||||
/**
|
||||
* @brief Enable/Disable the sleeping technique.
|
||||
* The sleeping technique is used to put bodies that are not moving int32_to sleep
|
||||
* to speed up the simulation.
|
||||
* @param[in] _isSleepingEnabled True if you want to enable the sleeping technique and false otherwise
|
||||
*/
|
||||
void enableSleeping(bool _isSleepingEnabled);
|
||||
/**
|
||||
* @brief Get the sleep linear velocity
|
||||
* @return The current sleep linear velocity (in meters per second)
|
||||
*/
|
||||
float getSleepLinearVelocity() const;
|
||||
/// Set the sleep linear velocity.
|
||||
void setSleepLinearVelocity(float sleepLinearVelocity);
|
||||
/// Return the current sleep angular velocity
|
||||
/**
|
||||
* @brief Set the sleep linear velocity
|
||||
* @param[in] _sleepLinearVelocity The new sleep linear velocity (in meters per second)
|
||||
*/
|
||||
void setSleepLinearVelocity(float _sleepLinearVelocity);
|
||||
/**
|
||||
* @brief Return the current sleep angular velocity
|
||||
* @return The sleep angular velocity (in radian per second)
|
||||
*/
|
||||
float getSleepAngularVelocity() const;
|
||||
/// Set the sleep angular velocity.
|
||||
void setSleepAngularVelocity(float sleepAngularVelocity);
|
||||
/// Return the time a body is required to stay still before sleeping
|
||||
/**
|
||||
* @brief Set the sleep angular velocity.
|
||||
* When the velocity of a body becomes smaller than the sleep linear/angular
|
||||
* velocity for a given amount of time, the body starts sleeping and does not need
|
||||
* to be simulated anymore.
|
||||
* @param[in] _sleepAngularVelocity The sleep angular velocity (in radian per second)
|
||||
*/
|
||||
void setSleepAngularVelocity(float _sleepAngularVelocity);
|
||||
/**
|
||||
* @brief Get the time a body is required to stay still before sleeping
|
||||
* @return Time a body is required to stay still before sleeping (in seconds)
|
||||
*/
|
||||
float getTimeBeforeSleep() const;
|
||||
/// Set the time a body is required to stay still before sleeping
|
||||
/**
|
||||
* @brief Set the time a body is required to stay still before sleeping
|
||||
* @param timeBeforeSleep Time a body is required to stay still before sleeping (in seconds)
|
||||
*/
|
||||
void setTimeBeforeSleep(float timeBeforeSleep);
|
||||
/// Set an event listener object to receive events callbacks.
|
||||
void setEventListener(EventListener* eventListener);
|
||||
/**
|
||||
* @brief Set an event listener object to receive events callbacks.
|
||||
* @note If you use nullptr as an argument, the events callbacks will be disabled.
|
||||
* @param[in] _eventListener Pointer to the event listener object that will receive
|
||||
* event callbacks during the simulation
|
||||
*/
|
||||
void setEventListener(EventListener* _eventListener);
|
||||
void testCollision(const ProxyShape* _shape,
|
||||
CollisionCallback* _callback) override;
|
||||
virtual void testCollision(const ProxyShape* _shape1,
|
||||
const ProxyShape* _shape2,
|
||||
CollisionCallback* _callback) override;
|
||||
const ProxyShape* _shape2,
|
||||
CollisionCallback* _callback) override;
|
||||
virtual void testCollision(const CollisionBody* _body,
|
||||
CollisionCallback* _callback) override;
|
||||
CollisionCallback* _callback) override;
|
||||
virtual void testCollision(const CollisionBody* _body1,
|
||||
const CollisionBody* _body2,
|
||||
CollisionCallback* _callback) override;
|
||||
const CollisionBody* _body2,
|
||||
CollisionCallback* _callback) override;
|
||||
/// Test and report collisions between all shapes of the world
|
||||
virtual void testCollision(CollisionCallback* _callback) override;
|
||||
/// Return the list of all contacts of the world
|
||||
/**
|
||||
* @brief Get list of all contacts.
|
||||
* @return The list of all contacts of the world
|
||||
*/
|
||||
etk::Vector<const ContactManifold*> getContactsList() const;
|
||||
friend class RigidBody;
|
||||
};
|
||||
|
@ -26,9 +26,12 @@ def get_maintainer():
|
||||
|
||||
def configure(target, my_module):
|
||||
my_module.add_src_file([
|
||||
'test/Test.cpp',
|
||||
'test/TestSuite.cpp',
|
||||
'test/main.cpp'
|
||||
'test/main.cpp',
|
||||
'test/testAABB.cpp',
|
||||
'test/testCollisionWorld.cpp',
|
||||
'test/testDynamicAABBTree.cpp',
|
||||
'test/testPointInside.cpp',
|
||||
'test/testRaycast.cpp',
|
||||
])
|
||||
my_module.add_depend([
|
||||
'ephysics',
|
||||
|
@ -1,22 +0,0 @@
|
||||
# Minimum cmake version required
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
# Project configuration
|
||||
PROJECT(TESTS)
|
||||
|
||||
# Headers
|
||||
INCLUDE_DIRECTORIES(${REACTPHYSICS3D_SOURCE_DIR}/test)
|
||||
|
||||
# Sources files of tests
|
||||
file (
|
||||
GLOB_RECURSE
|
||||
TESTS_SOURCE_FILES
|
||||
${REACTPHYSICS3D_SOURCE_DIR}/test/*
|
||||
)
|
||||
|
||||
# Create the tests executable
|
||||
ADD_EXECUTABLE(tests ${TESTS_SOURCE_FILES})
|
||||
|
||||
TARGET_LINK_LIBRARIES(tests reactphysics3d)
|
||||
|
||||
ADD_TEST(Test tests)
|
@ -1,90 +0,0 @@
|
||||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://www.ephysics.com *
|
||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include <test/Test.hpp>
|
||||
#include <typeinfo>
|
||||
#include <iomanip>
|
||||
|
||||
using namespace ephysics;
|
||||
|
||||
/// Constructor
|
||||
Test::Test(const etk::String& name, etk::Stream* stream)
|
||||
: m_name(name), mNbPassedTests(0), mNbFailedTests(0), mOutputStream(stream) {
|
||||
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
Test::~Test() {
|
||||
|
||||
}
|
||||
|
||||
// Called to test a boolean condition.
|
||||
// This method should not be called directly in your test but you should call test() instead (macro)
|
||||
void Test::applyTest(bool condition, const etk::String& testText,
|
||||
const char* filename, long lineNumber) {
|
||||
|
||||
// If the boolean condition is true
|
||||
if (condition) {
|
||||
|
||||
// The test passed, call the succeed() method
|
||||
succeed();
|
||||
}
|
||||
else { // If the boolean condition is false
|
||||
|
||||
// The test failed, call the applyFail() method
|
||||
applyFail(testText, filename, lineNumber);
|
||||
}
|
||||
}
|
||||
|
||||
// Called when a test has failed.
|
||||
// This method should not be called directly in your test buy you should call fail() instead (macro)
|
||||
void Test::applyFail(const etk::String& testText, const char* filename, long lineNumber) {
|
||||
|
||||
if (mOutputStream) {
|
||||
|
||||
// Display the failure message
|
||||
*mOutputStream << m_name << " failure : (" << testText << "), " <<
|
||||
filename << "(line " << lineNumber << ")" << std::endl;
|
||||
}
|
||||
|
||||
// Increase the number of failed tests
|
||||
mNbFailedTests++;
|
||||
}
|
||||
|
||||
/// Display the report of the unit test and return the number of failed tests
|
||||
long Test::report() const {
|
||||
|
||||
if(mOutputStream) {
|
||||
*mOutputStream << std::left << std::setw(30) << std::setfill(' ')
|
||||
<< "Test " + m_name + " :" << std::setw(10) << "Passed: "
|
||||
<< std::setw(8) << mNbPassedTests
|
||||
<< std::setw(13) << "Failed: "
|
||||
<< std::setw(8) << mNbFailedTests << std::endl;
|
||||
}
|
||||
|
||||
// Return the number of failed tests
|
||||
return mNbFailedTests;
|
||||
}
|
154
test/Test.hpp
154
test/Test.hpp
@ -1,154 +0,0 @@
|
||||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://www.ephysics.com *
|
||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef TEST_H
|
||||
#define TEST_H
|
||||
|
||||
// Libraries
|
||||
#include <etk/String.hpp>
|
||||
|
||||
/// Reactphysics3D namespace
|
||||
namespace ephysics {
|
||||
|
||||
// Macros
|
||||
#define test(condition) applyTest(condition, #condition, __FILE__, __LINE__)
|
||||
#define fail(text) applyFail(text, __FILE__, __LINE__);
|
||||
|
||||
// Class Test
|
||||
/**
|
||||
* This abstract class represents a unit test. To create a unit test, you simply
|
||||
* need to create a class that inherits from the Test class, override the run() method and
|
||||
* use the test() and fail() macros.
|
||||
*/
|
||||
class Test {
|
||||
|
||||
private :
|
||||
|
||||
// ---------- Attributes ---------- //
|
||||
|
||||
/// Name of the test
|
||||
etk::String m_name;
|
||||
|
||||
/// Number of tests that passed
|
||||
long mNbPassedTests;
|
||||
|
||||
/// Number of tests that failed
|
||||
long mNbFailedTests;
|
||||
|
||||
/// Output stream
|
||||
etk::Stream* mOutputStream;
|
||||
|
||||
// ---------- Methods ---------- //
|
||||
|
||||
/// Copy constructor is private
|
||||
Test(const Test&);
|
||||
|
||||
/// Assignment operator is private
|
||||
Test& operator=(const Test& test);
|
||||
|
||||
protected :
|
||||
|
||||
// ---------- Methods ---------- //
|
||||
|
||||
/// Called to test a boolean condition.
|
||||
/// This method should not be called directly in your test but you should
|
||||
/// call test() instead (macro)
|
||||
void applyTest(bool condition, const etk::String& testText,
|
||||
const char* filename, long lineNumber);
|
||||
|
||||
/// Called when a test has failed.
|
||||
/// This method should not be called directly in your test buy you should
|
||||
/// call fail() instead (macro)
|
||||
void applyFail(const etk::String& testText, const char* filename, long lineNumber);
|
||||
|
||||
public :
|
||||
|
||||
// ---------- Methods ---------- //
|
||||
|
||||
/// Constructor
|
||||
Test(const etk::String& name, etk::Stream* stream = &std::cout);
|
||||
|
||||
/// Destructor
|
||||
virtual ~Test();
|
||||
|
||||
/// Return the number of passed tests
|
||||
long getNbPassedTests() const;
|
||||
|
||||
/// Return the number of failed tests
|
||||
long getNbFailedTests() const;
|
||||
|
||||
/// Return the output stream
|
||||
const etk::Stream* getOutputStream() const;
|
||||
|
||||
/// Set the output stream
|
||||
void setOutputStream(etk::Stream *stream);
|
||||
|
||||
/// Run the unit test
|
||||
virtual void run() = 0;
|
||||
|
||||
/// Called when a test passed
|
||||
void succeed();
|
||||
|
||||
/// Reset the unit test
|
||||
virtual void reset();
|
||||
|
||||
/// Display the report of the unit test and return the number of failed tests
|
||||
long report() const;
|
||||
};
|
||||
|
||||
// Called when a test passed
|
||||
inline void Test::succeed() {
|
||||
mNbPassedTests++;
|
||||
}
|
||||
|
||||
// Reset the unit test
|
||||
inline void Test::reset() {
|
||||
mNbPassedTests = 0;
|
||||
mNbFailedTests = 0;
|
||||
}
|
||||
|
||||
// Return the number of passed tests
|
||||
inline long Test::getNbPassedTests() const {
|
||||
return mNbPassedTests;
|
||||
}
|
||||
|
||||
// Return the number of failed tests
|
||||
inline long Test::getNbFailedTests() const {
|
||||
return mNbFailedTests;
|
||||
}
|
||||
|
||||
// Return the output stream
|
||||
inline const etk::Stream* Test::getOutputStream() const {
|
||||
return mOutputStream;
|
||||
}
|
||||
|
||||
// Set the output stream
|
||||
inline void Test::setOutputStream(etk::Stream* stream) {
|
||||
mOutputStream = stream;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,144 +0,0 @@
|
||||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://www.ephysics.com *
|
||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Librairies
|
||||
#include <test/TestSuite.hpp>
|
||||
|
||||
using namespace ephysics;
|
||||
|
||||
// Constructor
|
||||
TestSuite::TestSuite(const etk::String& name, etk::Stream* outputStream)
|
||||
: m_name(name), mOutputStream(outputStream) {
|
||||
|
||||
}
|
||||
|
||||
// Return the number of passed tests
|
||||
long TestSuite::getNbPassedTests() const {
|
||||
|
||||
long nbPassedTests = 0;
|
||||
|
||||
for (size_t i=0; i<mTests.size(); i++) {
|
||||
assert(mTests[i]);
|
||||
nbPassedTests += mTests[i]->getNbPassedTests();
|
||||
}
|
||||
|
||||
return nbPassedTests;
|
||||
}
|
||||
|
||||
// Return the number of failed tests
|
||||
long TestSuite::getNbFailedTests() const {
|
||||
long nbFailedTests = 0;
|
||||
|
||||
for (size_t i=0; i<mTests.size(); i++) {
|
||||
assert(mTests[i]);
|
||||
nbFailedTests += mTests[i]->getNbFailedTests();
|
||||
}
|
||||
|
||||
return nbFailedTests;
|
||||
}
|
||||
|
||||
// Add a unit test in the test suite
|
||||
void TestSuite::addTest(Test* test) {
|
||||
if (test == NULL) {
|
||||
throw std::invalid_argument("Error : You cannot add a NULL test in the test suite.");
|
||||
}
|
||||
else if (mOutputStream != NULL && test->getOutputStream() == NULL) {
|
||||
test->setOutputStream(mOutputStream);
|
||||
}
|
||||
|
||||
// Add the test to the suite
|
||||
mTests.pushBack(test);
|
||||
|
||||
// Reset the added test
|
||||
test->reset();
|
||||
}
|
||||
|
||||
// Add a test suite to the current test suite
|
||||
void TestSuite::addTestSuite(const TestSuite& testSuite) {
|
||||
|
||||
// Add each test of the test suite to the current one
|
||||
for (size_t i =0; i < testSuite.mTests.size(); i++) {
|
||||
assert(testSuite.mTests[i] != NULL);
|
||||
addTest(testSuite.mTests[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Launch the tests of the test suite
|
||||
void TestSuite::run() {
|
||||
|
||||
// Reset all the tests
|
||||
reset();
|
||||
|
||||
// Run all the tests
|
||||
for (size_t i=0; i < mTests.size(); i++) {
|
||||
assert(mTests[i] != NULL);
|
||||
mTests[i]->run();
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the test suite
|
||||
void TestSuite::reset() {
|
||||
for(size_t i=0; i < mTests.size(); ++i) {
|
||||
assert(mTests[i]);
|
||||
mTests[i]->reset();
|
||||
}
|
||||
}
|
||||
|
||||
// Display the tests report and return the number of failed tests
|
||||
long TestSuite::report() const {
|
||||
if (mOutputStream != NULL) {
|
||||
long nbFailedTests = 0;
|
||||
|
||||
*mOutputStream << "Test Suite \"" << m_name << "\"\n";
|
||||
size_t i;
|
||||
for (i=0; i < 70; i++) {
|
||||
*mOutputStream << "=";
|
||||
}
|
||||
*mOutputStream << "=" << std::endl;
|
||||
for (i=0; i < mTests.size(); i++) {
|
||||
assert(mTests[i] != NULL);
|
||||
nbFailedTests += mTests[i]->report();
|
||||
}
|
||||
for (i=0; i < 70; i++) {
|
||||
*mOutputStream << "=";
|
||||
}
|
||||
*mOutputStream << "=" << std::endl;
|
||||
|
||||
// Return the number of failed tests
|
||||
return nbFailedTests;
|
||||
}
|
||||
else {
|
||||
return getNbFailedTests();
|
||||
}
|
||||
}
|
||||
|
||||
// Delete all the tests
|
||||
void TestSuite::clear() {
|
||||
|
||||
for (size_t i=0; i<mTests.size(); i++) {
|
||||
delete mTests[i];
|
||||
mTests[i] = NULL;
|
||||
}
|
||||
}
|
@ -1,125 +0,0 @@
|
||||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://www.ephysics.com *
|
||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef TEST_SUITE_H
|
||||
#define TEST_SUITE_H
|
||||
|
||||
// Libraries
|
||||
#include <test/Test.hpp>
|
||||
#include <etk/Vector.hpp>
|
||||
|
||||
/// Reactphysics3D namespace
|
||||
namespace ephysics {
|
||||
|
||||
// Class TestSuite
|
||||
/**
|
||||
* This class represents a test suite that can
|
||||
* contains multiple unit tests. You can also add a test suite inside
|
||||
* another test suite (all the tests of the first test suite will be added
|
||||
* to the second one).
|
||||
*/
|
||||
class TestSuite {
|
||||
|
||||
private :
|
||||
|
||||
// ---------- Attributes ---------- //
|
||||
|
||||
/// Name of the test suite
|
||||
etk::String m_name;
|
||||
|
||||
/// Output stream
|
||||
etk::Stream* mOutputStream;
|
||||
|
||||
/// All the tests of the test suite
|
||||
etk::Vector<Test*> mTests;
|
||||
|
||||
// ---------- Methods ---------- //
|
||||
|
||||
/// Reset the test suite
|
||||
void reset();
|
||||
|
||||
/// Private copy-constructor
|
||||
TestSuite(const TestSuite& testSuite);
|
||||
|
||||
/// Private assigmnent operator
|
||||
TestSuite& operator=(const TestSuite testSuite);
|
||||
|
||||
public :
|
||||
|
||||
// ---------- Methods ---------- //
|
||||
|
||||
/// Constructor
|
||||
TestSuite(const etk::String& name, etk::Stream* outputStream = &std::cout);
|
||||
|
||||
/// Return the name of the test suite
|
||||
etk::String getName() const;
|
||||
|
||||
/// Return the number of passed tests
|
||||
long getNbPassedTests() const;
|
||||
|
||||
/// Return the number of failed tests
|
||||
long getNbFailedTests() const;
|
||||
|
||||
/// Return the output stream
|
||||
const etk::Stream* getOutputStream() const;
|
||||
|
||||
/// Set the output stream
|
||||
void setOutputStream(etk::Stream* outputStream);
|
||||
|
||||
/// Add a unit test in the test suite
|
||||
void addTest(Test* test);
|
||||
|
||||
/// Add a test suite to the current test suite
|
||||
void addTestSuite(const TestSuite& testSuite);
|
||||
|
||||
/// Launch the tests of the test suite
|
||||
void run();
|
||||
|
||||
/// Display the tests report and return the number of failed tests
|
||||
long report() const;
|
||||
|
||||
// Delete all the tests
|
||||
void clear();
|
||||
|
||||
};
|
||||
|
||||
// Return the name of the test suite
|
||||
inline etk::String TestSuite::getName() const {
|
||||
return m_name;
|
||||
}
|
||||
|
||||
// Return the output stream
|
||||
inline const etk::Stream* TestSuite::getOutputStream() const {
|
||||
return mOutputStream;
|
||||
}
|
||||
|
||||
// Set the output stream
|
||||
inline void TestSuite::setOutputStream(etk::Stream* outputStream) {
|
||||
mOutputStream = outputStream;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,69 +1,22 @@
|
||||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://www.ephysics.com *
|
||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2017, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
|
||||
// Libraries
|
||||
#include <test/TestSuite.hpp>
|
||||
#include <test/tests/mathematics/TestMathematicsFunctions.hpp>
|
||||
#include <test/tests/collision/TestPointInside.hpp>
|
||||
#include <test/tests/collision/TestRaycast.hpp>
|
||||
#include <test/tests/collision/TestCollisionWorld.hpp>
|
||||
#include <test/tests/collision/TestAABB.hpp>
|
||||
#include <test/tests/collision/TestDynamicAABBTree.hpp>
|
||||
#include <etk/types.hpp>
|
||||
#include <test-debug/debug.hpp>
|
||||
#include <etk/Vector.hpp>
|
||||
#include <etk/String.hpp>
|
||||
#include <etk/etk.hpp>
|
||||
#include <etk/stdTools.hpp>
|
||||
#include <etk/String.hpp>
|
||||
|
||||
using namespace ephysics;
|
||||
|
||||
int32_t main() {
|
||||
#include <etest/etest.hpp>
|
||||
|
||||
TestSuite testSuite("ReactPhysics3D Tests");
|
||||
|
||||
// ---------- Mathematics tests ---------- //
|
||||
|
||||
testSuite.addTest(new Testvec2("vec2"));
|
||||
testSuite.addTest(new Testvec3("vec3"));
|
||||
testSuite.addTest(new Testetk::Transform3D("Transform"));
|
||||
testSuite.addTest(new Testetk::Quaternion("Quaternion"));
|
||||
testSuite.addTest(new Testetk::Matrix3x3("Matrix3x3"));
|
||||
testSuite.addTest(new Testetk::Matrix2x2("Matrix2x2"));
|
||||
testSuite.addTest(new TestMathematicsFunctions("Maths Functions"));
|
||||
|
||||
// ---------- Collision Detection tests ---------- //
|
||||
|
||||
testSuite.addTest(new TestAABB("AABB"));
|
||||
testSuite.addTest(new TestPointInside("IsPointInside"));
|
||||
testSuite.addTest(new TestRaycast("Raycasting"));
|
||||
testSuite.addTest(new TestCollisionWorld("CollisionWorld"));
|
||||
testSuite.addTest(new TestDynamicAABBTree("DynamicAABBTree"));
|
||||
|
||||
// Run the tests
|
||||
testSuite.run();
|
||||
|
||||
// Display the report
|
||||
long nbFailedTests = testSuite.report();
|
||||
|
||||
// Clear the tests from the test suite
|
||||
testSuite.clear();
|
||||
|
||||
return nbFailedTests;
|
||||
int main(int argc, const char *argv[]) {
|
||||
// init test engine:
|
||||
etest::init(argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
@ -1,290 +0,0 @@
|
||||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://www.ephysics.com *
|
||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef TEST_AABB_H
|
||||
#define TEST_AABB_H
|
||||
|
||||
// Libraries
|
||||
#include <ephysics/ephysics.hpp>
|
||||
|
||||
/// Reactphysics3D namespace
|
||||
namespace ephysics {
|
||||
|
||||
|
||||
// Class TestAABB
|
||||
/**
|
||||
* Unit test for the AABB class.
|
||||
*/
|
||||
class TestAABB : public Test {
|
||||
|
||||
private :
|
||||
|
||||
// ---------- Atributes ---------- //
|
||||
|
||||
AABB m_AABB1;
|
||||
AABB m_AABB2;
|
||||
AABB m_AABB3;
|
||||
AABB m_AABB4;
|
||||
|
||||
public :
|
||||
|
||||
// ---------- Methods ---------- //
|
||||
|
||||
/// Constructor
|
||||
TestAABB(const etk::String& name) : Test(name) {
|
||||
|
||||
m_AABB1.setMin(vec3(-10, -10, -10));
|
||||
m_AABB1.setMax(vec3(10, 10, 10));
|
||||
|
||||
// AABB2 int32_tersect with AABB1
|
||||
m_AABB2.setMin(vec3(-5, 4, -30));
|
||||
m_AABB2.setMax(vec3(-2, 20, 30));
|
||||
|
||||
// AABB3 contains AABB1
|
||||
m_AABB3.setMin(vec3(-25, -25, -25));
|
||||
m_AABB3.setMax(vec3(25, 25, 25));
|
||||
|
||||
// AABB4 does not collide with AABB1
|
||||
m_AABB4.setMin(vec3(-40, -40, -40));
|
||||
m_AABB4.setMax(vec3(-15, -25, -12));
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
~TestAABB() {
|
||||
|
||||
}
|
||||
|
||||
/// Run the tests
|
||||
void run() {
|
||||
testBasicMethods();
|
||||
testMergeMethods();
|
||||
testIntersection();
|
||||
}
|
||||
|
||||
void testBasicMethods() {
|
||||
|
||||
// -------- Test constructors -------- //
|
||||
AABB aabb1;
|
||||
AABB aabb2(vec3(-3, -5, -8), vec3(65, -1, 56));
|
||||
vec3 trianglePoints[] = {
|
||||
vec3(-5, 7, 23), vec3(45, -34, -73), vec3(-12, 98, 76)
|
||||
};
|
||||
AABB aabb3 = AABB::createAABBForTriangle(trianglePoints);
|
||||
|
||||
test(aabb1.getMin().x() == 0);
|
||||
test(aabb1.getMin().y() == 0);
|
||||
test(aabb1.getMin().z() == 0);
|
||||
test(aabb1.getMax().x() == 0);
|
||||
test(aabb1.getMax().y() == 0);
|
||||
test(aabb1.getMax().z() == 0);
|
||||
|
||||
test(aabb2.getMin().x() == -3);
|
||||
test(aabb2.getMin().y() == -5);
|
||||
test(aabb2.getMin().z() == -8);
|
||||
test(aabb2.getMax().x() == 65);
|
||||
test(aabb2.getMax().y() == -1);
|
||||
test(aabb2.getMax().z() == 56);
|
||||
|
||||
test(aabb3.getMin().x() == -12);
|
||||
test(aabb3.getMin().y() == -34);
|
||||
test(aabb3.getMin().z() == -73);
|
||||
test(aabb3.getMax().x() == 45);
|
||||
test(aabb3.getMax().y() == 98);
|
||||
test(aabb3.getMax().z() == 76);
|
||||
|
||||
// -------- Test inflate() -------- //
|
||||
AABB aabbInflate(vec3(-3, 4, 8), vec3(-1, 6, 32));
|
||||
aabbInflate.inflate(1, 2, 3);
|
||||
test(approxEqual(aabbInflate.getMin().x(), -4, 0.00001));
|
||||
test(approxEqual(aabbInflate.getMin().y(), 2, 0.00001));
|
||||
test(approxEqual(aabbInflate.getMin().z(), 5, 0.00001));
|
||||
test(approxEqual(aabbInflate.getMax().x(), 0, 0.00001));
|
||||
test(approxEqual(aabbInflate.getMax().y(), 8, 0.00001));
|
||||
test(approxEqual(aabbInflate.getMax().z(), 35, 0.00001));
|
||||
|
||||
// -------- Test getExtent() --------- //
|
||||
|
||||
test(approxEqual(m_AABB1.getExtent().x(), 20));
|
||||
test(approxEqual(m_AABB1.getExtent().y(), 20));
|
||||
test(approxEqual(m_AABB1.getExtent().z(), 20));
|
||||
|
||||
test(approxEqual(m_AABB2.getExtent().x(), 3));
|
||||
test(approxEqual(m_AABB2.getExtent().y(), 16));
|
||||
test(approxEqual(m_AABB2.getExtent().z(), 60));
|
||||
|
||||
test(approxEqual(m_AABB3.getExtent().x(), 50));
|
||||
test(approxEqual(m_AABB3.getExtent().y(), 50));
|
||||
test(approxEqual(m_AABB3.getExtent().z(), 50));
|
||||
|
||||
// -------- Test getCenter() -------- //
|
||||
|
||||
test(m_AABB1.getCenter().x() == 0);
|
||||
test(m_AABB1.getCenter().y() == 0);
|
||||
test(m_AABB1.getCenter().z() == 0);
|
||||
|
||||
test(approxEqual(m_AABB2.getCenter().x(), -3.5));
|
||||
test(approxEqual(m_AABB2.getCenter().y(), 12));
|
||||
test(approxEqual(m_AABB2.getCenter().z(), 0));
|
||||
|
||||
// -------- Test setMin(), setMax(), getMin(), getMax() -------- //
|
||||
|
||||
AABB aabb5;
|
||||
aabb5.setMin(vec3(-12, 34, 6));
|
||||
aabb5.setMax(vec3(-3, 56, 20));
|
||||
|
||||
test(aabb5.getMin().x() == -12);
|
||||
test(aabb5.getMin().y() == 34);
|
||||
test(aabb5.getMin().z() == 6);
|
||||
test(aabb5.getMax().x() == -3);
|
||||
test(aabb5.getMax().y() == 56);
|
||||
test(aabb5.getMax().z() == 20);
|
||||
|
||||
// -------- Test assignment operator -------- //
|
||||
|
||||
AABB aabb6;
|
||||
aabb6 = aabb2;
|
||||
|
||||
test(aabb6.getMin().x() == -3);
|
||||
test(aabb6.getMin().y() == -5);
|
||||
test(aabb6.getMin().z() == -8);
|
||||
test(aabb6.getMax().x() == 65);
|
||||
test(aabb6.getMax().y() == -1);
|
||||
test(aabb6.getMax().z() == 56);
|
||||
|
||||
// -------- Test getVolume() -------- //
|
||||
|
||||
test(approxEqual(m_AABB1.getVolume(), 8000));
|
||||
test(approxEqual(m_AABB2.getVolume(), 2880));
|
||||
}
|
||||
|
||||
void testMergeMethods() {
|
||||
|
||||
AABB aabb1(vec3(-45, 7, -2), vec3(23, 8, 1));
|
||||
AABB aabb2(vec3(-15, 6, 23), vec3(-5, 9, 45));
|
||||
|
||||
// -------- Test mergeTwoAABBs() -------- //
|
||||
|
||||
AABB aabb3;
|
||||
aabb3.mergeTwoAABBs(aabb1, m_AABB1);
|
||||
|
||||
test(aabb3.getMin().x() == -45);
|
||||
test(aabb3.getMin().y() == -10);
|
||||
test(aabb3.getMin().z() == -10);
|
||||
test(aabb3.getMax().x() == 23);
|
||||
test(aabb3.getMax().y() == 10);
|
||||
test(aabb3.getMax().z() == 10);
|
||||
|
||||
AABB aabb4;
|
||||
aabb4.mergeTwoAABBs(aabb1, aabb2);
|
||||
|
||||
test(aabb4.getMin().x() == -45);
|
||||
test(aabb4.getMin().y() == 6);
|
||||
test(aabb4.getMin().z() == -2);
|
||||
test(aabb4.getMax().x() == 23);
|
||||
test(aabb4.getMax().y() == 9);
|
||||
test(aabb4.getMax().z() == 45);
|
||||
|
||||
// -------- Test mergeWithAABB() -------- //
|
||||
|
||||
aabb1.mergeWithAABB(m_AABB1);
|
||||
|
||||
test(aabb1.getMin().x() == -45);
|
||||
test(aabb1.getMin().y() == -10);
|
||||
test(aabb1.getMin().z() == -10);
|
||||
test(aabb1.getMax().x() == 23);
|
||||
test(aabb1.getMax().y() == 10);
|
||||
test(aabb1.getMax().z() == 10);
|
||||
|
||||
aabb2.mergeWithAABB(m_AABB1);
|
||||
|
||||
test(aabb2.getMin().x() == -15);
|
||||
test(aabb2.getMin().y() == -10);
|
||||
test(aabb2.getMin().z() == -10);
|
||||
test(aabb2.getMax().x() == 10);
|
||||
test(aabb2.getMax().y() == 10);
|
||||
test(aabb2.getMax().z() == 45);
|
||||
}
|
||||
|
||||
void testIntersection() {
|
||||
|
||||
// -------- Test contains(AABB) -------- //
|
||||
test(!m_AABB1.contains(m_AABB2));
|
||||
test(m_AABB3.contains(m_AABB1));
|
||||
test(!m_AABB1.contains(m_AABB3));
|
||||
test(!m_AABB1.contains(m_AABB4));
|
||||
test(!m_AABB4.contains(m_AABB1));
|
||||
|
||||
// -------- Test contains(vec3) -------- //
|
||||
test(m_AABB1.contains(vec3(0, 0, 0)));
|
||||
test(m_AABB1.contains(vec3(-5, 6, 9)));
|
||||
test(m_AABB1.contains(vec3(-9, -4, -9)));
|
||||
test(m_AABB1.contains(vec3(9, 4, 7)));
|
||||
test(!m_AABB1.contains(vec3(-11, -4, -9)));
|
||||
test(!m_AABB1.contains(vec3(1, 12, -9)));
|
||||
test(!m_AABB1.contains(vec3(1, 8, -13)));
|
||||
test(!m_AABB1.contains(vec3(-14, 82, -13)));
|
||||
|
||||
// -------- Test testCollision() -------- //
|
||||
test(m_AABB1.testCollision(m_AABB2));
|
||||
test(m_AABB2.testCollision(m_AABB1));
|
||||
test(m_AABB1.testCollision(m_AABB3));
|
||||
test(m_AABB3.testCollision(m_AABB1));
|
||||
test(!m_AABB1.testCollision(m_AABB4));
|
||||
test(!m_AABB4.testCollision(m_AABB1));
|
||||
|
||||
// -------- Test testCollisionTriangleAABB() -------- //
|
||||
|
||||
AABB aabb(vec3(100, 100, 100), vec3(200, 200, 200));
|
||||
vec3 trianglePoints[] = {
|
||||
vec3(-2, 4, 6), vec3(20, -34, -73), vec3(-12, 98, 76)
|
||||
};
|
||||
test(m_AABB1.testCollisionTriangleAABB(trianglePoints));
|
||||
test(!aabb.testCollisionTriangleAABB(trianglePoints));
|
||||
|
||||
// -------- Test testRayIntersect() -------- //
|
||||
|
||||
Ray ray1(vec3(-20, 4, -7), vec3(20, 4, -7));
|
||||
Ray ray2(vec3(-20, 11, -7), vec3(20, 11, -7));
|
||||
Ray ray3(vec3(0, 15, 0), vec3(0, -15, 0));
|
||||
Ray ray4(vec3(0, -15, 0), vec3(0, 15, 0));
|
||||
Ray ray5(vec3(-3, 4, 8), vec3(-7, 9, 4));
|
||||
Ray ray6(vec3(-4, 6, -100), vec3(-4, 6, -9));
|
||||
Ray ray7(vec3(-4, 6, -100), vec3(-4, 6, -11), 0.6);
|
||||
Ray ray8(vec3(-403, -432, -100), vec3(134, 643, 23));
|
||||
|
||||
test(m_AABB1.testRayIntersect(ray1));
|
||||
test(!m_AABB1.testRayIntersect(ray2));
|
||||
test(m_AABB1.testRayIntersect(ray3));
|
||||
test(m_AABB1.testRayIntersect(ray4));
|
||||
test(m_AABB1.testRayIntersect(ray5));
|
||||
test(m_AABB1.testRayIntersect(ray6));
|
||||
test(!m_AABB1.testRayIntersect(ray7));
|
||||
test(!m_AABB1.testRayIntersect(ray8));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,343 +0,0 @@
|
||||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://www.ephysics.com *
|
||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef TEST_COLLISION_WORLD_H
|
||||
#define TEST_COLLISION_WORLD_H
|
||||
|
||||
// Libraries
|
||||
#include <ephysics/ephysics.hpp>
|
||||
|
||||
/// Reactphysics3D namespace
|
||||
namespace ephysics {
|
||||
|
||||
// Enumeration for categories
|
||||
enum CollisionCategory {
|
||||
CATEGORY_1 = 0x0001,
|
||||
CATEGORY_2 = 0x0002,
|
||||
CATEGORY_3 = 0x0004
|
||||
};
|
||||
|
||||
// TODO : Add test for concave shape collision here
|
||||
|
||||
// Class
|
||||
class WorldCollisionCallback : public CollisionCallback
|
||||
{
|
||||
public:
|
||||
|
||||
bool boxCollideWithSphere1;
|
||||
bool boxCollideWithCylinder;
|
||||
bool sphere1CollideWithCylinder;
|
||||
bool sphere1CollideWithSphere2;
|
||||
|
||||
CollisionBody* boxBody;
|
||||
CollisionBody* sphere1Body;
|
||||
CollisionBody* sphere2Body;
|
||||
CollisionBody* cylinderBody;
|
||||
|
||||
WorldCollisionCallback()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
boxCollideWithSphere1 = false;
|
||||
boxCollideWithCylinder = false;
|
||||
sphere1CollideWithCylinder = false;
|
||||
sphere1CollideWithSphere2 = false;
|
||||
}
|
||||
|
||||
// This method will be called for contact
|
||||
virtual void notifyContact(const ContactPointInfo& contactPointInfo) {
|
||||
|
||||
if (isContactBetweenBodies(boxBody, sphere1Body, contactPointInfo)) {
|
||||
boxCollideWithSphere1 = true;
|
||||
}
|
||||
else if (isContactBetweenBodies(boxBody, cylinderBody, contactPointInfo)) {
|
||||
boxCollideWithCylinder = true;
|
||||
}
|
||||
else if (isContactBetweenBodies(sphere1Body, cylinderBody, contactPointInfo)) {
|
||||
sphere1CollideWithCylinder = true;
|
||||
}
|
||||
else if (isContactBetweenBodies(sphere1Body, sphere2Body, contactPointInfo)) {
|
||||
sphere1CollideWithSphere2 = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool isContactBetweenBodies(const CollisionBody* body1, const CollisionBody* body2,
|
||||
const ContactPointInfo& contactPointInfo) {
|
||||
return (contactPointInfo.shape1->getBody()->getID() == body1->getID() &&
|
||||
contactPointInfo.shape2->getBody()->getID() == body2->getID()) ||
|
||||
(contactPointInfo.shape2->getBody()->getID() == body1->getID() &&
|
||||
contactPointInfo.shape1->getBody()->getID() == body2->getID());
|
||||
}
|
||||
};
|
||||
|
||||
// Class TestCollisionWorld
|
||||
/**
|
||||
* Unit test for the CollisionWorld class.
|
||||
*/
|
||||
class TestCollisionWorld : public Test {
|
||||
|
||||
private :
|
||||
|
||||
// ---------- Atributes ---------- //
|
||||
|
||||
// Physics world
|
||||
CollisionWorld* m_world;
|
||||
|
||||
// Bodies
|
||||
CollisionBody* mBoxBody;
|
||||
CollisionBody* mSphere1Body;
|
||||
CollisionBody* mSphere2Body;
|
||||
CollisionBody* mCylinderBody;
|
||||
|
||||
// Collision shapes
|
||||
BoxShape* mBoxShape;
|
||||
SphereShape* mSphereShape;
|
||||
CylinderShape* mCylinderShape;
|
||||
|
||||
// Proxy shapes
|
||||
ProxyShape* mBoxProxyShape;
|
||||
ProxyShape* mSphere1ProxyShape;
|
||||
ProxyShape* mSphere2ProxyShape;
|
||||
ProxyShape* mCylinderProxyShape;
|
||||
|
||||
// Collision callback class
|
||||
WorldCollisionCallback m_collisionCallback;
|
||||
|
||||
public :
|
||||
|
||||
// ---------- Methods ---------- //
|
||||
|
||||
/// Constructor
|
||||
TestCollisionWorld(const etk::String& name) : Test(name) {
|
||||
|
||||
// Create the world
|
||||
m_world = new CollisionWorld();
|
||||
|
||||
// Create the bodies
|
||||
etk::Transform3D boxTransform(vec3(10, 0, 0), etk::Quaternion::identity());
|
||||
mBoxBody = m_world->createCollisionBody(boxetk::Transform3D);
|
||||
mBoxShape = new BoxShape(vec3(3, 3, 3));
|
||||
mBoxProxyShape = mBoxBody->addCollisionShape(mBoxShape, etk::Transform3D::identity());
|
||||
|
||||
mSphereShape = new SphereShape(3.0);
|
||||
etk::Transform3D sphere1Transform(vec3(10,5, 0), etk::Quaternion::identity());
|
||||
mSphere1Body = m_world->createCollisionBody(sphere1etk::Transform3D);
|
||||
mSphere1ProxyShape = mSphere1Body->addCollisionShape(mSphereShape, etk::Transform3D::identity());
|
||||
|
||||
etk::Transform3D sphere2Transform(vec3(30, 10, 10), etk::Quaternion::identity());
|
||||
mSphere2Body = m_world->createCollisionBody(sphere2etk::Transform3D);
|
||||
mSphere2ProxyShape = mSphere2Body->addCollisionShape(mSphereShape, etk::Transform3D::identity());
|
||||
|
||||
etk::Transform3D cylinderTransform(vec3(10, -5, 0), etk::Quaternion::identity());
|
||||
mCylinderBody = m_world->createCollisionBody(cylinderetk::Transform3D);
|
||||
mCylinderShape = new CylinderShape(2, 5);
|
||||
mCylinderProxyShape = mCylinderBody->addCollisionShape(mCylinderShape, etk::Transform3D::identity());
|
||||
|
||||
// Assign collision categories to proxy shapes
|
||||
mBoxProxyShape->setCollisionCategoryBits(CATEGORY_1);
|
||||
mSphere1ProxyShape->setCollisionCategoryBits(CATEGORY_1);
|
||||
mSphere2ProxyShape->setCollisionCategoryBits(CATEGORY_2);
|
||||
mCylinderProxyShape->setCollisionCategoryBits(CATEGORY_3);
|
||||
|
||||
m_collisionCallback.boxBody = mBoxBody;
|
||||
m_collisionCallback.sphere1Body = mSphere1Body;
|
||||
m_collisionCallback.sphere2Body = mSphere2Body;
|
||||
m_collisionCallback.cylinderBody = mCylinderBody;
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
~TestCollisionWorld() {
|
||||
delete mBoxShape;
|
||||
delete mSphereShape;
|
||||
delete mCylinderShape;
|
||||
}
|
||||
|
||||
/// Run the tests
|
||||
void run() {
|
||||
|
||||
testCollisions();
|
||||
}
|
||||
|
||||
void testCollisions() {
|
||||
|
||||
m_collisionCallback.reset();
|
||||
m_world->testCollision(&m_collisionCallback);
|
||||
test(m_collisionCallback.boxCollideWithSphere1);
|
||||
test(m_collisionCallback.boxCollideWithCylinder);
|
||||
test(!m_collisionCallback.sphere1CollideWithCylinder);
|
||||
test(!m_collisionCallback.sphere1CollideWithSphere2);
|
||||
|
||||
test(m_world->testAABBOverlap(mBoxBody, mSphere1Body));
|
||||
test(m_world->testAABBOverlap(mBoxBody, mCylinderBody));
|
||||
test(!m_world->testAABBOverlap(mSphere1Body, mCylinderBody));
|
||||
test(!m_world->testAABBOverlap(mSphere1Body, mSphere2Body));
|
||||
|
||||
test(m_world->testAABBOverlap(mBoxProxyShape, mSphere1ProxyShape));
|
||||
test(m_world->testAABBOverlap(mBoxProxyShape, mCylinderProxyShape));
|
||||
test(!m_world->testAABBOverlap(mSphere1ProxyShape, mCylinderProxyShape));
|
||||
test(!m_world->testAABBOverlap(mSphere1ProxyShape, mSphere2ProxyShape));
|
||||
|
||||
m_collisionCallback.reset();
|
||||
m_world->testCollision(mCylinderBody, &m_collisionCallback);
|
||||
test(!m_collisionCallback.boxCollideWithSphere1);
|
||||
test(m_collisionCallback.boxCollideWithCylinder);
|
||||
test(!m_collisionCallback.sphere1CollideWithCylinder);
|
||||
test(!m_collisionCallback.sphere1CollideWithSphere2);
|
||||
|
||||
m_collisionCallback.reset();
|
||||
m_world->testCollision(mBoxBody, mSphere1Body, &m_collisionCallback);
|
||||
test(m_collisionCallback.boxCollideWithSphere1);
|
||||
test(!m_collisionCallback.boxCollideWithCylinder);
|
||||
test(!m_collisionCallback.sphere1CollideWithCylinder);
|
||||
test(!m_collisionCallback.sphere1CollideWithSphere2);
|
||||
|
||||
m_collisionCallback.reset();
|
||||
m_world->testCollision(mBoxBody, mCylinderBody, &m_collisionCallback);
|
||||
test(!m_collisionCallback.boxCollideWithSphere1);
|
||||
test(m_collisionCallback.boxCollideWithCylinder);
|
||||
test(!m_collisionCallback.sphere1CollideWithCylinder);
|
||||
test(!m_collisionCallback.sphere1CollideWithSphere2);
|
||||
|
||||
m_collisionCallback.reset();
|
||||
m_world->testCollision(mCylinderProxyShape, &m_collisionCallback);
|
||||
test(!m_collisionCallback.boxCollideWithSphere1);
|
||||
test(m_collisionCallback.boxCollideWithCylinder);
|
||||
test(!m_collisionCallback.sphere1CollideWithCylinder);
|
||||
test(!m_collisionCallback.sphere1CollideWithSphere2);
|
||||
|
||||
m_collisionCallback.reset();
|
||||
m_world->testCollision(mBoxProxyShape, mCylinderProxyShape, &m_collisionCallback);
|
||||
test(!m_collisionCallback.boxCollideWithSphere1);
|
||||
test(m_collisionCallback.boxCollideWithCylinder);
|
||||
test(!m_collisionCallback.sphere1CollideWithCylinder);
|
||||
test(!m_collisionCallback.sphere1CollideWithSphere2);
|
||||
|
||||
// Move sphere 1 to collide with sphere 2
|
||||
mSphere1Body->setTransform(Transform(vec3(30, 15, 10), etk::Quaternion::identity()));
|
||||
|
||||
m_collisionCallback.reset();
|
||||
m_world->testCollision(&m_collisionCallback);
|
||||
test(!m_collisionCallback.boxCollideWithSphere1);
|
||||
test(m_collisionCallback.boxCollideWithCylinder);
|
||||
test(!m_collisionCallback.sphere1CollideWithCylinder);
|
||||
test(m_collisionCallback.sphere1CollideWithSphere2);
|
||||
|
||||
m_collisionCallback.reset();
|
||||
m_world->testCollision(mBoxBody, mSphere1Body, &m_collisionCallback);
|
||||
test(!m_collisionCallback.boxCollideWithSphere1);
|
||||
test(!m_collisionCallback.boxCollideWithCylinder);
|
||||
test(!m_collisionCallback.sphere1CollideWithCylinder);
|
||||
test(!m_collisionCallback.sphere1CollideWithSphere2);
|
||||
|
||||
m_collisionCallback.reset();
|
||||
m_world->testCollision(mBoxBody, mCylinderBody, &m_collisionCallback);
|
||||
test(!m_collisionCallback.boxCollideWithSphere1);
|
||||
test(m_collisionCallback.boxCollideWithCylinder);
|
||||
test(!m_collisionCallback.sphere1CollideWithCylinder);
|
||||
test(!m_collisionCallback.sphere1CollideWithSphere2);
|
||||
|
||||
// Move sphere 1 to collide with box
|
||||
mSphere1Body->setTransform(Transform(vec3(10, 5, 0), etk::Quaternion::identity()));
|
||||
|
||||
// --------- Test collision with inactive bodies --------- //
|
||||
|
||||
m_collisionCallback.reset();
|
||||
mBoxBody->setIsActive(false);
|
||||
mCylinderBody->setIsActive(false);
|
||||
mSphere1Body->setIsActive(false);
|
||||
mSphere2Body->setIsActive(false);
|
||||
m_world->testCollision(&m_collisionCallback);
|
||||
test(!m_collisionCallback.boxCollideWithSphere1);
|
||||
test(!m_collisionCallback.boxCollideWithCylinder);
|
||||
test(!m_collisionCallback.sphere1CollideWithCylinder);
|
||||
test(!m_collisionCallback.sphere1CollideWithSphere2);
|
||||
|
||||
test(!m_world->testAABBOverlap(mBoxBody, mSphere1Body));
|
||||
test(!m_world->testAABBOverlap(mBoxBody, mCylinderBody));
|
||||
test(!m_world->testAABBOverlap(mSphere1Body, mCylinderBody));
|
||||
test(!m_world->testAABBOverlap(mSphere1Body, mSphere2Body));
|
||||
|
||||
test(!m_world->testAABBOverlap(mBoxProxyShape, mSphere1ProxyShape));
|
||||
test(!m_world->testAABBOverlap(mBoxProxyShape, mCylinderProxyShape));
|
||||
test(!m_world->testAABBOverlap(mSphere1ProxyShape, mCylinderProxyShape));
|
||||
test(!m_world->testAABBOverlap(mSphere1ProxyShape, mSphere2ProxyShape));
|
||||
|
||||
mBoxBody->setIsActive(true);
|
||||
mCylinderBody->setIsActive(true);
|
||||
mSphere1Body->setIsActive(true);
|
||||
mSphere2Body->setIsActive(true);
|
||||
|
||||
// --------- Test collision with collision filtering -------- //
|
||||
|
||||
mBoxProxyShape->setCollideWithMaskBits(CATEGORY_1 | CATEGORY_3);
|
||||
mSphere1ProxyShape->setCollideWithMaskBits(CATEGORY_1 | CATEGORY_2);
|
||||
mSphere2ProxyShape->setCollideWithMaskBits(CATEGORY_1);
|
||||
mCylinderProxyShape->setCollideWithMaskBits(CATEGORY_1);
|
||||
|
||||
m_collisionCallback.reset();
|
||||
m_world->testCollision(&m_collisionCallback);
|
||||
test(m_collisionCallback.boxCollideWithSphere1);
|
||||
test(m_collisionCallback.boxCollideWithCylinder);
|
||||
test(!m_collisionCallback.sphere1CollideWithCylinder);
|
||||
test(!m_collisionCallback.sphere1CollideWithSphere2);
|
||||
|
||||
// Move sphere 1 to collide with sphere 2
|
||||
mSphere1Body->setTransform(Transform(vec3(30, 15, 10), etk::Quaternion::identity()));
|
||||
|
||||
m_collisionCallback.reset();
|
||||
m_world->testCollision(&m_collisionCallback);
|
||||
test(!m_collisionCallback.boxCollideWithSphere1);
|
||||
test(m_collisionCallback.boxCollideWithCylinder);
|
||||
test(!m_collisionCallback.sphere1CollideWithCylinder);
|
||||
test(m_collisionCallback.sphere1CollideWithSphere2);
|
||||
|
||||
mBoxProxyShape->setCollideWithMaskBits(CATEGORY_2);
|
||||
mSphere1ProxyShape->setCollideWithMaskBits(CATEGORY_2);
|
||||
mSphere2ProxyShape->setCollideWithMaskBits(CATEGORY_3);
|
||||
mCylinderProxyShape->setCollideWithMaskBits(CATEGORY_1);
|
||||
|
||||
m_collisionCallback.reset();
|
||||
m_world->testCollision(&m_collisionCallback);
|
||||
test(!m_collisionCallback.boxCollideWithSphere1);
|
||||
test(!m_collisionCallback.boxCollideWithCylinder);
|
||||
test(!m_collisionCallback.sphere1CollideWithCylinder);
|
||||
test(!m_collisionCallback.sphere1CollideWithSphere2);
|
||||
|
||||
// Move sphere 1 to collide with box
|
||||
mSphere1Body->setTransform(Transform(vec3(10, 5, 0), etk::Quaternion::identity()));
|
||||
|
||||
mBoxProxyShape->setCollideWithMaskBits(0xFFFF);
|
||||
mSphere1ProxyShape->setCollideWithMaskBits(0xFFFF);
|
||||
mSphere2ProxyShape->setCollideWithMaskBits(0xFFFF);
|
||||
mCylinderProxyShape->setCollideWithMaskBits(0xFFFF);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,523 +0,0 @@
|
||||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://www.ephysics.com *
|
||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef TEST_DYNAMIC_AABB_TREE_H
|
||||
#define TEST_DYNAMIC_AABB_TREE_H
|
||||
|
||||
// Libraries
|
||||
#include <test/Test.hpp>
|
||||
#include <ephysics/collision/broadphase/DynamicAABBTree.hpp>
|
||||
#include <etk/Vector.hpp>
|
||||
|
||||
/// Reactphysics3D namespace
|
||||
namespace ephysics {
|
||||
|
||||
class OverlapCallback : public DynamicAABBTreeOverlapCallback {
|
||||
|
||||
public :
|
||||
|
||||
etk::Vector<int32_t> mOverlapNodes;
|
||||
|
||||
// Called when a overlapping node has been found during the call to
|
||||
// DynamicAABBTree:reportAllShapesOverlappingWithAABB()
|
||||
virtual void notifyOverlappingNode(int32_t nodeId) {
|
||||
mOverlapNodes.pushBack(nodeId);
|
||||
}
|
||||
|
||||
void reset() {
|
||||
mOverlapNodes.clear();
|
||||
}
|
||||
|
||||
bool isOverlapping(int32_t nodeId) const {
|
||||
return std::find(mOverlapNodes.begin(), mOverlapNodes.end(), nodeId) != mOverlapNodes.end();
|
||||
}
|
||||
};
|
||||
|
||||
class DynamicTreeRaycastCallback : public DynamicAABBTreeRaycastCallback {
|
||||
|
||||
public:
|
||||
|
||||
etk::Vector<int32_t> mHitNodes;
|
||||
|
||||
// Called when the AABB of a leaf node is hit by a ray
|
||||
virtual float raycastBroadPhaseShape(int32_t nodeId, const Ray& ray) {
|
||||
mHitNodes.pushBack(nodeId);
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
mHitNodes.clear();
|
||||
}
|
||||
|
||||
bool isHit(int32_t nodeId) const {
|
||||
return std::find(mHitNodes.begin(), mHitNodes.end(), nodeId) != mHitNodes.end();
|
||||
}
|
||||
};
|
||||
|
||||
// Class TestDynamicAABBTree
|
||||
/**
|
||||
* Unit test for the dynamic AABB tree
|
||||
*/
|
||||
class TestDynamicAABBTree : public Test {
|
||||
|
||||
private :
|
||||
|
||||
// ---------- Atributes ---------- //
|
||||
|
||||
OverlapCallback mOverlapCallback;
|
||||
DynamicTreeRaycastCallback m_raycastCallback;
|
||||
|
||||
|
||||
|
||||
public :
|
||||
|
||||
// ---------- Methods ---------- //
|
||||
|
||||
/// Constructor
|
||||
TestDynamicAABBTree(const etk::String& name): Test(name) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// Run the tests
|
||||
void run() {
|
||||
|
||||
testBasicsMethods();
|
||||
testOverlapping();
|
||||
testRaycast();
|
||||
|
||||
}
|
||||
|
||||
void testBasicsMethods() {
|
||||
|
||||
// ------------ Create tree ---------- //
|
||||
|
||||
// Dynamic AABB Tree
|
||||
DynamicAABBTree tree;
|
||||
|
||||
int32_t object1Data = 56;
|
||||
int32_t object2Data = 23;
|
||||
int32_t object3Data = 13;
|
||||
int32_t object4Data = 7;
|
||||
|
||||
// First object
|
||||
AABB aabb1 = AABB(vec3(-6, 4, -3), vec3(4, 8, 3));
|
||||
int32_t object1Id = tree.addObject(aabb1, &object1Data);
|
||||
|
||||
// Second object
|
||||
AABB aabb2 = AABB(vec3(5, 2, -3), vec3(10, 7, 3));
|
||||
int32_t object2Id = tree.addObject(aabb2, &object2Data);
|
||||
|
||||
// Third object
|
||||
AABB aabb3 = AABB(vec3(-5, 1, -3), vec3(-2, 3, 3));
|
||||
int32_t object3Id = tree.addObject(aabb3, &object3Data);
|
||||
|
||||
// Fourth object
|
||||
AABB aabb4 = AABB(vec3(0, -4, -3), vec3(3, -2, 3));
|
||||
int32_t object4Id = tree.addObject(aabb4, &object4Data);
|
||||
|
||||
// ----------- Tests ----------- //
|
||||
|
||||
// Test root AABB
|
||||
AABB rootAABB = tree.getRootAABB();
|
||||
test(rootAABB.getMin().x() == -6);
|
||||
test(rootAABB.getMin().y() == -4);
|
||||
test(rootAABB.getMin().z() == -3);
|
||||
test(rootAABB.getMax().x() == 10);
|
||||
test(rootAABB.getMax().y() == 8);
|
||||
test(rootAABB.getMax().z() == 3);
|
||||
|
||||
// Test data stored at the nodes of the tree
|
||||
test(*(int32_t*)(tree.getNodeDataPointer(object1Id)) == object1Data);
|
||||
test(*(int32_t*)(tree.getNodeDataPointer(object2Id)) == object2Data);
|
||||
test(*(int32_t*)(tree.getNodeDataPointer(object3Id)) == object3Data);
|
||||
test(*(int32_t*)(tree.getNodeDataPointer(object4Id)) == object4Data);
|
||||
}
|
||||
|
||||
void testOverlapping() {
|
||||
|
||||
// ------------- Create tree ----------- //
|
||||
|
||||
// Dynamic AABB Tree
|
||||
DynamicAABBTree tree;
|
||||
|
||||
int32_t object1Data = 56;
|
||||
int32_t object2Data = 23;
|
||||
int32_t object3Data = 13;
|
||||
int32_t object4Data = 7;
|
||||
|
||||
// First object
|
||||
AABB aabb1 = AABB(vec3(-6, 4, -3), vec3(4, 8, 3));
|
||||
int32_t object1Id = tree.addObject(aabb1, &object1Data);
|
||||
|
||||
// Second object
|
||||
AABB aabb2 = AABB(vec3(5, 2, -3), vec3(10, 7, 3));
|
||||
int32_t object2Id = tree.addObject(aabb2, &object2Data);
|
||||
|
||||
// Third object
|
||||
AABB aabb3 = AABB(vec3(-5, 1, -3), vec3(-2, 3, 3));
|
||||
int32_t object3Id = tree.addObject(aabb3, &object3Data);
|
||||
|
||||
// Fourth object
|
||||
AABB aabb4 = AABB(vec3(0, -4, -3), vec3(3, -2, 3));
|
||||
int32_t object4Id = tree.addObject(aabb4, &object4Data);
|
||||
|
||||
// ---------- Tests ---------- //
|
||||
|
||||
// AABB overlapping nothing
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(vec3(-10, 12, -4), vec3(10, 50, 4)), mOverlapCallback);
|
||||
test(!mOverlapCallback.isOverlapping(object1Id));
|
||||
test(!mOverlapCallback.isOverlapping(object2Id));
|
||||
test(!mOverlapCallback.isOverlapping(object3Id));
|
||||
test(!mOverlapCallback.isOverlapping(object4Id));
|
||||
|
||||
// AABB overlapping everything
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(vec3(-15, -15, -4), vec3(15, 15, 4)), mOverlapCallback);
|
||||
test(mOverlapCallback.isOverlapping(object1Id));
|
||||
test(mOverlapCallback.isOverlapping(object2Id));
|
||||
test(mOverlapCallback.isOverlapping(object3Id));
|
||||
test(mOverlapCallback.isOverlapping(object4Id));
|
||||
|
||||
// AABB overlapping object 1 and 3
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(vec3(-4, 2, -4), vec3(-1, 7, 4)), mOverlapCallback);
|
||||
test(mOverlapCallback.isOverlapping(object1Id));
|
||||
test(!mOverlapCallback.isOverlapping(object2Id));
|
||||
test(mOverlapCallback.isOverlapping(object3Id));
|
||||
test(!mOverlapCallback.isOverlapping(object4Id));
|
||||
|
||||
// AABB overlapping object 3 and 4
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(vec3(-6, -5, -2), vec3(2, 2, 0)), mOverlapCallback);
|
||||
test(!mOverlapCallback.isOverlapping(object1Id));
|
||||
test(!mOverlapCallback.isOverlapping(object2Id));
|
||||
test(mOverlapCallback.isOverlapping(object3Id));
|
||||
test(mOverlapCallback.isOverlapping(object4Id));
|
||||
|
||||
// AABB overlapping object 2
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(vec3(5, -10, -2), vec3(7, 10, 9)), mOverlapCallback);
|
||||
test(!mOverlapCallback.isOverlapping(object1Id));
|
||||
test(mOverlapCallback.isOverlapping(object2Id));
|
||||
test(!mOverlapCallback.isOverlapping(object3Id));
|
||||
test(!mOverlapCallback.isOverlapping(object4Id));
|
||||
|
||||
// ---- Update the object AABBs with the initial AABBs (no reinsertion) ----- //
|
||||
|
||||
tree.updateObject(object1Id, aabb1, vec3(0.0f,0.0f,0.0f)(), false);
|
||||
tree.updateObject(object2Id, aabb2, vec3(0.0f,0.0f,0.0f)(), false);
|
||||
tree.updateObject(object3Id, aabb3, vec3(0.0f,0.0f,0.0f)(), false);
|
||||
tree.updateObject(object4Id, aabb4, vec3(0.0f,0.0f,0.0f)(), false);
|
||||
|
||||
// AABB overlapping nothing
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(vec3(-10, 12, -4), vec3(10, 50, 4)), mOverlapCallback);
|
||||
test(!mOverlapCallback.isOverlapping(object1Id));
|
||||
test(!mOverlapCallback.isOverlapping(object2Id));
|
||||
test(!mOverlapCallback.isOverlapping(object3Id));
|
||||
test(!mOverlapCallback.isOverlapping(object4Id));
|
||||
|
||||
// AABB overlapping everything
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(vec3(-15, -15, -4), vec3(15, 15, 4)), mOverlapCallback);
|
||||
test(mOverlapCallback.isOverlapping(object1Id));
|
||||
test(mOverlapCallback.isOverlapping(object2Id));
|
||||
test(mOverlapCallback.isOverlapping(object3Id));
|
||||
test(mOverlapCallback.isOverlapping(object4Id));
|
||||
|
||||
// AABB overlapping object 1 and 3
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(vec3(-4, 2, -4), vec3(-1, 7, 4)), mOverlapCallback);
|
||||
test(mOverlapCallback.isOverlapping(object1Id));
|
||||
test(!mOverlapCallback.isOverlapping(object2Id));
|
||||
test(mOverlapCallback.isOverlapping(object3Id));
|
||||
test(!mOverlapCallback.isOverlapping(object4Id));
|
||||
|
||||
// AABB overlapping object 3 and 4
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(vec3(-6, -5, -2), vec3(2, 2, 0)), mOverlapCallback);
|
||||
test(!mOverlapCallback.isOverlapping(object1Id));
|
||||
test(!mOverlapCallback.isOverlapping(object2Id));
|
||||
test(mOverlapCallback.isOverlapping(object3Id));
|
||||
test(mOverlapCallback.isOverlapping(object4Id));
|
||||
|
||||
// AABB overlapping object 2
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(vec3(5, -10, -2), vec3(7, 10, 9)), mOverlapCallback);
|
||||
test(!mOverlapCallback.isOverlapping(object1Id));
|
||||
test(mOverlapCallback.isOverlapping(object2Id));
|
||||
test(!mOverlapCallback.isOverlapping(object3Id));
|
||||
test(!mOverlapCallback.isOverlapping(object4Id));
|
||||
|
||||
// ---- Update the object AABBs with the initial AABBs (with reinsertion) ----- //
|
||||
|
||||
tree.updateObject(object1Id, aabb1, vec3(0.0f,0.0f,0.0f)(), true);
|
||||
tree.updateObject(object2Id, aabb2, vec3(0.0f,0.0f,0.0f)(), true);
|
||||
tree.updateObject(object3Id, aabb3, vec3(0.0f,0.0f,0.0f)(), true);
|
||||
tree.updateObject(object4Id, aabb4, vec3(0.0f,0.0f,0.0f)(), true);
|
||||
|
||||
// AABB overlapping nothing
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(vec3(-10, 12, -4), vec3(10, 50, 4)), mOverlapCallback);
|
||||
test(!mOverlapCallback.isOverlapping(object1Id));
|
||||
test(!mOverlapCallback.isOverlapping(object2Id));
|
||||
test(!mOverlapCallback.isOverlapping(object3Id));
|
||||
test(!mOverlapCallback.isOverlapping(object4Id));
|
||||
|
||||
// AABB overlapping everything
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(vec3(-15, -15, -4), vec3(15, 15, 4)), mOverlapCallback);
|
||||
test(mOverlapCallback.isOverlapping(object1Id));
|
||||
test(mOverlapCallback.isOverlapping(object2Id));
|
||||
test(mOverlapCallback.isOverlapping(object3Id));
|
||||
test(mOverlapCallback.isOverlapping(object4Id));
|
||||
|
||||
// AABB overlapping object 1 and 3
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(vec3(-4, 2, -4), vec3(-1, 7, 4)), mOverlapCallback);
|
||||
test(mOverlapCallback.isOverlapping(object1Id));
|
||||
test(!mOverlapCallback.isOverlapping(object2Id));
|
||||
test(mOverlapCallback.isOverlapping(object3Id));
|
||||
test(!mOverlapCallback.isOverlapping(object4Id));
|
||||
|
||||
// AABB overlapping object 3 and 4
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(vec3(-6, -5, -2), vec3(2, 2, 0)), mOverlapCallback);
|
||||
test(!mOverlapCallback.isOverlapping(object1Id));
|
||||
test(!mOverlapCallback.isOverlapping(object2Id));
|
||||
test(mOverlapCallback.isOverlapping(object3Id));
|
||||
test(mOverlapCallback.isOverlapping(object4Id));
|
||||
|
||||
// AABB overlapping object 2
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(vec3(5, -10, -2), vec3(7, 10, 9)), mOverlapCallback);
|
||||
test(!mOverlapCallback.isOverlapping(object1Id));
|
||||
test(mOverlapCallback.isOverlapping(object2Id));
|
||||
test(!mOverlapCallback.isOverlapping(object3Id));
|
||||
test(!mOverlapCallback.isOverlapping(object4Id));
|
||||
|
||||
// ---- Move objects 2 and 3 ----- //
|
||||
|
||||
AABB newAABB2(vec3(-7, 10, -3), vec3(1, 13, 3));
|
||||
tree.updateObject(object2Id, newAABB2, vec3(0.0f,0.0f,0.0f)());
|
||||
|
||||
AABB newAABB3(vec3(7, -6, -3), vec3(9, 1, 3));
|
||||
tree.updateObject(object3Id, newAABB3, vec3(0.0f,0.0f,0.0f)());
|
||||
|
||||
// AABB overlapping object 3
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(vec3(6, -10, -2), vec3(8, 5, 3)), mOverlapCallback);
|
||||
test(!mOverlapCallback.isOverlapping(object1Id));
|
||||
test(!mOverlapCallback.isOverlapping(object2Id));
|
||||
test(mOverlapCallback.isOverlapping(object3Id));
|
||||
test(!mOverlapCallback.isOverlapping(object4Id));
|
||||
|
||||
// AABB overlapping objects 1, 2
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(vec3(-8, 5, -3), vec3(-2, 11, 3)), mOverlapCallback);
|
||||
test(mOverlapCallback.isOverlapping(object1Id));
|
||||
test(mOverlapCallback.isOverlapping(object2Id));
|
||||
test(!mOverlapCallback.isOverlapping(object3Id));
|
||||
test(!mOverlapCallback.isOverlapping(object4Id));
|
||||
|
||||
}
|
||||
|
||||
void testRaycast() {
|
||||
|
||||
// ------------- Create tree ----------- //
|
||||
|
||||
// Dynamic AABB Tree
|
||||
DynamicAABBTree tree;
|
||||
|
||||
int32_t object1Data = 56;
|
||||
int32_t object2Data = 23;
|
||||
int32_t object3Data = 13;
|
||||
int32_t object4Data = 7;
|
||||
|
||||
// First object
|
||||
AABB aabb1 = AABB(vec3(-6, 4, -3), vec3(4, 8, 3));
|
||||
int32_t object1Id = tree.addObject(aabb1, &object1Data);
|
||||
|
||||
// Second object
|
||||
AABB aabb2 = AABB(vec3(5, 2, -3), vec3(10, 7, 3));
|
||||
int32_t object2Id = tree.addObject(aabb2, &object2Data);
|
||||
|
||||
// Third object
|
||||
AABB aabb3 = AABB(vec3(-5, 1, -3), vec3(-2, 3, 3));
|
||||
int32_t object3Id = tree.addObject(aabb3, &object3Data);
|
||||
|
||||
// Fourth object
|
||||
AABB aabb4 = AABB(vec3(0, -4, -3), vec3(3, -2, 3));
|
||||
int32_t object4Id = tree.addObject(aabb4, &object4Data);
|
||||
|
||||
// ---------- Tests ---------- //
|
||||
|
||||
// Ray with no hits
|
||||
m_raycastCallback.reset();
|
||||
Ray ray1(vec3(4.5, -10, -5), vec3(4.5, 10, -5));
|
||||
tree.raycast(ray1, m_raycastCallback);
|
||||
test(!m_raycastCallback.isHit(object1Id));
|
||||
test(!m_raycastCallback.isHit(object2Id));
|
||||
test(!m_raycastCallback.isHit(object3Id));
|
||||
test(!m_raycastCallback.isHit(object4Id));
|
||||
|
||||
// Ray that hits object 1
|
||||
m_raycastCallback.reset();
|
||||
Ray ray2(vec3(-1, -20, -2), vec3(-1, 20, -2));
|
||||
tree.raycast(ray2, m_raycastCallback);
|
||||
test(m_raycastCallback.isHit(object1Id));
|
||||
test(!m_raycastCallback.isHit(object2Id));
|
||||
test(!m_raycastCallback.isHit(object3Id));
|
||||
test(!m_raycastCallback.isHit(object4Id));
|
||||
|
||||
// Ray that hits object 1 and 2
|
||||
m_raycastCallback.reset();
|
||||
Ray ray3(vec3(-7, 6, -2), vec3(8, 6, -2));
|
||||
tree.raycast(ray3, m_raycastCallback);
|
||||
test(m_raycastCallback.isHit(object1Id));
|
||||
test(m_raycastCallback.isHit(object2Id));
|
||||
test(!m_raycastCallback.isHit(object3Id));
|
||||
test(!m_raycastCallback.isHit(object4Id));
|
||||
|
||||
// Ray that hits object 3
|
||||
m_raycastCallback.reset();
|
||||
Ray ray4(vec3(-7, 2, 0), vec3(-1, 2, 0));
|
||||
tree.raycast(ray4, m_raycastCallback);
|
||||
test(!m_raycastCallback.isHit(object1Id));
|
||||
test(!m_raycastCallback.isHit(object2Id));
|
||||
test(m_raycastCallback.isHit(object3Id));
|
||||
test(!m_raycastCallback.isHit(object4Id));
|
||||
|
||||
// ---- Update the object AABBs with the initial AABBs (no reinsertion) ----- //
|
||||
|
||||
tree.updateObject(object1Id, aabb1, vec3(0.0f,0.0f,0.0f)(), false);
|
||||
tree.updateObject(object2Id, aabb2, vec3(0.0f,0.0f,0.0f)(), false);
|
||||
tree.updateObject(object3Id, aabb3, vec3(0.0f,0.0f,0.0f)(), false);
|
||||
tree.updateObject(object4Id, aabb4, vec3(0.0f,0.0f,0.0f)(), false);
|
||||
|
||||
// Ray with no hits
|
||||
m_raycastCallback.reset();
|
||||
tree.raycast(ray1, m_raycastCallback);
|
||||
test(!m_raycastCallback.isHit(object1Id));
|
||||
test(!m_raycastCallback.isHit(object2Id));
|
||||
test(!m_raycastCallback.isHit(object3Id));
|
||||
test(!m_raycastCallback.isHit(object4Id));
|
||||
|
||||
// Ray that hits object 1
|
||||
m_raycastCallback.reset();
|
||||
tree.raycast(ray2, m_raycastCallback);
|
||||
test(m_raycastCallback.isHit(object1Id));
|
||||
test(!m_raycastCallback.isHit(object2Id));
|
||||
test(!m_raycastCallback.isHit(object3Id));
|
||||
test(!m_raycastCallback.isHit(object4Id));
|
||||
|
||||
// Ray that hits object 1 and 2
|
||||
m_raycastCallback.reset();
|
||||
tree.raycast(ray3, m_raycastCallback);
|
||||
test(m_raycastCallback.isHit(object1Id));
|
||||
test(m_raycastCallback.isHit(object2Id));
|
||||
test(!m_raycastCallback.isHit(object3Id));
|
||||
test(!m_raycastCallback.isHit(object4Id));
|
||||
|
||||
// Ray that hits object 3
|
||||
m_raycastCallback.reset();
|
||||
tree.raycast(ray4, m_raycastCallback);
|
||||
test(!m_raycastCallback.isHit(object1Id));
|
||||
test(!m_raycastCallback.isHit(object2Id));
|
||||
test(m_raycastCallback.isHit(object3Id));
|
||||
test(!m_raycastCallback.isHit(object4Id));
|
||||
|
||||
// ---- Update the object AABBs with the initial AABBs (with reinsertion) ----- //
|
||||
|
||||
tree.updateObject(object1Id, aabb1, vec3(0.0f,0.0f,0.0f)(), true);
|
||||
tree.updateObject(object2Id, aabb2, vec3(0.0f,0.0f,0.0f)(), true);
|
||||
tree.updateObject(object3Id, aabb3, vec3(0.0f,0.0f,0.0f)(), true);
|
||||
tree.updateObject(object4Id, aabb4, vec3(0.0f,0.0f,0.0f)(), true);
|
||||
|
||||
// Ray with no hits
|
||||
m_raycastCallback.reset();
|
||||
tree.raycast(ray1, m_raycastCallback);
|
||||
test(!m_raycastCallback.isHit(object1Id));
|
||||
test(!m_raycastCallback.isHit(object2Id));
|
||||
test(!m_raycastCallback.isHit(object3Id));
|
||||
test(!m_raycastCallback.isHit(object4Id));
|
||||
|
||||
// Ray that hits object 1
|
||||
m_raycastCallback.reset();
|
||||
tree.raycast(ray2, m_raycastCallback);
|
||||
test(m_raycastCallback.isHit(object1Id));
|
||||
test(!m_raycastCallback.isHit(object2Id));
|
||||
test(!m_raycastCallback.isHit(object3Id));
|
||||
test(!m_raycastCallback.isHit(object4Id));
|
||||
|
||||
// Ray that hits object 1 and 2
|
||||
m_raycastCallback.reset();
|
||||
tree.raycast(ray3, m_raycastCallback);
|
||||
test(m_raycastCallback.isHit(object1Id));
|
||||
test(m_raycastCallback.isHit(object2Id));
|
||||
test(!m_raycastCallback.isHit(object3Id));
|
||||
test(!m_raycastCallback.isHit(object4Id));
|
||||
|
||||
// Ray that hits object 3
|
||||
m_raycastCallback.reset();
|
||||
tree.raycast(ray4, m_raycastCallback);
|
||||
test(!m_raycastCallback.isHit(object1Id));
|
||||
test(!m_raycastCallback.isHit(object2Id));
|
||||
test(m_raycastCallback.isHit(object3Id));
|
||||
test(!m_raycastCallback.isHit(object4Id));
|
||||
|
||||
// ---- Move objects 2 and 3 ----- //
|
||||
|
||||
AABB newAABB2(vec3(-7, 10, -3), vec3(1, 13, 3));
|
||||
tree.updateObject(object2Id, newAABB2, vec3(0.0f,0.0f,0.0f)());
|
||||
|
||||
AABB newAABB3(vec3(7, -6, -3), vec3(9, 1, 3));
|
||||
tree.updateObject(object3Id, newAABB3, vec3(0.0f,0.0f,0.0f)());
|
||||
|
||||
// Ray that hits object 1, 2
|
||||
Ray ray5(vec3(-4, -5, 0), vec3(-4, 12, 0));
|
||||
m_raycastCallback.reset();
|
||||
tree.raycast(ray5, m_raycastCallback);
|
||||
test(m_raycastCallback.isHit(object1Id));
|
||||
test(m_raycastCallback.isHit(object2Id));
|
||||
test(!m_raycastCallback.isHit(object3Id));
|
||||
test(!m_raycastCallback.isHit(object4Id));
|
||||
|
||||
// Ray that hits object 3 and 4
|
||||
Ray ray6(vec3(11, -3, 1), vec3(-2, -3, 1));
|
||||
m_raycastCallback.reset();
|
||||
tree.raycast(ray6, m_raycastCallback);
|
||||
test(!m_raycastCallback.isHit(object1Id));
|
||||
test(!m_raycastCallback.isHit(object2Id));
|
||||
test(m_raycastCallback.isHit(object3Id));
|
||||
test(m_raycastCallback.isHit(object4Id));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,765 +0,0 @@
|
||||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://www.ephysics.com *
|
||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef TEST_POINT_INSIDE_H
|
||||
#define TEST_POINT_INSIDE_H
|
||||
|
||||
// Libraries
|
||||
#include <test/Test.hpp>
|
||||
#include <ephysics/collision/shapes/BoxShape.hpp>
|
||||
#include <ephysics/collision/shapes/SphereShape.hpp>
|
||||
#include <ephysics/collision/shapes/CapsuleShape.hpp>
|
||||
#include <ephysics/collision/shapes/ConeShape.hpp>
|
||||
#include <ephysics/collision/shapes/ConvexMeshShape.hpp>
|
||||
#include <ephysics/collision/shapes/CylinderShape.hpp>
|
||||
|
||||
/// Reactphysics3D namespace
|
||||
namespace ephysics {
|
||||
|
||||
// Class TestPointInside
|
||||
/**
|
||||
* Unit test for the CollisionBody::testPointInside() method.
|
||||
*/
|
||||
class TestPointInside : public Test {
|
||||
|
||||
private :
|
||||
|
||||
// ---------- Atributes ---------- //
|
||||
|
||||
// Physics world
|
||||
CollisionWorld* m_world;
|
||||
|
||||
// Bodies
|
||||
CollisionBody* mBoxBody;
|
||||
CollisionBody* mSphereBody;
|
||||
CollisionBody* mCapsuleBody;
|
||||
CollisionBody* mConeBody;
|
||||
CollisionBody* mConvexMeshBody;
|
||||
CollisionBody* mConvexMeshBodyEdgesInfo;
|
||||
CollisionBody* mCylinderBody;
|
||||
CollisionBody* mCompoundBody;
|
||||
|
||||
// Collision shapes
|
||||
BoxShape* mBoxShape;
|
||||
SphereShape* mSphereShape;
|
||||
CapsuleShape* mCapsuleShape;
|
||||
ConeShape* mConeShape;
|
||||
ConvexMeshShape* mConvexMeshShape;
|
||||
ConvexMeshShape* mConvexMeshShapeBodyEdgesInfo;
|
||||
CylinderShape* mCylinderShape;
|
||||
|
||||
// etk::Transform3D
|
||||
etk::Transform3D m_bodyTransform;
|
||||
etk::Transform3D m_shapeTransform;
|
||||
etk::Transform3D mLocalShapeToWorld;
|
||||
etk::Transform3D mLocalShape2ToWorld;
|
||||
|
||||
// Proxy Shapes
|
||||
ProxyShape* mBoxProxyShape;
|
||||
ProxyShape* mSphereProxyShape;
|
||||
ProxyShape* mCapsuleProxyShape;
|
||||
ProxyShape* mConeProxyShape;
|
||||
ProxyShape* mConvexMeshProxyShape;
|
||||
ProxyShape* mConvexMeshProxyShapeEdgesInfo;
|
||||
ProxyShape* mCylinderProxyShape;
|
||||
|
||||
public :
|
||||
|
||||
// ---------- Methods ---------- //
|
||||
|
||||
/// Constructor
|
||||
TestPointInside(const etk::String& name) : Test(name) {
|
||||
|
||||
// Create the world
|
||||
m_world = new CollisionWorld();
|
||||
|
||||
// Body transform
|
||||
vec3 position(-3, 2, 7);
|
||||
etk::Quaternion orientation(PI / 5, PI / 6, PI / 7);
|
||||
m_bodyetk::Transform3D = Transform(position, orientation);
|
||||
|
||||
// Create the bodies
|
||||
mBoxBody = m_world->createCollisionBody(m_bodyetk::Transform3D);
|
||||
mSphereBody = m_world->createCollisionBody(m_bodyetk::Transform3D);
|
||||
mCapsuleBody = m_world->createCollisionBody(m_bodyetk::Transform3D);
|
||||
mConeBody = m_world->createCollisionBody(m_bodyetk::Transform3D);
|
||||
mConvexMeshBody = m_world->createCollisionBody(m_bodyetk::Transform3D);
|
||||
mConvexMeshBodyEdgesInfo = m_world->createCollisionBody(m_bodyetk::Transform3D);
|
||||
mCylinderBody = m_world->createCollisionBody(m_bodyetk::Transform3D);
|
||||
mCompoundBody = m_world->createCollisionBody(m_bodyetk::Transform3D);
|
||||
|
||||
// Collision shape transform
|
||||
vec3 shapePosition(1, -4, -3);
|
||||
etk::Quaternion shapeOrientation(3 * PI / 6 , -PI / 8, PI / 3);
|
||||
m_shapeTransform = Transform(shapePosition, shapeOrientation);
|
||||
|
||||
// Compute the the transform from a local shape point to world-space
|
||||
mLocalShapeToWorld = m_bodyetk::Transform3D * m_shapeTransform;
|
||||
|
||||
// Create collision shapes
|
||||
mBoxShape = new BoxShape(vec3(2, 3, 4), 0);
|
||||
mBoxProxyShape = mBoxBody->addCollisionShape(mBoxShape, m_shapeTransform);
|
||||
|
||||
mSphereShape = new SphereShape(3);
|
||||
mSphereProxyShape = mSphereBody->addCollisionShape(mSphereShape, m_shapeTransform);
|
||||
|
||||
mCapsuleShape = new CapsuleShape(2, 10);
|
||||
mCapsuleProxyShape = mCapsuleBody->addCollisionShape(mCapsuleShape, m_shapeTransform);
|
||||
|
||||
mConeShape = new ConeShape(2, 6, 0);
|
||||
mConeProxyShape = mConeBody->addCollisionShape(mConeShape, m_shapeTransform);
|
||||
|
||||
mConvexMeshShape = new ConvexMeshShape(0.0); // Box of dimension (2, 3, 4)
|
||||
mConvexMeshShape->addVertex(vec3(-2, -3, -4));
|
||||
mConvexMeshShape->addVertex(vec3(2, -3, -4));
|
||||
mConvexMeshShape->addVertex(vec3(2, -3, 4));
|
||||
mConvexMeshShape->addVertex(vec3(-2, -3, 4));
|
||||
mConvexMeshShape->addVertex(vec3(-2, 3, -4));
|
||||
mConvexMeshShape->addVertex(vec3(2, 3, -4));
|
||||
mConvexMeshShape->addVertex(vec3(2, 3, 4));
|
||||
mConvexMeshShape->addVertex(vec3(-2, 3, 4));
|
||||
mConvexMeshProxyShape = mConvexMeshBody->addCollisionShape(mConvexMeshShape, m_shapeTransform);
|
||||
|
||||
mConvexMeshShapeBodyEdgesInfo = new ConvexMeshShape(0.0);
|
||||
mConvexMeshShapeBodyEdgesInfo->addVertex(vec3(-2, -3, -4));
|
||||
mConvexMeshShapeBodyEdgesInfo->addVertex(vec3(2, -3, -4));
|
||||
mConvexMeshShapeBodyEdgesInfo->addVertex(vec3(2, -3, 4));
|
||||
mConvexMeshShapeBodyEdgesInfo->addVertex(vec3(-2, -3, 4));
|
||||
mConvexMeshShapeBodyEdgesInfo->addVertex(vec3(-2, 3, -4));
|
||||
mConvexMeshShapeBodyEdgesInfo->addVertex(vec3(2, 3, -4));
|
||||
mConvexMeshShapeBodyEdgesInfo->addVertex(vec3(2, 3, 4));
|
||||
mConvexMeshShapeBodyEdgesInfo->addVertex(vec3(-2, 3, 4));
|
||||
mConvexMeshShapeBodyEdgesInfo->addEdge(0, 1);
|
||||
mConvexMeshShapeBodyEdgesInfo->addEdge(1, 2);
|
||||
mConvexMeshShapeBodyEdgesInfo->addEdge(2, 3);
|
||||
mConvexMeshShapeBodyEdgesInfo->addEdge(0, 3);
|
||||
mConvexMeshShapeBodyEdgesInfo->addEdge(4, 5);
|
||||
mConvexMeshShapeBodyEdgesInfo->addEdge(5, 6);
|
||||
mConvexMeshShapeBodyEdgesInfo->addEdge(6, 7);
|
||||
mConvexMeshShapeBodyEdgesInfo->addEdge(4, 7);
|
||||
mConvexMeshShapeBodyEdgesInfo->addEdge(0, 4);
|
||||
mConvexMeshShapeBodyEdgesInfo->addEdge(1, 5);
|
||||
mConvexMeshShapeBodyEdgesInfo->addEdge(2, 6);
|
||||
mConvexMeshShapeBodyEdgesInfo->addEdge(3, 7);
|
||||
mConvexMeshShapeBodyEdgesInfo->setIsEdgesInformationUsed(true);
|
||||
mConvexMeshProxyShapeEdgesInfo = mConvexMeshBodyEdgesInfo->addCollisionShape(
|
||||
mConvexMeshShapeBodyEdgesInfo,
|
||||
m_shapeTransform);
|
||||
|
||||
mCylinderShape = new CylinderShape(3, 8, 0);
|
||||
mCylinderProxyShape = mCylinderBody->addCollisionShape(mCylinderShape, m_shapeTransform);
|
||||
|
||||
// Compound shape is a cylinder and a sphere
|
||||
vec3 positionShape2(vec3(4, 2, -3));
|
||||
etk::Quaternion orientationShape2(-3 *PI / 8, 1.5 * PI/ 3, PI / 13);
|
||||
etk::Transform3D shapeTransform2(positionShape2, orientationShape2);
|
||||
mLocalShape2ToWorld = m_bodyetk::Transform3D * shapeTransform2;
|
||||
mCompoundBody->addCollisionShape(mCylinderShape, m_shapeTransform);
|
||||
mCompoundBody->addCollisionShape(mSphereShape, shapeTransform2);
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
~TestPointInside() {
|
||||
delete mBoxShape;
|
||||
delete mSphereShape;
|
||||
delete mCapsuleShape;
|
||||
delete mConeShape;
|
||||
delete mConvexMeshShape;
|
||||
delete mConvexMeshShapeBodyEdgesInfo;
|
||||
delete mCylinderShape;
|
||||
}
|
||||
|
||||
/// Run the tests
|
||||
void run() {
|
||||
testBox();
|
||||
testSphere();
|
||||
testCapsule();
|
||||
testCone();
|
||||
testConvexMesh();
|
||||
testCylinder();
|
||||
testCompound();
|
||||
}
|
||||
|
||||
/// Test the ProxyBoxShape::testPointInside() and
|
||||
/// CollisionBody::testPointInside() methods
|
||||
void testBox() {
|
||||
|
||||
// Tests with CollisionBody
|
||||
test(mBoxBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, 0)));
|
||||
test(mBoxBody->testPointInside(mLocalShapeToWorld * vec3(-1.9, 0, 0)));
|
||||
test(mBoxBody->testPointInside(mLocalShapeToWorld * vec3(1.9, 0, 0)));
|
||||
test(mBoxBody->testPointInside(mLocalShapeToWorld * vec3(0, -2.9, 0)));
|
||||
test(mBoxBody->testPointInside(mLocalShapeToWorld * vec3(0, 2.9, 0)));
|
||||
test(mBoxBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, -3.9)));
|
||||
test(mBoxBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, 3.9)));
|
||||
test(mBoxBody->testPointInside(mLocalShapeToWorld * vec3(-1.9, -2.9, -3.9)));
|
||||
test(mBoxBody->testPointInside(mLocalShapeToWorld * vec3(1.9, 2.9, 3.9)));
|
||||
test(mBoxBody->testPointInside(mLocalShapeToWorld * vec3(-1, -2, -1.5)));
|
||||
test(mBoxBody->testPointInside(mLocalShapeToWorld * vec3(-1, 2, -2.5)));
|
||||
test(mBoxBody->testPointInside(mLocalShapeToWorld * vec3(1, -2, 3.5)));
|
||||
|
||||
test(!mBoxBody->testPointInside(mLocalShapeToWorld * vec3(-2.1, 0, 0)));
|
||||
test(!mBoxBody->testPointInside(mLocalShapeToWorld * vec3(2.1, 0, 0)));
|
||||
test(!mBoxBody->testPointInside(mLocalShapeToWorld * vec3(0, -3.1, 0)));
|
||||
test(!mBoxBody->testPointInside(mLocalShapeToWorld * vec3(0, 3.1, 0)));
|
||||
test(!mBoxBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, -4.1)));
|
||||
test(!mBoxBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, 4.1)));
|
||||
test(!mBoxBody->testPointInside(mLocalShapeToWorld * vec3(-2.1, -3.1, -4.1)));
|
||||
test(!mBoxBody->testPointInside(mLocalShapeToWorld * vec3(2.1, 3.1, 4.1)));
|
||||
test(!mBoxBody->testPointInside(mLocalShapeToWorld * vec3(-10, -2, -1.5)));
|
||||
test(!mBoxBody->testPointInside(mLocalShapeToWorld * vec3(-1, 4, -2.5)));
|
||||
test(!mBoxBody->testPointInside(mLocalShapeToWorld * vec3(1, -2, 4.5)));
|
||||
|
||||
// Tests with ProxyBoxShape
|
||||
test(mBoxProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, 0)));
|
||||
test(mBoxProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1.9, 0, 0)));
|
||||
test(mBoxProxyShape->testPointInside(mLocalShapeToWorld * vec3(1.9, 0, 0)));
|
||||
test(mBoxProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -2.9, 0)));
|
||||
test(mBoxProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 2.9, 0)));
|
||||
test(mBoxProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, -3.9)));
|
||||
test(mBoxProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, 3.9)));
|
||||
test(mBoxProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1.9, -2.9, -3.9)));
|
||||
test(mBoxProxyShape->testPointInside(mLocalShapeToWorld * vec3(1.9, 2.9, 3.9)));
|
||||
test(mBoxProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1, -2, -1.5)));
|
||||
test(mBoxProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1, 2, -2.5)));
|
||||
test(mBoxProxyShape->testPointInside(mLocalShapeToWorld * vec3(1, -2, 3.5)));
|
||||
|
||||
test(!mBoxProxyShape->testPointInside(mLocalShapeToWorld * vec3(-2.1, 0, 0)));
|
||||
test(!mBoxProxyShape->testPointInside(mLocalShapeToWorld * vec3(2.1, 0, 0)));
|
||||
test(!mBoxProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -3.1, 0)));
|
||||
test(!mBoxProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 3.1, 0)));
|
||||
test(!mBoxProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, -4.1)));
|
||||
test(!mBoxProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, 4.1)));
|
||||
test(!mBoxProxyShape->testPointInside(mLocalShapeToWorld * vec3(-2.1, -3.1, -4.1)));
|
||||
test(!mBoxProxyShape->testPointInside(mLocalShapeToWorld * vec3(2.1, 3.1, 4.1)));
|
||||
test(!mBoxProxyShape->testPointInside(mLocalShapeToWorld * vec3(-10, -2, -1.5)));
|
||||
test(!mBoxProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1, 4, -2.5)));
|
||||
test(!mBoxProxyShape->testPointInside(mLocalShapeToWorld * vec3(1, -2, 4.5)));
|
||||
}
|
||||
|
||||
/// Test the ProxySphereShape::testPointInside() and
|
||||
/// CollisionBody::testPointInside() methods
|
||||
void testSphere() {
|
||||
|
||||
// Tests with CollisionBody
|
||||
test(mSphereBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, 0)));
|
||||
test(mSphereBody->testPointInside(mLocalShapeToWorld * vec3(2.9, 0, 0)));
|
||||
test(mSphereBody->testPointInside(mLocalShapeToWorld * vec3(-2.9, 0, 0)));
|
||||
test(mSphereBody->testPointInside(mLocalShapeToWorld * vec3(0, 2.9, 0)));
|
||||
test(mSphereBody->testPointInside(mLocalShapeToWorld * vec3(0, -2.9, 0)));
|
||||
test(mSphereBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, 2.9)));
|
||||
test(mSphereBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, 2.9)));
|
||||
test(mSphereBody->testPointInside(mLocalShapeToWorld * vec3(-1, -2, -1.5)));
|
||||
test(mSphereBody->testPointInside(mLocalShapeToWorld * vec3(-1, 2, -1.5)));
|
||||
test(mSphereBody->testPointInside(mLocalShapeToWorld * vec3(1, -2, 1.5)));
|
||||
|
||||
test(!mSphereBody->testPointInside(mLocalShapeToWorld * vec3(3.1, 0, 0)));
|
||||
test(!mSphereBody->testPointInside(mLocalShapeToWorld * vec3(-3.1, 0, 0)));
|
||||
test(!mSphereBody->testPointInside(mLocalShapeToWorld * vec3(0, 3.1, 0)));
|
||||
test(!mSphereBody->testPointInside(mLocalShapeToWorld * vec3(0, -3.1, 0)));
|
||||
test(!mSphereBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, 3.1)));
|
||||
test(!mSphereBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, -3.1)));
|
||||
test(!mSphereBody->testPointInside(mLocalShapeToWorld * vec3(-2, -2, -2)));
|
||||
test(!mSphereBody->testPointInside(mLocalShapeToWorld * vec3(-2, 2, -1.5)));
|
||||
test(!mSphereBody->testPointInside(mLocalShapeToWorld * vec3(1.5, -2, 2.5)));
|
||||
|
||||
// Tests with ProxySphereShape
|
||||
test(mSphereProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, 0)));
|
||||
test(mSphereProxyShape->testPointInside(mLocalShapeToWorld * vec3(2.9, 0, 0)));
|
||||
test(mSphereProxyShape->testPointInside(mLocalShapeToWorld * vec3(-2.9, 0, 0)));
|
||||
test(mSphereProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 2.9, 0)));
|
||||
test(mSphereProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -2.9, 0)));
|
||||
test(mSphereProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, 2.9)));
|
||||
test(mSphereProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, 2.9)));
|
||||
test(mSphereProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1, -2, -1.5)));
|
||||
test(mSphereProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1, 2, -1.5)));
|
||||
test(mSphereProxyShape->testPointInside(mLocalShapeToWorld * vec3(1, -2, 1.5)));
|
||||
|
||||
test(!mSphereProxyShape->testPointInside(mLocalShapeToWorld * vec3(3.1, 0, 0)));
|
||||
test(!mSphereProxyShape->testPointInside(mLocalShapeToWorld * vec3(-3.1, 0, 0)));
|
||||
test(!mSphereProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 3.1, 0)));
|
||||
test(!mSphereProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -3.1, 0)));
|
||||
test(!mSphereProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, 3.1)));
|
||||
test(!mSphereProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, -3.1)));
|
||||
test(!mSphereProxyShape->testPointInside(mLocalShapeToWorld * vec3(-2, -2, -2)));
|
||||
test(!mSphereProxyShape->testPointInside(mLocalShapeToWorld * vec3(-2, 2, -1.5)));
|
||||
test(!mSphereProxyShape->testPointInside(mLocalShapeToWorld * vec3(1.5, -2, 2.5)));
|
||||
}
|
||||
|
||||
/// Test the ProxyCapsuleShape::testPointInside() and
|
||||
/// CollisionBody::testPointInside() methods
|
||||
void testCapsule() {
|
||||
|
||||
// Tests with CollisionBody
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, 0)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0, 5, 0)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0, -5, 0)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0, -6.9, 0)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0, 6.9, 0)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, 1.9)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, -1.9)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(1.9, 0, 0)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(-1.9, 0, 0)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0.9, 0, 0.9)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0.9, 0, -0.9)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0, 5, 1.9)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0, 5, -1.9)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(1.9, 5, 0)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(-1.9, 5, 0)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0.9, 5, 0.9)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0.9, 5, -0.9)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0, -5, 1.9)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0, -5, -1.9)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(1.9, -5, 0)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(-1.9, -5, 0)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0.9, -5, 0.9)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0.9, -5, -0.9)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(-1.7, -4, -0.9)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(-1, 2, 0.4)));
|
||||
test(mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(1.3, 1, 1.5)));
|
||||
|
||||
test(!mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0, -7.1, 0)));
|
||||
test(!mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0, 7.1, 0)));
|
||||
test(!mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, 2.1)));
|
||||
test(!mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, -2.1)));
|
||||
test(!mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(2.1, 0, 0)));
|
||||
test(!mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(-2.1, 0, 0)));
|
||||
test(!mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0, 5, 2.1)));
|
||||
test(!mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0, 5, -2.1)));
|
||||
test(!mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(2.1, 5, 0)));
|
||||
test(!mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(-2.1, 5, 0)));
|
||||
test(!mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(1.5, 5, 1.6)));
|
||||
test(!mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(1.5, 5, -1.7)));
|
||||
test(!mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0, -5, 2.1)));
|
||||
test(!mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(0, -5, -2.1)));
|
||||
test(!mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(2.1, -5, 0)));
|
||||
test(!mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(-2.1, -5, 0)));
|
||||
test(!mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(1.5, -5, 1.6)));
|
||||
test(!mCapsuleBody->testPointInside(mLocalShapeToWorld * vec3(1.5, -5, -1.7)));
|
||||
|
||||
// Tests with ProxyCapsuleShape
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, 0)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 5, 0)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -5, 0)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -6.9, 0)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 6.9, 0)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, 1.9)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, -1.9)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(1.9, 0, 0)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1.9, 0, 0)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0.9, 0, 0.9)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0.9, 0, -0.9)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 5, 1.9)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 5, -1.9)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(1.9, 5, 0)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1.9, 5, 0)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0.9, 5, 0.9)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0.9, 5, -0.9)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -5, 1.9)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -5, -1.9)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(1.9, -5, 0)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1.9, -5, 0)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0.9, -5, 0.9)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0.9, -5, -0.9)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1.7, -4, -0.9)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1, 2, 0.4)));
|
||||
test(mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(1.3, 1, 1.5)));
|
||||
|
||||
test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -7.1, 0)));
|
||||
test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 7.1, 0)));
|
||||
test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, 2.1)));
|
||||
test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, -2.1)));
|
||||
test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(2.1, 0, 0)));
|
||||
test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(-2.1, 0, 0)));
|
||||
test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 5, 2.1)));
|
||||
test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 5, -2.1)));
|
||||
test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(2.1, 5, 0)));
|
||||
test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(-2.1, 5, 0)));
|
||||
test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(1.5, 5, 1.6)));
|
||||
test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(1.5, 5, -1.7)));
|
||||
test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -5, 2.1)));
|
||||
test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -5, -2.1)));
|
||||
test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(2.1, -5, 0)));
|
||||
test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(-2.1, -5, 0)));
|
||||
test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(1.5, -5, 1.6)));
|
||||
test(!mCapsuleProxyShape->testPointInside(mLocalShapeToWorld * vec3(1.5, -5, -1.7)));
|
||||
}
|
||||
|
||||
/// Test the ProxyConeShape::testPointInside() and
|
||||
/// CollisionBody::testPointInside() methods
|
||||
void testCone() {
|
||||
|
||||
// Tests with CollisionBody
|
||||
test(mConeBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, 0)));
|
||||
test(mConeBody->testPointInside(mLocalShapeToWorld * vec3(0.9, 0, 0)));
|
||||
test(mConeBody->testPointInside(mLocalShapeToWorld * vec3(-0.9, 0, 0)));
|
||||
test(mConeBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, 0.9)));
|
||||
test(mConeBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, -0.9)));
|
||||
test(mConeBody->testPointInside(mLocalShapeToWorld * vec3(0.6, 0, -0.7)));
|
||||
test(mConeBody->testPointInside(mLocalShapeToWorld * vec3(0.6, 0, 0.7)));
|
||||
test(mConeBody->testPointInside(mLocalShapeToWorld * vec3(-0.6, 0, -0.7)));
|
||||
test(mConeBody->testPointInside(mLocalShapeToWorld * vec3(-0.6, 0, 0.7)));
|
||||
test(mConeBody->testPointInside(mLocalShapeToWorld * vec3(0, 2.9, 0)));
|
||||
test(mConeBody->testPointInside(mLocalShapeToWorld * vec3(0, -2.9, 0)));
|
||||
test(mConeBody->testPointInside(mLocalShapeToWorld * vec3(1.96, -2.9, 0)));
|
||||
test(mConeBody->testPointInside(mLocalShapeToWorld * vec3(-1.96, -2.9, 0)));
|
||||
test(mConeBody->testPointInside(mLocalShapeToWorld * vec3(0, -2.9, 1.96)));
|
||||
test(mConeBody->testPointInside(mLocalShapeToWorld * vec3(0, -2.9, -1.96)));
|
||||
test(mConeBody->testPointInside(mLocalShapeToWorld * vec3(1.3, -2.9, -1.4)));
|
||||
test(mConeBody->testPointInside(mLocalShapeToWorld * vec3(-1.3, -2.9, 1.4)));
|
||||
|
||||
test(!mConeBody->testPointInside(mLocalShapeToWorld * vec3(1.1, 0, 0)));
|
||||
test(!mConeBody->testPointInside(mLocalShapeToWorld * vec3(-1.1, 0, 0)));
|
||||
test(!mConeBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, 1.1)));
|
||||
test(!mConeBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, -1.1)));
|
||||
test(!mConeBody->testPointInside(mLocalShapeToWorld * vec3(0.8, 0, -0.8)));
|
||||
test(!mConeBody->testPointInside(mLocalShapeToWorld * vec3(0.8, 0, 0.8)));
|
||||
test(!mConeBody->testPointInside(mLocalShapeToWorld * vec3(-0.8, 0, -0.8)));
|
||||
test(!mConeBody->testPointInside(mLocalShapeToWorld * vec3(-0.8, 0, 0.8)));
|
||||
test(!mConeBody->testPointInside(mLocalShapeToWorld * vec3(0, 3.1, 0)));
|
||||
test(!mConeBody->testPointInside(mLocalShapeToWorld * vec3(0, -3.1, 0)));
|
||||
test(!mConeBody->testPointInside(mLocalShapeToWorld * vec3(1.97, -2.9, 0)));
|
||||
test(!mConeBody->testPointInside(mLocalShapeToWorld * vec3(-1.97, -2.9, 0)));
|
||||
test(!mConeBody->testPointInside(mLocalShapeToWorld * vec3(0, -2.9, 1.97)));
|
||||
test(!mConeBody->testPointInside(mLocalShapeToWorld * vec3(0, -2.9, -1.97)));
|
||||
test(!mConeBody->testPointInside(mLocalShapeToWorld * vec3(1.5, -2.9, -1.5)));
|
||||
test(!mConeBody->testPointInside(mLocalShapeToWorld * vec3(-1.5, -2.9, 1.5)));
|
||||
|
||||
// Tests with ProxyConeShape
|
||||
test(mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, 0)));
|
||||
test(mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(0.9, 0, 0)));
|
||||
test(mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(-0.9, 0, 0)));
|
||||
test(mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, 0.9)));
|
||||
test(mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, -0.9)));
|
||||
test(mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(0.6, 0, -0.7)));
|
||||
test(mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(0.6, 0, 0.7)));
|
||||
test(mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(-0.6, 0, -0.7)));
|
||||
test(mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(-0.6, 0, 0.7)));
|
||||
test(mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 2.9, 0)));
|
||||
test(mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -2.9, 0)));
|
||||
test(mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(1.96, -2.9, 0)));
|
||||
test(mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1.96, -2.9, 0)));
|
||||
test(mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -2.9, 1.96)));
|
||||
test(mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -2.9, -1.96)));
|
||||
test(mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(1.3, -2.9, -1.4)));
|
||||
test(mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1.3, -2.9, 1.4)));
|
||||
|
||||
test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(1.1, 0, 0)));
|
||||
test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1.1, 0, 0)));
|
||||
test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, 1.1)));
|
||||
test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, -1.1)));
|
||||
test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(0.8, 0, -0.8)));
|
||||
test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(0.8, 0, 0.8)));
|
||||
test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(-0.8, 0, -0.8)));
|
||||
test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(-0.8, 0, 0.8)));
|
||||
test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 3.1, 0)));
|
||||
test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -3.1, 0)));
|
||||
test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(1.97, -2.9, 0)));
|
||||
test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1.97, -2.9, 0)));
|
||||
test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -2.9, 1.97)));
|
||||
test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -2.9, -1.97)));
|
||||
test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(1.5, -2.9, -1.5)));
|
||||
test(!mConeProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1.5, -2.9, 1.5)));
|
||||
}
|
||||
|
||||
/// Test the ProxyConvexMeshShape::testPointInside() and
|
||||
/// CollisionBody::testPointInside() methods
|
||||
void testConvexMesh() {
|
||||
|
||||
// ----- Tests without using edges information ----- //
|
||||
|
||||
// Tests with CollisionBody
|
||||
test(mConvexMeshBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, 0)));
|
||||
test(mConvexMeshBody->testPointInside(mLocalShapeToWorld * vec3(-1.9, 0, 0)));
|
||||
test(mConvexMeshBody->testPointInside(mLocalShapeToWorld * vec3(1.9, 0, 0)));
|
||||
test(mConvexMeshBody->testPointInside(mLocalShapeToWorld * vec3(0, -2.9, 0)));
|
||||
test(mConvexMeshBody->testPointInside(mLocalShapeToWorld * vec3(0, 2.9, 0)));
|
||||
test(mConvexMeshBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, -3.9)));
|
||||
test(mConvexMeshBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, 3.9)));
|
||||
test(mConvexMeshBody->testPointInside(mLocalShapeToWorld * vec3(-1.9, -2.9, -3.9)));
|
||||
test(mConvexMeshBody->testPointInside(mLocalShapeToWorld * vec3(1.9, 2.9, 3.9)));
|
||||
test(mConvexMeshBody->testPointInside(mLocalShapeToWorld * vec3(-1, -2, -1.5)));
|
||||
test(mConvexMeshBody->testPointInside(mLocalShapeToWorld * vec3(-1, 2, -2.5)));
|
||||
test(mConvexMeshBody->testPointInside(mLocalShapeToWorld * vec3(1, -2, 3.5)));
|
||||
|
||||
test(!mConvexMeshBody->testPointInside(mLocalShapeToWorld * vec3(-2.1, 0, 0)));
|
||||
test(!mConvexMeshBody->testPointInside(mLocalShapeToWorld * vec3(2.1, 0, 0)));
|
||||
test(!mConvexMeshBody->testPointInside(mLocalShapeToWorld * vec3(0, -3.1, 0)));
|
||||
test(!mConvexMeshBody->testPointInside(mLocalShapeToWorld * vec3(0, 3.1, 0)));
|
||||
test(!mConvexMeshBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, -4.1)));
|
||||
test(!mConvexMeshBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, 4.1)));
|
||||
test(!mConvexMeshBody->testPointInside(mLocalShapeToWorld * vec3(-2.1, -3.1, -4.1)));
|
||||
test(!mConvexMeshBody->testPointInside(mLocalShapeToWorld * vec3(2.1, 3.1, 4.1)));
|
||||
test(!mConvexMeshBody->testPointInside(mLocalShapeToWorld * vec3(-10, -2, -1.5)));
|
||||
test(!mConvexMeshBody->testPointInside(mLocalShapeToWorld * vec3(-1, 4, -2.5)));
|
||||
test(!mConvexMeshBody->testPointInside(mLocalShapeToWorld * vec3(1, -2, 4.5)));
|
||||
|
||||
// Tests with ProxyConvexMeshShape
|
||||
test(mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, 0)));
|
||||
test(mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1.9, 0, 0)));
|
||||
test(mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * vec3(1.9, 0, 0)));
|
||||
test(mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -2.9, 0)));
|
||||
test(mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 2.9, 0)));
|
||||
test(mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, -3.9)));
|
||||
test(mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, 3.9)));
|
||||
test(mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1.9, -2.9, -3.9)));
|
||||
test(mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * vec3(1.9, 2.9, 3.9)));
|
||||
test(mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1, -2, -1.5)));
|
||||
test(mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1, 2, -2.5)));
|
||||
test(mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * vec3(1, -2, 3.5)));
|
||||
|
||||
test(!mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * vec3(-2.1, 0, 0)));
|
||||
test(!mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * vec3(2.1, 0, 0)));
|
||||
test(!mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -3.1, 0)));
|
||||
test(!mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 3.1, 0)));
|
||||
test(!mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, -4.1)));
|
||||
test(!mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, 4.1)));
|
||||
test(!mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * vec3(-2.1, -3.1, -4.1)));
|
||||
test(!mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * vec3(2.1, 3.1, 4.1)));
|
||||
test(!mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * vec3(-10, -2, -1.5)));
|
||||
test(!mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1, 4, -2.5)));
|
||||
test(!mConvexMeshProxyShape->testPointInside(mLocalShapeToWorld * vec3(1, -2, 4.5)));
|
||||
|
||||
// ----- Tests using edges information ----- //
|
||||
|
||||
// Tests with CollisionBody
|
||||
test(mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(0, 0, 0)));
|
||||
test(mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(-1.9, 0, 0)));
|
||||
test(mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(1.9, 0, 0)));
|
||||
test(mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(0, -2.9, 0)));
|
||||
test(mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(0, 2.9, 0)));
|
||||
test(mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(0, 0, -3.9)));
|
||||
test(mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(0, 0, 3.9)));
|
||||
test(mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(-1.9, -2.9, -3.9)));
|
||||
test(mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(1.9, 2.9, 3.9)));
|
||||
test(mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(-1, -2, -1.5)));
|
||||
test(mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(-1, 2, -2.5)));
|
||||
test(mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(1, -2, 3.5)));
|
||||
|
||||
test(!mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(-2.1, 0, 0)));
|
||||
test(!mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(2.1, 0, 0)));
|
||||
test(!mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(0, -3.1, 0)));
|
||||
test(!mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(0, 3.1, 0)));
|
||||
test(!mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(0, 0, -4.1)));
|
||||
test(!mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(0, 0, 4.1)));
|
||||
test(!mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(-2.1, -3.1, -4.1)));
|
||||
test(!mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(2.1, 3.1, 4.1)));
|
||||
test(!mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(-10, -2, -1.5)));
|
||||
test(!mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(-1, 4, -2.5)));
|
||||
test(!mConvexMeshBodyEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(1, -2, 4.5)));
|
||||
|
||||
// Tests with ProxyConvexMeshShape
|
||||
test(mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(0, 0, 0)));
|
||||
test(mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(-1.9, 0, 0)));
|
||||
test(mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(1.9, 0, 0)));
|
||||
test(mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(0, -2.9, 0)));
|
||||
test(mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(0, 2.9, 0)));
|
||||
test(mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(0, 0, -3.9)));
|
||||
test(mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(0, 0, 3.9)));
|
||||
test(mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(-1.9, -2.9, -3.9)));
|
||||
test(mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(1.9, 2.9, 3.9)));
|
||||
test(mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(-1, -2, -1.5)));
|
||||
test(mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(-1, 2, -2.5)));
|
||||
test(mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(1, -2, 3.5)));
|
||||
|
||||
test(!mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(-2.1, 0, 0)));
|
||||
test(!mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(2.1, 0, 0)));
|
||||
test(!mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(0, -3.1, 0)));
|
||||
test(!mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(0, 3.1, 0)));
|
||||
test(!mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(0, 0, -4.1)));
|
||||
test(!mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(0, 0, 4.1)));
|
||||
test(!mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(-2.1, -3.1, -4.1)));
|
||||
test(!mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(2.1, 3.1, 4.1)));
|
||||
test(!mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(-10, -2, -1.5)));
|
||||
test(!mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(-1, 4, -2.5)));
|
||||
test(!mConvexMeshProxyShapeEdgesInfo->testPointInside(mLocalShapeToWorld * vec3(1, -2, 4.5)));
|
||||
}
|
||||
|
||||
/// Test the ProxyCylinderShape::testPointInside() and
|
||||
/// CollisionBody::testPointInside() methods
|
||||
void testCylinder() {
|
||||
|
||||
// Tests with CollisionBody
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, 0)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(0, 3.9, 0)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(0, -3.9, 0)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(2.9, 0, 0)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(-2.9, 0, 0)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, 2.9)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, -2.9)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(1.7, 0, 1.7)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(1.7, 0, -1.7)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(-1.7, 0, -1.7)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(-1.7, 0, 1.7)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(2.9, 3.9, 0)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(-2.9, 3.9, 0)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(0, 3.9, 2.9)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(0, 3.9, -2.9)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(1.7, 3.9, 1.7)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(1.7, 3.9, -1.7)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(-1.7, 3.9, -1.7)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(-1.7, 3.9, 1.7)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(2.9, -3.9, 0)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(-2.9, -3.9, 0)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(0, -3.9, 2.9)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(0, -3.9, -2.9)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(1.7, -3.9, 1.7)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(1.7, -3.9, -1.7)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(-1.7, -3.9, -1.7)));
|
||||
test(mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(-1.7, -3.9, 1.7)));
|
||||
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(0, 4.1, 0)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(0, -4.1, 0)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(3.1, 0, 0)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(-3.1, 0, 0)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, 3.1)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, -3.1)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(2.2, 0, 2.2)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(2.2, 0, -2.2)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(-2.2, 0, -2.2)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(-1.3, 0, 2.8)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(3.1, 3.9, 0)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(-3.1, 3.9, 0)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(0, 3.9, 3.1)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(0, 3.9, -3.1)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(2.2, 3.9, 2.2)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(2.2, 3.9, -2.2)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(-2.2, 3.9, -2.2)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(-2.2, 3.9, 2.2)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(3.1, -3.9, 0)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(-3.1, -3.9, 0)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(0, -3.9, 3.1)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(0, -3.9, -3.1)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(2.2, -3.9, 2.2)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(2.2, -3.9, -2.2)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(-2.2, -3.9, -2.2)));
|
||||
test(!mCylinderBody->testPointInside(mLocalShapeToWorld * vec3(-2.2, -3.9, 2.2)));
|
||||
|
||||
// Tests with ProxyCylinderShape
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, 0)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 3.9, 0)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -3.9, 0)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(2.9, 0, 0)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(-2.9, 0, 0)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, 2.9)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, -2.9)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(1.7, 0, 1.7)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(1.7, 0, -1.7)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1.7, 0, -1.7)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1.7, 0, 1.7)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(2.9, 3.9, 0)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(-2.9, 3.9, 0)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 3.9, 2.9)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 3.9, -2.9)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(1.7, 3.9, 1.7)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(1.7, 3.9, -1.7)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1.7, 3.9, -1.7)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1.7, 3.9, 1.7)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(2.9, -3.9, 0)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(-2.9, -3.9, 0)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -3.9, 2.9)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -3.9, -2.9)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(1.7, -3.9, 1.7)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(1.7, -3.9, -1.7)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1.7, -3.9, -1.7)));
|
||||
test(mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1.7, -3.9, 1.7)));
|
||||
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 4.1, 0)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -4.1, 0)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(3.1, 0, 0)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(-3.1, 0, 0)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, 3.1)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 0, -3.1)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(2.2, 0, 2.2)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(2.2, 0, -2.2)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(-2.2, 0, -2.2)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(-1.3, 0, 2.8)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(3.1, 3.9, 0)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(-3.1, 3.9, 0)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 3.9, 3.1)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, 3.9, -3.1)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(2.2, 3.9, 2.2)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(2.2, 3.9, -2.2)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(-2.2, 3.9, -2.2)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(-2.2, 3.9, 2.2)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(3.1, -3.9, 0)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(-3.1, -3.9, 0)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -3.9, 3.1)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(0, -3.9, -3.1)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(2.2, -3.9, 2.2)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(2.2, -3.9, -2.2)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(-2.2, -3.9, -2.2)));
|
||||
test(!mCylinderProxyShape->testPointInside(mLocalShapeToWorld * vec3(-2.2, -3.9, 2.2)));
|
||||
}
|
||||
|
||||
/// Test the CollisionBody::testPointInside() method
|
||||
void testCompound() {
|
||||
|
||||
// Points on the cylinder
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, 0)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(0, 3.9, 0)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(0, -3.9, 0)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(2.9, 0, 0)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(-2.9, 0, 0)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, 2.9)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(0, 0, -2.9)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(1.7, 0, 1.7)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(1.7, 0, -1.7)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(-1.7, 0, -1.7)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(-1.7, 0, 1.7)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(2.9, 3.9, 0)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(-2.9, 3.9, 0)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(0, 3.9, 2.9)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(0, 3.9, -2.9)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(1.7, 3.9, 1.7)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(1.7, 3.9, -1.7)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(-1.7, 3.9, -1.7)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(-1.7, 3.9, 1.7)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(2.9, -3.9, 0)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(-2.9, -3.9, 0)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(0, -3.9, 2.9)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(0, -3.9, -2.9)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(1.7, -3.9, 1.7)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(1.7, -3.9, -1.7)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(-1.7, -3.9, -1.7)));
|
||||
test(mCompoundBody->testPointInside(mLocalShapeToWorld * vec3(-1.7, -3.9, 1.7)));
|
||||
|
||||
// Points on the sphere
|
||||
test(mCompoundBody->testPointInside(mLocalShape2ToWorld * vec3(0, 0, 0)));
|
||||
test(mCompoundBody->testPointInside(mLocalShape2ToWorld * vec3(2.9, 0, 0)));
|
||||
test(mCompoundBody->testPointInside(mLocalShape2ToWorld * vec3(-2.9, 0, 0)));
|
||||
test(mCompoundBody->testPointInside(mLocalShape2ToWorld * vec3(0, 2.9, 0)));
|
||||
test(mCompoundBody->testPointInside(mLocalShape2ToWorld * vec3(0, -2.9, 0)));
|
||||
test(mCompoundBody->testPointInside(mLocalShape2ToWorld * vec3(0, 0, 2.9)));
|
||||
test(mCompoundBody->testPointInside(mLocalShape2ToWorld * vec3(0, 0, 2.9)));
|
||||
test(mCompoundBody->testPointInside(mLocalShape2ToWorld * vec3(-1, -2, -1.5)));
|
||||
test(mCompoundBody->testPointInside(mLocalShape2ToWorld * vec3(-1, 2, -1.5)));
|
||||
test(mCompoundBody->testPointInside(mLocalShape2ToWorld * vec3(1, -2, 1.5)));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,133 +0,0 @@
|
||||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://www.ephysics.com *
|
||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef TEST_MATHEMATICS_FUNCTIONS_H
|
||||
#define TEST_MATHEMATICS_FUNCTIONS_H
|
||||
|
||||
// Libraries
|
||||
#include <test/Test.hpp>
|
||||
#include <ephysics/mathematics/mathematics_functions.hpp>
|
||||
|
||||
/// Reactphysics3D namespace
|
||||
namespace ephysics {
|
||||
|
||||
// Class TestMathematicsFunctions
|
||||
/**
|
||||
* Unit test for mathematics functions
|
||||
*/
|
||||
class TestMathematicsFunctions : public Test {
|
||||
|
||||
private :
|
||||
|
||||
// ---------- Atributes ---------- //
|
||||
|
||||
|
||||
|
||||
public :
|
||||
|
||||
// ---------- Methods ---------- //
|
||||
|
||||
/// Constructor
|
||||
TestMathematicsFunctions(const etk::String& name): Test(name) {}
|
||||
|
||||
/// Run the tests
|
||||
void run() {
|
||||
|
||||
// Test approxEqual()
|
||||
test(approxEqual(2, 7, 5.2));
|
||||
test(approxEqual(7, 2, 5.2));
|
||||
test(approxEqual(6, 6));
|
||||
test(!approxEqual(1, 5));
|
||||
test(!approxEqual(1, 5, 3));
|
||||
test(approxEqual(-2, -2));
|
||||
test(approxEqual(-2, -7, 6));
|
||||
test(!approxEqual(-2, 7, 2));
|
||||
test(approxEqual(-3, 8, 12));
|
||||
test(!approxEqual(-3, 8, 6));
|
||||
|
||||
// Test clamp()
|
||||
test(clamp(4, -3, 5) == 4);
|
||||
test(clamp(-3, 1, 8) == 1);
|
||||
test(clamp(45, -6, 7) == 7);
|
||||
test(clamp(-5, -2, -1) == -2);
|
||||
test(clamp(-5, -9, -1) == -5);
|
||||
test(clamp(6, 6, 9) == 6);
|
||||
test(clamp(9, 6, 9) == 9);
|
||||
test(clamp(float(4), float(-3), float(5)) == float(4));
|
||||
test(clamp(float(-3), float(1), float(8)) == float(1));
|
||||
test(clamp(float(45), float(-6), float(7)) == float(7));
|
||||
test(clamp(float(-5), float(-2), float(-1)) == float(-2));
|
||||
test(clamp(float(-5), float(-9), float(-1)) == float(-5));
|
||||
test(clamp(float(6), float(6), float(9)) == float(6));
|
||||
test(clamp(float(9), float(6), float(9)) == float(9));
|
||||
|
||||
// Test min3()
|
||||
test(min3(1, 5, 7) == 1);
|
||||
test(min3(-4, 2, 4) == -4);
|
||||
test(min3(-1, -5, -7) == -7);
|
||||
test(min3(13, 5, 47) == 5);
|
||||
test(min3(4, 4, 4) == 4);
|
||||
|
||||
// Test max3()
|
||||
test(max3(1, 5, 7) == 7);
|
||||
test(max3(-4, 2, 4) == 4);
|
||||
test(max3(-1, -5, -7) == -1);
|
||||
test(max3(13, 5, 47) == 47);
|
||||
test(max3(4, 4, 4) == 4);
|
||||
|
||||
// Test sameSign()
|
||||
test(sameSign(4, 53));
|
||||
test(sameSign(-4, -8));
|
||||
test(!sameSign(4, -7));
|
||||
test(!sameSign(-4, 53));
|
||||
|
||||
// Test computeBarycentricCoordinatesInTriangle()
|
||||
vec3 a(0, 0, 0);
|
||||
vec3 b(5, 0, 0);
|
||||
vec3 c(0, 0, 5);
|
||||
vec3 testPoint(4, 0, 1);
|
||||
float u,v,w;
|
||||
computeBarycentricCoordinatesInTriangle(a, b, c, a, u, v, w);
|
||||
test(approxEqual(u, 1.0, 0.000001));
|
||||
test(approxEqual(v, 0.0, 0.000001));
|
||||
test(approxEqual(w, 0.0, 0.000001));
|
||||
computeBarycentricCoordinatesInTriangle(a, b, c, b, u, v, w);
|
||||
test(approxEqual(u, 0.0, 0.000001));
|
||||
test(approxEqual(v, 1.0, 0.000001));
|
||||
test(approxEqual(w, 0.0, 0.000001));
|
||||
computeBarycentricCoordinatesInTriangle(a, b, c, c, u, v, w);
|
||||
test(approxEqual(u, 0.0, 0.000001));
|
||||
test(approxEqual(v, 0.0, 0.000001));
|
||||
test(approxEqual(w, 1.0, 0.000001));
|
||||
|
||||
computeBarycentricCoordinatesInTriangle(a, b, c, testPoint, u, v, w);
|
||||
test(approxEqual(u + v + w, 1.0, 0.000001));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,251 +0,0 @@
|
||||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://www.ephysics.com *
|
||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef TEST_MATRIX2X2_H
|
||||
#define TEST_MATRIX2X2_H
|
||||
|
||||
// Libraries
|
||||
#include <test/Test.hpp>
|
||||
#include <etk/math/Matrix2x2.hpp>
|
||||
|
||||
/// Reactphysics3D namespace
|
||||
namespace ephysics {
|
||||
|
||||
// Class Testetk::Matrix2x2
|
||||
/**
|
||||
* Unit test for the etk::Matrix2x2 class
|
||||
*/
|
||||
class Testetk::Matrix2x2 : public Test {
|
||||
|
||||
private :
|
||||
|
||||
// ---------- Atributes ---------- //
|
||||
|
||||
/// Identity transform
|
||||
etk::Matrix2x2 mIdentity;
|
||||
|
||||
/// First example matrix
|
||||
etk::Matrix2x2 mMatrix1;
|
||||
|
||||
public :
|
||||
|
||||
// ---------- Methods ---------- //
|
||||
|
||||
/// Constructor
|
||||
Testetk::Matrix2x2(const etk::String& name)
|
||||
: Test(name), mIdentity(etk::Matrix2x2::identity()), mMatrix1(2, 24, -4, 5) {
|
||||
|
||||
}
|
||||
|
||||
/// Run the tests
|
||||
void run() {
|
||||
testConstructors();
|
||||
testGetSet();
|
||||
testIdentity();
|
||||
testZero();
|
||||
testOthersMethods();
|
||||
testOperators();
|
||||
}
|
||||
|
||||
/// Test the constructors
|
||||
void testConstructors() {
|
||||
|
||||
etk::Matrix2x2 test1(5.0);
|
||||
etk::Matrix2x2 test2(2, 3, 4, 5);
|
||||
etk::Matrix2x2 test3(mMatrix1);
|
||||
|
||||
test(test1[0][0] == 5);
|
||||
test(test1[0][1] == 5);
|
||||
test(test1[1][0] == 5);
|
||||
test(test1[1][1] == 5);
|
||||
|
||||
test(test2[0][0] == 2);
|
||||
test(test2[0][1] == 3);
|
||||
test(test2[1][0] == 4);
|
||||
test(test2[1][1] == 5);
|
||||
|
||||
test(test3 == mMatrix1);
|
||||
}
|
||||
|
||||
/// Test the getter and setter methods
|
||||
void testGetSet() {
|
||||
|
||||
// Test method to set all the values
|
||||
etk::Matrix2x2 test2;
|
||||
test2.setValue(2, 24, -4, 5);
|
||||
test(test2 == mMatrix1);
|
||||
|
||||
// Test method to set to zero
|
||||
test2.setZero();
|
||||
test(test2 == etk::Matrix2x2(0, 0, 0, 0));
|
||||
|
||||
// Test method that returns a column
|
||||
vec2 column1 = mMatrix1.getColumn(0);
|
||||
vec2 column2 = mMatrix1.getColumn(1);
|
||||
test(column1 == vec2(2, -4));
|
||||
test(column2 == vec2(24, 5));
|
||||
|
||||
// Test method that returns a row
|
||||
vec2 row1 = mMatrix1.getRow(0);
|
||||
vec2 row2 = mMatrix1.getRow(1);
|
||||
test(row1 == vec2(2, 24));
|
||||
test(row2 == vec2(-4, 5));
|
||||
}
|
||||
|
||||
/// Test the identity methods
|
||||
void testIdentity() {
|
||||
|
||||
etk::Matrix2x2 identity = Matrix2x2::identity();
|
||||
etk::Matrix2x2 test1;
|
||||
test1.setToIdentity();
|
||||
|
||||
test(identity[0][0] == 1);
|
||||
test(identity[0][1] == 0);
|
||||
test(identity[1][0] == 0);
|
||||
test(identity[1][1] == 1);
|
||||
|
||||
test(test1 == etk::Matrix2x2::identity());
|
||||
}
|
||||
|
||||
/// Test the zero method
|
||||
void testZero() {
|
||||
|
||||
etk::Matrix2x2 zero = Matrix2x2::zero();
|
||||
|
||||
test(zero[0][0] == 0);
|
||||
test(zero[0][1] == 0);
|
||||
test(zero[1][0] == 0);
|
||||
test(zero[1][1] == 0);
|
||||
}
|
||||
|
||||
/// Test others methods
|
||||
void testOthersMethods() {
|
||||
|
||||
// Test transpose
|
||||
etk::Matrix2x2 transpose = mMatrix1.getTranspose();
|
||||
test(transpose == etk::Matrix2x2(2, -4, 24, 5));
|
||||
|
||||
// Test trace
|
||||
test(mMatrix1.getTrace() ==7);
|
||||
test(etk::Matrix2x2::identity().getTrace() == 2);
|
||||
|
||||
// Test determinant
|
||||
etk::Matrix2x2 matrix(-24, 64, 253, -35);
|
||||
test(mMatrix1.getDeterminant() == 106);
|
||||
test(matrix.getDeterminant() == -15352);
|
||||
test(mIdentity.getDeterminant() == 1);
|
||||
|
||||
// Test inverse
|
||||
etk::Matrix2x2 matrix2(1, 2, 3, 4);
|
||||
etk::Matrix2x2 inverseMatrix = matrix2.getInverse();
|
||||
test(approxEqual(inverseMatrix[0][0], float(-2), float(10e-6)));
|
||||
test(approxEqual(inverseMatrix[0][1], float(1), float(10e-6)));
|
||||
test(approxEqual(inverseMatrix[1][0], float(1.5), float(10e-6)));
|
||||
test(approxEqual(inverseMatrix[1][1], float(-0.5), float(10e-6)));
|
||||
etk::Matrix2x2 inverseMatrix1 = mMatrix1.getInverse();
|
||||
test(approxEqual(inverseMatrix1[0][0], float(0.047169811), float(10e-6)));
|
||||
test(approxEqual(inverseMatrix1[0][1], float(-0.226415094), float(10e-6)));
|
||||
test(approxEqual(inverseMatrix1[1][0], float(0.037735849), float(10e-6)));
|
||||
test(approxEqual(inverseMatrix1[1][1], float(0.018867925), float(10e-6)));
|
||||
|
||||
// Test absolute matrix
|
||||
etk::Matrix2x2 matrix3(-2, -3, -4, -5);
|
||||
test(matrix.getAbsolute() == etk::Matrix2x2(24, 64, 253, 35));
|
||||
etk::Matrix2x2 absoluteMatrix = matrix3.getAbsolute();
|
||||
test(absoluteMatrix == etk::Matrix2x2(2, 3, 4, 5));
|
||||
}
|
||||
|
||||
/// Test the operators
|
||||
void testOperators() {
|
||||
|
||||
// Test addition
|
||||
etk::Matrix2x2 matrix1(2, 3, 4, 5);
|
||||
etk::Matrix2x2 matrix2(-2, 3, -5, 10);
|
||||
etk::Matrix2x2 addition1 = matrix1 + matrix2;
|
||||
etk::Matrix2x2 addition2(matrix1);
|
||||
addition2 += matrix2;
|
||||
test(addition1 == etk::Matrix2x2(0, 6, -1, 15));
|
||||
test(addition2 == etk::Matrix2x2(0, 6, -1, 15));
|
||||
|
||||
// Test substraction
|
||||
etk::Matrix2x2 substraction1 = matrix1 - matrix2;
|
||||
etk::Matrix2x2 substraction2(matrix1);
|
||||
substraction2 -= matrix2;
|
||||
test(substraction1 == etk::Matrix2x2(4, 0, 9, -5));
|
||||
test(substraction2 == etk::Matrix2x2(4, 0, 9, -5));
|
||||
|
||||
// Test negative operator
|
||||
etk::Matrix2x2 negative = -matrix1;
|
||||
test(negative == etk::Matrix2x2(-2, -3, -4, -5));
|
||||
|
||||
// Test multiplication with a number
|
||||
etk::Matrix2x2 multiplication1 = 3 * matrix1;
|
||||
etk::Matrix2x2 multiplication2 = matrix1 * 3;
|
||||
etk::Matrix2x2 multiplication3(matrix1);
|
||||
multiplication3 *= 3;
|
||||
test(multiplication1 == etk::Matrix2x2(6, 9, 12, 15));
|
||||
test(multiplication2 == etk::Matrix2x2(6, 9, 12, 15));
|
||||
test(multiplication3 == etk::Matrix2x2(6, 9, 12, 15));
|
||||
|
||||
// Test multiplication with a matrix
|
||||
etk::Matrix2x2 multiplication4 = matrix1 * matrix2;
|
||||
etk::Matrix2x2 multiplication5 = matrix2 * matrix1;
|
||||
test(multiplication4 == etk::Matrix2x2(-19, 36, -33, 62));
|
||||
test(multiplication5 == etk::Matrix2x2(8, 9, 30, 35));
|
||||
|
||||
// Test multiplication with a vector
|
||||
vec2 vector1(3, -32);
|
||||
vec2 vector2(-31, -422);
|
||||
vec2 test1 = matrix1 * vector1;
|
||||
vec2 test2 = matrix2 * vector2;
|
||||
test(test1 == vec2(-90, -148));
|
||||
test(test2 == vec2(-1204, -4065));
|
||||
|
||||
// Test equality operators
|
||||
test(etk::Matrix2x2(34, 38, 43, 64) ==
|
||||
etk::Matrix2x2(34, 38, 43, 64));
|
||||
test(etk::Matrix2x2(34, 64, 43, 7) !=
|
||||
etk::Matrix2x2(34, 38, 43, 64));
|
||||
|
||||
// Test operator to read a value
|
||||
test(mMatrix1[0][0] == 2);
|
||||
test(mMatrix1[0][1] == 24);
|
||||
test(mMatrix1[1][0] == -4);
|
||||
test(mMatrix1[1][1] == 5);
|
||||
|
||||
// Test operator to set a value
|
||||
etk::Matrix2x2 test3;
|
||||
test3[0][0] = 2;
|
||||
test3[0][1] = 24;
|
||||
test3[1][0] = -4;
|
||||
test3[1][1] = 5;
|
||||
test(test3 == mMatrix1);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,304 +0,0 @@
|
||||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://www.ephysics.com *
|
||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef TEST_MATRIX3X3_H
|
||||
#define TEST_MATRIX3X3_H
|
||||
|
||||
// Libraries
|
||||
#include <test/Test.hpp>
|
||||
#include <etk/math/Matrix3x3.hpp>
|
||||
|
||||
/// Reactphysics3D namespace
|
||||
namespace ephysics {
|
||||
|
||||
// Class Testetk::Matrix3x3
|
||||
/**
|
||||
* Unit test for the etk::Matrix3x3 class
|
||||
*/
|
||||
class Testetk::Matrix3x3 : public Test {
|
||||
|
||||
private :
|
||||
|
||||
// ---------- Atributes ---------- //
|
||||
|
||||
/// Identity transform
|
||||
etk::Matrix3x3 mIdentity;
|
||||
|
||||
/// First example matrix
|
||||
etk::Matrix3x3 mMatrix1;
|
||||
|
||||
public :
|
||||
|
||||
// ---------- Methods ---------- //
|
||||
|
||||
/// Constructor
|
||||
Testetk::Matrix3x3(const etk::String& name)
|
||||
: Test(name), mIdentity(etk::Matrix3x3::identity()),
|
||||
mMatrix1(2, 24, 4, 5, -6, 234, -15, 11, 66) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// Run the tests
|
||||
void run() {
|
||||
testConstructors();
|
||||
testGetSet();
|
||||
testIdentity();
|
||||
testZero();
|
||||
testOthersMethods();
|
||||
testOperators();
|
||||
}
|
||||
|
||||
/// Test the constructors
|
||||
void testConstructors() {
|
||||
|
||||
etk::Matrix3x3 test1(5.0);
|
||||
etk::Matrix3x3 test2(2, 3, 4, 5, 6, 7, 8, 9, 10);
|
||||
etk::Matrix3x3 test3(mMatrix1);
|
||||
test(test1[0][0] == 5);
|
||||
test(test1[0][1] == 5);
|
||||
test(test1[0][2] == 5);
|
||||
test(test1[1][0] == 5);
|
||||
test(test1[1][1] == 5);
|
||||
test(test1[1][2] == 5);
|
||||
test(test1[2][0] == 5);
|
||||
test(test1[2][1] == 5);
|
||||
test(test1[2][2] == 5);
|
||||
|
||||
test(test2[0][0] == 2);
|
||||
test(test2[0][1] == 3);
|
||||
test(test2[0][2] == 4);
|
||||
test(test2[1][0] == 5);
|
||||
test(test2[1][1] == 6);
|
||||
test(test2[1][2] == 7);
|
||||
test(test2[2][0] == 8);
|
||||
test(test2[2][1] == 9);
|
||||
test(test2[2][2] == 10);
|
||||
|
||||
test(test3 == mMatrix1);
|
||||
}
|
||||
|
||||
/// Test the getter and setter methods
|
||||
void testGetSet() {
|
||||
|
||||
// Test method to set all the values
|
||||
etk::Matrix3x3 test2;
|
||||
test2.setValue(2, 24, 4, 5, -6, 234, -15, 11, 66);
|
||||
test(test2 == mMatrix1);
|
||||
|
||||
// Test method to set to zero
|
||||
test2.setZero();
|
||||
test(test2 == etk::Matrix3x3(0, 0, 0, 0, 0, 0, 0, 0, 0));
|
||||
|
||||
// Test method that returns a column
|
||||
vec3 column1 = mMatrix1.getColumn(0);
|
||||
vec3 column2 = mMatrix1.getColumn(1);
|
||||
vec3 column3 = mMatrix1.getColumn(2);
|
||||
test(column1 == vec3(2, 5, -15));
|
||||
test(column2 == vec3(24, -6, 11));
|
||||
test(column3 == vec3(4, 234, 66));
|
||||
|
||||
// Test method that returns a row
|
||||
vec3 row1 = mMatrix1.getRow(0);
|
||||
vec3 row2 = mMatrix1.getRow(1);
|
||||
vec3 row3 = mMatrix1.getRow(2);
|
||||
test(row1 == vec3(2, 24, 4));
|
||||
test(row2 == vec3(5, -6, 234));
|
||||
test(row3 == vec3(-15, 11, 66));
|
||||
}
|
||||
|
||||
/// Test the identity methods
|
||||
void testIdentity() {
|
||||
|
||||
etk::Matrix3x3 identity = Matrix3x3::identity();
|
||||
etk::Matrix3x3 test1;
|
||||
test1.setToIdentity();
|
||||
|
||||
test(identity[0][0] == 1);
|
||||
test(identity[0][1] == 0);
|
||||
test(identity[0][2] == 0);
|
||||
test(identity[1][0] == 0);
|
||||
test(identity[1][1] == 1);
|
||||
test(identity[1][2] == 0);
|
||||
test(identity[2][0] == 0);
|
||||
test(identity[2][1] == 0);
|
||||
test(identity[2][2] == 1);
|
||||
|
||||
test(test1 == etk::Matrix3x3::identity());
|
||||
}
|
||||
|
||||
/// Test the zero method
|
||||
void testZero() {
|
||||
|
||||
etk::Matrix3x3 zero = Matrix3x3::zero();
|
||||
|
||||
test(zero[0][0] == 0);
|
||||
test(zero[0][1] == 0);
|
||||
test(zero[0][2] == 0);
|
||||
test(zero[1][0] == 0);
|
||||
test(zero[1][1] == 0);
|
||||
test(zero[1][2] == 0);
|
||||
test(zero[2][0] == 0);
|
||||
test(zero[2][1] == 0);
|
||||
test(zero[2][2] == 0);
|
||||
}
|
||||
|
||||
/// Test others methods
|
||||
void testOthersMethods() {
|
||||
|
||||
// Test transpose
|
||||
etk::Matrix3x3 transpose = mMatrix1.getTranspose();
|
||||
test(transpose == etk::Matrix3x3(2, 5, -15, 24, -6, 11, 4, 234, 66));
|
||||
|
||||
// Test trace
|
||||
test(mMatrix1.getTrace() == 62);
|
||||
test(etk::Matrix3x3::identity().getTrace() == 3);
|
||||
|
||||
// Test determinant
|
||||
etk::Matrix3x3 matrix(-24, 64, 253, -35, 52, 72, 21, -35, -363);
|
||||
test(mMatrix1.getDeterminant() == -98240);
|
||||
test(matrix.getDeterminant() == -290159);
|
||||
test(mIdentity.getDeterminant() == 1);
|
||||
|
||||
// Test inverse
|
||||
etk::Matrix3x3 inverseMatrix = matrix.getInverse();
|
||||
test(approxEqual(inverseMatrix[0][0], float(0.056369), float(10e-6)));
|
||||
test(approxEqual(inverseMatrix[0][1], float(-0.049549), float(10e-6)));
|
||||
test(approxEqual(inverseMatrix[0][2], float(0.029460), float(10e-6)));
|
||||
test(approxEqual(inverseMatrix[1][0], float(0.038575), float(10e-6)));
|
||||
test(approxEqual(inverseMatrix[1][1], float(-0.011714), float(10e-6)));
|
||||
test(approxEqual(inverseMatrix[1][2], float(0.024562), float(10e-6)));
|
||||
test(approxEqual(inverseMatrix[2][0], float(-0.000458), float(10e-6)));
|
||||
test(approxEqual(inverseMatrix[2][1], float(-0.001737), float(10e-6)));
|
||||
test(approxEqual(inverseMatrix[2][2], float(-0.003419), float(10e-6)));
|
||||
etk::Matrix3x3 inverseMatrix1 = mMatrix1.getInverse();
|
||||
test(approxEqual(inverseMatrix1[0][0], float(0.030232), float(10e-6)));
|
||||
test(approxEqual(inverseMatrix1[0][1], float(0.015676), float(10e-6)));
|
||||
test(approxEqual(inverseMatrix1[0][2], float(-0.057410), float(10e-6)));
|
||||
test(approxEqual(inverseMatrix1[1][0], float(0.039088), float(10e-6)));
|
||||
test(approxEqual(inverseMatrix1[1][1], float(-0.001954), float(10e-6)));
|
||||
test(approxEqual(inverseMatrix1[1][2], float(0.004560), float(10e-6)));
|
||||
test(approxEqual(inverseMatrix1[2][0], float(0.000356), float(10e-6)));
|
||||
test(approxEqual(inverseMatrix1[2][1], float(0.003888), float(10e-6)));
|
||||
test(approxEqual(inverseMatrix1[2][2], float(0.001344), float(10e-6)));
|
||||
|
||||
// Test absolute matrix
|
||||
etk::Matrix3x3 matrix2(-2, -3, -4, -5, -6, -7, -8, -9, -10);
|
||||
test(matrix.getAbsolute() == etk::Matrix3x3(24, 64, 253, 35, 52, 72, 21, 35, 363));
|
||||
etk::Matrix3x3 absoluteMatrix = matrix2.getAbsolute();
|
||||
test(absoluteMatrix == etk::Matrix3x3(2, 3, 4, 5, 6, 7, 8, 9, 10));
|
||||
|
||||
// Test method that computes skew-symmetric matrix for cross product
|
||||
vec3 vector1(3, -5, 6);
|
||||
vec3 vector2(73, 42, 26);
|
||||
etk::Matrix3x3 skewMatrix = etk::Matrix3x3::computeSkewSymmetricMatrixForCrossProduct(vector1);
|
||||
test(skewMatrix == etk::Matrix3x3(0, -6, -5, 6, 0, -3, 5, 3, 0));
|
||||
vec3 crossProduct1 = vector1.cross(vector2);
|
||||
vec3 crossProduct2 = skewMatrix * vector2;
|
||||
test(crossProduct1 == crossProduct2);
|
||||
}
|
||||
|
||||
/// Test the operators
|
||||
void testOperators() {
|
||||
|
||||
// Test addition
|
||||
etk::Matrix3x3 matrix1(2, 3, 4, 5, 6, 7, 8, 9, 10);
|
||||
etk::Matrix3x3 matrix2(-2, 3, -5, 10, 4, 7, 2, 5, 8);
|
||||
etk::Matrix3x3 addition1 = matrix1 + matrix2;
|
||||
etk::Matrix3x3 addition2(matrix1);
|
||||
addition2 += matrix2;
|
||||
test(addition1 == etk::Matrix3x3(0, 6, -1, 15, 10, 14, 10, 14, 18));
|
||||
test(addition2 == etk::Matrix3x3(0, 6, -1, 15, 10, 14, 10, 14, 18));
|
||||
|
||||
// Test substraction
|
||||
etk::Matrix3x3 substraction1 = matrix1 - matrix2;
|
||||
etk::Matrix3x3 substraction2(matrix1);
|
||||
substraction2 -= matrix2;
|
||||
test(substraction1 == etk::Matrix3x3(4, 0, 9, -5, 2, 0, 6, 4, 2));
|
||||
test(substraction2 == etk::Matrix3x3(4, 0, 9, -5, 2, 0, 6, 4, 2));
|
||||
|
||||
// Test negative operator
|
||||
etk::Matrix3x3 negative = -matrix1;
|
||||
test(negative == etk::Matrix3x3(-2, -3, -4, -5, -6, -7, -8, -9, -10));
|
||||
|
||||
// Test multiplication with a number
|
||||
etk::Matrix3x3 multiplication1 = 3 * matrix1;
|
||||
etk::Matrix3x3 multiplication2 = matrix1 * 3;
|
||||
etk::Matrix3x3 multiplication3(matrix1);
|
||||
multiplication3 *= 3;
|
||||
test(multiplication1 == etk::Matrix3x3(6, 9, 12, 15, 18, 21, 24, 27, 30));
|
||||
test(multiplication2 == etk::Matrix3x3(6, 9, 12, 15, 18, 21, 24, 27, 30));
|
||||
test(multiplication3 == etk::Matrix3x3(6, 9, 12, 15, 18, 21, 24, 27, 30));
|
||||
|
||||
// Test multiplication with a matrix
|
||||
etk::Matrix3x3 multiplication4 = matrix1 * matrix2;
|
||||
etk::Matrix3x3 multiplication5 = matrix2 * matrix1;
|
||||
test(multiplication4 == etk::Matrix3x3(34, 38, 43, 64, 74, 73, 94, 110, 103));
|
||||
test(multiplication5 == etk::Matrix3x3(-29, -33, -37, 96, 117, 138, 93, 108, 123));
|
||||
|
||||
// Test multiplication with a vector
|
||||
vec3 vector1(3, -32, 59);
|
||||
vec3 vector2(-31, -422, 34);
|
||||
vec3 test1 = matrix1 * vector1;
|
||||
vec3 test2 = matrix2 * vector2;
|
||||
test(test1 == vec3(146, 236, 326));
|
||||
test(test2 == vec3(-1374, -1760, -1900));
|
||||
|
||||
// Test equality operators
|
||||
test(etk::Matrix3x3(34, 38, 43, 64, 74, 73, 94, 110, 103) ==
|
||||
etk::Matrix3x3(34, 38, 43, 64, 74, 73, 94, 110, 103));
|
||||
test(etk::Matrix3x3(34, 64, 43, 7, -1, 73, 94, 110, 103) !=
|
||||
etk::Matrix3x3(34, 38, 43, 64, 74, 73, 94, 110, 103));
|
||||
|
||||
// Test operator to read a value
|
||||
test(mMatrix1[0][0] == 2);
|
||||
test(mMatrix1[0][1] == 24);
|
||||
test(mMatrix1[0][2] == 4);
|
||||
test(mMatrix1[1][0] == 5);
|
||||
test(mMatrix1[1][1] == -6);
|
||||
test(mMatrix1[1][2] == 234);
|
||||
test(mMatrix1[2][0] == -15);
|
||||
test(mMatrix1[2][1] == 11);
|
||||
test(mMatrix1[2][2] == 66);
|
||||
|
||||
// Test operator to set a value
|
||||
etk::Matrix3x3 test3;
|
||||
test3[0][0] = 2;
|
||||
test3[0][1] = 24;
|
||||
test3[0][2] = 4;
|
||||
test3[1][0] = 5;
|
||||
test3[1][1] = -6;
|
||||
test3[1][2] = 234;
|
||||
test3[2][0] = -15;
|
||||
test3[2][1] = 11;
|
||||
test3[2][2] = 66;
|
||||
test(test3 == mMatrix1);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,271 +0,0 @@
|
||||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://www.ephysics.com *
|
||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef TEST_QUATERNION_H
|
||||
#define TEST_QUATERNION_H
|
||||
|
||||
// Libraries
|
||||
#include <test/Test.hpp>
|
||||
#include <ephysics/mathematics/etk::Quaternion.hpp>
|
||||
|
||||
/// Reactphysics3D namespace
|
||||
namespace ephysics {
|
||||
|
||||
// Class Testetk::Quaternion
|
||||
/**
|
||||
* Unit test for the etk::Quaternion class
|
||||
*/
|
||||
class Testetk::Quaternion : public Test {
|
||||
|
||||
private :
|
||||
|
||||
// ---------- Atributes ---------- //
|
||||
|
||||
/// Identity etk::Quaternion
|
||||
etk::Quaternion mIdentity;
|
||||
|
||||
/// First test quaternion
|
||||
etk::Quaternion mQuaternion1;
|
||||
|
||||
public :
|
||||
|
||||
// ---------- Methods ---------- //
|
||||
|
||||
/// Constructor
|
||||
Testetk::Quaternion(const etk::String& name) : Test(name), mIdentity(Quaternion::identity()) {
|
||||
|
||||
float sinA = sin(float(PI/8.0));
|
||||
float cosA = cos(float(PI/8.0));
|
||||
vec3 vector(2, 3, 4);
|
||||
vector.normalize();
|
||||
metk::Quaternion1 = etk::Quaternion(vector.x() * sinA, vector.y() * sinA, vector.z() * sinA, cosA);
|
||||
metk::Quaternion1.normalize();
|
||||
}
|
||||
|
||||
/// Run the tests
|
||||
void run() {
|
||||
testConstructors();
|
||||
testUnitLengthNormalize();
|
||||
testOthersMethods();
|
||||
testOperators();
|
||||
}
|
||||
|
||||
/// Test the constructors
|
||||
void testConstructors() {
|
||||
|
||||
etk::Quaternion quaternion1(mQuaternion1);
|
||||
test(metk::Quaternion1 == quaternion1);
|
||||
|
||||
etk::Quaternion quaternion2(4, 5, 6, 7);
|
||||
test(quaternion2 == etk::Quaternion(4, 5, 6, 7));
|
||||
|
||||
etk::Quaternion quaternion3(8, vec3(3, 5, 2));
|
||||
test(quaternion3 == etk::Quaternion(3, 5, 2, 8));
|
||||
|
||||
etk::Quaternion quaternion4(mQuaternion1.getMatrix());
|
||||
test(approxEqual(quaternion4.x(), metk::Quaternion1.x));
|
||||
test(approxEqual(quaternion4.y(), metk::Quaternion1.y));
|
||||
test(approxEqual(quaternion4.z(), metk::Quaternion1.z));
|
||||
test(approxEqual(quaternion4.w, metk::Quaternion1.w));
|
||||
|
||||
// Test conversion from Euler angles to quaternion
|
||||
|
||||
const float PI_OVER_2 = PI * 0.5f;
|
||||
const float PI_OVER_4 = PI_OVER_2 * 0.5f;
|
||||
etk::Quaternion quaternion5(PI_OVER_2, 0, 0);
|
||||
etk::Quaternion quaternionTest5(etk::sin(PI_OVER_4), 0, 0, etk::cos(PI_OVER_4));
|
||||
quaternionTest5.normalize();
|
||||
test(approxEqual(quaternion5.x(), quaternionTest5.x));
|
||||
test(approxEqual(quaternion5.y(), quaternionTest5.y));
|
||||
test(approxEqual(quaternion5.z(), quaternionTest5.z));
|
||||
test(approxEqual(quaternion5.w, quaternionTest5.w));
|
||||
|
||||
etk::Quaternion quaternion6(0, PI_OVER_2, 0);
|
||||
etk::Quaternion quaternionTest6(0, etk::sin(PI_OVER_4), 0, etk::cos(PI_OVER_4));
|
||||
quaternionTest6.normalize();
|
||||
test(approxEqual(quaternion6.x(), quaternionTest6.x));
|
||||
test(approxEqual(quaternion6.y(), quaternionTest6.y));
|
||||
test(approxEqual(quaternion6.z(), quaternionTest6.z));
|
||||
test(approxEqual(quaternion6.w, quaternionTest6.w));
|
||||
|
||||
etk::Quaternion quaternion7(vec3(0, 0, PI_OVER_2));
|
||||
etk::Quaternion quaternionTest7(0, 0, etk::sin(PI_OVER_4), etk::cos(PI_OVER_4));
|
||||
quaternionTest7.normalize();
|
||||
test(approxEqual(quaternion7.x(), quaternionTest7.x));
|
||||
test(approxEqual(quaternion7.y(), quaternionTest7.y));
|
||||
test(approxEqual(quaternion7.z(), quaternionTest7.z));
|
||||
test(approxEqual(quaternion7.w, quaternionTest7.w));
|
||||
}
|
||||
|
||||
/// Test unit, length, normalize methods
|
||||
void testUnitLengthNormalize() {
|
||||
|
||||
// Test method that returns the length
|
||||
etk::Quaternion quaternion(2, 3, -4, 5);
|
||||
test(approxEqual(quaternion.length(), sqrt(float(54.0))));
|
||||
|
||||
// Test method that returns a unit quaternion
|
||||
test(approxEqual(quaternion.safeNormalized().length(), 1.0));
|
||||
|
||||
// Test the normalization method
|
||||
etk::Quaternion quaternion2(4, 5, 6, 7);
|
||||
quaternion2.normalize();
|
||||
test(approxEqual(quaternion2.length(), 1.0));
|
||||
}
|
||||
|
||||
/// Test others methods
|
||||
void testOthersMethods() {
|
||||
|
||||
// Test the method to set the values
|
||||
etk::Quaternion quaternion;
|
||||
quaternion.setValue(1, 2, 3, 4);
|
||||
test(quaternion == etk::Quaternion(1, 2, 3, 4));
|
||||
|
||||
// Test the method to set the quaternion to zero
|
||||
quaternion.setZero();
|
||||
test(quaternion == etk::Quaternion(0, 0, 0, 0));
|
||||
|
||||
// Tes the methods to get or set to identity
|
||||
etk::Quaternion identity1(1, 2, 3, 4);
|
||||
identity1.setToIdentity();
|
||||
test(identity1 == etk::Quaternion(0, 0, 0, 1));
|
||||
test(etk::Quaternion::identity() == etk::Quaternion(0, 0, 0, 1));
|
||||
|
||||
// Test the method to get the vector (x, y, z)
|
||||
vec3 v = metk::Quaternion1.getVectorV();
|
||||
test(v.x() == metk::Quaternion1.x);
|
||||
test(v.y() == metk::Quaternion1.y);
|
||||
test(v.z() == metk::Quaternion1.z);
|
||||
|
||||
// Test the conjugate method
|
||||
etk::Quaternion conjugate = mQuaternion1.getConjugate();
|
||||
test(conjugate.x() == -metk::Quaternion1.x);
|
||||
test(conjugate.y() == -metk::Quaternion1.y);
|
||||
test(conjugate.z() == -metk::Quaternion1.z);
|
||||
test(conjugate.w == metk::Quaternion1.w);
|
||||
|
||||
// Test the inverse methods
|
||||
etk::Quaternion inverse1 = mQuaternion1.getInverse();
|
||||
etk::Quaternion inverse2(mQuaternion1);
|
||||
inverse2.inverse();
|
||||
test(inverse2 == inverse1);
|
||||
etk::Quaternion product = mQuaternion1 * inverse1;
|
||||
test(approxEqual(product.x(), mIdentity.x, float(10e-6)));
|
||||
test(approxEqual(product.y(), mIdentity.y, float(10e-6)));
|
||||
test(approxEqual(product.z(), mIdentity.z, float(10e-6)));
|
||||
test(approxEqual(product.w, mIdentity.w, float(10e-6)));
|
||||
|
||||
// Test the dot product
|
||||
etk::Quaternion quaternion1(2, 3, 4, 5);
|
||||
etk::Quaternion quaternion2(6, 7, 8, 9);
|
||||
float dotProduct = quaternion1.dot(quaternion2);
|
||||
test(dotProduct == 110);
|
||||
|
||||
// Test the method that returns the rotation angle and axis
|
||||
vec3 axis;
|
||||
float angle;
|
||||
vec3 originalAxis = vec3(2, 3, 4).safeNormalized();
|
||||
metk::Quaternion1.getRotationAngleAxis(angle, axis);
|
||||
test(approxEqual(axis.x(), originalAxis.x));
|
||||
test(approxEqual(angle, float(PI/4.0), float(10e-6)));
|
||||
|
||||
// Test the method that returns the corresponding matrix
|
||||
etk::Matrix3x3 matrix = metk::Quaternion1.getMatrix();
|
||||
vec3 vector(56, -2, 82);
|
||||
vec3 vector1 = matrix * vector;
|
||||
vec3 vector2 = metk::Quaternion1 * vector;
|
||||
test(approxEqual(vector1.x(), vector2.x, float(10e-6)));
|
||||
test(approxEqual(vector1.y(), vector2.y, float(10e-6)));
|
||||
test(approxEqual(vector1.z(), vector2.z, float(10e-6)));
|
||||
|
||||
// Test slerp method
|
||||
etk::Quaternion quatStart = quaternion1.safeNormalized();
|
||||
etk::Quaternion quatEnd = quaternion2.safeNormalized();
|
||||
etk::Quaternion test1 = etk::Quaternion::slerp(quatStart, quatEnd, 0.0);
|
||||
etk::Quaternion test2 = etk::Quaternion::slerp(quatStart, quatEnd, 1.0);
|
||||
test(test1 == quatStart);
|
||||
test(test2 == quatEnd);
|
||||
float sinA = sin(float(PI/4.0));
|
||||
float cosA = cos(float(PI/4.0));
|
||||
etk::Quaternion quat(sinA, 0, 0, cosA);
|
||||
etk::Quaternion test3 = etk::Quaternion::slerp(mIdentity, quat, 0.5f);
|
||||
test(approxEqual(test3.x(), sin(float(PI/8.0))));
|
||||
test(approxEqual(test3.y(), 0.0));
|
||||
test(approxEqual(test3.z(), 0.0));
|
||||
test(approxEqual(test3.w, cos(float(PI/8.0)), float(10e-6)));
|
||||
}
|
||||
|
||||
/// Test overloaded operators
|
||||
void testOperators() {
|
||||
|
||||
// Test addition
|
||||
etk::Quaternion quat1(4, 5, 2, 10);
|
||||
etk::Quaternion quat2(-2, 7, 8, 3);
|
||||
etk::Quaternion test1 = quat1 + quat2;
|
||||
etk::Quaternion test11(-6, 52, 2, 8);
|
||||
test11 += quat1;
|
||||
test(test1 == etk::Quaternion(2, 12, 10, 13));
|
||||
test(test11 == etk::Quaternion(-2, 57, 4, 18));
|
||||
|
||||
// Test substraction
|
||||
etk::Quaternion test2 = quat1 - quat2;
|
||||
etk::Quaternion test22(-73, 62, 25, 9);
|
||||
test22 -= quat1;
|
||||
test(test2 == etk::Quaternion(6, -2, -6, 7));
|
||||
test(test22 == etk::Quaternion(-77, 57, 23, -1));
|
||||
|
||||
// Test multiplication with a number
|
||||
etk::Quaternion test3 = quat1 * 3.0;
|
||||
test(test3 == etk::Quaternion(12, 15, 6, 30));
|
||||
|
||||
// Test multiplication between two quaternions
|
||||
etk::Quaternion test4 = quat1 * quat2;
|
||||
etk::Quaternion test5 = mQuaternion1 * mIdentity;
|
||||
test(test4 == etk::Quaternion(18, 49, 124, -13));
|
||||
test(test5 == metk::Quaternion1);
|
||||
|
||||
// Test multiplication between a quaternion and a point
|
||||
vec3 point(5, -24, 563);
|
||||
vec3 vector1 = mIdentity * point;
|
||||
vec3 vector2 = metk::Quaternion1 * point;
|
||||
vec3 testvec2 = metk::Quaternion1.getMatrix() * point;
|
||||
test(vector1 == point);
|
||||
test(approxEqual(vector2.x(), testvec2.x, float(10e-5)));
|
||||
test(approxEqual(vector2.y(), testvec2.y, float(10e-5)));
|
||||
test(approxEqual(vector2.z(), testvec2.z, float(10e-5)));
|
||||
|
||||
// Test assignment operator
|
||||
etk::Quaternion quaternion;
|
||||
quaternion = metk::Quaternion1;
|
||||
test(quaternion == metk::Quaternion1);
|
||||
|
||||
// Test equality operator
|
||||
test(metk::Quaternion1 == mQuaternion1);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,215 +0,0 @@
|
||||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://www.ephysics.com *
|
||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef TEST_TRANSFORM_H
|
||||
#define TEST_TRANSFORM_H
|
||||
|
||||
// Libraries
|
||||
#include <test/Test.hpp>
|
||||
#include <etk/math/Transform3D.hpp>
|
||||
|
||||
/// Reactphysics3D namespace
|
||||
namespace ephysics {
|
||||
|
||||
// Class Testetk::Transform3D
|
||||
/**
|
||||
* Unit test for the etk::Transform3D class
|
||||
*/
|
||||
class Testetk::Transform3D : public Test {
|
||||
|
||||
private :
|
||||
|
||||
// ---------- Atributes ---------- //
|
||||
|
||||
/// Identity transform
|
||||
etk::Transform3D mIdentityTransform;
|
||||
|
||||
/// First example transform
|
||||
etk::Transform3D m_transform1;
|
||||
|
||||
/// Second example transform
|
||||
etk::Transform3D m_transform2;
|
||||
|
||||
public :
|
||||
|
||||
// ---------- Methods ---------- //
|
||||
|
||||
/// Constructor
|
||||
Testetk::Transform3D(const etk::String& name) : Test(name) {
|
||||
|
||||
mIdentityetk::Transform3D.setToIdentity();
|
||||
|
||||
float sinA = sin(PI/8.0f);
|
||||
float cosA = cos(PI/8.0f);
|
||||
m_transform1 = etk::Transform3D(vec3(4, 5, 6), etk::Quaternion(sinA, sinA, sinA, cosA));
|
||||
|
||||
float sinB = sin(PI/3.0f);
|
||||
float cosB = cos(PI/3.0f);
|
||||
m_transform2 = etk::Transform3D(vec3(8, 45, -6), etk::Quaternion(sinB, sinB, sinB, cosB));
|
||||
}
|
||||
|
||||
/// Run the tests
|
||||
void run() {
|
||||
testConstructors();
|
||||
testGetSet();
|
||||
testInverse();
|
||||
testGetSetOpenGLMatrix();
|
||||
testInterpolateetk::Transform3D();
|
||||
testIdentity();
|
||||
testOperators();
|
||||
}
|
||||
|
||||
/// Test the constructors
|
||||
void testConstructors() {
|
||||
etk::Transform3D transform1(vec3(1, 2, 3), etk::Quaternion(6, 7, 8, 9));
|
||||
etk::Transform3D transform2(vec3(4, 5, 6), etk::Matrix3x3(1, 0, 0, 0, 1, 0, 0, 0, 1));
|
||||
etk::Transform3D transform3(transform1);
|
||||
test(transform1.getPosition() == vec3(1, 2, 3));
|
||||
test(transform1.getOrientation() == etk::Quaternion(6, 7, 8, 9));
|
||||
test(transform2.getPosition() == vec3(4, 5, 6));
|
||||
test(transform2.getOrientation() == etk::Quaternion::identity());
|
||||
test(transform3 == transform1);
|
||||
}
|
||||
|
||||
/// Test getter and setter
|
||||
void testGetSet() {
|
||||
test(mIdentityetk::Transform3D.getPosition() == vec3(0, 0, 0));
|
||||
test(mIdentityetk::Transform3D.getOrientation() == etk::Quaternion::identity());
|
||||
etk::Transform3D transform;
|
||||
transform.setPosition(vec3(5, 7, 8));
|
||||
transform.setOrientation(etk::Quaternion(1, 2, 3, 1));
|
||||
test(transform.getPosition() == vec3(5, 7, 8));
|
||||
test(transform.getOrientation() == etk::Quaternion(1, 2, 3, 1));
|
||||
transform.setToIdentity();
|
||||
test(transform.getPosition() == vec3(0, 0, 0));
|
||||
test(transform.getOrientation() == etk::Quaternion::identity());
|
||||
}
|
||||
|
||||
/// Test the inverse
|
||||
void testInverse() {
|
||||
etk::Transform3D inverseTransform = m_transform1.getInverse();
|
||||
vec3 vector(2, 3, 4);
|
||||
vec3 tempVector = m_transform1 * vector;
|
||||
vec3 tempvec2 = inverseetk::Transform3D * tempVector;
|
||||
test(approxEqual(tempvec2.x(), vector.x, float(10e-6)));
|
||||
test(approxEqual(tempvec2.y(), vector.y, float(10e-6)));
|
||||
test(approxEqual(tempvec2.z(), vector.z, float(10e-6)));
|
||||
}
|
||||
|
||||
/// Test methods to set and get transform matrix from and to OpenGL
|
||||
void testGetSetOpenGLMatrix() {
|
||||
etk::Transform3D transform;
|
||||
vec3 position = m_transform1.getPosition();
|
||||
etk::Matrix3x3 orientation = m_transform1.getOrientation().getMatrix();
|
||||
float openglMatrix[16] = {orientation[0][0], orientation[1][0],
|
||||
orientation[2][0], 0,
|
||||
orientation[0][1], orientation[1][1],
|
||||
orientation[2][1], 0,
|
||||
orientation[0][2], orientation[1][2],
|
||||
orientation[2][2], 0,
|
||||
position.x(), position.y(), position.z(), 1};
|
||||
transform.setFromOpenGL(openglMatrix);
|
||||
float openglMatrix2[16];
|
||||
transform.getOpenGLMatrix(openglMatrix2);
|
||||
test(approxEqual(openglMatrix2[0], orientation[0][0]));
|
||||
test(approxEqual(openglMatrix2[1], orientation[1][0]));
|
||||
test(approxEqual(openglMatrix2[2], orientation[2][0]));
|
||||
test(approxEqual(openglMatrix2[3], 0));
|
||||
test(approxEqual(openglMatrix2[4], orientation[0][1]));
|
||||
test(approxEqual(openglMatrix2[5], orientation[1][1]));
|
||||
test(approxEqual(openglMatrix2[6], orientation[2][1]));
|
||||
test(approxEqual(openglMatrix2[7], 0));
|
||||
test(approxEqual(openglMatrix2[8], orientation[0][2]));
|
||||
test(approxEqual(openglMatrix2[9], orientation[1][2]));
|
||||
test(approxEqual(openglMatrix2[10], orientation[2][2]));
|
||||
test(approxEqual(openglMatrix2[11], 0));
|
||||
test(approxEqual(openglMatrix2[12], position.x()));
|
||||
test(approxEqual(openglMatrix2[13], position.y()));
|
||||
test(approxEqual(openglMatrix2[14], position.z()));
|
||||
test(approxEqual(openglMatrix2[15], 1));
|
||||
}
|
||||
|
||||
/// Test the method to int32_terpolate transforms
|
||||
void testInterpolateetk::Transform3D() {
|
||||
etk::Transform3D transformStart = Transform::int32_terpolateTransforms(m_transform1, m_transform2,0);
|
||||
etk::Transform3D transformEnd = Transform::int32_terpolateTransforms(m_transform1, m_transform2,1);
|
||||
test(transformStart == m_transform1);
|
||||
test(transformEnd == m_transform2);
|
||||
|
||||
float sinA = sin(PI/3.0f);
|
||||
float cosA = cos(PI/3.0f);
|
||||
float sinB = sin(PI/6.0f);
|
||||
float cosB = cos(PI/6.0f);
|
||||
etk::Transform3D transform1(vec3(4, 5, 6), etk::Quaternion::identity());
|
||||
etk::Transform3D transform2(vec3(8, 11, 16), etk::Quaternion(sinA, sinA, sinA, cosA));
|
||||
etk::Transform3D transform = Transform::int32_terpolateTransforms(transform1, transform2, 0.5);
|
||||
vec3 position = transform.getPosition();
|
||||
etk::Quaternion orientation = transform.getOrientation();
|
||||
test(approxEqual(position.x(), 6));
|
||||
test(approxEqual(position.y(), 8));
|
||||
test(approxEqual(position.z(), 11));
|
||||
test(approxEqual(orientation.x(), sinB));
|
||||
test(approxEqual(orientation.y(), sinB));
|
||||
test(approxEqual(orientation.z(), sinB));
|
||||
test(approxEqual(orientation.w, cosB));
|
||||
}
|
||||
|
||||
/// Test the identity methods
|
||||
void testIdentity() {
|
||||
etk::Transform3D transform = Transform::identity();
|
||||
test(transform.getPosition() == vec3(0, 0, 0));
|
||||
test(transform.getOrientation() == etk::Quaternion::identity());
|
||||
|
||||
etk::Transform3D transform2(vec3(5, 6, 2), etk::Quaternion(3, 5, 1, 6));
|
||||
transform2.setToIdentity();
|
||||
test(transform2.getPosition() == vec3(0, 0, 0));
|
||||
test(transform2.getOrientation() == etk::Quaternion::identity());
|
||||
}
|
||||
|
||||
/// Test the overloaded operators
|
||||
void testOperators() {
|
||||
|
||||
// Equality, inequality operator
|
||||
test(m_transform1 == m_transform1);
|
||||
test(m_transform1 != m_transform2);
|
||||
|
||||
// Assignment operator
|
||||
etk::Transform3D transform;
|
||||
transform = m_transform1;
|
||||
test(transform == m_transform1);
|
||||
|
||||
// Multiplication
|
||||
vec3 vector(7, 53, 5);
|
||||
vec3 vector2 = m_transform2 * (m_transform1 * vector);
|
||||
vec3 vector3 = (m_transform2 * m_transform1) * vector;
|
||||
test(approxEqual(vector2.x(), vector3.x, float(10e-6)));
|
||||
test(approxEqual(vector2.y(), vector3.y, float(10e-6)));
|
||||
test(approxEqual(vector2.z(), vector3.z, float(10e-6)));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,221 +0,0 @@
|
||||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://www.ephysics.com *
|
||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef TEST_VECTOR2_H
|
||||
#define TEST_VECTOR2_H
|
||||
|
||||
// Libraries
|
||||
#include <test/Test.hpp>
|
||||
#include <etk/math/Vector2D.hpp>
|
||||
|
||||
/// Reactphysics3D namespace
|
||||
namespace ephysics {
|
||||
|
||||
// Class Testvec2
|
||||
/**
|
||||
* Unit test for the vec2 class
|
||||
*/
|
||||
class Testvec2 : public Test {
|
||||
|
||||
private :
|
||||
|
||||
// ---------- Atributes ---------- //
|
||||
|
||||
/// Zero vector
|
||||
vec2 mVectorZero;
|
||||
|
||||
// Vector (3, 4)
|
||||
vec2 mvec34;
|
||||
|
||||
public :
|
||||
|
||||
// ---------- Methods ---------- //
|
||||
|
||||
/// Constructor
|
||||
Testvec2(const etk::String& name) : Test(name), mVectorZero(0, 0), mvec34(3, 4) {}
|
||||
|
||||
/// Run the tests
|
||||
void run() {
|
||||
testConstructors();
|
||||
testLengthMethods();
|
||||
testDotProduct();
|
||||
testOthersMethods();
|
||||
testOperators();
|
||||
}
|
||||
|
||||
/// Test the constructors, getter and setter
|
||||
void testConstructors() {
|
||||
|
||||
// Test constructor
|
||||
test(mVectorZero.x() == 0.0);
|
||||
test(mVectorZero.y() == 0.0);
|
||||
test(mvec34.x() == 3.0);
|
||||
test(mvec34.y() == 4.0);
|
||||
|
||||
// Test copy-constructor
|
||||
vec2 newVector(mvec34);
|
||||
test(newVector.x() == 3.0);
|
||||
test(newVector.y() == 4.0);
|
||||
|
||||
// Test method to set values
|
||||
vec2 newvec2;
|
||||
newvec2.setValue(float(6.1), float(7.2));
|
||||
test(approxEqual(newvec2.x(), float(6.1)));
|
||||
test(approxEqual(newvec2.y(), float(7.2)));
|
||||
|
||||
// Test method to set to zero
|
||||
newvec2.setZero();
|
||||
test(newvec2 == vec2(0, 0));
|
||||
}
|
||||
|
||||
/// Test the length, unit vector and normalize methods
|
||||
void testLengthMethods() {
|
||||
|
||||
// Test length methods
|
||||
test(mVectorZero.length() == 0.0);
|
||||
test(mVectorZero.length2() == 0.0);
|
||||
test(vec2(1, 0).length() == 1.0);
|
||||
test(vec2(0, 1).length() == 1.0);
|
||||
test(mvec34.length2() == 25.0);
|
||||
|
||||
// Test unit vector methods
|
||||
test(vec2(1, 0).isUnit());
|
||||
test(vec2(0, 1).isUnit());
|
||||
test(!mvec34.isUnit());
|
||||
test(vec2(5, 0).safeNormalized() == vec2(1, 0));
|
||||
test(vec2(0, 5).safeNormalized() == vec2(0, 1));
|
||||
|
||||
test(!mvec34.isZero());
|
||||
test(mVectorZero.isZero());
|
||||
|
||||
// Test normalization method
|
||||
vec2 mVector10(1, 0);
|
||||
vec2 mVector01(0, 1);
|
||||
vec2 mVector50(5, 0);
|
||||
vec2 mVector05(0, 5);
|
||||
mVector10.normalize();
|
||||
mVector01.normalize();
|
||||
mVector50.normalize();
|
||||
mVector05.normalize();
|
||||
test(mVector10 == vec2(1, 0));
|
||||
test(mVector01 == vec2(0, 1));
|
||||
test(mVector50 == vec2(1, 0));
|
||||
test(mVector05 == vec2(0, 1));
|
||||
}
|
||||
|
||||
/// Test the dot product
|
||||
void testDotProduct() {
|
||||
|
||||
// Test the dot product
|
||||
test(vec2(5, 0).dot(vec2(0, 8)) == 0);
|
||||
test(vec2(5, 8).dot(vec2(0, 0)) == 0);
|
||||
test(vec2(12, 45).dot(vec2(0, 0)) == 0);
|
||||
test(vec2(5, 7).dot(vec2(5, 7)) == 74);
|
||||
test(vec2(3, 6).dot(vec2(-3, -6)) == -45);
|
||||
test(vec2(2, 3).dot(vec2(-7, 4)) == -2);
|
||||
test(vec2(4, 3).dot(vec2(8, 9)) == 59);
|
||||
}
|
||||
|
||||
/// Test others methods
|
||||
void testOthersMethods() {
|
||||
|
||||
// Test the method that returns the absolute vector
|
||||
test(vec2(4, 5).absolute() == vec2(4, 5));
|
||||
test(vec2(-7, -24).absolute() == vec2(7, 24));
|
||||
|
||||
// Test the method that returns the minimal element
|
||||
test(vec2(6, 35).getMinAxis() == 0);
|
||||
test(vec2(564, 45).getMinAxis() == 1);
|
||||
test(vec2(98, 23).getMinAxis() == 1);
|
||||
test(vec2(-53, -25).getMinAxis() == 0);
|
||||
|
||||
// Test the method that returns the maximal element
|
||||
test(vec2(6, 35).getMaxAxis() == 1);
|
||||
test(vec2(7, 537).getMaxAxis() == 1);
|
||||
test(vec2(98, 23).getMaxAxis() == 0);
|
||||
test(vec2(-53, -25).getMaxAxis() == 1);
|
||||
|
||||
// Test the methot that return a max/min vector
|
||||
vec2 vec1(-5, 4);
|
||||
vec2 vec2(-8, 6);
|
||||
test(vec2::min(vec1, vec2) == vec2(-8, 4));
|
||||
test(vec2::max(vec1, vec2) == vec2(-5, 6));
|
||||
}
|
||||
|
||||
/// Test the operators
|
||||
void testOperators() {
|
||||
|
||||
// Test the [] operator
|
||||
test(mvec34[0] == 3);
|
||||
test(mvec34[1] == 4);
|
||||
|
||||
// Assignment operator
|
||||
vec2 newVector(6, 4);
|
||||
newVector = vec2(7, 8);
|
||||
test(newVector == vec2(7, 8));
|
||||
|
||||
// Equality, inequality operators
|
||||
test(vec2(5, 7) == vec2(5, 7));
|
||||
test(vec2(63, 64) != vec2(63, 84));
|
||||
test(vec2(63, 64) != vec2(12, 64));
|
||||
|
||||
// Addition, substraction
|
||||
vec2 vector1(6, 33);
|
||||
vec2 vector2(7, 68);
|
||||
test(vec2(63, 24) + vec2(3, 4) == vec2(66, 28));
|
||||
test(vec2(63, 24) - vec2(3, 4) == vec2(60, 20));
|
||||
vector1 += vec2(5, 10);
|
||||
vector2 -= vec2(10, 21);
|
||||
test(vector1 == vec2(11, 43));
|
||||
test(vector2 == vec2(-3, 47));
|
||||
|
||||
// Multiplication, division
|
||||
vec2 vector3(6, 33);
|
||||
vec2 vector4(15, 60);
|
||||
test(vec2(63, 24) * 3 == vec2(189, 72));
|
||||
test(3 * vec2(63, 24) == vec2(189, 72));
|
||||
test(vec2(14, 8) / 2 == vec2(7, 4));
|
||||
vector3 *= 10;
|
||||
vector4 /= 3;
|
||||
test(vector3 == vec2(60, 330));
|
||||
test(vector4 == vec2(5, 20));
|
||||
vec2 vector5(21, 80);
|
||||
vec2 vector6(7, 10);
|
||||
vec2 vector7 = vector5 * vector6;
|
||||
test(vector7 == vec2(147, 800));
|
||||
vec2 vector8 = vector5 / vector6;
|
||||
test(approxEqual(vector8.x(), 3));
|
||||
test(approxEqual(vector8.y(), 8));
|
||||
|
||||
// Negative operator
|
||||
vec2 vector9(-34, 5);
|
||||
vec2 negative = -vector9;
|
||||
test(negative == vec2(34, -5));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,246 +0,0 @@
|
||||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://www.ephysics.com *
|
||||
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef TEST_VECTOR3_H
|
||||
#define TEST_VECTOR3_H
|
||||
|
||||
// Libraries
|
||||
#include <test/Test.hpp>
|
||||
#include <etk/math/Vector3D.hpp>
|
||||
|
||||
/// Reactphysics3D namespace
|
||||
namespace ephysics {
|
||||
|
||||
// Class Testvec3
|
||||
/**
|
||||
* Unit test for the vec3 class
|
||||
*/
|
||||
class Testvec3 : public Test {
|
||||
|
||||
private :
|
||||
|
||||
// ---------- Atributes ---------- //
|
||||
|
||||
/// Zero vector
|
||||
vec3 mVectorZero;
|
||||
|
||||
// Vector (3, 4, 5)
|
||||
vec3 mvec345;
|
||||
|
||||
public :
|
||||
|
||||
// ---------- Methods ---------- //
|
||||
|
||||
/// Constructor
|
||||
Testvec3(const etk::String& name): Test(name),mVectorZero(0, 0, 0),mvec345(3, 4, 5) {}
|
||||
|
||||
/// Run the tests
|
||||
void run() {
|
||||
testConstructors();
|
||||
testLengthMethods();
|
||||
testDotCrossProducts();
|
||||
testOthersMethods();
|
||||
testOperators();
|
||||
}
|
||||
|
||||
/// Test the constructors, getter and setter
|
||||
void testConstructors() {
|
||||
|
||||
// Test constructor
|
||||
test(mVectorZero.x() == 0.0);
|
||||
test(mVectorZero.y() == 0.0);
|
||||
test(mVectorZero.z() == 0.0);
|
||||
test(mvec345.x() == 3.0);
|
||||
test(mvec345.y() == 4.0);
|
||||
test(mvec345.z() == 5.0);
|
||||
|
||||
// Test copy-constructor
|
||||
vec3 newVector(mvec345);
|
||||
test(newVector.x() == 3.0);
|
||||
test(newVector.y() == 4.0);
|
||||
test(newVector.z() == 5.0);
|
||||
|
||||
// Test method to set values
|
||||
vec3 newvec2;
|
||||
newvec2.setValue(float(6.1), float(7.2), float(8.6));
|
||||
test(approxEqual(newvec2.x(), float(6.1)));
|
||||
test(approxEqual(newvec2.y(), float(7.2)));
|
||||
test(approxEqual(newvec2.z(), float(8.6)));
|
||||
|
||||
// Test method to set to zero
|
||||
newvec2.setZero();
|
||||
test(newvec2 == vec3(0, 0, 0));
|
||||
}
|
||||
|
||||
/// Test the length, unit vector and normalize methods
|
||||
void testLengthMethods() {
|
||||
|
||||
// Test length methods
|
||||
test(mVectorZero.length() == 0.0);
|
||||
test(mVectorZero.length2() == 0.0);
|
||||
test(vec3(1, 0, 0).length() == 1.0);
|
||||
test(vec3(0, 1, 0).length() == 1.0);
|
||||
test(vec3(0, 0, 1).length() == 1.0);
|
||||
test(mvec345.length2() == 50.0);
|
||||
|
||||
// Test unit vector methods
|
||||
test(vec3(1, 0, 0).isUnit());
|
||||
test(vec3(0, 1, 0).isUnit());
|
||||
test(vec3(0, 0, 1).isUnit());
|
||||
test(!mvec345.isUnit());
|
||||
test(vec3(5, 0, 0).safeNormalized() == vec3(1, 0, 0));
|
||||
test(vec3(0, 5, 0).safeNormalized() == vec3(0, 1, 0));
|
||||
test(vec3(0, 0, 5).safeNormalized() == vec3(0, 0, 1));
|
||||
|
||||
test(!mvec345.isZero());
|
||||
test(mVectorZero.isZero());
|
||||
|
||||
// Test normalization method
|
||||
vec3 mVector100(1, 0, 0);
|
||||
vec3 mVector010(0, 1, 0);
|
||||
vec3 mVector001(0, 0, 1);
|
||||
vec3 mVector500(5, 0, 0);
|
||||
vec3 mVector050(0, 5, 0);
|
||||
vec3 mVector005(0, 0, 5);
|
||||
mVector100.normalize();
|
||||
mVector010.normalize();
|
||||
mVector001.normalize();
|
||||
mVector500.normalize();
|
||||
mVector050.normalize();
|
||||
mVector005.normalize();
|
||||
test(mVector100 == vec3(1, 0, 0));
|
||||
test(mVector010 == vec3(0, 1, 0));
|
||||
test(mVector001 == vec3(0, 0, 1));
|
||||
test(mVector500 == vec3(1, 0, 0));
|
||||
test(mVector050 == vec3(0, 1, 0));
|
||||
test(mVector005 == vec3(0, 0, 1));
|
||||
}
|
||||
|
||||
/// Test the dot and cross products
|
||||
void testDotCrossProducts() {
|
||||
|
||||
// Test the dot product
|
||||
test(vec3(5, 0, 0).dot(vec3(0, 8, 0)) == 0);
|
||||
test(vec3(5, 8, 0).dot(vec3(0, 0, 6)) == 0);
|
||||
test(vec3(12, 45, 83).dot(vec3(0, 0, 0)) == 0);
|
||||
test(vec3(5, 7, 8).dot(vec3(5, 7, 8)) == 138);
|
||||
test(vec3(3, 6, 78).dot(vec3(-3, -6, -78)) == -6129);
|
||||
test(vec3(2, 3, 5).dot(vec3(2, 3, 5)) == 38);
|
||||
test(vec3(4, 3, 2).dot(vec3(8, 9, 10)) == 79);
|
||||
|
||||
// Test the cross product
|
||||
test(vec3(0, 0, 0).cross(vec3(0, 0, 0)) == vec3(0, 0, 0));
|
||||
test(vec3(6, 7, 2).cross(vec3(6, 7, 2)) == vec3(0, 0, 0));
|
||||
test(vec3(1, 0, 0).cross(vec3(0, 1, 0)) == vec3(0, 0, 1));
|
||||
test(vec3(0, 1, 0).cross(vec3(0, 0, 1)) == vec3(1, 0, 0));
|
||||
test(vec3(0, 0, 1).cross(vec3(0, 1, 0)) == vec3(-1, 0, 0));
|
||||
test(vec3(4, 7, 24).cross(vec3(8, 13, 11)) == vec3(-235, 148, -4));
|
||||
test(vec3(-4, 42, -2).cross(vec3(35, 7, -21)) == vec3(-868, -154, -1498));
|
||||
}
|
||||
|
||||
/// Test others methods
|
||||
void testOthersMethods() {
|
||||
|
||||
// Test the method that returns the absolute vector
|
||||
test(vec3(4, 5, 6).absolute() == vec3(4, 5, 6));
|
||||
test(vec3(-7, -24, -12).absolute() == vec3(7, 24, 12));
|
||||
|
||||
// Test the method that returns the minimal element
|
||||
test(vec3(6, 35, 82).getMinAxis() == 0);
|
||||
test(vec3(564, 45, 532).getMinAxis() == 1);
|
||||
test(vec3(98, 23, 3).getMinAxis() == 2);
|
||||
test(vec3(-53, -25, -63).getMinAxis() == 2);
|
||||
|
||||
// Test the method that returns the maximal element
|
||||
test(vec3(6, 35, 82).getMaxAxis() == 2);
|
||||
test(vec3(7, 533, 36).getMaxAxis() == 1);
|
||||
test(vec3(98, 23, 3).getMaxAxis() == 0);
|
||||
test(vec3(-53, -25, -63).getMaxAxis() == 1);
|
||||
|
||||
// Test the methot that return a max/min vector
|
||||
vec3 vec1(-5, 4, 2);
|
||||
vec3 vec2(-8, 6, -1);
|
||||
test(vec3::min(vec1, vec2) == vec3(-8, 4, -1));
|
||||
test(vec3::max(vec1, vec2) == vec3(-5, 6, 2));
|
||||
}
|
||||
|
||||
/// Test the operators
|
||||
void testOperators() {
|
||||
|
||||
// Test the [] operator
|
||||
test(mvec345[0] == 3);
|
||||
test(mvec345[1] == 4);
|
||||
test(mvec345[2] == 5);
|
||||
|
||||
// Assignment operator
|
||||
vec3 newVector(6, 4, 2);
|
||||
newVector = vec3(7, 8, 9);
|
||||
test(newVector == vec3(7, 8, 9));
|
||||
|
||||
// Equality, inequality operators
|
||||
test(vec3(5, 7, 3) == vec3(5, 7, 3));
|
||||
test(vec3(63, 64, 24) != vec3(63, 64, 5));
|
||||
test(vec3(63, 64, 24) != vec3(12, 64, 24));
|
||||
test(vec3(63, 64, 24) != vec3(63, 8, 24));
|
||||
|
||||
// Addition, substraction
|
||||
vec3 vector1(6, 33, 62);
|
||||
vec3 vector2(7, 68, 35);
|
||||
test(vec3(63, 24, 5) + vec3(3, 4, 2) == vec3(66, 28, 7));
|
||||
test(vec3(63, 24, 5) - vec3(3, 4, 2) == vec3(60, 20, 3));
|
||||
vector1 += vec3(5, 10, 12);
|
||||
vector2 -= vec3(10, 21, 5);
|
||||
test(vector1 == vec3(11, 43, 74));
|
||||
test(vector2 == vec3(-3, 47, 30));
|
||||
|
||||
// Multiplication, division
|
||||
vec3 vector3(6, 33, 62);
|
||||
vec3 vector4(15, 60, 33);
|
||||
test(vec3(63, 24, 5) * 3 == vec3(189, 72, 15));
|
||||
test(3 * vec3(63, 24, 5) == vec3(189, 72, 15));
|
||||
test(vec3(14, 8, 50) / 2 == vec3(7, 4, 25));
|
||||
vector3 *= 10;
|
||||
vector4 /= 3;
|
||||
test(vector3 == vec3(60, 330, 620));
|
||||
test(vector4 == vec3(5, 20, 11));
|
||||
vec3 vector5(21, 80, 45);
|
||||
vec3 vector6(7, 10, 3);
|
||||
vec3 vector7 = vector5 * vector6;
|
||||
test(vector7 == vec3(147, 800, 135));
|
||||
vec3 vector8 = vector5 / vector6;
|
||||
test(approxEqual(vector8.x(), 3));
|
||||
test(approxEqual(vector8.y(), 8));
|
||||
test(approxEqual(vector8.z(), 15));
|
||||
|
||||
// Negative operator
|
||||
vec3 vector9(-34, 5, 422);
|
||||
vec3 negative = -vector9;
|
||||
test(negative == vec3(34, -5, -422));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user