1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
// cloth rendering
// simulate
// setup scene
const MASS = 0.1;
class Particle {
constructor(x, y, z, mass) {
this.position = new THREE.Vector3(x, y, z);
this.previous = new THREE.Vector3(x, y, z);
this.acceleration = new THREE.Vector3(0, 0, 0);
this.mass = mass;
}
addForce(force) {
}
verlet(dt) {
}
}
class Cloth {
constructor(width, height, numPointsWidth, numPointsHeight) {
this.width = width;
this.height = height;
this.numPointsWidth = numPointsWidth;
this.numPointsHeight = numPointsHeight;
/**
* distance between two vertices horizontally/vertically
* divide by the number of points minus one
* because there are (n - 1) lines between n vertices
*/
let stepWidth = width / (numPointsWidth - 1);
let stepHeight = height / (numPointsHeight - 1);
/**
* iterate over the number of vertices in x/y axis
* and add a new Particle to "particles"
*/
this.particles = [];
for (let y = 0; y < numPointsHeight; y++) {
for (let x = 0; x < numPointsWidth; x++) {
this.particles.push(
new Particle(
(x - ((numPointsWidth-1)/2)) * stepWidth,
height - (y + ((numPointsHeight-1)/2)) * stepHeight,
0,
MASS)
);
}
}
}
generateGeometry() {
const geometry = new THREE.BufferGeometry();
const vertices = [];
const normals = [];
const indices = [];
for (let particle of this.particles) {
vertices.push(
particle.position.x,
particle.position.y,
particle.position.z);
}
const numPointsWidth = this.numPointsWidth;
const numPointsHeight = this.numPointsHeight;
/**
* helper function to calculate index of vertex
* in "vertices" array based on its x and y positions
* in the mesh
* @param {number} x - x index of vertex
* @param {number} y - y index of vertex
*/
function getVertexIndex(x, y) {
return y * numPointsWidth + x;
}
/**
* generate faces based on 4 vertices
* and 6 springs each
*/
for (let y = 0; y < numPointsHeight - 1; y++) {
for (let x = 0; x < numPointsWidth - 1; x++) {
indices.push(
getVertexIndex(x, y),
getVertexIndex(x+1, y),
getVertexIndex(x+1, y+1)
);
indices.push(
getVertexIndex(x, y),
getVertexIndex(x+1, y+1),
getVertexIndex(x, y+1)
);
}
}
geometry.setIndex(indices);
geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
//geometry.setAttribute('normal', new THREE.Float32BufferAttribute(normals, 3));
geometry.computeBoundingSphere();
geometry.computeVertexNormals();
return geometry;
}
updateGeometry(geometry) {
}
}
|