diff --git a/testbed/CMakeLists.txt b/testbed/CMakeLists.txt index 29459aaf..db74010a 100755 --- a/testbed/CMakeLists.txt +++ b/testbed/CMakeLists.txt @@ -123,6 +123,8 @@ set(COMMON_SOURCES # Examples scenes source files set(SCENES_SOURCES + scenes/ballandsocketjointsnet/BallAndSocketJointsNetScene.h + scenes/ballandsocketjointsnet/BallAndSocketJointsNetScene.cpp scenes/cubes/CubesScene.h scenes/cubes/CubesScene.cpp scenes/joints/JointsScene.h diff --git a/testbed/scenes/ballandsocketjointsnet/BallAndSocketJointsNetScene.cpp b/testbed/scenes/ballandsocketjointsnet/BallAndSocketJointsNetScene.cpp new file mode 100644 index 00000000..b0e9f038 --- /dev/null +++ b/testbed/scenes/ballandsocketjointsnet/BallAndSocketJointsNetScene.cpp @@ -0,0 +1,202 @@ +/******************************************************************************** +* 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 "BallAndSocketJointsNetScene.h" +#include + +// Namespaces +using namespace openglframework; +using namespace ballandsocketjointsnetscene; + +// Constructor +BallAndSocketJointsNetScene::BallAndSocketJointsNetScene(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, 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 all the spheres of the scene + for (int i=0; isetColor(mObjectColorDemo); + sphere->setSleepingColor(mSleepingColorDemo); + + // Change the material properties of the rigid body + rp3d::Material& material = sphere->getCollider()->getMaterial(); + material.setBounciness(rp3d::decimal(0.0)); + + // Add the sphere the list of sphere in the scene + mNetSpheres[i][j] = sphere; + mPhysicsObjects.push_back(sphere); + } + } + + // Set the position of the spheres before the joints creation + reset(); + + // Create the Ball-and-Socket joints + createJoints(); + + // Create the main sphere + mMainSphere = new Sphere(true, 10, mPhysicsCommon, mPhysicsWorld, meshFolderPath); + mMainSphere->setColor(mObjectColorDemo); + mMainSphere->setSleepingColor(mSleepingColorDemo); + rp3d::Vector3 initPosition(0, 0, 0); + rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); + rp3d::Transform transform(initPosition, initOrientation); + mMainSphere->setTransform(transform); + mMainSphere->getRigidBody()->setType(rp3d::BodyType::STATIC); + rp3d::Material& material = mMainSphere->getCollider()->getMaterial(); + material.setBounciness(rp3d::decimal(0.0)); + mPhysicsObjects.push_back(mMainSphere); + + // 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 +BallAndSocketJointsNetScene::~BallAndSocketJointsNetScene() { + + // 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(mNetSpheres[i][j]->getRigidBody()); + } + } + mPhysicsWorld->destroyRigidBody(mMainSphere->getRigidBody()); + + // Destroy the physics world + mPhysicsCommon.destroyPhysicsWorld(mPhysicsWorld); +} + +// Create the joints +void BallAndSocketJointsNetScene::createJoints() { + + for (int i=0; i 0) { + + // Create the joint info object + rp3d::RigidBody* body1 = mNetSpheres[i-1][j]->getRigidBody(); + rp3d::RigidBody* body2 = mNetSpheres[i][j]->getRigidBody(); + rp3d::Vector3 body1Position = body1->getTransform().getPosition(); + rp3d::Vector3 body2Position = body2->getTransform().getPosition(); + //const rp3d::Vector3 anchorPointWorldSpace = 0.5 * (body1Position + body2Position); + const rp3d::Vector3 anchorPointWorldSpace = body2Position; + rp3d::BallAndSocketJointInfo jointInfo(body1, body2, anchorPointWorldSpace); + jointInfo.isCollisionEnabled = false; + rp3d::BallAndSocketJoint* joint = dynamic_cast( mPhysicsWorld->createJoint(jointInfo)); + mBallAndSocketJoints.push_back(joint); + } + + if (j > 0) { + + // Create the joint info object + rp3d::RigidBody* body1 = mNetSpheres[i][j-1]->getRigidBody(); + rp3d::RigidBody* body2 = mNetSpheres[i][j]->getRigidBody(); + rp3d::Vector3 body1Position = body1->getTransform().getPosition(); + rp3d::Vector3 body2Position = body2->getTransform().getPosition(); + const rp3d::Vector3 anchorPointWorldSpace = body2Position; + 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 BallAndSocketJointsNetScene::reset() { + + SceneDemo::reset(); + + const float space = 0.3f; + const float startX = -(NB_ROWS_NET_SPHERES / 2.0f * (2.0 * SPHERE_RADIUS + space)); + const float startZ = -(NB_ROWS_NET_SPHERES / 2.0f * (2.0 * SPHERE_RADIUS + space)); + + const rp3d::Quaternion initOrientation = rp3d::Quaternion::identity(); + + for (int i=0; isetTransform(transform); + } + } +} diff --git a/testbed/scenes/ballandsocketjointsnet/BallAndSocketJointsNetScene.h b/testbed/scenes/ballandsocketjointsnet/BallAndSocketJointsNetScene.h new file mode 100644 index 00000000..5f9cc7e4 --- /dev/null +++ b/testbed/scenes/ballandsocketjointsnet/BallAndSocketJointsNetScene.h @@ -0,0 +1,79 @@ +/******************************************************************************** +* 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_NET_SCENE_H +#define BALL_AND_SOCKET_JOINTS_NET_SCENE_H + +// Libraries +#include "openglframework.h" +#include +#include "Sphere.h" +#include "SceneDemo.h" + +namespace ballandsocketjointsnetscene { + +// Constants +const float SCENE_RADIUS = 40.0f; +const float SPHERE_RADIUS = 0.5f; +const int NB_ROWS_NET_SPHERES = 40; + +// Class JointsScene +class BallAndSocketJointsNetScene : public SceneDemo { + + protected : + + // -------------------- Attributes -------------------- // + + /// Spheres in the Ball-And-Socket joint net + Sphere* mNetSpheres[NB_ROWS_NET_SPHERES][NB_ROWS_NET_SPHERES]; + + /// Main sphere + Sphere* mMainSphere; + + /// Ball-And-Socket joints of the chain + std::vector mBallAndSocketJoints; + + // -------------------- Methods -------------------- // + + /// Create the joints + void createJoints(); + + public: + + // -------------------- Methods -------------------- // + + /// Constructor + BallAndSocketJointsNetScene(const std::string& name, EngineSettings& settings); + + /// Destructor + virtual ~BallAndSocketJointsNetScene() override ; + + /// Reset the scene + virtual void reset() override; +}; + +} + +#endif diff --git a/testbed/src/TestbedApplication.cpp b/testbed/src/TestbedApplication.cpp index b5d1dcd4..f3888924 100755 --- a/testbed/src/TestbedApplication.cpp +++ b/testbed/src/TestbedApplication.cpp @@ -39,6 +39,7 @@ #include "cubestack/CubeStackScene.h" #include "pile/PileScene.h" #include "boxtower/BoxTowerScene.h" +#include "ballandsocketjointsnet/BallAndSocketJointsNetScene.h" using namespace openglframework; using namespace jointsscene; @@ -51,6 +52,7 @@ using namespace collisiondetectionscene; using namespace cubestackscene; using namespace pilescene; using namespace boxtowerscene; +using namespace ballandsocketjointsnetscene; // Initialization of static variables const float TestbedApplication::SCROLL_SENSITIVITY = 0.08f; @@ -152,7 +154,12 @@ void TestbedApplication::createScenes() { mScenes.push_back(boxTowerScene); assert(mScenes.size() > 0); - const int firstSceneIndex = 0; + // Ball and Socket joints Net scene + BallAndSocketJointsNetScene* ballAndSocketJointsNetScene = new BallAndSocketJointsNetScene("BallAndSocket Joints Net", mEngineSettings); + mScenes.push_back(ballAndSocketJointsNetScene); + assert(mScenes.size() > 0); + + const int firstSceneIndex = 10; switchScene(mScenes[firstSceneIndex]); }