feat: particle aging
This commit is contained in:
parent
25d347cf35
commit
650a245f0a
|
|
@ -42,10 +42,10 @@ void SpawnPointCallback::Execute(vtkObject *caller, unsigned long evId, void *ca
|
||||||
|
|
||||||
points->InsertNextPoint(worldPos[0], worldPos[1], 0);
|
points->InsertNextPoint(worldPos[0], worldPos[1], 0);
|
||||||
this->particlesBeached->InsertNextValue(0);
|
this->particlesBeached->InsertNextValue(0);
|
||||||
|
this->particlesAge->InsertNextValue(0);
|
||||||
|
|
||||||
// FIXME: The below lines cause some weird interaction with our vtkTimer.
|
// FIXME: The below lines cause some weird interaction with our vtkTimer.
|
||||||
// see github issue https://github.com/MakeNEnjoy/interactive-track-and-trace/issues/28
|
// see github issue https://github.com/MakeNEnjoy/interactive-track-and-trace/issues/28
|
||||||
this->particlesBeached->Modified();
|
|
||||||
this->points->Modified();
|
this->points->Modified();
|
||||||
ren->GetRenderWindow()->Render();
|
ren->GetRenderWindow()->Render();
|
||||||
}
|
}
|
||||||
|
|
@ -80,3 +80,7 @@ void SpawnPointCallback::setUVGrid(const std::shared_ptr<UVGrid> &uvGrid) {
|
||||||
void SpawnPointCallback::setBeached(const vtkSmartPointer<vtkIntArray> &ints) {
|
void SpawnPointCallback::setBeached(const vtkSmartPointer<vtkIntArray> &ints) {
|
||||||
this->particlesBeached = ints;
|
this->particlesBeached = ints;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SpawnPointCallback::setAge(const vtkSmartPointer<vtkIntArray> &ints) {
|
||||||
|
this->particlesAge = ints;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ public:
|
||||||
|
|
||||||
void setBeached(const vtkSmartPointer<vtkIntArray> &parts);
|
void setBeached(const vtkSmartPointer<vtkIntArray> &parts);
|
||||||
|
|
||||||
|
void setAge(const vtkSmartPointer<vtkIntArray> &parts);
|
||||||
|
|
||||||
void setUVGrid(const std::shared_ptr<UVGrid> &uvGrid);
|
void setUVGrid(const std::shared_ptr<UVGrid> &uvGrid);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -32,6 +34,7 @@ private:
|
||||||
vtkSmartPointer<vtkPoints> points;
|
vtkSmartPointer<vtkPoints> points;
|
||||||
vtkSmartPointer<vtkRenderer> ren;
|
vtkSmartPointer<vtkRenderer> ren;
|
||||||
vtkSmartPointer<vtkIntArray> particlesBeached;
|
vtkSmartPointer<vtkIntArray> particlesBeached;
|
||||||
|
vtkSmartPointer<vtkIntArray> particlesAge;
|
||||||
std::shared_ptr<UVGrid> uvGrid;
|
std::shared_ptr<UVGrid> uvGrid;
|
||||||
vtkSmartPointer<vtkAbstractTransform> inverseCartographicProjection;
|
vtkSmartPointer<vtkAbstractTransform> inverseCartographicProjection;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ vtkSmartPointer<SpawnPointCallback> LGlyphLayer::createSpawnPointCallback() {
|
||||||
newPointCallBack->setRen(this->ren);
|
newPointCallBack->setRen(this->ren);
|
||||||
newPointCallBack->setUVGrid(this->uvGrid);
|
newPointCallBack->setUVGrid(this->uvGrid);
|
||||||
newPointCallBack->setBeached(this->particlesBeached);
|
newPointCallBack->setBeached(this->particlesBeached);
|
||||||
|
newPointCallBack->setAge(this->particlesAge);
|
||||||
return newPointCallBack;
|
return newPointCallBack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -35,20 +36,24 @@ vtkSmartPointer<SpawnPointCallback> LGlyphLayer::createSpawnPointCallback() {
|
||||||
/**
|
/**
|
||||||
* Build and returns a vtkLookupTable for the given number of colours in grayscale.
|
* Build and returns a vtkLookupTable for the given number of colours in grayscale.
|
||||||
* @param n : number of colours to add to the SetTableRange
|
* @param n : number of colours to add to the SetTableRange
|
||||||
* @return : a vtkLookupTable with grayscale colours from [1,1,1,1] to [0.5,0.5,0.5,0.5] in n steps.
|
* @return : a vtkLookupTable with grayscale colours from [1,1,1,1] to [1,1,1,0.25] in n steps.
|
||||||
*/
|
*/
|
||||||
vtkSmartPointer<vtkLookupTable> buildLut(int n) {
|
vtkSmartPointer<vtkLookupTable> buildLut(int n) {
|
||||||
vtkNew<vtkLookupTable> lut;
|
vtkNew<vtkLookupTable> lut;
|
||||||
lut->SetNumberOfColors(n+1);
|
lut->SetNumberOfColors(n);
|
||||||
lut->SetTableRange(0, n);
|
lut->SetTableRange(0, n);
|
||||||
lut->SetScaleToLinear();
|
lut->SetScaleToLinear();
|
||||||
lut->Build();
|
lut->Build();
|
||||||
for (int i=0; i < n; i++) {
|
for (int i=0; i < n; i++) {
|
||||||
lut->SetTableValue(i, 1-(0.5*i/(n-1)), 1-(0.5*i/(n-1)), 1-(0.5*i/(n-1)), 1-(0.5*i/(n-1)));
|
lut->SetTableValue(i, 1, 1, 1, 1-(0.75*i/(n-1)));
|
||||||
}
|
}
|
||||||
// set the last value to separate fully beached particles from those that have simply not moved in a bit.
|
lut->UseAboveRangeColorOn();
|
||||||
lut->SetTableValue(n-1, 0, 0, 0, 0.25);
|
lut->SetAboveRangeColor(1,1,1,0.20);
|
||||||
lut->SetTableValue(n, 0, 0, 0, 0);
|
|
||||||
|
// We cheat a little here: any particle with an age of -1 is out of bounds, and thus set invisible.
|
||||||
|
lut->UseBelowRangeColorOn();
|
||||||
|
lut->SetBelowRangeColor(1,1,1,0);
|
||||||
|
|
||||||
return lut;
|
return lut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,8 +69,13 @@ LGlyphLayer::LGlyphLayer(std::shared_ptr<UVGrid> uvGrid, std::unique_ptr<Advecti
|
||||||
this->particlesBeached->SetName("particlesBeached");
|
this->particlesBeached->SetName("particlesBeached");
|
||||||
this->particlesBeached->SetNumberOfComponents(0);
|
this->particlesBeached->SetNumberOfComponents(0);
|
||||||
|
|
||||||
|
this->particlesAge = vtkSmartPointer<vtkIntArray>::New();
|
||||||
|
this->particlesAge->SetName("particlesAge");
|
||||||
|
this->particlesAge->SetNumberOfComponents(0);
|
||||||
|
|
||||||
data->GetPointData()->AddArray(this->particlesBeached);
|
data->GetPointData()->AddArray(this->particlesBeached);
|
||||||
data->GetPointData()->SetActiveScalars("particlesBeached");
|
data->GetPointData()->AddArray(this->particlesAge);
|
||||||
|
data->GetPointData()->SetActiveScalars("particlesAge");
|
||||||
|
|
||||||
advector = std::move(advectionKernel);
|
advector = std::move(advectionKernel);
|
||||||
this->uvGrid = uvGrid;
|
this->uvGrid = uvGrid;
|
||||||
|
|
@ -86,8 +96,9 @@ LGlyphLayer::LGlyphLayer(std::shared_ptr<UVGrid> uvGrid, std::unique_ptr<Advecti
|
||||||
|
|
||||||
vtkNew<vtkPolyDataMapper> mapper;
|
vtkNew<vtkPolyDataMapper> mapper;
|
||||||
mapper->SetInputConnection(glyph2D->GetOutputPort());
|
mapper->SetInputConnection(glyph2D->GetOutputPort());
|
||||||
mapper->SetLookupTable(buildLut(this->beachedAtNumberOfTimes));
|
mapper->SetColorModeToMapScalars();
|
||||||
mapper->SetScalarRange(0, this->beachedAtNumberOfTimes+1);
|
mapper->SetLookupTable(buildLut(512));
|
||||||
|
mapper->UseLookupTableScalarRangeOn();
|
||||||
mapper->Update();
|
mapper->Update();
|
||||||
|
|
||||||
vtkNew<vtkActor> actor;
|
vtkNew<vtkActor> actor;
|
||||||
|
|
@ -101,6 +112,7 @@ void LGlyphLayer::spoofPoints() {
|
||||||
for (int j=0; j < 330; j+=5) {
|
for (int j=0; j < 330; j+=5) {
|
||||||
this->points->InsertNextPoint(-15.875+(12.875+15.875)/330*j, 46.125+(62.625-46.125)/330*i, 0);
|
this->points->InsertNextPoint(-15.875+(12.875+15.875)/330*j, 46.125+(62.625-46.125)/330*i, 0);
|
||||||
this->particlesBeached->InsertNextValue(0);
|
this->particlesBeached->InsertNextValue(0);
|
||||||
|
this->particlesAge->InsertNextValue(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->points->Modified();
|
this->points->Modified();
|
||||||
|
|
@ -113,16 +125,24 @@ void LGlyphLayer::updateData(int t) {
|
||||||
|
|
||||||
// iterate over every point.
|
// iterate over every point.
|
||||||
for (vtkIdType n=0; n < this->points->GetNumberOfPoints(); n++) {
|
for (vtkIdType n=0; n < this->points->GetNumberOfPoints(); n++) {
|
||||||
|
// first check: only update points within our grid's boundary.
|
||||||
|
this->points->GetPoint(n, point);
|
||||||
|
if (point[0] <= this->uvGrid->lonMin() or point[0] >= this->uvGrid->lonMax() or point[1] <= this->uvGrid->latMin() or point[1] >= this->uvGrid->latMax()) {
|
||||||
|
// sets any particle out of bounds to be beached - so it gets assigned the right colour in the lookup table.
|
||||||
|
this->particlesBeached->SetValue(n, this->beachedAtNumberOfTimes+1);
|
||||||
|
this->particlesAge->SetValue(n, -1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update particle age.
|
||||||
|
int age = this->particlesAge->GetValue(n);
|
||||||
|
if (age >= 0)
|
||||||
|
this->particlesAge->SetValue(n, age+1);
|
||||||
|
|
||||||
|
// second check: only update non-beached particles.
|
||||||
int beachedFor = this->particlesBeached->GetValue(n);
|
int beachedFor = this->particlesBeached->GetValue(n);
|
||||||
// first check: only update non-beached particles.
|
|
||||||
if (beachedFor < this->beachedAtNumberOfTimes-1) {
|
if (beachedFor < this->beachedAtNumberOfTimes-1) {
|
||||||
this->points->GetPoint(n, point);
|
|
||||||
// second check: only update points within our grid's boundary.
|
|
||||||
if (point[0] <= this->uvGrid->lonMin() or point[0] >= this->uvGrid->lonMax() or point[1] <= this->uvGrid->latMin() or point[1] >= this->uvGrid->latMax()) {
|
|
||||||
// sets any particle out of bounds to be beached - so it gets assigned the right colour in the lookup table.
|
|
||||||
this->particlesBeached->SetValue(n, this->beachedAtNumberOfTimes+1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
oldX = point[0]; oldY = point[1];
|
oldX = point[0]; oldY = point[1];
|
||||||
|
|
||||||
// supersampling
|
// supersampling
|
||||||
|
|
@ -140,7 +160,10 @@ void LGlyphLayer::updateData(int t) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (modifiedData) this->points->Modified();
|
if (modifiedData) {
|
||||||
|
this->particlesAge->Modified();
|
||||||
|
this->points->Modified();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LGlyphLayer::addObservers(vtkSmartPointer<vtkRenderWindowInteractor> interactor) {
|
void LGlyphLayer::addObservers(vtkSmartPointer<vtkRenderWindowInteractor> interactor) {
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,9 @@
|
||||||
class LGlyphLayer : public Layer {
|
class LGlyphLayer : public Layer {
|
||||||
private:
|
private:
|
||||||
vtkSmartPointer<vtkPoints> points;
|
vtkSmartPointer<vtkPoints> points;
|
||||||
|
vtkSmartPointer<vtkPolyData> data;
|
||||||
vtkSmartPointer<vtkIntArray> particlesBeached;
|
vtkSmartPointer<vtkIntArray> particlesBeached;
|
||||||
|
vtkSmartPointer<vtkIntArray> particlesAge;
|
||||||
std::unique_ptr<AdvectionKernel> advector;
|
std::unique_ptr<AdvectionKernel> advector;
|
||||||
std::shared_ptr<UVGrid> uvGrid;
|
std::shared_ptr<UVGrid> uvGrid;
|
||||||
int dt = 3600;
|
int dt = 3600;
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ int main() {
|
||||||
cout << "Starting vtk..." << endl;
|
cout << "Starting vtk..." << endl;
|
||||||
|
|
||||||
auto l = new LGlyphLayer(uvGrid, std::move(kernelRK4BoundaryChecked));
|
auto l = new LGlyphLayer(uvGrid, std::move(kernelRK4BoundaryChecked));
|
||||||
// l->spoofPoints();
|
l->spoofPoints();
|
||||||
l->setDt(DT);
|
l->setDt(DT);
|
||||||
|
|
||||||
unique_ptr<Program> program = make_unique<Program>(DT);
|
unique_ptr<Program> program = make_unique<Program>(DT);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue