SW Cloth Sim

Cloth sim

by steveow

HTML

<div id="info">
  <a onclick="simulateRunning = !simulateRunning;">Run</a> |
  <a onclick="wind = !wind;">Wind</a>
</div>


<script  src=https://cdnjs.cloudflare.com/ajax/libs/three.js/91/three.min.js ></script>

<script src=https://threejs.org/examples/js/libs/stats.min.js ></script>

<script src=https://threejs.org/examples/js/controls/OrbitControls.js> </script>

CSS

body {
  font-family: sans-serif;
  background-color: #000;
  color: #000;
  margin: 0px;
  overflow: hidden;
}

#info {
  position: absolute;
  padding: 10px;
  width: 100%;
  text-align: center;
  background: white;
}

a {
  text-decoration: underline;
  cursor: pointer;
}

JavaScript

/*
 * Cloth Simulation using a relaxed constraints solver
 */

// Suggested Readings

// Advanced Character Physics by Thomas Jakobsen Character
// http://freespace.virgin.net/hugo.elias/models/m_cloth.htm
// http://en.wikipedia.org/wiki/Cloth_modeling
// http://cg.alexandra.dk/tag/spring-mass-system/
// Real-time Cloth Animation http://www.darwin3d.com/gamedev/articles/col0599.pdf

var DAMPING = 0.03;//...0.03
var DRAG = 1 - DAMPING;
var MASS = 0.1;//...0.1
var restDistance = 25;

var xSegs = 10;
var ySegs = 14;

var clothFunction = plane( restDistance * xSegs, restDistance * ySegs );

var cloth = new Cloth( xSegs, ySegs );

var GRAVITY = 981 * 1.4 * 3;
var gravity = new THREE.Vector3( 0, - GRAVITY, 0 ).multiplyScalar( MASS );


var TIMESTEP = 18 / 1000;
var TIMESTEP_SQ = TIMESTEP * TIMESTEP;

var pins = [];


var wind = true;
var windStrength = 2;
var windForce = new THREE.Vector3( 0, 0, 0 );

var ballPosition = new THREE.Vector3( 0, - 45, 0 );
var ballSize = 60; //40

var tmpForce = new THREE.Vector3();

var lastTime;


function plane( width, height ) 
{

  return function ( u, v, optionalTarget ) 
  {

    var result = optionalTarget || new THREE.Vector3();

    var x = ( u - 0.5 ) * width;
    var y = ( v + 0.5 ) * height;
    var z = 0;

    return result.set( x, y, z );

  };

}

function Particle( x, y, z, mass ) 
{

  this.position = clothFunction( x, y ); // position
  this.previous = clothFunction( x, y ); // previous
  this.original = clothFunction( x, y ); //...used for pins & resetting
  this.a = new THREE.Vector3( 0, 0, 0 ); // acceleration
  this.mass = mass;
  this.invMass = 1 / mass;
  this.tmp = new THREE.Vector3();
  this.tmp2 = new THREE.Vector3();

}

// Force -> Acceleration

Particle.prototype.addForce = function( force ) 
{

  this.a.add(
    this.tmp2.copy( force ).multiplyScalar( this.invMass )
  );

};


// Performs Verlet integration

Particle.prototype.integrate = function( timesq ) 
{

  var newPos = this.tmp.subVectors(...