Skip to content
Snippets Groups Projects
Unverified Commit 4b123f34 authored by Jamie Temple's avatar Jamie Temple
Browse files

feat: textile simulation

parent b4678136
No related branches found
No related tags found
1 merge request!1feat: base project
images/bezier.png

38.9 KiB

images/quaternions.png

101 KiB

images/simulation.png

107 KiB

......@@ -15,6 +15,5 @@
<a href="pages/quaternion.html">Quaternions</a>
<a href="pages/simulation.html">Cloth Simulation</a>
</nav>
</body>
</html>
......@@ -16,9 +16,17 @@ class QuaternionDemo extends PipelineData {
light.position.set(1, 1, 1);
this.scene.add(light);
const pointLight = new THREE.PointLight(0x6e6e8e, 1);
pointLight.position.set(-1, -1, -1);
this.scene.add(pointLight);
const backLight = new THREE.PointLight(0x6e6e8e, 1);
backLight.position.set(-1, -1, -1);
this.scene.add(backLight);
const lightA = new THREE.PointLight(0x8eaa8e, 1);
lightA.position.set(2, 2, 0);
this.scene.add(lightA);
const lightC = new THREE.PointLight(0x8eaa7f, 1);
lightC.position.set(-2, 0, -2);
this.scene.add(lightC);
const axes = new Axes(5);
this.addRenderable(axes);
......
......@@ -26,7 +26,7 @@ class RotationHelper extends Shape implements PipelineObserver, PipelineDraggabl
// UNIT SPHERE
// The projection of ijk onto the sphere. The fourth dimension is the color.
const geometrySphere = new THREE.SphereBufferGeometry(1, 32, 32);
const matSphere = new THREE.MeshBasicMaterial({ color: primeColor, opacity: 0.9, transparent: true });
const matSphere = new THREE.MeshBasicMaterial({ color: primeColor, opacity: .8, transparent: true });
this._unitSphere = new THREE.Mesh(geometrySphere, matSphere);
// POINTS AND LINES
......@@ -51,6 +51,8 @@ class RotationHelper extends Shape implements PipelineObserver, PipelineDraggabl
this._object3d.add(this._qPoints[i].object());
for (let i = 0; i < 5; i++)
this._object3d.add(this._qLines[i].object());
this._object3d.position.x = 2.5;
}
update(_deltaTime: number): void {
......
import * as THREE from 'three';
import { PipelineData } from "../core/Pipeline";
import { Particle } from "./cgPhysix/particle";
import { SimulationSettings } from './SimulationSettings';
import { Simulation } from "./Simulation";
import { SimulationData } from './SimulationData';
class SimulationDemo extends PipelineData {
public constructor() { super(); }
data(): void {
const sim = new SimulationSettings();
this.addGUIElement(sim);
SimulationSettings.generateTextile();
this.scene.add(SimulationSettings.container);
const data = new SimulationData();
this.addGUIElement(data);
this.addRenderable(data);
const simulation = new Simulation();
this.addObserver(simulation);
}
}
......
import * as THREE from 'three';
import { PipelineObserver } from "../core/Pipeline";
import { Particle } from './physics/particle';
import { SimulationData } from "./SimulationData";
export class Simulation implements PipelineObserver {
public static readonly G = new THREE.Vector3(0, -9.807, 0);
public static current: Particle;
constructor() {
SimulationData.generateTextile();
}
update(_deltaTime: number): void {
const h = _deltaTime / 100;
for (let t = 0; t < _deltaTime; t += h) {
SimulationData.pList.forEach(pSub => {
pSub.forEach(p => {
if (p.usePhysics) {
Simulation.current = p;
let x = [p.position.x, p.position.y, p.position.z,
p.velocity.x, p.velocity.y, p.velocity.z];
x = SimulationData.INTEGRATORS[SimulationData.integratorType].step(x, h, Simulation.derivation);
p.setState(x[0], x[1], x[2], x[3], x[4], x[5]);
}
});
})
}
}
public static derivation(x: Array<number>): Array<number> {
// 1. create new array to store derivatives
let xDot = new Array<number>(x.length);
// 2. derivative of position => velocity
xDot[0] = x[3];
xDot[1] = x[4];
xDot[2] = x[5];
// 3. derivative of velocity => acceleration
// 3.1 accumulate forces
let totalForce = new THREE.Vector3(0, 0, 0);
totalForce.add(SimulationData.externalForce);
// 3.2 accumulate spring forces
Simulation.current.references.forEach(spring => {
const force = spring.force(Simulation.current.position);
totalForce.add(force);
});
// 3.3 damping force
const dampingForce = Simulation.current.velocity.clone().multiplyScalar(-SimulationData.damping);
totalForce.add(dampingForce);
// 3.3 acceleration = force / mass
let totalAcceleration = totalForce.divideScalar(Simulation.current.mass);
totalAcceleration.add(Simulation.G);
// 4. derivative of acceleration => velocity
xDot[3] = totalAcceleration.x;
xDot[4] = totalAcceleration.y;
xDot[5] = totalAcceleration.z;
return xDot;
}
}
\ No newline at end of file
......@@ -47,6 +47,11 @@ export class Particle implements PipelineRenderable {
(this.mesh.material as THREE.MeshBasicMaterial).color.set(color);
}
public setState(px: number, py: number, pz: number, vx: number, vy: number, vz: number): void {
this.velocity.set(vx, vy, vz);
this.setPosition(px, py, pz);
}
public setPosition(x: number, y: number, z: number): void {
this.position.set(x, y, z);
this.mesh.position.copy(this.position);
......
......@@ -33,14 +33,14 @@ export abstract class Spring {
abstract get springConstant(): number;
public force(x: number, y: number, z: number): THREE.Vector3 {
public force(p: THREE.Vector3): THREE.Vector3 {
let direction = this.positionB.clone().sub(this.positionA);
const distance = direction.length();
direction.normalize();
const sign = distance / Math.abs(distance);
const result = direction.multiplyScalar(this.springConstant * (distance - this.restingLength) * sign);
//const sign = distance / Math.abs(distance);
const result = direction.multiplyScalar(this.springConstant * (distance - this.restingLength));
if (this.positionA === new THREE.Vector3(x, y, z)) {
if (this.positionA === p) {
return result;
}
......
......@@ -188,8 +188,8 @@ class Pipeline {
data.observers.forEach(observer => { this.addPipelineObserver(observer); });
data.guiElements.forEach(guiElement => { this.addGUI(guiElement); });
// picking stuff
document.addEventListener( 'mousedown', (event) => {
event.preventDefault();
let mouse3D = new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1,
-( event.clientY / window.innerHeight ) * 2 + 1,
0.5 );
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment