From 152c239a2aab98bb00c8f340e39ffbb643720f01 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Sat, 17 Oct 2020 18:00:23 +0200 Subject: [PATCH] Add ball-and-socket joints chain and hinge joints chain demos in testbed application --- testbed/CMakeLists.txt | 4 + .../BallAndSocketJointsChainScene.cpp | 159 ++++++++++++++++++ .../BallAndSocketJointsChainScene.h | 76 +++++++++ .../HingeJointsChainScene.cpp | 159 ++++++++++++++++++ .../hingejointschain/HingeJointsChainScene.h | 76 +++++++++ testbed/src/TestbedApplication.cpp | 15 +- 6 files changed, 487 insertions(+), 2 deletions(-) create mode 100644 testbed/scenes/ballandsocketjointschain/BallAndSocketJointsChainScene.cpp create mode 100644 testbed/scenes/ballandsocketjointschain/BallAndSocketJointsChainScene.h create mode 100644 testbed/scenes/hingejointschain/HingeJointsChainScene.cpp create mode 100644 testbed/scenes/hingejointschain/HingeJointsChainScene.h diff --git a/testbed/CMakeLists.txt b/testbed/CMakeLists.txt index db74010a..ea09cef7 100755 --- a/testbed/CMakeLists.txt +++ b/testbed/CMakeLists.txt @@ -125,6 +125,10 @@ set(COMMON_SOURCES set(SCENES_SOURCES scenes/ballandsocketjointsnet/BallAndSocketJointsNetScene.h scenes/ballandsocketjointsnet/BallAndSocketJointsNetScene.cpp + scenes/ballandsocketjointschain/BallAndSocketJointsChainScene.h + scenes/ballandsocketjointschain/BallAndSocketJointsChainScene.cpp + scenes/hingejointschain/HingeJointsChainScene.h + scenes/hingejointschain/HingeJointsChainScene.cpp scenes/cubes/CubesScene.h scenes/cubes/CubesScene.cpp scenes/joints/JointsScene.h diff --git a/testbed/scenes/ballandsocketjointschain/BallAndSocketJointsChainScene.cpp b/testbed/scenes/ballandsocketjointschain/BallAndSocketJointsChainScene.cpp new file mode 100644 index 00000000..8653d1c2 --- /dev/null +++ b/testbed/scenes/ballandsocketjointschain/BallAndSocketJointsChainScene.cpp @@ -0,0 +1,159 @@ +/******************************************************************************** +* 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 "BallAndSocketJointsChainScene.h" +#include + +// Namespaces +using namespace openglframework; +using namespace ballandsocketjointschainscene; + +// Constructor +BallAndSocketJointsChainScene::BallAndSocketJointsChainScene(const std::string& name, EngineSettings& settings) + : SceneDemo(name, settings, true, SCENE_RADIUS) { + + std::string meshFolderPath("meshes/"); + + // Compute the radius and the center of the scene + openglframework::Vector3 center(0, 0, 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 all the spheres of the scene + for (int i=0; isetColor(mObjectColorDemo); + mSpheres[i]->setSleepingColor(mSleepingColorDemo); + + // Change the material properties of the rigid body + rp3d::Material& material = mSpheres[i]->getCollider()->getMaterial(); + material.setBounciness(rp3d::decimal(0.0)); + + if (i == 0) { + mSpheres[i]->getRigidBody()->setType(rp3d::BodyType::STATIC); + } + + // Add the sphere the list of sphere in the scene + mPhysicsObjects.push_back(mSpheres[i]); + } + + // Set the position of the spheres before the joints creation + reset(); + + // Create the Ball-and-Socket joints + createJoints(); + + // 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 +BallAndSocketJointsChainScene::~BallAndSocketJointsChainScene() { + + // Destroy the joints + for (uint i=0; i < mBallAndSocketJoints.size(); i++) { + + mPhysicsWorld->destroyJoint(mBallAndSocketJoints[i]); + } + + // Destroy all the rigid bodies of the scene + for (int i=0; idestroyRigidBody(mSpheres[i]->getRigidBody()); + } + + // Destroy the physics world + mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); +} + +// Create the joints +void BallAndSocketJointsChainScene::createJoints() { + + for (int i=0; i < NB_SPHERES-1; i++) { + + // Create the joint info object + rp3d::RigidBody* body1 = mSpheres[i]->getRigidBody(); + rp3d::RigidBody* body2 = mSpheres[i+1]->getRigidBody(); + rp3d::Vector3 body1Position = body1->getTransform().getPosition(); + rp3d::Vector3 body2Position = body2->getTransform().getPosition(); + const rp3d::Vector3 anchorPointWorldSpace = body1Position; + rp3d::BallAndSocketJointInfo jointInfo(body1, body2, anchorPointWorldSpace); + jointInfo.isCollisionEnabled = false; + rp3d::BallAndSocketJoint* joint = dynamic_cast( mPhysicsWorld->createJoint(jointInfo)); + mBallAndSocketJoints.push_back(joint); + } +} + +// Reset the scene +void BallAndSocketJointsChainScene::reset() { + + SceneDemo::reset(); + + const float space = 0.5f; + + const rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); + + for (int i=0; isetTransform(transform); + } +} diff --git a/testbed/scenes/ballandsocketjointschain/BallAndSocketJointsChainScene.h b/testbed/scenes/ballandsocketjointschain/BallAndSocketJointsChainScene.h new file mode 100644 index 00000000..c3bbdebd --- /dev/null +++ b/testbed/scenes/ballandsocketjointschain/BallAndSocketJointsChainScene.h @@ -0,0 +1,76 @@ +/******************************************************************************** +* 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 BALL_AND_SOCKET_JOINTS_CHAIN_SCENE_H +#define BALL_AND_SOCKET_JOINTS_CHAIN_SCENE_H + +// Libraries +#include "openglframework.h" +#include +#include "Sphere.h" +#include "SceneDemo.h" + +namespace ballandsocketjointschainscene { + +// Constants +const float SCENE_RADIUS = 60.0f; +const float SPHERE_RADIUS = 1.0f; +const int NB_SPHERES = 20; + +// Class BallAndSocketJointsChain scene +class BallAndSocketJointsChainScene : public SceneDemo { + + protected : + + // -------------------- Attributes -------------------- // + + /// Spheres in the Ball-And-Socket joint net + Sphere* mSpheres[NB_SPHERES]; + + /// Ball-And-Socket joints of the chain + std::vector mBallAndSocketJoints; + + // -------------------- Methods -------------------- // + + /// Create the joints + void createJoints(); + + public: + + // -------------------- Methods -------------------- // + + /// Constructor + BallAndSocketJointsChainScene(const std::string& name, EngineSettings& settings); + + /// Destructor + virtual ~BallAndSocketJointsChainScene() override ; + + /// Reset the scene + virtual void reset() override; +}; + +} + +#endif diff --git a/testbed/scenes/hingejointschain/HingeJointsChainScene.cpp b/testbed/scenes/hingejointschain/HingeJointsChainScene.cpp new file mode 100644 index 00000000..e6ebc47f --- /dev/null +++ b/testbed/scenes/hingejointschain/HingeJointsChainScene.cpp @@ -0,0 +1,159 @@ +/******************************************************************************** +* 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 "HingeJointsChainScene.h" +#include + +// Namespaces +using namespace openglframework; +using namespace hingejointschainscene; + +// Constructor +HingeJointsChainScene::HingeJointsChainScene(const std::string& name, EngineSettings& settings) + : SceneDemo(name, settings, true, SCENE_RADIUS) { + + std::string meshFolderPath("meshes/"); + + // Compute the radius and the center of the scene + openglframework::Vector3 center(0, 0, 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 all the boxes of the scene + for (int i=0; isetColor(mObjectColorDemo); + mBoxes[i]->setSleepingColor(mSleepingColorDemo); + + // Change the material properties of the rigid body + rp3d::Material& material = mBoxes[i]->getCollider()->getMaterial(); + material.setBounciness(rp3d::decimal(0.0)); + + if (i == 0) { + mBoxes[i]->getRigidBody()->setType(rp3d::BodyType::STATIC); + } + + // Add the box the list of boxes in the scene + mPhysicsObjects.push_back(mBoxes[i]); + } + + // Set the position of the boxes before the joints creation + reset(); + + // Create the Ball-and-Socket joints + createJoints(); + + // 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 +HingeJointsChainScene::~HingeJointsChainScene() { + + // Destroy the joints + for (uint i=0; i < mHingeJoints.size(); i++) { + + mPhysicsWorld->destroyJoint(mHingeJoints[i]); + } + + // Destroy all the rigid bodies of the scene + for (int i=0; idestroyRigidBody(mBoxes[i]->getRigidBody()); + } + + // Destroy the physics world + mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); +} + +// Create the joints +void HingeJointsChainScene::createJoints() { + + for (int i=0; i < NB_BOXES-1; i++) { + + // Create the joint info object + rp3d::RigidBody* body1 = mBoxes[i]->getRigidBody(); + rp3d::RigidBody* body2 = mBoxes[i+1]->getRigidBody(); + rp3d::Vector3 body1Position = body1->getTransform().getPosition(); + rp3d::Vector3 body2Position = body2->getTransform().getPosition(); + const rp3d::Vector3 anchorPointWorldSpace = body1Position + rp3d::Vector3(BOX_SIZE.x / 2.0f, 0, 0); + rp3d::HingeJointInfo jointInfo(body1, body2, anchorPointWorldSpace, rp3d::Vector3(0, 0, 1)); + jointInfo.isCollisionEnabled = false; + rp3d::HingeJoint* joint = dynamic_cast(mPhysicsWorld->createJoint(jointInfo)); + mHingeJoints.push_back(joint); + } +} + +// Reset the scene +void HingeJointsChainScene::reset() { + + SceneDemo::reset(); + + const float space = 0.3f; + + const rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); + + for (int i=0; isetTransform(transform); + } +} diff --git a/testbed/scenes/hingejointschain/HingeJointsChainScene.h b/testbed/scenes/hingejointschain/HingeJointsChainScene.h new file mode 100644 index 00000000..ad37b612 --- /dev/null +++ b/testbed/scenes/hingejointschain/HingeJointsChainScene.h @@ -0,0 +1,76 @@ +/******************************************************************************** +* 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_JOINTS_CHAIN_SCENE_H +#define HINGE_JOINTS_CHAIN_SCENE_H + +// Libraries +#include "openglframework.h" +#include +#include "Box.h" +#include "SceneDemo.h" + +namespace hingejointschainscene { + +// Constants +const float SCENE_RADIUS = 60.0f; +const openglframework::Vector3 BOX_SIZE = openglframework::Vector3(2, 1, 1); +const int NB_BOXES = 20; + +// Class HingeJointsChain scene +class HingeJointsChainScene : public SceneDemo { + + protected : + + // -------------------- Attributes -------------------- // + + /// Boxes + Box* mBoxes[NB_BOXES]; + + /// Hinge joints of the chain + std::vector mHingeJoints; + + // -------------------- Methods -------------------- // + + /// Create the joints + void createJoints(); + + public: + + // -------------------- Methods -------------------- // + + /// Constructor + HingeJointsChainScene(const std::string& name, EngineSettings& settings); + + /// Destructor + virtual ~HingeJointsChainScene() override ; + + /// Reset the scene + virtual void reset() override; +}; + +} + +#endif diff --git a/testbed/src/TestbedApplication.cpp b/testbed/src/TestbedApplication.cpp index 78e5a812..337ea96a 100755 --- a/testbed/src/TestbedApplication.cpp +++ b/testbed/src/TestbedApplication.cpp @@ -40,6 +40,8 @@ #include "pile/PileScene.h" #include "boxtower/BoxTowerScene.h" #include "ballandsocketjointsnet/BallAndSocketJointsNetScene.h" +#include "ballandsocketjointschain/BallAndSocketJointsChainScene.h" +#include "hingejointschain/HingeJointsChainScene.h" using namespace openglframework; using namespace jointsscene; @@ -53,6 +55,8 @@ using namespace cubestackscene; using namespace pilescene; using namespace boxtowerscene; using namespace ballandsocketjointsnetscene; +using namespace ballandsocketjointschainscene; +using namespace hingejointschainscene; // Initialization of static variables const float TestbedApplication::SCROLL_SENSITIVITY = 0.08f; @@ -147,16 +151,23 @@ void TestbedApplication::createScenes() { // Pile scene PileScene* pileScene = new PileScene("Pile", mEngineSettings); mScenes.push_back(pileScene); - assert(mScenes.size() > 0); // Box Tower scene BoxTowerScene* boxTowerScene = new BoxTowerScene("Box Tower", mEngineSettings); mScenes.push_back(boxTowerScene); - assert(mScenes.size() > 0); // Ball and Socket joints Net scene BallAndSocketJointsNetScene* ballAndSocketJointsNetScene = new BallAndSocketJointsNetScene("BallAndSocket Joints Net", mEngineSettings); mScenes.push_back(ballAndSocketJointsNetScene); + + // Ball and Socket joints chain scene + BallAndSocketJointsChainScene* ballAndSocketJointsChainScene = new BallAndSocketJointsChainScene("BallAndSocket Joints Chain", mEngineSettings); + mScenes.push_back(ballAndSocketJointsChainScene); + + // Hinge joints chain scene + HingeJointsChainScene* hingeJointsChainScene = new HingeJointsChainScene("Hinge Joints Chain", mEngineSettings); + mScenes.push_back(hingeJointsChainScene); + assert(mScenes.size() > 0); const int firstSceneIndex = 0;