Skip to content

Commit a1d4b0b

Browse files
committed
new emitter concept for variable velocity
1 parent c5a063d commit a1d4b0b

10 files changed

Lines changed: 237 additions & 437 deletions

File tree

SPlisHSPlasH/Emitter.cpp

Lines changed: 173 additions & 372 deletions
Large diffs are not rendered by default.

SPlisHSPlasH/Emitter.h

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,25 @@ namespace SPH
1515
const unsigned int width, const unsigned int height,
1616
const Vector3r &pos, const Matrix3r & rotation,
1717
const Real velocity,
18-
const unsigned int type = 0);
18+
const unsigned int type = 0,
19+
const bool useBoundary = false);
1920
virtual ~Emitter();
2021

2122
protected:
2223
FluidModel *m_model;
2324
unsigned int m_width;
2425
unsigned int m_height;
26+
unsigned int m_depth;
27+
Vector3r m_size{0, 0, 0};
2528
Vector3r m_x;
2629
Matrix3r m_rotation;
2730
Real m_velocity;
2831
unsigned int m_type;
29-
Real m_nextEmitTime;
30-
Real m_emitStartTime;
31-
Real m_emitEndTime;
32-
unsigned int m_emitCounter;
32+
Real m_emitStartTime{0};
33+
Real m_emitEndTime{std::numeric_limits<Real>::max()};
34+
unsigned int m_emitCounter{0};
3335
unsigned int m_objectId;
36+
bool m_useBoundary;
3437

3538
FORCE_INLINE bool inBox(const Vector3r &x, const Vector3r &xBox, const Matrix3r &rotBox, const Vector3r &scaleBox)
3639
{
@@ -53,12 +56,11 @@ namespace SPH
5356

5457
public:
5558
void emitParticles(std::vector <unsigned int> &reusedParticles, unsigned int &indexReuse, unsigned int &numEmittedParticles);
56-
void emitParticlesCircle(std::vector <unsigned int> &reusedParticles, unsigned int &indexReuse, unsigned int &numEmittedParticles);
57-
Real getNextEmitTime() const { return m_nextEmitTime; }
58-
void setNextEmitTime(Real val) { m_nextEmitTime = val; }
59-
void setEmitStartTime(Real val) { m_emitStartTime = val; setNextEmitTime(val); }
59+
void setEmitStartTime(Real val) { m_emitStartTime = val; }
6060
void setEmitEndTime(Real val) { m_emitEndTime = val; }
61+
static int getDepth();
6162
static Vector3r getSize(const Real width, const Real height, const int type);
63+
static Vector3r getSizeExtraMargin(const Real width, const Real height, const int type);
6264

6365
void step(std::vector <unsigned int> &reusedParticles, unsigned int &indexReuse, unsigned int &numEmittedParticles);
6466
virtual void reset();

SPlisHSPlasH/EmitterSystem.cpp

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,6 @@ void EmitterSystem::step()
5959
// reset particle state
6060
Simulation *sim = Simulation::getCurrent();
6161
const unsigned int nModels = sim->numberOfFluidModels();
62-
for (unsigned int m = 0; m < nModels; m++)
63-
{
64-
FluidModel *fm = sim->getFluidModel(m);
65-
const unsigned int numParticles = fm->numActiveParticles();
66-
#pragma omp parallel for schedule(static) default(shared)
67-
for (int i = 0; i < (int)numParticles; i++)
68-
{
69-
if (fm->getParticleState(i) == ParticleState::AnimatedByEmitter)
70-
fm->setParticleState(i, ParticleState::Active);
71-
}
72-
}
7362

7463
reuseParticles();
7564
unsigned int indexReuse = 0;
@@ -96,13 +85,15 @@ void EmitterSystem::reset()
9685
void EmitterSystem::addEmitter(const unsigned int width, const unsigned int height,
9786
const Vector3r &pos, const Matrix3r & rotation,
9887
const Real velocity,
99-
const unsigned int type)
88+
const unsigned int type,
89+
const bool useBoundary)
10090
{
10191
m_emitters.push_back(new Emitter(m_model,
10292
width, height,
10393
pos, rotation,
10494
velocity,
105-
type));
95+
type,
96+
useBoundary));
10697
}
10798

