3D Mass-Spring Locomotion

Class Instructor Date Language Ta'ed Code
CS 7492 Simulation of Biological Systems Greg Turk (Expanded as personal project) Spring 2015-Summer 2015 C++ No Github Repo - particle sim

For this simulation I took my Constrained Particle Sim and added a lot of functionality, including iterative, positional constraints and implicit integrator spring force handling via a conjugate gradient solver. The rest length of a set of springs is modified to displace a mass which then generates rolling motion via frictional contact between particles and a flat collider.

This project was the final project for the Simulation of Biological Systems class and required a creature to exhibit mass-spring-motivated motion. I originally focused on building a jelly-fish simulator, with a flock of creatures floating and moving in a fluid simulation, where the body of each creature would cyclically constrict and expand, allowing for motion in a particular direction against the fluid within which it floated. To accomplish this, I felt a body mesh for the creature would need to be chosen that was as close to spherical as possible, to minimize any directional bias, while having a minimal number of vertices (that I would model as particles - too few and the body would not retain the spherical appearance I desired, while too many might compromise computational speed unacceptably), and these vertices should be as close to equidistant from all their neighbors as possible. I've been fascinated by the higher-face-count polygons like the icosedron (20-sided) and rhombic triacontehedron (30-sided), especially the latter (with the golden ratio exhibited in each rhombic face making it particularly pleasing), since I played D&D in the early 80's, and still have many examples of each in my old dice bag from back then, and so I thought a rhombic triacontehedron would be a good choice here.

Unfortunately the jelly-fish idea had to be scrapped - there were bugs in my simulation of the directional force generation from the body constriction in the fluid simulation causing it to be unstable, but I did retain the RT as my mass-spring creature, instead making a self-rolling ball (sort of like a simulation of BB-8, the new droid from Star Wars VII, although I was unaware of BB-8 at the time). The RT "creature body" consisted of the following :

  1. 32 Vertices : modeled as particles with unit mass.
  2. 60 (+30) Edges : modeled as positional constraints (I added 30 more that bisected each face, effectively creating a 60-sided mesh of near-equilateral triangles, for stability).
  3. Creature Body : modeled by a particle at the center of the mesh with 100x the mass of any of the mesh particles.
  4. 32 "Ligaments" : modeled as springs, these suspended the creature's "body" within the RT "shell".
  5. Ground : a frictional flat collider that the RT vertex particles would interact with.

The simulation works as follows : when a direction and speed of motion is specified by the user via mouse-drag, the springs holding the body mass decrease in their length tangent to that direction ("In Front" of the body), while increasing in their length component in the negative tangent direction (i.e. "Behind" the body). This would maintain the shape of the RT surface, while displacing the central mass in a particular direction and causing the construct to want to roll due to gravity. The algorithm for making the sphere move while retaining its shape was as follows :

%Mass-Spring-based movement
%shakeVal holds user-entered force - set to 0 on click to initialize
if (msClicked) { shakeVal.setZero(); }	
%derive and accumulate all spring-based quantities and forces, including modified lengths from user input.									
if (msDragged) { addForcesToMassSpringCtrl(scaleInput, msDragged, msDragVal); }
%apply extant environmental forces to system
applyForcesToSystem();
%apply spring forces to system
applySpringForcesToSystem();
%check for, and handle, collisions for all particles to see if any hit the ground
bool colTest = handlePartCldrCollision();			
if (colTest) {	
	flags[mass2HasHitGrnd] = true;
	flags[mass2ChkHasHitGrnd] = false;
}
%solver for positional constraints via iterative refinement : move every particle toward equidistant from all its neighbors, repeat 100 times.
satisfyPosConstraints();							
%integrate particles in system via implicit method and conjugate gradient solver to get new positions and velocities, and update system.
solveImpEuler4MassSpring();						

I didn't force the particles in contact with the collider to "stick" to the ground (frictional model is not completely accurate), and I would jump start the motion with a force to all the particles in the direction of the user input, so some sliding is exhibited in this older video, especially when the direction is changed. I have since repaired this for more realistic motion.

Rolling Mass-spring Rhombic Triacontehedron