abouttreesummaryrefslogcommitdiff
path: root/Scripts/cloth.js
blob: 05ff6f1f30eb54da8985b99c786d3596662f214e (plain)
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) {

  }
}