10899
void EmitterSystem::enableReuseParticles(const Vector3r &boxMin /*= Vector3r(-1, -1, -1)*/, const Vector3r &boxMax /*= Vector3r(1, 1, 1)*/)

SPlisHSPlasH/EmitterSystem.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ namespace SPH
3434
void disableReuseParticles();
3535
void addEmitter(const unsigned int width, const unsigned int height,
3636
const Vector3r &pos, const Matrix3r & rotation,
37-
const Real velocity,
38-
const unsigned int type);
37+
const Real velocity,const unsigned int type,
38+
const bool useBoundary = false);
3939
unsigned int numEmitters() const { return static_cast<unsigned int>(m_emitters.size()); }
4040
std::vector<Emitter*> &getEmitters() { return m_emitters; }
4141

SPlisHSPlasH/Utilities/SceneParameterObjects.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ int EmitterParameterObject::EMITTER_ROTANGLE = -1;
138138
int EmitterParameterObject::EMITTER_STARTTIME = -1;
139139
int EmitterParameterObject::EMITTER_ENDTIME = -1;
140140
int EmitterParameterObject::EMITTER_TYPE = -1;
141+
int EmitterParameterObject::EMITTER_USEBOUNDARY = -1;
141142

142143
void EmitterParameterObject::initParameters()
143144
{
@@ -180,6 +181,10 @@ void EmitterParameterObject::initParameters()
180181
EMITTER_TYPE = createNumericParameter<unsigned int>("type", "Emitter type", &type);
181182
setGroup(EMITTER_TYPE, "Emitter");
182183
setDescription(EMITTER_TYPE, "Defines the shape of the emitter: 0: box, 1: circle.");
184+
185+
EMITTER_USEBOUNDARY = createBoolParameter("useBoundary", "Use Boundary", &useBoundary);
186+
setGroup(EMITTER_USEBOUNDARY, "Emitter");
187+
setDescription(EMITTER_USEBOUNDARY, "Creates a boundary model around the emitter if defined");
183188
}
184189

185190

SPlisHSPlasH/Utilities/SceneParameterObjects.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ namespace Utilities
144144
Real emitStartTime;
145145
Real emitEndTime;
146146
unsigned int type; // type: 0 = rectangular, 1 = circle
147+
bool useBoundary;
147148

148149
EmitterParameterObject()
149150
{
@@ -158,10 +159,11 @@ namespace Utilities
158159
emitStartTime = 0.0;
159160
emitEndTime = std::numeric_limits<Real>::max();
160161
type = 0;
162+
useBoundary = false;
161163
}
162164

163165
EmitterParameterObject(std::string id_, unsigned int width_, unsigned int height_, Vector3r x_, Real velocity_, Vector3r axis_,
164-
Real angle_, Real emitStartTime_, Real emitEndTime_, unsigned int type_)
166+
Real angle_, Real emitStartTime_, Real emitEndTime_, unsigned int type_, bool useBoundary_)
165167
{
166168
id = id_;
167169
width = width_;
@@ -173,6 +175,7 @@ namespace Utilities
173175
emitStartTime = emitStartTime_;
174176
emitEndTime = emitEndTime_;
175177
type = type_;
178+
useBoundary = useBoundary_;
176179
}
177180

178181
static int EMITTER_ID;
@@ -185,6 +188,7 @@ namespace Utilities
185188
static int EMITTER_STARTTIME;
186189
static int EMITTER_ENDTIME;
187190
static int EMITTER_TYPE;
191+
static int EMITTER_USEBOUNDARY;
188192

189193
virtual void initParameters();
190194
};

