Refactor profiler and add logger
This commit is contained in:
parent
393bb0ed88
commit
2e28b5ad8f
|
@ -31,6 +31,7 @@
|
|||
#include <cfloat>
|
||||
#include <utility>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include "decimal.h"
|
||||
#include "containers/Pair.h"
|
||||
|
||||
|
@ -110,6 +111,9 @@ constexpr decimal DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER = decimal(1.7);
|
|||
*/
|
||||
struct WorldSettings {
|
||||
|
||||
/// Name of the world
|
||||
std::string worldName = "";
|
||||
|
||||
/// Distance threshold for two contact points for a valid persistent contact (in meters)
|
||||
decimal persistentContactDistanceThreshold = decimal(0.03);
|
||||
|
||||
|
|
|
@ -36,9 +36,11 @@ using namespace std;
|
|||
uint CollisionWorld::mNbWorlds = 0;
|
||||
|
||||
// Constructor
|
||||
CollisionWorld::CollisionWorld(const string& name, const WorldSettings& worldSettings)
|
||||
CollisionWorld::CollisionWorld(const WorldSettings& worldSettings, Logger* logger, Profiler* profiler)
|
||||
: mConfig(worldSettings), mCollisionDetection(this, mMemoryManager), mBodies(mMemoryManager.getPoolAllocator()), mCurrentBodyId(0),
|
||||
mFreeBodiesIds(mMemoryManager.getPoolAllocator()), mEventListener(nullptr), mName(name) {
|
||||
mFreeBodiesIds(mMemoryManager.getPoolAllocator()), mEventListener(nullptr), mName(worldSettings.worldName),
|
||||
mProfiler(profiler), mLogger(logger), mIsProfilerCreatedByUser(profiler != nullptr),
|
||||
mIsLoggerCreatedByUser(logger != nullptr) {
|
||||
|
||||
// Automatically generate a name for the world
|
||||
if (mName == "") {
|
||||
|
@ -55,20 +57,33 @@ CollisionWorld::CollisionWorld(const string& name, const WorldSettings& worldSet
|
|||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
// Add a destination file for the profiling data
|
||||
mProfiler.addFileDestination("rp3d_profiling_" + mName + ".txt", Profiler::Format::Text);
|
||||
// If the user has not provided its own profiler, we create one
|
||||
if (mProfiler == nullptr) {
|
||||
|
||||
mProfiler = new Profiler();
|
||||
|
||||
// Add a destination file for the profiling data
|
||||
mProfiler->addFileDestination("rp3d_profiling_" + mName + ".txt", Profiler::Format::Text);
|
||||
}
|
||||
|
||||
|
||||
// Set the profiler
|
||||
mCollisionDetection.setProfiler(&mProfiler);
|
||||
mCollisionDetection.setProfiler(mProfiler);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef IS_LOGGING_ACTIVE
|
||||
|
||||
// Add a log destination file
|
||||
uint logLevel = static_cast<uint>(Logger::Level::Info) | static_cast<uint>(Logger::Level::Warning) |
|
||||
static_cast<uint>(Logger::Level::Error);
|
||||
mLogger.addFileDestination("rp3d_log_" + mName + ".html", logLevel, Logger::Format::HTML);
|
||||
// If the user has not provided its own logger, we create one
|
||||
if (mLogger == nullptr) {
|
||||
|
||||
mLogger = new Logger();
|
||||
|
||||
// Add a log destination file
|
||||
uint logLevel = static_cast<uint>(Logger::Level::Info) | static_cast<uint>(Logger::Level::Warning) |
|
||||
static_cast<uint>(Logger::Level::Error);
|
||||
mLogger->addFileDestination("rp3d_log_" + mName + ".html", logLevel, Logger::Format::HTML);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -89,6 +104,24 @@ CollisionWorld::~CollisionWorld() {
|
|||
destroyCollisionBody(mBodies[i]);
|
||||
}
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
/// Delete the profiler
|
||||
if (!mIsProfilerCreatedByUser) {
|
||||
delete mProfiler;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef IS_LOGGING_ACTIVE
|
||||
|
||||
/// Delete the logger
|
||||
if (!mIsLoggerCreatedByUser) {
|
||||
delete mLogger;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
assert(mBodies.size() == 0);
|
||||
}
|
||||
|
||||
|
@ -117,7 +150,7 @@ CollisionBody* CollisionWorld::createCollisionBody(const Transform& transform) {
|
|||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
collisionBody->setProfiler(&mProfiler);
|
||||
collisionBody->setProfiler(mProfiler);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -87,15 +87,21 @@ class CollisionWorld {
|
|||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
/// Real-time hierarchical profiler
|
||||
Profiler mProfiler;
|
||||
Profiler* mProfiler;
|
||||
#endif
|
||||
|
||||
#ifdef IS_LOGGING_ACTIVE
|
||||
|
||||
/// Logger
|
||||
Logger mLogger;
|
||||
Logger* mLogger;
|
||||
#endif
|
||||
|
||||
/// True if the profiler has been created by the user
|
||||
bool mIsProfilerCreatedByUser;
|
||||
|
||||
/// True if the logger has been created by the user
|
||||
bool mIsLoggerCreatedByUser;
|
||||
|
||||
/// Total number of worlds
|
||||
static uint mNbWorlds;
|
||||
|
||||
|
@ -112,7 +118,8 @@ class CollisionWorld {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
CollisionWorld(const std::string& name = "", const WorldSettings& worldSettings = WorldSettings());
|
||||
CollisionWorld(const WorldSettings& worldSettings = WorldSettings(), Logger* logger = nullptr,
|
||||
Profiler* profiler = nullptr);
|
||||
|
||||
/// Destructor
|
||||
virtual ~CollisionWorld();
|
||||
|
@ -161,14 +168,14 @@ class CollisionWorld {
|
|||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
/// Return a reference to the profiler
|
||||
Profiler& getProfiler();
|
||||
Profiler* getProfiler();
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef IS_LOGGING_ACTIVE
|
||||
|
||||
/// Return a reference to the logger
|
||||
Logger& getLogger();
|
||||
Logger* getLogger();
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -255,8 +262,8 @@ inline const std::string& CollisionWorld::getName() const {
|
|||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
// Return a reference to the profiler
|
||||
inline Profiler& CollisionWorld::getProfiler() {
|
||||
// Return a pointer to the profiler
|
||||
inline Profiler* CollisionWorld::getProfiler() {
|
||||
return mProfiler;
|
||||
}
|
||||
|
||||
|
@ -264,8 +271,8 @@ inline Profiler& CollisionWorld::getProfiler() {
|
|||
|
||||
#ifdef IS_LOGGING_ACTIVE
|
||||
|
||||
// Return a reference to the logger
|
||||
inline Logger& CollisionWorld::getLogger() {
|
||||
// Return a pointer to the logger
|
||||
inline Logger* CollisionWorld::getLogger() {
|
||||
return mLogger;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,8 +39,9 @@ using namespace std;
|
|||
/**
|
||||
* @param gravity Gravity vector in the world (in meters per second squared)
|
||||
*/
|
||||
DynamicsWorld::DynamicsWorld(const Vector3& gravity, const string& name, const WorldSettings& worldSettings)
|
||||
: CollisionWorld(name, worldSettings),
|
||||
DynamicsWorld::DynamicsWorld(const Vector3& gravity, const WorldSettings& worldSettings,
|
||||
Logger* logger, Profiler* profiler)
|
||||
: CollisionWorld(worldSettings, logger, profiler),
|
||||
mContactSolver(mMemoryManager, mConfig),
|
||||
mNbVelocitySolverIterations(mConfig.defaultVelocitySolverNbIterations),
|
||||
mNbPositionSolverIterations(mConfig.defaultPositionSolverNbIterations),
|
||||
|
@ -58,13 +59,13 @@ DynamicsWorld::DynamicsWorld(const Vector3& gravity, const string& name, const W
|
|||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
// Set the profiler
|
||||
mConstraintSolver.setProfiler(&mProfiler);
|
||||
mContactSolver.setProfiler(&mProfiler);
|
||||
mConstraintSolver.setProfiler(mProfiler);
|
||||
mContactSolver.setProfiler(mProfiler);
|
||||
|
||||
#endif
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World,
|
||||
"Dynamics world " + mName + " has been created");
|
||||
"Dynamics World: Dynamics world " + mName + " has been created");
|
||||
|
||||
}
|
||||
|
||||
|
@ -87,11 +88,11 @@ DynamicsWorld::~DynamicsWorld() {
|
|||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
// Print the profiling report into the destinations
|
||||
mProfiler.printReport();
|
||||
mProfiler->printReport();
|
||||
#endif
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World,
|
||||
"Dynamics world " + mName + " has been destroyed");
|
||||
"Dynamics World: Dynamics world " + mName + " has been destroyed");
|
||||
}
|
||||
|
||||
// Update the physics simulation
|
||||
|
@ -102,10 +103,10 @@ void DynamicsWorld::update(decimal timeStep) {
|
|||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
// Increment the frame counter of the profiler
|
||||
mProfiler.incrementFrameCounter();
|
||||
mProfiler->incrementFrameCounter();
|
||||
#endif
|
||||
|
||||
RP3D_PROFILE("DynamicsWorld::update()", &mProfiler);
|
||||
RP3D_PROFILE("DynamicsWorld::update()", mProfiler);
|
||||
|
||||
mTimeStep = timeStep;
|
||||
|
||||
|
@ -153,7 +154,7 @@ void DynamicsWorld::update(decimal timeStep) {
|
|||
/// the sympletic Euler time stepping scheme.
|
||||
void DynamicsWorld::integrateRigidBodiesPositions() {
|
||||
|
||||
RP3D_PROFILE("DynamicsWorld::integrateRigidBodiesPositions()", &mProfiler);
|
||||
RP3D_PROFILE("DynamicsWorld::integrateRigidBodiesPositions()", mProfiler);
|
||||
|
||||
// For each island of the world
|
||||
for (uint i=0; i < mNbIslands; i++) {
|
||||
|
@ -192,7 +193,7 @@ void DynamicsWorld::integrateRigidBodiesPositions() {
|
|||
// Update the postion/orientation of the bodies
|
||||
void DynamicsWorld::updateBodiesState() {
|
||||
|
||||
RP3D_PROFILE("DynamicsWorld::updateBodiesState()", &mProfiler);
|
||||
RP3D_PROFILE("DynamicsWorld::updateBodiesState()", mProfiler);
|
||||
|
||||
// For each island of the world
|
||||
for (uint islandIndex = 0; islandIndex < mNbIslands; islandIndex++) {
|
||||
|
@ -229,7 +230,7 @@ void DynamicsWorld::updateBodiesState() {
|
|||
// Initialize the bodies velocities arrays for the next simulation step.
|
||||
void DynamicsWorld::initVelocityArrays() {
|
||||
|
||||
RP3D_PROFILE("DynamicsWorld::initVelocityArrays()", &mProfiler);
|
||||
RP3D_PROFILE("DynamicsWorld::initVelocityArrays()", mProfiler);
|
||||
|
||||
// Allocate memory for the bodies velocity arrays
|
||||
uint nbBodies = mRigidBodies.size();
|
||||
|
@ -271,7 +272,7 @@ void DynamicsWorld::initVelocityArrays() {
|
|||
/// contact solver.
|
||||
void DynamicsWorld::integrateRigidBodiesVelocities() {
|
||||
|
||||
RP3D_PROFILE("DynamicsWorld::integrateRigidBodiesVelocities()", &mProfiler);
|
||||
RP3D_PROFILE("DynamicsWorld::integrateRigidBodiesVelocities()", mProfiler);
|
||||
|
||||
// Initialize the bodies velocity arrays
|
||||
initVelocityArrays();
|
||||
|
@ -333,7 +334,7 @@ void DynamicsWorld::integrateRigidBodiesVelocities() {
|
|||
// Solve the contacts and constraints
|
||||
void DynamicsWorld::solveContactsAndConstraints() {
|
||||
|
||||
RP3D_PROFILE("DynamicsWorld::solveContactsAndConstraints()", &mProfiler);
|
||||
RP3D_PROFILE("DynamicsWorld::solveContactsAndConstraints()", mProfiler);
|
||||
|
||||
// Set the velocities arrays
|
||||
mContactSolver.setSplitVelocitiesArrays(mSplitLinearVelocities, mSplitAngularVelocities);
|
||||
|
@ -383,7 +384,7 @@ void DynamicsWorld::solveContactsAndConstraints() {
|
|||
// Solve the position error correction of the constraints
|
||||
void DynamicsWorld::solvePositionCorrection() {
|
||||
|
||||
RP3D_PROFILE("DynamicsWorld::solvePositionCorrection()", &mProfiler);
|
||||
RP3D_PROFILE("DynamicsWorld::solvePositionCorrection()", mProfiler);
|
||||
|
||||
// Do not continue if there is no constraints
|
||||
if (mJoints.size() == 0) return;
|
||||
|
@ -426,7 +427,7 @@ RigidBody* DynamicsWorld::createRigidBody(const Transform& transform) {
|
|||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
rigidBody->setProfiler(&mProfiler);
|
||||
rigidBody->setProfiler(mProfiler);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -645,7 +646,7 @@ uint DynamicsWorld::computeNextAvailableJointId() {
|
|||
/// it). Then, we create an island with this group of connected bodies.
|
||||
void DynamicsWorld::computeIslands() {
|
||||
|
||||
RP3D_PROFILE("DynamicsWorld::computeIslands()", &mProfiler);
|
||||
RP3D_PROFILE("DynamicsWorld::computeIslands()", mProfiler);
|
||||
|
||||
uint nbBodies = mRigidBodies.size();
|
||||
|
||||
|
@ -792,7 +793,7 @@ void DynamicsWorld::computeIslands() {
|
|||
/// time, we put all the bodies of the island to sleep.
|
||||
void DynamicsWorld::updateSleepingBodies() {
|
||||
|
||||
RP3D_PROFILE("DynamicsWorld::updateSleepingBodies()", &mProfiler);
|
||||
RP3D_PROFILE("DynamicsWorld::updateSleepingBodies()", mProfiler);
|
||||
|
||||
const decimal sleepLinearVelocitySquare = mSleepLinearVelocity * mSleepLinearVelocity;
|
||||
const decimal sleepAngularVelocitySquare = mSleepAngularVelocity * mSleepAngularVelocity;
|
||||
|
|
|
@ -162,8 +162,8 @@ class DynamicsWorld : public CollisionWorld {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
DynamicsWorld(const Vector3& mGravity, const std::string& name = "",
|
||||
const WorldSettings& worldSettings = WorldSettings());
|
||||
DynamicsWorld(const Vector3& mGravity, const WorldSettings& worldSettings = WorldSettings(),
|
||||
Logger* logger = nullptr, Profiler* profiler = nullptr);
|
||||
|
||||
/// Destructor
|
||||
virtual ~DynamicsWorld() override;
|
||||
|
|
|
@ -92,10 +92,14 @@ void Logger::removeAllDestinations() {
|
|||
// Log something
|
||||
void Logger::log(Level level, Category category, const std::string& message) {
|
||||
|
||||
// Get current time
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto time = std::chrono::system_clock::to_time_t(now);
|
||||
|
||||
// For each destination
|
||||
for (auto it = mDestinations.begin(); it != mDestinations.end(); ++it) {
|
||||
|
||||
(*it)->write(message, level, category);
|
||||
(*it)->write(time, message, level, category);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#ifndef REACTPHYSICS3D_LOGGER_H
|
||||
#define REACTPHYSICS3D_LOGGER_H
|
||||
|
||||
#ifdef IS_LOGGING_ACTIVE
|
||||
|
||||
// Libraries
|
||||
#include "containers/List.h"
|
||||
|
@ -35,6 +34,7 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
/// ReactPhysics3D namespace
|
||||
namespace reactphysics3d {
|
||||
|
@ -57,6 +57,26 @@ class Logger {
|
|||
/// Log verbosity level
|
||||
enum class Format {Text, HTML};
|
||||
|
||||
/// Return the name of a category
|
||||
static std::string getCategoryName(Category category) {
|
||||
|
||||
switch(category) {
|
||||
case Category::World: return "World";
|
||||
case Category::Body: return "Body";
|
||||
case Category::Joint: return "Joint";
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the name of a level
|
||||
static std::string getLevelName(Level level) {
|
||||
|
||||
switch(level) {
|
||||
case Level::Info: return "Information";
|
||||
case Level::Warning: return "Warning";
|
||||
case Level::Error: return "Error";
|
||||
}
|
||||
}
|
||||
|
||||
/// Log formatter
|
||||
class Formatter {
|
||||
|
||||
|
@ -83,7 +103,7 @@ class Logger {
|
|||
}
|
||||
|
||||
/// Format a log message
|
||||
virtual std::string format(const std::string& message, Level level, Category category) = 0;
|
||||
virtual std::string format(const time_t& time, const std::string& message, Level level, Category category) = 0;
|
||||
};
|
||||
|
||||
class TextFormatter : public Formatter {
|
||||
|
@ -101,8 +121,8 @@ class Logger {
|
|||
}
|
||||
|
||||
/// Format a log message
|
||||
virtual std::string format(const std::string& message, Level level,
|
||||
Category category) override {
|
||||
virtual std::string format(const time_t& time, const std::string& message,
|
||||
Level level, Category category) override {
|
||||
return message;
|
||||
}
|
||||
};
|
||||
|
@ -120,6 +140,7 @@ class Logger {
|
|||
ss << "<html>" << std::endl;
|
||||
ss << "<head>" << std::endl;
|
||||
ss << "<title>ReactPhysics3D Logs</title>" << std::endl;
|
||||
ss << "<style>" << generateCSS() << "</style>" << std::endl;
|
||||
ss << "</head>" << std::endl;
|
||||
ss << "<body>" << std::endl;
|
||||
|
||||
|
@ -137,6 +158,60 @@ class Logger {
|
|||
return ss.str();
|
||||
}
|
||||
|
||||
std::string generateCSS() const {
|
||||
return "body {"
|
||||
" background-color: #f7f7f9;"
|
||||
"} "
|
||||
"body > div { clear:both; } "
|
||||
"body > div > div { float: left; } "
|
||||
".line { "
|
||||
"font-family: SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace; "
|
||||
"font-size: 13px; "
|
||||
"color: #212529; "
|
||||
"margin: 0px 5px 2px 5px; "
|
||||
"} "
|
||||
".time { "
|
||||
"margin-right: 10px; "
|
||||
"width:100px; "
|
||||
"} "
|
||||
".level { "
|
||||
"margin-right: 10px; "
|
||||
"width: 110px; "
|
||||
"}"
|
||||
".category { "
|
||||
"margin-right: 10px; "
|
||||
"width: 120px; "
|
||||
"font-weight: bold; "
|
||||
"}"
|
||||
".message { "
|
||||
"color: #2e2e2e; "
|
||||
"word-wrap: break-word; "
|
||||
"max-width: 800px; "
|
||||
"} "
|
||||
".body > .category { "
|
||||
"color: #007bff; "
|
||||
"} "
|
||||
".world > .category { "
|
||||
"color: #4f9fcf; "
|
||||
"} "
|
||||
".joint > .category { "
|
||||
"color: #6c757d; "
|
||||
"} "
|
||||
".warning { "
|
||||
"color: #f0ad4e; "
|
||||
"} "
|
||||
".error { "
|
||||
"color: #d44950; "
|
||||
"} ";
|
||||
}
|
||||
|
||||
/// Convert a string to lower case
|
||||
std::string toLowerCase(const std::string& text) {
|
||||
std::string textLower = text;
|
||||
std::transform(textLower.begin(), textLower.end(), textLower.begin(), ::tolower);
|
||||
return textLower;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
|
@ -150,14 +225,34 @@ class Logger {
|
|||
}
|
||||
|
||||
/// Format a log message
|
||||
virtual std::string format(const std::string& message, Level level,
|
||||
Category category) override {
|
||||
virtual std::string format(const time_t& time, const std::string& message,
|
||||
Level level, Category category) override {
|
||||
|
||||
std::stringstream ss;
|
||||
|
||||
ss << "<p>";
|
||||
ss << "<div class='line " + toLowerCase(getCategoryName(category)) + " " + toLowerCase(getLevelName(level)) + "'>";
|
||||
|
||||
// Time
|
||||
ss << "<div class='time'>";
|
||||
ss << std::put_time(std::localtime(&time), "%X");
|
||||
ss << "</div>";
|
||||
|
||||
// Level
|
||||
ss << "<div class='level'>";
|
||||
ss << getLevelName(level);
|
||||
ss << "</div>";
|
||||
|
||||
// Category
|
||||
ss << "<div class='category'>";
|
||||
ss << getCategoryName(category);
|
||||
ss << "</div>";
|
||||
|
||||
// Message
|
||||
ss << "<div class='message'>";
|
||||
ss << message;
|
||||
ss << "</p>";
|
||||
ss << "</div>";
|
||||
|
||||
ss << "</div>";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
@ -187,7 +282,7 @@ class Logger {
|
|||
}
|
||||
|
||||
/// Write a message into the output stream
|
||||
virtual void write(const std::string& message, Level level, Category category) = 0;
|
||||
virtual void write(const time_t& time, const std::string& message, Level level, Category category) = 0;
|
||||
};
|
||||
|
||||
class FileDestination : public Destination {
|
||||
|
@ -228,8 +323,8 @@ class Logger {
|
|||
}
|
||||
|
||||
/// Write a message into the output stream
|
||||
virtual void write(const std::string& message, Level level, Category category) override {
|
||||
mFileStream << formatter->format(message, level, category) << std::endl;
|
||||
virtual void write(const time_t& time, const std::string& message, Level level, Category category) override {
|
||||
mFileStream << formatter->format(time, message, level, category) << std::endl << std::flush;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -259,8 +354,9 @@ class Logger {
|
|||
}
|
||||
|
||||
/// Write a message into the output stream
|
||||
virtual void write(const std::string& message, Level level, Category category) override {
|
||||
mOutputStream << message << std::endl;
|
||||
virtual void write(const time_t& time, const std::string& message, Level level, Category category) override {
|
||||
mOutputStream << std::put_time(std::localtime(&time), "%Y-%m-%d %X") << ": ";
|
||||
mOutputStream << message << std::endl << std::flush;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -303,12 +399,12 @@ class Logger {
|
|||
void log(Level level, Category category, const std::string& message);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#ifdef IS_LOGGING_ACTIVE
|
||||
|
||||
// Use this macro to log something
|
||||
#define RP3D_LOG(logger, level, category, message) logger.log(level, category, message)
|
||||
|
||||
|
||||
}
|
||||
#define RP3D_LOG(logger, level, category, message) logger->log(level, category, message)
|
||||
|
||||
#else // If logger is not active
|
||||
|
||||
|
|
|
@ -46,8 +46,11 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
|
|||
// Set the center of the scene
|
||||
setScenePosition(center, SCENE_RADIUS);
|
||||
|
||||
rp3d::WorldSettings worldSettings;
|
||||
worldSettings.worldName = name;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mPhysicsWorld = new rp3d::CollisionWorld(name);
|
||||
mPhysicsWorld = new rp3d::CollisionWorld(worldSettings);
|
||||
|
||||
// ---------- Sphere 1 ---------- //
|
||||
|
||||
|
|
|
@ -45,8 +45,11 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
|
|||
// Gravity vector in the dynamics world
|
||||
rp3d::Vector3 gravity(0, -9.81f, 0);
|
||||
|
||||
rp3d::WorldSettings worldSettings;
|
||||
worldSettings.worldName = name;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, name);
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||
|
||||
for (int i=0; i<NB_COMPOUND_SHAPES; i++) {
|
||||
|
||||
|
|
|
@ -45,8 +45,11 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
|
|||
// Gravity vector in the dynamics world
|
||||
rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0);
|
||||
|
||||
rp3d::WorldSettings worldSettings;
|
||||
worldSettings.worldName = name;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, name);
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||
|
||||
// ---------- Create the boxes ----------- //
|
||||
for (int i = 0; i<NB_COMPOUND_SHAPES; i++) {
|
||||
|
|
|
@ -43,8 +43,11 @@ CubesScene::CubesScene(const std::string& name, EngineSettings& settings)
|
|||
// Gravity vector in the dynamics world
|
||||
rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0);
|
||||
|
||||
rp3d::WorldSettings worldSettings;
|
||||
worldSettings.worldName = name;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, name);
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||
|
||||
// Create all the cubes of the scene
|
||||
for (int i=0; i<NB_CUBES; i++) {
|
||||
|
|
|
@ -43,8 +43,11 @@ CubeStackScene::CubeStackScene(const std::string& name, EngineSettings& settings
|
|||
// Gravity vector in the dynamics world
|
||||
rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0);
|
||||
|
||||
rp3d::WorldSettings worldSettings;
|
||||
worldSettings.worldName = name;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, name);
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||
|
||||
// Create all the cubes of the scene
|
||||
for (int i=1; i<=NB_FLOORS; i++) {
|
||||
|
|
|
@ -45,8 +45,11 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
|
|||
// Gravity vector in the dynamics world
|
||||
rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0);
|
||||
|
||||
rp3d::WorldSettings worldSettings;
|
||||
worldSettings.worldName = name;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, name);
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||
|
||||
for (int i = 0; i<NB_COMPOUND_SHAPES; i++) {
|
||||
|
||||
|
|
|
@ -44,8 +44,11 @@ JointsScene::JointsScene(const std::string& name, EngineSettings& settings)
|
|||
// Gravity vector in the dynamics world
|
||||
rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0);
|
||||
|
||||
rp3d::WorldSettings worldSettings;
|
||||
worldSettings.worldName = name;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, name);
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||
|
||||
// Create the Ball-and-Socket joint
|
||||
createBallAndSocketJoints();
|
||||
|
|
|
@ -44,8 +44,11 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
|
|||
// Set the center of the scene
|
||||
setScenePosition(center, SCENE_RADIUS);
|
||||
|
||||
rp3d::WorldSettings worldSettings;
|
||||
worldSettings.worldName = name;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mPhysicsWorld = new rp3d::CollisionWorld(name);
|
||||
mPhysicsWorld = new rp3d::CollisionWorld(worldSettings);
|
||||
|
||||
// ---------- Dumbbell ---------- //
|
||||
|
||||
|
|
|
@ -170,6 +170,7 @@ void Gui::createSettingsPanel() {
|
|||
checkboxSleeping->setChecked(mApp->mEngineSettings.isSleepingEnabled);
|
||||
checkboxSleeping->setCallback([&](bool value) {
|
||||
mApp->mEngineSettings.isSleepingEnabled = value;
|
||||
mApp->notifyEngineSetttingsChanged();
|
||||
});
|
||||
|
||||
// Enabled/Disable Gravity
|
||||
|
@ -177,6 +178,7 @@ void Gui::createSettingsPanel() {
|
|||
checkboxGravity->setChecked(mApp->mEngineSettings.isGravityEnabled);
|
||||
checkboxGravity->setCallback([&](bool value) {
|
||||
mApp->mEngineSettings.isGravityEnabled = value;
|
||||
mApp->notifyEngineSetttingsChanged();
|
||||
});
|
||||
|
||||
// Timestep
|
||||
|
@ -202,6 +204,7 @@ void Gui::createSettingsPanel() {
|
|||
if (finalValue < 1 || finalValue > 1000) return false;
|
||||
|
||||
mApp->mEngineSettings.timeStep = finalValue / 1000.0f;
|
||||
mApp->notifyEngineSetttingsChanged();
|
||||
textboxTimeStep->setValue(out.str());
|
||||
}
|
||||
catch (...) {
|
||||
|
@ -233,6 +236,7 @@ void Gui::createSettingsPanel() {
|
|||
if (value < 1 || value > 1000) return false;
|
||||
|
||||
mApp->mEngineSettings.nbVelocitySolverIterations = value;
|
||||
mApp->notifyEngineSetttingsChanged();
|
||||
textboxVelocityIterations->setValue(out.str());
|
||||
}
|
||||
catch (...) {
|
||||
|
@ -264,6 +268,7 @@ void Gui::createSettingsPanel() {
|
|||
if (value < 1 || value > 1000) return false;
|
||||
|
||||
mApp->mEngineSettings.nbPositionSolverIterations = value;
|
||||
mApp->notifyEngineSetttingsChanged();
|
||||
textboxPositionIterations->setValue(out.str());
|
||||
}
|
||||
catch (...) {
|
||||
|
@ -298,6 +303,7 @@ void Gui::createSettingsPanel() {
|
|||
if (finalValue < 1 || finalValue > 100000) return false;
|
||||
|
||||
mApp->mEngineSettings.timeBeforeSleep = finalValue / 1000.0f;
|
||||
mApp->notifyEngineSetttingsChanged();
|
||||
textboxTimeSleep->setValue(out.str());
|
||||
}
|
||||
catch (...) {
|
||||
|
@ -332,6 +338,7 @@ void Gui::createSettingsPanel() {
|
|||
if (finalValue < 0 || finalValue > 10000) return false;
|
||||
|
||||
mApp->mEngineSettings.sleepLinearVelocity = finalValue;
|
||||
mApp->notifyEngineSetttingsChanged();
|
||||
textboxSleepLinearVel->setValue(out.str());
|
||||
}
|
||||
catch (...) {
|
||||
|
@ -366,6 +373,7 @@ void Gui::createSettingsPanel() {
|
|||
if (finalValue < 0 || finalValue > 10000) return false;
|
||||
|
||||
mApp->mEngineSettings.sleepAngularVelocity = finalValue;
|
||||
mApp->notifyEngineSetttingsChanged();
|
||||
textboxSleepAngularVel->setValue(out.str());
|
||||
}
|
||||
catch (...) {
|
||||
|
|
|
@ -232,6 +232,9 @@ class Scene {
|
|||
|
||||
/// Return all the contact points of the scene
|
||||
std::vector<ContactPoint> virtual getContactPoints();
|
||||
|
||||
/// Update the engine settings
|
||||
virtual void updateEngineSettings() = 0;
|
||||
};
|
||||
|
||||
// Called when a keyboard event occurs
|
||||
|
|
|
@ -123,18 +123,6 @@ void SceneDemo::updatePhysics() {
|
|||
|
||||
if (getDynamicsWorld() != nullptr) {
|
||||
|
||||
// Update the physics engine parameters
|
||||
getDynamicsWorld()->setIsGratityEnabled(mEngineSettings.isGravityEnabled);
|
||||
rp3d::Vector3 gravity(mEngineSettings.gravity.x, mEngineSettings.gravity.y,
|
||||
mEngineSettings.gravity.z);
|
||||
getDynamicsWorld()->setGravity(gravity);
|
||||
getDynamicsWorld()->enableSleeping(mEngineSettings.isSleepingEnabled);
|
||||
getDynamicsWorld()->setSleepLinearVelocity(mEngineSettings.sleepLinearVelocity);
|
||||
getDynamicsWorld()->setSleepAngularVelocity(mEngineSettings.sleepAngularVelocity);
|
||||
getDynamicsWorld()->setNbIterationsPositionSolver(mEngineSettings.nbPositionSolverIterations);
|
||||
getDynamicsWorld()->setNbIterationsVelocitySolver(mEngineSettings.nbVelocitySolverIterations);
|
||||
getDynamicsWorld()->setTimeBeforeSleep(mEngineSettings.timeBeforeSleep);
|
||||
|
||||
// Take a simulation step
|
||||
getDynamicsWorld()->update(mEngineSettings.timeStep);
|
||||
}
|
||||
|
@ -448,3 +436,22 @@ std::vector<ContactPoint> SceneDemo::computeContactPointsOfWorld(rp3d::DynamicsW
|
|||
|
||||
return contactPoints;
|
||||
}
|
||||
|
||||
// Update the engine settings
|
||||
void SceneDemo::updateEngineSettings() {
|
||||
|
||||
if (getDynamicsWorld() != nullptr) {
|
||||
|
||||
// Update the physics engine parameters
|
||||
getDynamicsWorld()->setIsGratityEnabled(mEngineSettings.isGravityEnabled);
|
||||
rp3d::Vector3 gravity(mEngineSettings.gravity.x, mEngineSettings.gravity.y,
|
||||
mEngineSettings.gravity.z);
|
||||
getDynamicsWorld()->setGravity(gravity);
|
||||
getDynamicsWorld()->enableSleeping(mEngineSettings.isSleepingEnabled);
|
||||
getDynamicsWorld()->setSleepLinearVelocity(mEngineSettings.sleepLinearVelocity);
|
||||
getDynamicsWorld()->setSleepAngularVelocity(mEngineSettings.sleepAngularVelocity);
|
||||
getDynamicsWorld()->setNbIterationsPositionSolver(mEngineSettings.nbPositionSolverIterations);
|
||||
getDynamicsWorld()->setNbIterationsVelocitySolver(mEngineSettings.nbVelocitySolverIterations);
|
||||
getDynamicsWorld()->setTimeBeforeSleep(mEngineSettings.timeBeforeSleep);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -151,6 +151,9 @@ class SceneDemo : public Scene {
|
|||
/// Render the scene (possibly in multiple passes for shadow mapping)
|
||||
virtual void render() override;
|
||||
|
||||
/// Update the engine settings
|
||||
virtual void updateEngineSettings() override;
|
||||
|
||||
/// Render the scene in a single pass
|
||||
virtual void renderSinglePass(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix);
|
||||
|
||||
|
|
|
@ -271,9 +271,16 @@ void TestbedApplication::switchScene(Scene* newScene) {
|
|||
// Reset the scene
|
||||
mCurrentScene->reset();
|
||||
|
||||
mCurrentScene->updateEngineSettings();
|
||||
|
||||
resizeEvent(Vector2i(0, 0));
|
||||
}
|
||||
|
||||
// Notify that the engine settings have changed
|
||||
void TestbedApplication::notifyEngineSetttingsChanged() {
|
||||
mCurrentScene->updateEngineSettings();
|
||||
}
|
||||
|
||||
// Check the OpenGL errors
|
||||
void TestbedApplication::checkOpenGLErrorsInternal(const char* file, int line) {
|
||||
GLenum glError;
|
||||
|
|
|
@ -199,6 +199,9 @@ class TestbedApplication : public Screen {
|
|||
/// Enable/Disable Vertical synchronization
|
||||
void enableVSync(bool enable);
|
||||
|
||||
/// Notify that the engine settings have changed
|
||||
void notifyEngineSetttingsChanged();
|
||||
|
||||
// -------------------- Friendship -------------------- //
|
||||
|
||||
friend class Gui;
|
||||
|
|
Loading…
Reference in New Issue
Block a user