1#ifndef PLUGINBODYDELAUNAYMASSSPRINGDAMPER_HPP
2#define PLUGINBODYDELAUNAYMASSSPRINGDAMPER_HPP
11#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
12#include <CGAL/Delaunay_triangulation_3.h>
13#include <CGAL/Triangulation_vertex_base_with_info_3.h>
18using K = CGAL::Exact_predicates_inexact_constructions_kernel;
19using Vb = CGAL::Triangulation_vertex_base_with_info_3<void *, K>;
20using Tds = CGAL::Triangulation_data_structure_3<Vb>;
21using Delaunay = CGAL::Delaunay_triangulation_3<K, Tds>;
36 template<
typename cell_t>
55 bool coherence =
true;
59 typename Delaunay::Finite_vertices_iterator vit;
62 cell_t *c =
static_cast<cell_t *
>(vit->info());
64 if ((c->getBody().getPosition() -
pos).length()
70 }
else coherence =
false;
78 typename Delaunay::Finite_vertices_iterator vit;
80 for (
int i = 0; i <
triangulation.number_of_vertices(); ++i) {
81 cell_t *c =
static_cast<cell_t *
>(vit->info());
82 c->clearConnectedCells();
84 if ((c->getBody().getPosition() -
pos).length()
86 Point p(c->getBody().getPosition().x(), c->getBody().getPosition().y(), c->getBody().getPosition().z());
99 template<
typename world_t>
101 for (cell_t *c : w->cells) c->clearConnectedCells();
105 for (cell_t *c : w->cells) {
106 c->clearConnectedCells();
108 points.
push_back(
Point(c->getBody().getPosition().x(), c->getBody().getPosition().y(),
109 c->getBody().getPosition().z()));
115 boost::make_zip_iterator(boost::make_tuple(points.
end(), indices.
end())));
128 typename Delaunay::Finite_edges_iterator eit;
131 cell_t *c1 =
static_cast<cell_t *
>(eit->first->vertex(eit->second)->info());
132 cell_t *c2 =
static_cast<cell_t *
>(eit->first->vertex(eit->third)->info());
133 if (c1 !=
nullptr && c2 !=
nullptr) {
134 if ((c1->getBody().getPosition() - c2->getBody().getPosition()).length() <=
135 (c1->getBody().getBoundingBoxRadius() + c2->getBody().getBoundingBoxRadius()) *
neighbourCoeff) {
137 float_t k = 10 * (c1->getBody().getMass() + c2->getBody().getMass()) / 2;
138 float_t l = c1->getBody().getBoundingBoxRadius() * c1->getBody().getAdhesion() + c2->getBody().getBoundingBoxRadius() * c2->getBody().getAdhesion();
139 float_t c = r * 2.0 *
sqrt((c1->getBody().getMass() + c2->getBody().getMass()) * k);
142 c1->addConnectedCell(c2);
143 c2->addConnectedCell(c1);
157 template<
typename world_t>
161 for (cell_t *c : w->newCells) {
162 points.
push_back(
Point(c->getBody().getPosition().x(), c->getBody().getPosition().y(), c->getBody().getPosition().z()));
167 boost::make_zip_iterator(boost::make_tuple(points.
end(), indices.
end())));
174 typename Delaunay::Finite_vertices_iterator vit;
177 auto *c1 =
static_cast<cell_t *
>(vit->info());
193 (msd.getConnection().first->getBody().getForce().length() >
minForce || msd.getConnection().second->getBody().getForce().length() >
minForce))
204 template<
typename world_t>
207 for (cell_t *c : w->cells) {
211 c->getBody().setPrevposition(c->getBody().getPosition());
212 c->getBody().setPosition(c->getBody().getPosition() + c->getBody().getVelocity() *
physicsDt);
224 template<
typename world_t>
226 for (cell_t *c : w->cells) {
227 c->getBody().resetForce();
240 template<
typename world_t>
242 double numberOfSteps = w->dt /
physicsDt;
243 for (
unsigned i = 0; i < numberOfSteps; i++) {
298 template<
typename world_t>
312 template<
typename world_t>
325 template<
typename world_t>
338 template<
typename world_t>
340 for (cell_t *c : w->cells) {
Defines the MassSpringDamper class for mass-spring-damper physics.
CGAL::Delaunay_triangulation_3< K, Tds > Delaunay
CGAL::Delaunay_triangulation_3< K, Tds > Delaunay
CGAL::Triangulation_vertex_base_with_info_3< void *, K > Vb
CGAL::Triangulation_data_structure_3< Vb > Tds
CGAL::Exact_predicates_inexact_constructions_kernel K
Class for managing Delaunay triangulation and mass-spring-damper physics.
std::vector< MassSpringDamper< cell_t > > springList
void setPhysicsDt(double dt)
Sets the physics dt.
void applyPhysics(world_t *w)
Applies the physics with a coherent time step.
void moveDelaunay()
Moves the points in the triangulation to match their real positions.
void updateForces()
Updates forces and checks if the forces are too weak to be considered.
void updatePositions(world_t *w)
Updates positions and checks if the movements are too weak to be considered.
void preDeleteDeadCellsUpdate(world_t *w)
Pre-delete dead cells update hook for MecaCell.
bool isDelaunayCoherent()
Checks the coherence of the Delaunay triangulation.
void removeCells()
Removes dead cells from the triangulation.
void setNeighbourCoeff(double c)
Sets the neighbour coefficient.
void springCreation()
Creates the list of springs.
void setCoherenceCoeff(double c)
Sets the coherence coefficient.
void endUpdate(world_t *w)
End update hook for MecaCell.
PluginDelaunayMassSpringDamper()
Constructor.
void preBehaviorUpdate(world_t *w)
Pre-behavior update hook for MecaCell.
void setMaxSpeed(double s)
Sets the maximum speed.
void computeDelaunay(world_t *w)
Computes the Delaunay triangulation from the list of cells.
void addCells(world_t *w)
Adds new cells to the triangulation.
void setMinForce(double f)
Sets the minimum force.
bool areMovementsNegligible
void resetForces(world_t *w)
Resets the forces acting on the cells.
void onAddCell(world_t *w)
On add cell hook for MecaCell.
Class for managing mass-spring-damper physics.
general purpose 3D vector/point class.
double length() const
compute the length of the vector
A simple vector class template.
void push_back(const T &value)
Adds an element to the end of the vector.
iterator begin()
Returns an iterator to the first element.
void clear()
Clears the contents of the vector.
iterator end()
Returns an iterator to the last element.
Namespace for Delaunay triangulation and mass-spring-based physics-related classes and functions.
Vector3D Vec
alias for Vector3D
iostream cout
Standard output stream.
double sqrt(double x)
Computes the square root of a number.
iostream endl
End-of-line manipulator.