JSFiddle - React, Tailwind, and code Playground
HTML
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/[email protected]/dist/es-module-shims.js"></script>
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/[email protected]/build/three.module.js"
}
}
</script>
JavaScript
import * as THREE from 'three';
import { OrbitControls } from 'https://unpkg.com/[email protected]/examples/jsm/controls/OrbitControls.js';
import { ParametricGeometry } from 'https://unpkg.com/[email protected]/examples/jsm/geometries/ParametricGeometry.js';
const params = {
enableWind: true,
showBall: false,
togglePins: togglePins
};
const DAMPING = 0.03;
const DRAG = 1 - DAMPING;
const MASS = 0.1;
const restDistance = 25;
const xSegs = 10;
const ySegs = 10;
const clothFunction = plane( restDistance * xSegs, restDistance * ySegs );
const GRAVITY = 981 * 1.4;
const gravity = new THREE.Vector3( 0, - GRAVITY, 0 ).multiplyScalar( MASS );
const TIMESTEP = 18 / 1000;
const TIMESTEP_SQ = TIMESTEP * TIMESTEP;
let pins = [];
const windForce = new THREE.Vector3( 0, 0, 0 );
const ballPosition = new THREE.Vector3( 0, - 45, 0 );
const ballSize = 60; //40
const tmpForce = new THREE.Vector3();
const diff = new THREE.Vector3();
class Particle {
constructor( x, y, z, mass ) {
this.position = new THREE.Vector3();
this.previous = new THREE.Vector3();
this.original = new THREE.Vector3();
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();
// init
clothFunction( x, y, this.position ); // position
clothFunction( x, y, this.previous ); // previous
clothFunction( x, y, this.original );
}
// Force -> Acceleration
addForce( force ) {
this.a.add(
this.tmp2.copy( force ).multiplyScalar( this.invMass )
);
}
// Performs Verlet integration
integrate( timesq ) {
const newPos = this.tmp.subVectors( this.position, this.previous );
newPos.multiplyScalar( DRAG ).add( this.position );
newPos.add( this.a.multiplyScalar( timesq ) );
this.tmp = this.previous;
this.previous = this.position;
this.position = newPos;
this.a.set( 0, 0, 0 );
}
}
class Cloth {
...