diff --git a/testbed/CMakeLists.txt b/testbed/CMakeLists.txt index b832c65f..8e0ff946 100755 --- a/testbed/CMakeLists.txt +++ b/testbed/CMakeLists.txt @@ -155,6 +155,8 @@ set(SCENES_SOURCES scenes/fixedjoint/FixedJointScene.cpp scenes/ballandsocketjoint/BallAndSocketJointScene.h scenes/ballandsocketjoint/BallAndSocketJointScene.cpp + scenes/hingejoint/HingeJointScene.h + scenes/hingejoint/HingeJointScene.cpp ) # Create the executable diff --git a/testbed/scenes/hingejoint/HingeJointScene.cpp b/testbed/scenes/hingejoint/HingeJointScene.cpp new file mode 100644 index 00000000..4f0ee76c --- /dev/null +++ b/testbed/scenes/hingejoint/HingeJointScene.cpp @@ -0,0 +1,145 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.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 "HingeJointScene.h" +#include + +// Namespaces +using namespace openglframework; +using namespace hingejointscene; + +// Constructor +HingeJointScene::HingeJointScene(const std::string& name, EngineSettings& settings) + : SceneDemo(name, settings, true, SCENE_RADIUS) { + + // Compute the radius and the center of the scene + openglframework::Vector3 center(0, 5, 0); + + // Set the center of the scene + setScenePosition(center, SCENE_RADIUS); + + // Gravity vector in the physics world + rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0); + + rp3d::PhysicsWorld::WorldSettings worldSettings; + worldSettings.worldName = name; + + // Logger + rp3d::DefaultLogger* defaultLogger = mPhysicsCommon.createDefaultLogger(); + uint logLevel = static_cast(rp3d::Logger::Level::Information) | static_cast(rp3d::Logger::Level::Warning) | + static_cast(rp3d::Logger::Level::Error); + defaultLogger->addFileDestination("rp3d_log_" + name + ".html", logLevel, rp3d::DefaultLogger::Format::HTML); + mPhysicsCommon.setLogger(defaultLogger); + + // Create the physics world for the physics simulation + rp3d::PhysicsWorld* physicsWorld = mPhysicsCommon.createPhysicsWorld(worldSettings); + physicsWorld->setEventListener(this); + mPhysicsWorld = physicsWorld; + + // Create the Hinge joint + createHingeJoint(); + + // Get the physics engine parameters + mEngineSettings.isGravityEnabled = mPhysicsWorld->isGravityEnabled(); + rp3d::Vector3 gravityVector = mPhysicsWorld->getGravity(); + mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); + mEngineSettings.isSleepingEnabled = mPhysicsWorld->isSleepingEnabled(); + mEngineSettings.sleepLinearVelocity = mPhysicsWorld->getSleepLinearVelocity(); + mEngineSettings.sleepAngularVelocity = mPhysicsWorld->getSleepAngularVelocity(); + mEngineSettings.nbPositionSolverIterations = mPhysicsWorld->getNbIterationsPositionSolver(); + mEngineSettings.nbVelocitySolverIterations = mPhysicsWorld->getNbIterationsVelocitySolver(); + mEngineSettings.timeBeforeSleep = mPhysicsWorld->getTimeBeforeSleep(); +} + +// Destructor +HingeJointScene::~HingeJointScene() { + + // Destroy the joints + mPhysicsWorld->destroyJoint(mJoint); + + // Destroy all the rigid bodies of the scene + mPhysicsWorld->destroyRigidBody(mBox1->getRigidBody()); + mPhysicsWorld->destroyRigidBody(mBox2->getRigidBody()); + + delete mBox1; + delete mBox2; + + // Destroy the physics world + mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); +} + +// Reset the scene +void HingeJointScene::reset() { + + SceneDemo::reset(); + + mBox1->setTransform(rp3d::Transform(rp3d::Vector3(0, 4, 0), rp3d::Quaternion::identity())); + mBox2->setTransform(rp3d::Transform(rp3d::Vector3(4, 4, 0), rp3d::Quaternion::identity())); +} + +/// Create the hinge joint +void HingeJointScene::createHingeJoint() { + + // --------------- Create the boxes --------------- // + + // Create a box and a corresponding rigid in the physics world + mBox1 = new Box(true, Vector3(4, 4, 4), mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); + mBox1->setTransform(rp3d::Transform(rp3d::Vector3(0, 4, 0), rp3d::Quaternion::identity())); + mBox1->getRigidBody()->setType(rp3d::BodyType::STATIC); + + // Set the box color + mBox1->setColor(mObjectColorDemo); + mBox1->setSleepingColor(mSleepingColorDemo); + + // Change the material properties of the rigid body + mPhysicsObjects.push_back(mBox1); + + // Create a box and a corresponding rigid in the physics world + mBox2 = new Box(true, Vector3(4, 4, 4), mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); + mBox2->setTransform(rp3d::Transform(rp3d::Vector3(4, 4, 0), rp3d::Quaternion::identity())); + + // Set the box color + mBox2->setColor(mObjectColorDemo); + mBox2->setSleepingColor(mSleepingColorDemo); + + // Change the material properties of the rigid body + mPhysicsObjects.push_back(mBox2); + + // --------------- Create the Hinge joint --------------- // + + // Create the joint info object + rp3d::RigidBody* body1 = mBox1->getRigidBody(); + rp3d::RigidBody* body2 = mBox2->getRigidBody(); + const rp3d::Vector3& body1Position = body1->getTransform().getPosition(); + const rp3d::Vector3& body2Position = body2->getTransform().getPosition(); + const rp3d::Vector3 anchorPointWorldSpace = 0.5 * (body2Position + body1Position) - rp3d::Vector3(0, 2, 0); + const rp3d::Vector3 hingeAxisWorldSpace(0, 0, 1); + rp3d::HingeJointInfo jointInfo(body1, body2, anchorPointWorldSpace, hingeAxisWorldSpace); + jointInfo.isCollisionEnabled = false; + + // Create the joint in the physics world + mJoint = dynamic_cast(mPhysicsWorld->createJoint(jointInfo)); +} diff --git a/testbed/scenes/hingejoint/HingeJointScene.h b/testbed/scenes/hingejoint/HingeJointScene.h new file mode 100644 index 00000000..4d64e32f --- /dev/null +++ b/testbed/scenes/hingejoint/HingeJointScene.h @@ -0,0 +1,81 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.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 HINGE_JOINT_SCENE_H +#define HINGE_JOINT_SCENE_H + +// Libraries +#include "openglframework.h" +#include +#include "Box.h" +#include "SceneDemo.h" + +namespace hingejointscene { + +// Constants +const float SCENE_RADIUS = 30.0f; +const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters +const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions in meters +const int NB_BALLSOCKETJOINT_BOXES = 7; // Number of Ball-And-Socket chain boxes +const int NB_HINGE_BOXES = 7; // Number of Hinge chain boxes + +// Class HingeJointScene +class HingeJointScene : public SceneDemo { + + protected : + + // -------------------- Attributes -------------------- // + + /// First box + Box* mBox1; + + /// Second box + Box* mBox2; + + /// Hinge joint + rp3d::HingeJoint* mJoint; + + // -------------------- Methods -------------------- // + + /// Create the boxes and joint for the Hinge joint example + void createHingeJoint(); + + public: + + // -------------------- Methods -------------------- // + + /// Constructor + HingeJointScene(const std::string& name, EngineSettings& settings); + + /// Destructor + virtual ~HingeJointScene() override ; + + /// Reset the scene + virtual void reset() override; +}; + +} + +#endif diff --git a/testbed/src/TestbedApplication.cpp b/testbed/src/TestbedApplication.cpp index b9c00b06..02289fa2 100755 --- a/testbed/src/TestbedApplication.cpp +++ b/testbed/src/TestbedApplication.cpp @@ -45,6 +45,7 @@ #include "bridge/BridgeScene.h" #include "fixedjoint/FixedJointScene.h" #include "ballandsocketjoint/BallAndSocketJointScene.h" +#include "hingejoint/HingeJointScene.h" using namespace openglframework; using namespace jointsscene; @@ -63,6 +64,7 @@ using namespace hingejointschainscene; using namespace bridgescene; using namespace fixedjointscene; using namespace ballandsocketjointscene; +using namespace hingejointscene; // Initialization of static variables const float TestbedApplication::SCROLL_SENSITIVITY = 0.08f; @@ -189,6 +191,10 @@ void TestbedApplication::createScenes() { BallAndSocketJointScene* ballAndSocketJointScene = new BallAndSocketJointScene("Ball and Socket joint", mEngineSettings); mScenes.push_back(ballAndSocketJointScene); + // Hinge joint scene + HingeJointScene* hingeJointScene = new HingeJointScene("Hinge joint", mEngineSettings); + mScenes.push_back(hingeJointScene); + assert(mScenes.size() > 0); const int firstSceneIndex = 0;