Simulator/PositionBasedDynamicsWrapper/PBDBoundarySimulator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ void PBDBoundarySimulator::initBoundaryData()
7070
PBDWrapper::RBData rb;
7171
rb.x = ed->x;
7272
rb.R = AngleAxisr(ed->angle, ed->axis).toRotationMatrix();
73-
rb.scale = Emitter::getSize(static_cast<Real>(ed->width), static_cast<Real>(ed->height), ed->type);
73+
rb.scale = Emitter::getSizeExtraMargin(static_cast<Real>(ed->width), static_cast<Real>(ed->height), ed->type);
7474
rb.restitution = 0.6;
7575
rb.friction = 0.1;
7676
if (ed->type == 0)

Simulator/SimulatorBase.cpp

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,39 +1315,38 @@ void SimulatorBase::createEmitters()
13151315
ed->width = 1;
13161316
ed->type = 0;
13171317
}
1318-
Matrix3r rot = AngleAxisr(ed->angle, ed->axis).toRotationMatrix();
1319-
model->getEmitterSystem()->addEmitter(
1320-
ed->width, ed->height,
1321-
ed->x, rot,
1322-
ed->velocity,
1323-
ed->type);
1324-
1325-
// Generate boundary geometry around emitters
1326-
Emitter *emitter = model->getEmitterSystem()->getEmitters().back();
1327-
BoundaryParameterObject *emitterBoundary = new BoundaryParameterObject();
1328-
emitterBoundary->dynamic = false;
1329-
emitterBoundary->isWall = false;
1330-
emitterBoundary->color = { 0.2f, 0.2f, 0.2f, 1.0f };
1331-
emitterBoundary->axis = ed->axis;
1332-
emitterBoundary->angle = ed->angle;
1333-
const Real supportRadius = sim->getSupportRadius();
1334-
const Vector3r & emitDir = rot.col(0);
1335-
emitterBoundary->scale = Emitter::getSize(static_cast<Real>(ed->width), static_cast<Real>(ed->height), ed->type);
1336-
const Vector3r pos = ed->x;
1337-
emitterBoundary->translation = pos;
1338-
emitterBoundary->samplesFile = "";
1339-
emitterBoundary->mapInvert = false;
1340-
emitterBoundary->mapResolution = Eigen::Matrix<unsigned int, 3, 1, Eigen::DontAlign>(20, 20, 20);
1341-
emitterBoundary->mapThickness = 0.0;
1342-
1343-
if (sim->is2DSimulation())
1344-
emitterBoundary->scale[2] = 2 * supportRadius;
1345-
1346-
if (ed->type == 0)
1347-
emitterBoundary->meshFile = FileSystem::normalizePath(getExePath() + "/resources/emitter_boundary/EmitterBox.obj");
1348-
else if (ed->type == 1)
1349-
emitterBoundary->meshFile = FileSystem::normalizePath(getExePath() + "/resources/emitter_boundary/EmitterCylinder.obj");
1350-
scene.boundaryModels.push_back(emitterBoundary);
1318+
Matrix3r rot = AngleAxisr(ed->angle, ed->axis.normalized()).toRotationMatrix();
1319+
model->getEmitterSystem()->addEmitter(ed->width, ed->height, ed->x, rot, ed->velocity, ed->type,
1320+
ed->useBoundary);
1321+
1322+
Emitter* emitter = model->getEmitterSystem()->getEmitters().back();
1323+
if (ed->useBoundary) {
1324+
// Generate boundary geometry around emitters
1325+
BoundaryParameterObject* emitterBoundary = new BoundaryParameterObject();
1326+
emitterBoundary->dynamic = false;
1327+
emitterBoundary->isWall = false;
1328+
emitterBoundary->color = {0.2f, 0.2f, 0.2f, 1.0f};
1329+
emitterBoundary->axis = ed->axis;
1330+
emitterBoundary->angle = ed->angle;
1331+
const Real supportRadius = sim->getSupportRadius();
1332+
const Vector3r& emitDir = rot.col(0);
1333+
emitterBoundary->scale = Emitter::getSizeExtraMargin(static_cast<Real>(ed->width), static_cast<Real>(ed->height), ed->type);
1334+
const Vector3r pos = ed->x;
1335+
emitterBoundary->translation = pos;
1336+
emitterBoundary->samplesFile = "";
1337+
emitterBoundary->mapInvert = false;
1338+
emitterBoundary->mapResolution = Eigen::Matrix<unsigned int, 3, 1, Eigen::DontAlign>(20, 20, 20);
1339+
emitterBoundary->mapThickness = 0.0;
1340+
1341+
if (sim->is2DSimulation())
1342+
emitterBoundary->scale[2] = 2 * supportRadius;
1343+
1344+
if (ed->type == 0)
1345+
emitterBoundary->meshFile = FileSystem::normalizePath(getExePath() + "/resources/emitter_boundary/EmitterBox.obj");
1346+
else if (ed->type == 1)
1347+
emitterBoundary->meshFile = FileSystem::normalizePath(getExePath() + "/resources/emitter_boundary/EmitterCylinder.obj");
1348+
scene.boundaryModels.push_back(emitterBoundary);
1349+
}
13511350

