]> gitweb.ps.run Git - cloth_sim/blob - Scripts/cloth.js
add Constraint class, add constraints to cloth
[cloth_sim] / Scripts / cloth.js
1 const MASS = 0.1;\r
2 \r
3 class Constraint {\r
4   constructor(p1, p2, distance) {\r
5     this.p1 = p1;\r
6     this.p2 = p2;\r
7     this.distance = distance;\r
8   }\r
9 }\r
10 \r
11 class Particle {\r
12   constructor(x, y, z, mass) {\r
13     this.position = new THREE.Vector3(x, y, z);\r
14     this.previous = new THREE.Vector3(x, y, z);\r
15     this.acceleration = new THREE.Vector3(0, 0, 0);\r
16     this.mass = mass;\r
17   }\r
18   addForce(force) {\r
19 \r
20   }\r
21   verlet(dt) {\r
22 \r
23   }\r
24 }\r
25 \r
26 class Cloth {\r
27   constructor(width, height, numPointsWidth, numPointsHeight) {\r
28     this.width = width;\r
29     this.height = height;\r
30     this.numPointsWidth = numPointsWidth;\r
31     this.numPointsHeight = numPointsHeight;\r
32 \r
33     /**\r
34      * distance between two vertices horizontally/vertically\r
35      * divide by the number of points minus one\r
36      * because there are (n - 1) lines between n vertices\r
37      */\r
38     let stepWidth = width / (numPointsWidth - 1);\r
39     let stepHeight = height / (numPointsHeight - 1);\r
40 \r
41     /**\r
42      * iterate over the number of vertices in x/y axis\r
43      * and add a new Particle to "particles"\r
44      */\r
45     this.particles = [];\r
46     for (let y = 0; y < numPointsHeight; y++) {\r
47       for (let x = 0; x < numPointsWidth; x++) {\r
48         this.particles.push(\r
49           new Particle(\r
50             (x - ((numPointsWidth-1)/2)) * stepWidth,\r
51             height - (y + ((numPointsHeight-1)/2)) * stepHeight,\r
52             0,\r
53             MASS)\r
54         );\r
55       }\r
56     }\r
57 \r
58     const REST_DIST_X = width / (numPointsWidth-1);\r
59     const REST_DIST_Y = height / (numPointsHeight-1);\r
60 \r
61     /**\r
62      * generate constraints (springs)\r
63      */\r
64     this.constraints = [];\r
65     for (let y = 0; y < numPointsHeight; y++) {\r
66       for (let x = 0; x < numPointsWidth; x++) {\r
67         if (x < numPointsWidth-1) {\r
68           this.constraints.push(new Constraint(\r
69             this.particles[this.getVertexIndex(x, y)],\r
70             this.particles[this.getVertexIndex(x+1, y)],\r
71             REST_DIST_X\r
72           ));\r
73         }\r
74         if (x < numPointsWidth-1) {\r
75           this.constraints.push(new Constraint(\r
76             this.particles[this.getVertexIndex(x, y)],\r
77             this.particles[this.getVertexIndex(x, y+1)],\r
78             REST_DIST_Y\r
79           ));\r
80         }\r
81       }\r
82     }\r
83   }\r
84   generateGeometry() {\r
85     const geometry = new THREE.BufferGeometry();\r
86 \r
87     const vertices = [];\r
88     const normals = [];\r
89     const indices = [];\r
90 \r
91     for (let particle of this.particles) {\r
92       vertices.push(\r
93         particle.position.x,\r
94         particle.position.y,\r
95         particle.position.z);\r
96     }\r
97 \r
98     const numPointsWidth = this.numPointsWidth;\r
99     const numPointsHeight = this.numPointsHeight;\r
100 \r
101     /**\r
102      * generate faces based on 4 vertices\r
103      * and 6 springs each\r
104      */\r
105     for (let y = 0; y < numPointsHeight - 1; y++) {\r
106       for (let x = 0; x < numPointsWidth - 1; x++) {\r
107         indices.push(\r
108           this.getVertexIndex(x, y),\r
109           this.getVertexIndex(x+1, y),\r
110           this.getVertexIndex(x+1, y+1)\r
111         );\r
112         indices.push(\r
113           this.getVertexIndex(x, y),\r
114           this.getVertexIndex(x+1, y+1),\r
115           this.getVertexIndex(x, y+1)\r
116         );\r
117       }\r
118     }\r
119 \r
120     geometry.setIndex(indices);\r
121     geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));\r
122     //geometry.setAttribute('normal', new THREE.Float32BufferAttribute(normals, 3));\r
123     geometry.computeBoundingSphere();\r
124     geometry.computeVertexNormals();\r
125 \r
126     return geometry;\r
127   }\r
128   updateGeometry(geometry) {\r
129 \r
130   }\r
131   satisfyConstraints() {\r
132 \r
133   }\r
134   simulate() {\r
135 \r
136   }\r
137   /**\r
138    * helper function to calculate index of vertex\r
139    * in "vertices" array based on its x and y positions\r
140    * in the mesh\r
141    * @param {number} x - x index of vertex\r
142    * @param {number} y - y index of vertex\r
143    */\r
144   getVertexIndex(x, y) {\r
145     return y * this.numPointsWidth + x;\r
146   }\r
147 }