- vertexWeights = [];\r
-\r
- \r
- /**\r
- * creates a rectangular piece of cloth\r
- * takes the size of the cloth\r
- * and the number of vertices it should be composed of\r
- * @param {number} width - width of the cloth\r
- * @param {number} height - height of the cloth\r
- * @param {number} numPointsWidth - number of vertices in horizontal direction\r
- * @param {number} numPointsHeight - number of vertices in vertical direction\r
- */\r
- createBasic(width, height, numPointsWidth, numPointsHeight) {\r
- /** resulting vertices and faces */\r
- let vertices = [];\r
- let faces = [];\r
-\r
- /**\r
- * distance between two vertices horizontally/vertically\r
- * divide by the number of points minus one\r
- * because there are (n - 1) lines between n vertices\r
- */\r
- let stepWidth = width / (numPointsWidth - 1);\r
- let stepHeight = height / (numPointsHeight - 1);\r
-\r
- /**\r
- * iterate over the number of vertices in x/y axis\r
- * and add a new Vector3 to "vertices"\r
- */\r
- for (let y = 0; y < numPointsHeight; y++) {\r
- for (let x = 0; x < numPointsWidth; x++) {\r
- vertices.push(\r
- new THREE.Vector3(x * stepWidth, height - y * stepHeight, 0)\r
- );\r
- }\r
- }\r
-\r
- /**\r
- * helper function to calculate index of vertex\r
- * in "vertices" array based on its x and y positions\r
- * in the mesh\r
- * @param {number} x - x index of vertex\r
- * @param {number} y - y index of vertex\r
- */\r
- function getVertexIndex(x, y) {\r
- return y * numPointsWidth + x;\r
- }\r
- \r
- /**\r
- * generate faces based on 4 vertices\r
- * and 6 springs each\r
- */\r
- for (let y = 0; y < numPointsHeight - 1; y++) {\r
- for (let x = 0; x < numPointsWidth - 1; x++) {\r
- let newFace = new Face(\r
- getVertexIndex(x, y),\r
- getVertexIndex(x, y + 1),\r
- getVertexIndex(x + 1, y),\r
- getVertexIndex(x + 1, y + 1),\r
- );\r
-\r
- newFace.springs.push(new Spring(vertices, getVertexIndex(x, y), getVertexIndex(x + 1, y)));\r
- newFace.springs.push(new Spring(vertices, getVertexIndex(x, y), getVertexIndex(x, y + 1)));\r
- newFace.springs.push(new Spring(vertices, getVertexIndex(x, y), getVertexIndex(x + 1, y + 1)));\r
- newFace.springs.push(new Spring(vertices, getVertexIndex(x + 1, y), getVertexIndex(x, y + 1)));\r
- newFace.springs.push(new Spring(vertices, getVertexIndex(x + 1, y), getVertexIndex(x + 1, y + 1)));\r
- newFace.springs.push(new Spring(vertices, getVertexIndex(x, y + 1), getVertexIndex(x + 1, y + 1)));\r
- \r
- faces.push(newFace);\r
- }\r
- }\r
-\r
- /**\r
- * call createExplicit\r
- * with generated vertices and faces\r
- */\r
- this.createExplicit(vertices, faces);\r
- }\r
-\r
- /**\r
- * Generate THREE JS Geometry\r
- * (list of vertices and list of indices representing triangles)\r
- * and calculate the weight of each face and split it between\r
- * surrounding vertices\r
- * @param {Array of Vector3} vertices \r
- * @param {Array of Face} faces \r
- */\r
- createExplicit(vertices, faces) {\r
- /**\r
- * Copy vertices and initialize vertex weights to 0\r
- */\r
- for (let i in vertices) {\r
- this.geometry.vertices.push(vertices[i]);\r
- this.vertexWeights.push(0);\r
- }\r
- /**\r
- * copy faces,\r
- * generate two triangles per face,\r
- * calculate weight of face as its area\r
- * and split between the 4 vertices\r
- */\r
- for (let i in faces) {\r
- let face = faces[i];\r
-\r
- /** copy faces to class member */\r
- this.faces.push(face);\r
-\r
- /** generate triangles */\r
- this.geometry.faces.push(new THREE.Face3(\r
- face.a, face.b, face.c\r
- ));\r
- this.geometry.faces.push(new THREE.Face3(\r
- face.c, face.b, face.d\r
- ));\r
- \r
- /**\r
- * calculate area of face as combined area of\r
- * its two composing triangles\r
- */\r
- let xLength = vectorLength(this.geometry.vertices[face.b], this.geometry.vertices[face.a]);\r
- let yLength = vectorLength(this.geometry.vertices[face.c], this.geometry.vertices[face.a]);\r
- let weight = xLength * yLength / 2;\r
-\r
- xLength = vectorLength(this.geometry.vertices[face.b], this.geometry.vertices[face.d]);\r
- yLength = vectorLength(this.geometry.vertices[face.c], this.geometry.vertices[face.d]);\r
- weight += xLength * yLength / 2;\r
-\r
- /**\r
- * split weight equally between four surrounding vertices\r
- */\r
- this.vertexWeights[face.a] += weight / 4;\r
- this.vertexWeights[face.b] += weight / 4;\r
- this.vertexWeights[face.c] += weight / 4;\r
- this.vertexWeights[face.d] += weight / 4;\r
- }\r
-\r
- /**\r
- * let THREE JS compute bounding sphere around generated mesh\r
- * needed for View Frustum Culling internally\r
- */\r
- this.geometry.computeBoundingSphere();\r
- }\r