13521351
// reuse particles if they are outside of a bounding box
13531352
bool emitterReuseParticles = false;

pySPlisHSPlasH/EmitterModule.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@ void EmitterModule(py::module m_sub){
2828
return SPH::Emitter(model, width, height, pos, rotation, velocity, type);
2929
}))
3030
.def("emitParticles", &SPH::Emitter::emitParticles)
31-
.def("emitParticlesCircle", &SPH::Emitter::emitParticlesCircle)
32-
.def("getNextEmitTime", &SPH::Emitter::getNextEmitTime)
33-
.def("setNextEmitTime", &SPH::Emitter::setNextEmitTime)
3431
.def("setEmitStartTime", &SPH::Emitter::setEmitStartTime)
3532
.def("setEmitEndTime", &SPH::Emitter::setEmitEndTime)
3633
.def("getPosition", &SPH::Emitter::getPosition)

pySPlisHSPlasH/UtilitiesModule.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -339,10 +339,10 @@ void UtilitiesModule(py::module m) {
339339

340340
py::class_<Utilities::EmitterParameterObject, GenParam::ParameterObject>(m_sub_sub, "EmitterData")
341341
.def(py::init<>())
342-
.def(py::init<std::string, unsigned int, unsigned int, Vector3r, Real, Vector3r, Real, Real, Real, unsigned int>(),
342+
.def(py::init<std::string, unsigned int, unsigned int, Vector3r, Real, Vector3r, Real, Real, Real, unsigned int, bool>(),
343343
"id"_a="Fluid", "width"_a=5, "height"_a=5, "x"_a=Vector3r::Zero(),
344344
"velocity"_a=1, "axis"_a = Vector3r(1, 0, 0), "angle"_a = 0.0, "emitStartTime"_a=0,
345-
"emitEndTime"_a=std::numeric_limits<Real>::max(), "type"_a=0)
345+
"emitEndTime"_a=std::numeric_limits<Real>::max(), "type"_a=0, "useBoundary"_a = false)
346346
.def_readwrite("id", &Utilities::EmitterParameterObject::id)
347347
.def_readwrite("width", &Utilities::EmitterParameterObject::width)
348348
.def_readwrite("height", &Utilities::EmitterParameterObject::height)
@@ -352,7 +352,8 @@ void UtilitiesModule(py::module m) {
352352
.def_readwrite("angle", &Utilities::EmitterParameterObject::angle)
353353
.def_readwrite("emitStartTime", &Utilities::EmitterParameterObject::emitStartTime)
354354
.def_readwrite("emitEndTime", &Utilities::EmitterParameterObject::emitEndTime)
355-
.def_readwrite("type", &Utilities::EmitterParameterObject::type);
355+
.def_readwrite("type", &Utilities::EmitterParameterObject::type)
356+
.def_readwrite("useBoundary", &Utilities::EmitterParameterObject::useBoundary);
356357

357358
py::class_<Utilities::AnimationFieldParameterObject, GenParam::ParameterObject>(m_sub_sub, "AnimationFieldData")
358359
.def(py::init<>())

0 commit comments

Comments
 (0)