]> gitweb.ps.run Git - cloth_sim/blob - Scripts/main.js
Render Vertices and Springs
[cloth_sim] / Scripts / main.js
1 function init() {\r
2   class Point {\r
3     constructor(x, y) {\r
4       this.x = x;\r
5       this.y = y;\r
6     }\r
7 \r
8     add(that) {\r
9       return new Point(\r
10         this.x + that.x,\r
11         this.y + that.y\r
12       );\r
13     }\r
14 \r
15     sub(that) {\r
16       return new Point(\r
17         this.x - that.x,\r
18         this.y - that.y\r
19       );\r
20     }\r
21 \r
22     dist(that) {\r
23       let a = this.x - that.x;\r
24       let b = this.y - that.y;\r
25       return Math.sqrt(a * a + b * b)\r
26     }\r
27   }\r
28 \r
29   function vectorLength(a, b) {\r
30     let v1 = new THREE.Vector3();\r
31     v1.set(a.x, a.y, a.z);\r
32     let v2 = new THREE.Vector3();\r
33     v2.set(b.x, b.y, b.z);\r
34 \r
35     return v1.sub(v2).length();\r
36   }\r
37 \r
38   class Face {\r
39     a;\r
40     b;\r
41     c;\r
42     d;\r
43 \r
44     springs = [];\r
45 \r
46     constructor(a, b, c, d) {\r
47       this.a = a;\r
48       this.b = b;\r
49       this.c = c;\r
50       this.d = d;\r
51     }\r
52   }\r
53 \r
54   class Spring {\r
55     restLength;\r
56     currentLength;\r
57     index1;\r
58     index2;\r
59 \r
60     constructor(vertices, index1, index2) {\r
61       this.index1 = index1;\r
62       this.index2 = index2;\r
63 \r
64       let length = vectorLength(vertices[index1], vertices[index2]);\r
65       this.restLength = length;\r
66       this.currentLength = length;\r
67     }\r
68   }\r
69 \r
70   class Cloth {\r
71     VertexWeight = 1;\r
72 \r
73     geometry = new THREE.Geometry();\r
74 \r
75     faces = [];\r
76 \r
77     vertexWeights = [];\r
78 \r
79     createBasic(width, height, numPointsWidth, numPointsHeight) {\r
80       let vertices = [];\r
81       let faces = [];\r
82 \r
83       let stepWidth = width / (numPointsWidth - 1);\r
84       let stepHeight = height / (numPointsHeight - 1);\r
85 \r
86       for (let y = 0; y < numPointsHeight; y++) {\r
87         for (let x = 0; x < numPointsWidth; x++) {\r
88           vertices.push(\r
89             new THREE.Vector3(x * stepWidth, height - y * stepHeight, 0)\r
90           );\r
91         }\r
92       }\r
93 \r
94       function getVertexIndex(x, y) {\r
95         return y * numPointsWidth + x;\r
96       }\r
97       \r
98       for (let y = 0; y < numPointsHeight - 1; y++) {\r
99         for (let x = 0; x < numPointsWidth - 1; x++) {\r
100           let newFace = new Face(\r
101             getVertexIndex(x, y),\r
102             getVertexIndex(x, y + 1),\r
103             getVertexIndex(x + 1, y),\r
104             getVertexIndex(x + 1, y + 1),\r
105           );\r
106 \r
107           newFace.springs.push(new Spring(vertices, getVertexIndex(x, y), getVertexIndex(x + 1, y)));\r
108           newFace.springs.push(new Spring(vertices, getVertexIndex(x, y), getVertexIndex(x, y + 1)));\r
109           newFace.springs.push(new Spring(vertices, getVertexIndex(x, y), getVertexIndex(x + 1, y + 1)));\r
110           newFace.springs.push(new Spring(vertices, getVertexIndex(x + 1, y), getVertexIndex(x, y + 1)));\r
111           newFace.springs.push(new Spring(vertices, getVertexIndex(x + 1, y), getVertexIndex(x + 1, y + 1)));\r
112           newFace.springs.push(new Spring(vertices, getVertexIndex(x, y + 1), getVertexIndex(x + 1, y + 1)));\r
113           \r
114           faces.push(newFace);\r
115         }\r
116       }\r
117 \r
118       this.createExplicit(vertices, faces);\r
119     }\r
120 \r
121     createExplicit(vertices, faces) {\r
122       for (let i in vertices) {\r
123         this.geometry.vertices.push(vertices[i]);\r
124         this.vertexWeights.push(0);\r
125       }\r
126       for (let i in faces) {\r
127         let face = faces[i];\r
128 \r
129         this.faces.push(face);\r
130 \r
131         this.geometry.faces.push(new THREE.Face3(\r
132           face.a, face.b, face.c\r
133         ));\r
134         this.geometry.faces.push(new THREE.Face3(\r
135           face.c, face.b, face.d\r
136         ));\r
137         \r
138         let xLength = vectorLength(this.geometry.vertices[face.b], this.geometry.vertices[face.a]);\r
139         let yLength = vectorLength(this.geometry.vertices[face.c], this.geometry.vertices[face.a]);\r
140         let weight = xLength * yLength / 2;\r
141 \r
142         xLength = vectorLength(this.geometry.vertices[face.b], this.geometry.vertices[face.d]);\r
143         yLength = vectorLength(this.geometry.vertices[face.c], this.geometry.vertices[face.d]);\r
144         weight += xLength * yLength / 2;\r
145 \r
146         this.vertexWeights[face.a] += weight / 4;\r
147         this.vertexWeights[face.b] += weight / 4;\r
148         this.vertexWeights[face.c] += weight / 4;\r
149         this.vertexWeights[face.d] += weight / 4;\r
150       }\r
151 \r
152       this.geometry.computeBoundingSphere();\r
153     }\r
154 \r
155     createDebugMesh(scene) {\r
156       function addLine(from, to, color) {\r
157         let geometry = new THREE.Geometry();\r
158         geometry.vertices.push(from);\r
159         geometry.vertices.push(to);\r
160         let material = new THREE.LineBasicMaterial( { color: color, linewidth: 10 } );\r
161         let line = new THREE.Line(geometry, material);\r
162         line.renderOrder = 1;\r
163         scene.add(line);\r
164       }\r
165       function addPoint(point, color) {\r
166         const geometry = new THREE.SphereGeometry( 0.05, 32, 32 );\r
167         const material = new THREE.MeshBasicMaterial( { color: color } );\r
168         const sphere = new THREE.Mesh( geometry, material );\r
169         sphere.position.set(point.x, point.y, point.z);\r
170         scene.add( sphere );\r
171       }\r
172 \r
173       let lineColor = 0x000000;\r
174       let pointColor = 0xff00000;\r
175 \r
176       for (let i in this.faces) {\r
177         let face = this.faces[i];\r
178         addLine(this.geometry.vertices[face.a], this.geometry.vertices[face.b], lineColor);\r
179         addLine(this.geometry.vertices[face.a], this.geometry.vertices[face.c], lineColor);\r
180         addLine(this.geometry.vertices[face.a], this.geometry.vertices[face.d], lineColor);\r
181         addLine(this.geometry.vertices[face.b], this.geometry.vertices[face.c], lineColor);\r
182         addLine(this.geometry.vertices[face.b], this.geometry.vertices[face.d], lineColor);\r
183         addLine(this.geometry.vertices[face.c], this.geometry.vertices[face.d], lineColor);\r
184 \r
185         addPoint(this.geometry.vertices[face.a], pointColor);\r
186         addPoint(this.geometry.vertices[face.b], pointColor);\r
187         addPoint(this.geometry.vertices[face.c], pointColor);\r
188         addPoint(this.geometry.vertices[face.d], pointColor);\r
189       }\r
190     }\r
191   }\r
192 \r
193   let mousePos = new Point();\r
194 \r
195   const canvasSpace = 200;\r
196 \r
197   const scene = new THREE.Scene();\r
198   const camera = new THREE.PerspectiveCamera(75, window.innerWidth / (window.innerHeight - canvasSpace), 0.1, 1000);\r
199 \r
200   const renderer = new THREE.WebGLRenderer();\r
201   renderer.setSize(window.innerWidth, window.innerHeight - canvasSpace);\r
202   document.getElementById("threejscontainer").appendChild(renderer.domElement);\r
203 \r
204   const directionalLight = new THREE.DirectionalLight(0xffffff, 1);\r
205   scene.add(directionalLight);\r
206 \r
207   let cloth = new Cloth();\r
208   cloth.createBasic(10, 10, 5, 5);\r
209   cloth.createDebugMesh(scene);\r
210 \r
211   const material = new THREE.MeshBasicMaterial({ color: 0x0000ff });\r
212   const mesh = new THREE.Mesh(cloth.geometry, material);\r
213   scene.add(mesh);\r
214 \r
215   camera.position.y = 5;\r
216   camera.position.z = 10;\r
217   //camera.lookAt(new THREE.Vector3(1, 0, 0));\r
218 \r
219   function animate(dt) {\r
220     requestAnimationFrame(animate);\r
221     renderer.render(scene, camera);\r
222   }\r
223 \r
224   let canvas = document.getElementsByTagName("canvas")[0];\r
225   let resize = function () {\r
226     w = window.innerWidth;\r
227     h = window.innerHeight - 200;\r
228     canvas.width = w;\r
229     canvas.height = h;\r
230   }\r
231   window.onresize = resize;\r
232   resize();\r
233   if (canvas.getContext) {\r
234     animate(performance.now());\r
235   }\r
236   canvas.onmousemove = (evt) => {\r
237     mousePos.x = evt.clientX;\r
238     mousePos.y = evt.clientY;\r
239   };\r
240 }