Lagrangian Liquid Simulation
Master Thesis project on simulation of liquids using Lagrangian approach and SPH
|
static class that deals with reading of xml configuration file and initialisations More...
#include <Configuration.h>
Static Public Member Functions | |
static void | initialiseWindow (int &o_frameRate, int &o_mouseMoveSensitivity, ngl::Real &o_timestep, bool &o_fpsTimerEnabled, bool &o_cacheEnabled, int &o_cacheSamplingInterval, bool &o_cacheAutomaticFlushEnabled, int &o_cacheAutomaticFlushInterval, bool &o_cacheExportRBDEnabled, bool &o_cacheExportBoundaryEnabled, std::string &o_path) |
set global parameters from the config file | |
static ngl::Camera | initialiseCamera (const float _aspect) |
create and return a camera from config file parameters | |
static ngl::Light | initialiseLight () |
create and return a light source from config file parameters | |
static std::vector < ShaderObject * > * | initialiseShader () |
create and return the list of shaders from config file parameters | |
static void | initialiseEnvironment (bool &o_obstacleEnabled, ngl::Vector &o_boundaryPosition, ngl::Vector &o_boundaryDimension, ngl::Real &o_boundaryRestitutionCoefficientForFluid, ngl::Real &o_boundaryRestitutionCoefficientForRBD, bool &o_boundaryBoundTop, std::vector< Particle > &o_sphereObstacleList, std::vector< Capsule > &o_capsuleObstacleList, ngl::Real &o_obstacleRestitutionCoefficient, bool &o_periodicWallEnabled, ngl::Real &o_periodicWallMaxAmplitude, ngl::Real &o_periodicWallSpeed, ngl::Real &o_periodicWallAngleIncrement, int &o_capsuleResolution) |
initialise environment | |
static void | initialiseFluidSolver (ngl::Real &o_smoothingLength, std::vector< FluidParticle > &o_particleList, std::vector< FluidParticle > &o_hoseParticlePrototypeList, std::vector< FluidParticle > &o_hoseParticleList, ngl::Vector &o_centerOfHose, ngl::Vector &o_velocityOfHose, bool &o_drawHoseMarker, bool &o_hoseWaitUntilFirstHitBoundary, bool &o_hoseWaitUntilFirstHitRBD) |
initialise solver | |
Static Public Attributes | |
static bool | s_debug = true |
debug parameter used in all the files to enable debugging and console output | |
static ngl::Real | s_accelerationOfFreeFall = -9.28 |
acceleration due to gravity(free fall) value | |
static ngl::Colour | s_normalColour |
particle default colour | |
static ngl::Colour | s_boundaryColour |
boundary colour | |
static int | s_nextParticleId = 0 |
global unique id available for creation of next particle in a fluid | |
static int | s_nextObstacleId = -1 |
global unique id available for creation of next obstacle | |
Static Private Member Functions | |
static std::vector< ngl::Real > | getFloatVectorFromString (const std::string _str, const int _d) |
utility function to split a string into a vector of floats | |
Static Private Attributes | |
static std::string | s_settingsDoc = "config/Settings.xml" |
the path of the configuration xml file |
static class that deals with reading of xml configuration file and initialisations
Definition at line 27 of file Configuration.h.
std::vector< ngl::Real > Configuration::getFloatVectorFromString | ( | const std::string | _str, |
const int | _d | ||
) | [static, private] |
utility function to split a string into a vector of floats
[in] | _str | the input string to be split |
[in] | _d | the count of split parts to be used as the size of the vector |
Definition at line 32 of file Configuration.cpp.
{ //split string into array of strings by "," std::vector<std::string> strArray; boost::split(strArray, _str, boost::is_any_of(",")); //loop through strings and convert to float array std::vector<ngl::Real> floatArray; for (int i = 0; i < _d; i++) floatArray.push_back(boost::lexical_cast<ngl::Real>(strArray[i])); //return array of float return floatArray; }
ngl::Camera Configuration::initialiseCamera | ( | const float | _aspect | ) | [static] |
create and return a camera from config file parameters
[in] | _aspect | the aspect ratio to be used for the camera creation |
Definition at line 90 of file Configuration.cpp.
References getFloatVectorFromString(), and s_settingsDoc.
{ //load settings xml file pugi::xml_document doc; doc.load_file(s_settingsDoc.c_str()); //get camera node pugi::xpath_node_set node = doc.select_nodes("/Settings/Camera"); //get near and far plane values float near = node.first().node().attribute("near").as_float(); float far = node.first().node().attribute("far").as_float(); //get fov int fov = node.first().node().attribute("fov").as_int(); //get from and to values and convert to float arrays std::vector<float> from = getFloatVectorFromString(node.first().node().attribute("from").value(), 3); std::vector<float> to = getFloatVectorFromString(node.first().node().attribute("to").value(), 3); //build vectors ngl::Vector eye(from[0], from[1], from[2]); ngl::Vector look(to[0], to[1], to[2]); ngl::Vector up(0, 1, 0); //create a camera with the read data ngl::Camera cam; cam.set(eye, look, up); cam.setShape(fov, _aspect, near, far, ngl::PERSPECTIVE); return cam; }
void Configuration::initialiseEnvironment | ( | bool & | o_obstacleEnabled, |
ngl::Vector & | o_boundaryPosition, | ||
ngl::Vector & | o_boundaryDimension, | ||
ngl::Real & | o_boundaryRestitutionCoefficientForFluid, | ||
ngl::Real & | o_boundaryRestitutionCoefficientForRBD, | ||
bool & | o_boundaryBoundTop, | ||
std::vector< Particle > & | o_sphereObstacleList, | ||
std::vector< Capsule > & | o_capsuleObstacleList, | ||
ngl::Real & | o_obstacleRestitutionCoefficient, | ||
bool & | o_periodicWallEnabled, | ||
ngl::Real & | o_periodicWallMaxAmplitude, | ||
ngl::Real & | o_periodicWallSpeed, | ||
ngl::Real & | o_periodicWallAngleIncrement, | ||
int & | o_capsuleResolution | ||
) | [static] |
initialise environment
[out] | o_obstacleEnabled | flag to toggle rbd |
[out] | o_boundaryPosition | boundary position |
[out] | o_boundaryDimension | boundary size |
[out] | o_boundaryRestitutionCoefficientForFluid | boundary-fluid restitution |
[out] | o_boundaryRestitutionCoefficientForRBD | boundary-rbd restitution |
[out] | o_boundaryBoundTop | flag to enable top face bounding |
[out] | o_sphereObstacleList | list of sphere rbd |
[out] | o_capsuleObstacleList | list of capsule rbd |
[out] | o_obstacleRestitutionCoefficient | rbd-fluid restitution |
[out] | o_periodicWallEnabled | flag to toggle periodic wall |
[out] | o_periodicWallMaxAmplitude | maximum amplitude of periodic wall |
[out] | o_periodicWallSpeed | speed factor of periodic wall |
[out] | o_periodicWallAngleIncrement | angle increment of periodic wall |
[out] | o_capsuleResolution | capsule resolution of drawing |
Definition at line 196 of file Configuration.cpp.
References s_nextObstacleId.
{ //load settings xml file pugi::xml_document doc; doc.load_file(s_settingsDoc.c_str()); //temporary variable std::vector<ngl::Real> tmp; //load global settings here pugi::xpath_node_set node = doc.select_nodes("/Settings/Environment"); //read info about the boundary tmp = getFloatVectorFromString(node.first().node().select_single_node("Boundary").node().attribute("position").value(), 3); o_boundaryPosition.set(tmp[0], tmp[1], tmp[2]); tmp = getFloatVectorFromString(node.first().node().select_single_node("Boundary").node().attribute("dimension").value(), 3); o_boundaryDimension.set(tmp[0], tmp[1], tmp[2]); o_boundaryRestitutionCoefficientForFluid = node.first().node().select_single_node("Boundary").node().attribute("restitutionForFluid").as_float(); o_boundaryRestitutionCoefficientForRBD = node.first().node().select_single_node("Boundary").node().attribute("restitutionForRBD").as_float(); o_boundaryBoundTop = node.first().node().select_single_node("Boundary").node().attribute("boundTop").as_bool(); //read info about periodic wall o_periodicWallEnabled = node.first().node().select_single_node("Boundary").node().attribute("periodicWallEnabled").as_bool(); node = node.first().node().select_single_node("Boundary").node().select_nodes("PeriodicWall"); o_periodicWallMaxAmplitude = node.first().node().attribute("maxAmplitude").as_float(); o_periodicWallSpeed = node.first().node().attribute("speed").as_float(); o_periodicWallAngleIncrement = node.first().node().attribute("angleIncrement").as_float(); //read info about obstacles node = doc.select_nodes("/Settings/Environment/Obstacles"); o_obstacleEnabled = node.first().node().attribute("enabled").as_bool(); o_obstacleRestitutionCoefficient = node.first().node().attribute("restitution").as_float(); o_capsuleResolution = node.first().node().attribute("capsuleResolution").as_int(); //get list of sphere obstacles node = node.first().node().select_nodes("Sphere"); for (pugi::xpath_node_set::const_iterator it = node.begin(); it != node.end(); ++it) { //get details for an obstacle pugi::xpath_node node1 = *it; //get parameters active parameter tmp = getFloatVectorFromString(node1.node().attribute("position").value(), 3); ngl::Vector position(tmp[0], tmp[1], tmp[2]); tmp = getFloatVectorFromString(node1.node().attribute("velocity").value(), 3); ngl::Vector velocity(tmp[0], tmp[1], tmp[2]); ngl::Real radius = node1.node().attribute("radius").as_float(); ngl::Real moveable = node1.node().attribute("moveable").as_bool(); tmp = getFloatVectorFromString(node1.node().attribute("colour").value(), 3); ngl::Colour colour(tmp[0], tmp[1], tmp[2]); //create and add obstacle to list o_sphereObstacleList.push_back ( Particle ( Configuration::s_nextObstacleId--, 0, position, colour, radius, moveable, velocity ) ); } //get list of capsule obstacles node = doc.select_nodes("/Settings/Environment/Obstacles/Capsule"); for (pugi::xpath_node_set::const_iterator it = node.begin(); it != node.end(); ++it) { //get details for an obstacle pugi::xpath_node node1 = *it; //get parameters active parameter tmp = getFloatVectorFromString(node1.node().attribute("position1").value(), 3); ngl::Vector position1(tmp[0], tmp[1], tmp[2]); tmp = getFloatVectorFromString(node1.node().attribute("position2").value(), 3); ngl::Vector position2(tmp[0], tmp[1], tmp[2]); ngl::Real incrementAngle = node1.node().attribute("incrementAngle").as_float(); ngl::Real initialAngle = node1.node().attribute("initialAngle").as_float(); ngl::Real radius = node1.node().attribute("radius").as_float(); ngl::Real moveable = node1.node().attribute("moveable").as_bool(); tmp = getFloatVectorFromString(node1.node().attribute("colour").value(), 3); ngl::Colour colour(tmp[0], tmp[1], tmp[2]); //calculate orientation vector ngl::Vector orientationVector = position2 - position1; //calculate height half ngl::Real height = orientationVector.length() / 2.0; //normalise orientation vector orientationVector.normalize(); //calculate centre position ngl::Vector centrePosition = position1 + (orientationVector * height); std::cout << "test Capsules : " << centrePosition << "\n"; //create and add obstacle to list o_capsuleObstacleList.push_back ( Capsule ( Configuration::s_nextObstacleId--, 0, centrePosition, colour, radius, height, orientationVector, incrementAngle, initialAngle, moveable ) ); } }
void Configuration::initialiseFluidSolver | ( | ngl::Real & | o_smoothingLength, |
std::vector< FluidParticle > & | o_particleList, | ||
std::vector< FluidParticle > & | o_hoseParticlePrototypeList, | ||
std::vector< FluidParticle > & | o_hoseParticleList, | ||
ngl::Vector & | o_centerOfHose, | ||
ngl::Vector & | o_velocityOfHose, | ||
bool & | o_drawHoseMarker, | ||
bool & | o_hoseWaitUntilFirstHitBoundary, | ||
bool & | o_hoseWaitUntilFirstHitRBD | ||
) | [static] |
initialise solver
[out] | o_smoothingLength | smoothing length of neighbour structure |
[out] | o_particleList | fluid particle list |
[out] | o_hoseParticlePrototypeList | list of sample particles for each fluid |
[out] | o_hoseParticleList | hose particles |
[out] | o_centerOfHose | centre position of hose |
[out] | o_velocityOfHose | velocity of hose |
[out] | o_drawHoseMarker | flag to toggle whether to draw hose marker |
[out] | o_hoseWaitUntilFirstHitBoundary | flag to toggle whether hose particles hit boundary first to start behaving as fluids |
[out] | o_hoseWaitUntilFirstHitRBD | flag to toggle whether hose particles hit RBD first to start behaving as fluids |
Definition at line 350 of file Configuration.cpp.
References s_nextParticleId.
{ //load settings xml file pugi::xml_document doc; doc.load_file(s_settingsDoc.c_str()); //load global settings here pugi::xpath_node_set node = doc.select_nodes("/Settings/FluidSolver"); //read smoothing length o_smoothingLength = node.first().node().attribute("smoothingLength").as_float(); //initially reserve space for maximum growth of particle list int initialReservedParticleCount =node.first().node().attribute("initialReservedParticleCount").as_int(); o_particleList.reserve(initialReservedParticleCount); //tmp variable std::vector<ngl::Real> tmp; //get hose info node = doc.select_nodes("/Settings/FluidSolver/Hose"); tmp = getFloatVectorFromString(node.first().node().attribute("center").value(), 3); o_centerOfHose = ngl::Vector(tmp[0], tmp[1], tmp[2]); o_hoseWaitUntilFirstHitBoundary = node.first().node().attribute("waitUntilHitBoundary").as_bool(); o_hoseWaitUntilFirstHitRBD = node.first().node().attribute("waitUntilHitRBD").as_bool(); o_drawHoseMarker = node.first().node().attribute("drawMarker").as_bool(); std::string hoseMeshName = node.first().node().select_single_node("Obj").node().child_value(); ngl::Obj hoseMesh(hoseMeshName); tmp = getFloatVectorFromString(node.first().node().select_single_node("Obj").node().attribute("center").value(), 3); ngl::Vector centerOfHoseMesh(tmp[0], tmp[1], tmp[2]); tmp = getFloatVectorFromString(node.first().node().select_single_node("Velocity").node().attribute("value").value(), 3); o_velocityOfHose = ngl::Vector(tmp[0], tmp[1], tmp[2]); for (int i = 0; i < hoseMesh.getNumVerts(); i++) { //create particle @ mesh vertices and add to hose particle list o_hoseParticleList.push_back ( FluidParticle ( 0, 0, 0, centerOfHoseMesh + hoseMesh.getVertexAtIndex(i) ) ); } //get a list of fluids node = doc.select_nodes("/Settings/FluidSolver/Fluid"); for (pugi::xpath_node_set::const_iterator it = node.begin(); it != node.end(); ++it) { //get details for a fluid pugi::xpath_node node = *it; //get its active parameter bool isActive = node.node().attribute("active").as_bool(); //skip this fluid if not active if (isActive) { //else, active fluid => go on creating and adding particles of fluid to particle list //read parameters ngl::Real volume = boost::lexical_cast<ngl::Real>(node.node().select_single_node("Volume").node().child_value()); ngl::Real materialDensity = boost::lexical_cast<ngl::Real>(node.node().select_single_node("MaterialDensity").node().child_value()); tmp = getFloatVectorFromString(node.node().select_single_node("Colour").node().attribute("value").value(), 3); ngl::Colour color(tmp[0], tmp[1], tmp[2]); std::string meshName = node.node().select_single_node("Obj").node().child_value(); ngl::Obj mesh(meshName); tmp = getFloatVectorFromString(node.node().select_single_node("Obj").node().attribute("center").value(), 3); ngl::Vector centerOfMesh(tmp[0], tmp[1], tmp[2]); tmp = getFloatVectorFromString(node.node().select_single_node("Velocity").node().attribute("value").value(), 3); ngl::Vector velocity(tmp[0], tmp[1], tmp[2]); ngl::Real viscosityConstant = boost::lexical_cast<ngl::Real>(node.node().select_single_node("ViscosityConstant").node().child_value()); ngl::Real gasConstant = boost::lexical_cast<ngl::Real>(node.node().select_single_node("GasConstant").node().child_value()); ngl::Real surfaceTensionCoefficient = node.node().select_single_node("SurfaceTension").node().attribute("coefficient").as_float(); ngl::Real surfaceTensionThreshold = node.node().select_single_node("SurfaceTension").node().attribute("threshold").as_float(); ngl::Real surfaceColorCoefficient = node.node().select_single_node("SurfaceTension").node().attribute("color").as_float(); ngl::Real interfaceTensionCoefficient = node.node().select_single_node("SurfaceInterface").node().attribute("coefficient").as_float(); ngl::Real interfaceTensionThreshold = node.node().select_single_node("SurfaceInterface").node().attribute("threshold").as_float(); ngl::Real interfaceColorCoefficient = node.node().select_single_node("SurfaceInterface").node().attribute("color").as_float(); ngl::Real radius = boost::lexical_cast<ngl::Real>(node.node().select_single_node("Radius").node().child_value()); std::string name = node.node().attribute("name").value(); //calculate mass per particle int particleCount = mesh.getNumVerts(); ngl::Real mass = materialDensity * (volume / ((ngl::Real)particleCount)); std::cout << "Mesh : " << meshName << "\tparticle count : " << particleCount << "\tunit mass : " << mass << "\n"; //create fluid particles from obj for (int i = 0; i < particleCount; i++) { //create particle @ mesh vertices and add to particle list o_particleList.push_back ( FluidParticle ( Configuration::s_nextParticleId++, mass, materialDensity, centerOfMesh + mesh.getVertexAtIndex(i), velocity, viscosityConstant, gasConstant, surfaceTensionCoefficient, surfaceTensionThreshold, surfaceColorCoefficient, interfaceTensionCoefficient, interfaceTensionThreshold, interfaceColorCoefficient, color, radius, name ) ); } std::cout << "Fluid : << " << name << "\tListSize : " << o_particleList.size() << "\n"; //add a sample of this fluid's particle to hose prototype list o_hoseParticlePrototypeList.push_back ( FluidParticle ( -1, mass, materialDensity, 0, 0, viscosityConstant, gasConstant, surfaceTensionCoefficient, surfaceTensionThreshold, surfaceColorCoefficient, interfaceTensionCoefficient, interfaceTensionThreshold, interfaceColorCoefficient, color, radius, name, o_hoseWaitUntilFirstHitBoundary, o_hoseWaitUntilFirstHitRBD ) ); } } }
ngl::Light Configuration::initialiseLight | ( | ) | [static] |
create and return a light source from config file parameters
Definition at line 123 of file Configuration.cpp.
References getFloatVectorFromString(), and s_settingsDoc.
{ //load settings xml file pugi::xml_document doc; doc.load_file(s_settingsDoc.c_str()); //get camera node pugi::xpath_node_set node = doc.select_nodes("/Settings/Light"); //get to values and convert to float array std::vector<float> to = getFloatVectorFromString(node.first().node().attribute("to").value(), 3); //get color values and convert to float array std::vector<float> color = getFloatVectorFromString(node.first().node().attribute("color").value(), 4); //build vectors ngl::Vector direction(to[0], to[1], to[2]); ngl::Colour lightColor(color[0], color[1], color[2], color[3]); //create a light with the read data ngl::Light light(direction, lightColor, ngl::LIGHTREMOTE); return light; }
std::vector< ShaderObject * > * Configuration::initialiseShader | ( | ) | [static] |
create and return the list of shaders from config file parameters
Definition at line 148 of file Configuration.cpp.
References s_settingsDoc.
{ //load settings xml file pugi::xml_document doc; doc.load_file(s_settingsDoc.c_str()); std::vector<ShaderObject*>* result = new std::vector<ShaderObject*>; //get list of normal shaders pugi::xpath_node_set node = doc.select_nodes("/Settings/Shaders/Shader"); for (pugi::xpath_node_set::const_iterator it = node.begin(); it != node.end(); ++it) { //get details for a shader pugi::xpath_node node = *it; //save values in array std::string name = node.node().attribute("name").value(); std::string vs = node.node().attribute("vertex").value(); std::string fs = node.node().attribute("fragment").value(); bool isSpecial = node.node().attribute("isSpecial").as_bool(); std::vector<std::string> attribNames; std::vector<int> attribValues; if (isSpecial) { //load attributes pugi::xpath_node_set attributes = node.node().select_nodes("Attrib"); for (pugi::xpath_node_set::const_iterator it1 = attributes.begin(); it1 != attributes.end(); ++it1) { pugi::xpath_node innerNode = *it1; std::string attribName = innerNode.node().attribute("name").value(); int value = innerNode.node().attribute("value").as_int(); attribNames.push_back(attribName); attribValues.push_back(value); } } //create a shader and add it to our list result->push_back(new ShaderObject(name, vs, fs, attribNames, attribValues, isSpecial)); } return result; }
void Configuration::initialiseWindow | ( | int & | o_frameRate, |
int & | o_mouseMoveSensitivity, | ||
ngl::Real & | o_timestep, | ||
bool & | o_fpsTimerEnabled, | ||
bool & | o_cacheEnabled, | ||
int & | o_cacheSamplingInterval, | ||
bool & | o_cacheAutomaticFlushEnabled, | ||
int & | o_cacheAutomaticFlushInterval, | ||
bool & | o_cacheExportRBDEnabled, | ||
bool & | o_cacheExportBoundaryEnabled, | ||
std::string & | o_path | ||
) | [static] |
set global parameters from the config file
[out] | o_frameRate | the frame rate for the simulation |
[out] | o_mouseMoveSensitivity | sensitivity value of the mouse (x,y) movement |
[out] | o_timestep | global timestep of simulation |
[out] | o_fpsTimerEnabled | global timestep of simulation |
[out] | o_cacheEnabled | flag to toggle cache |
[out] | o_cacheSamplingInterval | cache sampling interval |
[out] | o_cacheAutomaticFlushEnabled | flag to toggle automatic flush |
[out] | o_cacheAutomaticFlushInterval | automatic flush interval |
[out] | o_cacheExportRBDEnabled | flag to toggle cache of rbd |
[out] | o_cacheExportBoundaryEnabled | flag to toggle cache of boundary |
[out] | o_path | global timestep of simulation |
Definition at line 50 of file Configuration.cpp.
{ //load settings xml file pugi::xml_document doc; doc.load_file(s_settingsDoc.c_str()); //load global settings here pugi::xpath_node_set node = doc.select_nodes("/Settings/Global"); o_frameRate = node.first().node().attribute("fpsFrequency").as_int(); o_mouseMoveSensitivity = node.first().node().attribute("mouseSensitivity").as_int(); o_timestep = node.first().node().attribute("timestep").as_float(); o_fpsTimerEnabled = node.first().node().attribute("fpsTimerEnabled").as_bool(); //read cache parameters node = doc.select_nodes("/Settings/Cache"); o_cacheEnabled = node.first().node().attribute("enabled").as_bool(); o_cacheSamplingInterval = node.first().node().attribute("samplingInterval").as_int(); o_cacheAutomaticFlushEnabled = node.first().node().attribute("automaticFlush").as_bool(); o_cacheAutomaticFlushInterval = node.first().node().attribute("automaticFlushInterval").as_int(); o_cacheExportRBDEnabled = node.first().node().attribute("exportRBD").as_bool(); o_cacheExportBoundaryEnabled = node.first().node().attribute("exportBoundary").as_bool(); o_path = node.first().node().attribute("path").value(); }
ngl::Real Configuration::s_accelerationOfFreeFall = -9.28 [static] |
acceleration due to gravity(free fall) value
Definition at line 34 of file Configuration.h.
ngl::Colour Configuration::s_boundaryColour [static] |
boundary colour
Definition at line 40 of file Configuration.h.
bool Configuration::s_debug = true [static] |
debug parameter used in all the files to enable debugging and console output
Definition at line 31 of file Configuration.h.
int Configuration::s_nextObstacleId = -1 [static] |
global unique id available for creation of next obstacle
Definition at line 46 of file Configuration.h.
int Configuration::s_nextParticleId = 0 [static] |
global unique id available for creation of next particle in a fluid
Definition at line 43 of file Configuration.h.
ngl::Colour Configuration::s_normalColour [static] |
particle default colour
Definition at line 37 of file Configuration.h.
std::string Configuration::s_settingsDoc = "config/Settings.xml" [static, private] |
the path of the configuration xml file
Definition at line 146 of file Configuration.h.