]> gitweb.ps.run Git - cloth_sim/blob - Scripts/main.js
Add Spring Property
[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     static 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       return this.CreateExplicit(vertices, faces);\r
119     }\r
120 \r
121     static CreateExplicit(vertices, faces) {\r
122       let result = new Cloth();\r
123 \r
124       for (let i in vertices) {\r
125         result.geometry.vertices.push(vertices[i]);\r
126         result.vertexWeights.push(0);\r
127       }\r
128       console.log(vertices);\r
129       for (let i in faces) {\r
130         let face = faces[i];\r
131 \r
132         result.geometry.faces.push(new THREE.Face3(\r
133           face.a, face.b, face.c\r
134         ));\r
135         result.geometry.faces.push(new THREE.Face3(\r
136           face.c, face.b, face.d\r
137         ));\r
138 \r
139         console.log(face);\r
140         \r
141         let xLength = vectorLength(result.geometry.vertices[face.b], result.geometry.vertices[face.a]);\r
142         let yLength = vectorLength(result.geometry.vertices[face.c], result.geometry.vertices[face.a]);\r
143         let weight = xLength * yLength / 2;\r
144 \r
145         xLength = vectorLength(result.geometry.vertices[face.b], result.geometry.vertices[face.d]);\r
146         yLength = vectorLength(result.geometry.vertices[face.c], result.geometry.vertices[face.d]);\r
147         weight += xLength * yLength / 2;\r
148 \r
149         result.vertexWeights[face.a] += weight / 4;\r
150         result.vertexWeights[face.b] += weight / 4;\r
151         result.vertexWeights[face.c] += weight / 4;\r
152         result.vertexWeights[face.d] += weight / 4;\r
153       }\r
154 \r
155       result.geometry.computeBoundingSphere();\r
156 \r
157       return result;\r
158     }\r
159   }\r
160 \r
161   let mousePos = new Point();\r
162 \r
163   const canvasSpace = 200;\r
164 \r
165   const scene = new THREE.Scene();\r
166   const camera = new THREE.PerspectiveCamera(75, window.innerWidth / (window.innerHeight - canvasSpace), 0.1, 1000);\r
167 \r
168   const renderer = new THREE.WebGLRenderer();\r
169   renderer.setSize(window.innerWidth, window.innerHeight - canvasSpace);\r
170   document.getElementById("threejscontainer").appendChild(renderer.domElement);\r
171 \r
172   const directionalLight = new THREE.DirectionalLight(0xffffff, 1);\r
173   scene.add(directionalLight);\r
174 \r
175   let cloth = Cloth.CreateBasic(10, 10, 5, 5);\r
176   const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });\r
177   const mesh = new THREE.Mesh(cloth.geometry, material);\r
178   scene.add(mesh);\r
179 \r
180   camera.position.y = 5;\r
181   camera.position.z = 10;\r
182 \r
183   function animate(dt) {\r
184     requestAnimationFrame(animate);\r
185     renderer.render(scene, camera);\r
186   }\r
187 \r
188   let canvas = document.getElementsByTagName("canvas")[0];\r
189   let resize = function () {\r
190     w = window.innerWidth;\r
191     h = window.innerHeight - 200;\r
192     canvas.width = w;\r
193     canvas.height = h;\r
194   }\r
195   window.onresize = resize;\r
196   resize();\r
197   if (canvas.getContext) {\r
198     ctx = canvas.getContext('2d');\r
199     animate(performance.now());\r
200   }\r
201   canvas.onmousemove = (evt) => {\r
202     mousePos.x = evt.clientX;\r
203     mousePos.y = evt.clientY;\r
204   };\r
205 }