0

我需要在布料的模拟中实现风力的简单效果。我的布料由使用弹簧连接的 10x10 个顶点(cloth_vertices 数组中给出的 100 个索引)制成。弹簧定义如下:

function initMassSpringSystem() {

    // adding springs
    for (let i = 0; i < cloth_size - 1; i++) {
        for (let j = 0; j < cloth_size - 1; j++) {
            let top = i * cloth_size + j;
            // vertical 1
            spring_start.push(top);
            spring_end.push(top + cloth_size);
            spring_rest.push(1.0 / (cloth_size - 1));
            // horizontal 1
            spring_start.push(top);
            spring_end.push(top + 1);
            spring_rest.push(1.0 / (cloth_size - 1));
            // vertical 2
            spring_start.push(top + 1);
            spring_end.push(top + 1 + cloth_size);
            spring_rest.push(1.0 / (cloth_size - 1));
            // horizontal 1
            spring_start.push(top + cloth_size);
            spring_end.push(top + 1 + cloth_size);
            spring_rest.push(1.0 / (cloth_size - 1));
            // diagonal 1
            spring_start.push(top);
            spring_end.push(top + 1 + cloth_size);
            spring_rest.push(Math.sqrt(2) * 1.0 / (cloth_size - 1));
            // diagonal 2
            spring_start.push(top + 1);
            spring_end.push(top + cloth_size);
            spring_rest.push(Math.sqrt(2) * 1.0 / (cloth_size - 1));
        }
    }

    // initializing velocities and forces
    for (i = 0; i < cloth_size * cloth_size; i++) {
        v.push(vec3.fromValues(0.0, 0.0, 0.0));
        f.push(vec3.fromValues(0.0, 0.0, 0.0));
    }

    time = Date.now();
}

在我的函数 updateCloth() 中,我已经实现了重力、弹簧和阻尼力,它们可以正常工作,但现在的问题是应用风效果:

function updateCloth() {

    // ------------ Assignment ------------
    // You need to fill in the gaps in this function

    // initializing forces for every particle with gravity and any external forces
    for (i = 0; i < cloth_size * cloth_size; i++) {
    // gravity act on y direction. All forces are recalculated at each time stamp
        f[i][1] = - (mass * 9.8665);
    }

    // computing the forces exetrted by every spring and adding them to the forces acting on particles
    for (i = 0; i < spring_start.length; i++) {
        let p = spring_start[i]; // index of the particle/vertex which corresponds to one end of the spring
        let q = spring_end[i]; // index of the particle/vertex which corresponds to one end of the spring
        // positions of the two ends of the spring
        let x_p = vec3.fromValues(cloth_vertices[3 * p], cloth_vertices[3 * p + 1], cloth_vertices[3 * p + 2]);
        let x_q = vec3.fromValues(cloth_vertices[3 * q], cloth_vertices[3 * q + 1], cloth_vertices[3 * q + 2]);
        
        // Compute forces exert by the spring and the damping forces
        // Use the computed forces to update f[p] and f[q], i.e., accumulated forces which act on the particles
        
        

        
        // damping force
        let empty = vec3.fromValues(0, 0, 0);
        let e = vec3.fromValues(0,0,0);
        vec3.sub(e,x_q, x_p);
        let len_1 = vec3.distance(x_q,x_p);
        let c = vec3.fromValues(0, 0, 0);
        vec3.normalize(c,e);

        let b1 = vec3.fromValues(0,0,0);
        vec3.sub(b1,v[q], v[p]);
        vec3.divide(b1, b1, vec3.fromValues(spring_rest[i], spring_rest[i], spring_rest[i]));
        let b2 = c;
        let b = vec3.dot(b1, b2);

        let damping_force = damping * b * c[1];


        // hooke's law
        let second = (len_1/spring_rest[i])-1;
        let third = c[1];
        let hooke_law = k * second * third;

        // for f[p] y add forces, while subtract for [q] y because the force is in the opposite direction
        f[p][1] = f[p][1] + hooke_law + damping_force;
        f[q][1] = f[q][1] - hooke_law - damping_force;

        // WIND
        // take delta time
        const end_time = Date.now();
        const time_elapsed = end_time - time;
        // calculate wind force using a sinusoidal function (such that it oscillates)
        const wind = Math.sin(2 * Math.sin(time_elapsed)) + Math.sin(3.14 * Math.sin(time_elapsed));
        f[p][0] = wind;
        f[q][0] = -wind;


    }
    
    // updateing position an velocities of the particles based on forces and masses
    
    for (let i = 0; i < cloth_size * cloth_size; i++) {
        
        // fixed point to avoid cloth falling forever
        if ( i === 0 || i === cloth_size - 1) {
            
            // velocity of i-th particle
            v[i][0] = 0;
            v[i][1] = 0;
            v[i][2] = 0;
            
            // position of i-th particle
            cloth_vertices[3 * i] = cloth_vertices[3 * i];
            cloth_vertices[3 * i + 1] = cloth_vertices[3 * i + 1];
            cloth_vertices[3 * i + 2] = cloth_vertices[3 * i + 2];
        }
        else {

            // Here update the velocity and position of every particle
            // velocity of i-th particle
            v[i][1] = v[i][1] + (deltaT * (f[i][1] / mass));
            v[i][2] = 0;
            // wind
            v[i][0] = v[i][0] + (deltaT * (f[i][0] / mass));
            // console.log(v[i][0]);
            
            // position of i-th particle
            cloth_vertices[3*i + 1] = cloth_vertices[3*i + 1] + (deltaT * v[i][1]);
            // wind
            cloth_vertices[3*i+2] = cloth_vertices[3*i+2] + (deltaT * v[i][0]);
        }
    }

    // The three lines below will make sure that the buffer on the GPU,
    // which stores the positions of particles, will be updated.
    gl.bindBuffer(gl.ARRAY_BUFFER, clothVertexBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(cloth_vertices), gl.DYNAMIC_DRAW);
    gl.bindBuffer(gl.ARRAY_BUFFER, null);
}

该函数被多次调用以对另一个 run() 方法产生动画效果。我读到风的影响取决于时间变量,然后我取了整个函数执行之前(在调用 updateCloth() 之前定义的时间变量)和每次调用它之间的差异。然后我使用了一个简单的方程找到在我称之为风的互联网上,它允许有一个在负值和正值之间振荡的小值(~-2 / ~+2)。我将此力施加到 f[p],其中 p 是开始弹簧的顶点的索引,我将它的倒数施加到结束弹簧的 f[q](我输入负值,因为我知道在弹簧中一个顶点的力与另一个顶点的力相反,但我不确定这个想法是否也适用于风)。我只在 x 值上施加了这个力(实际上我有 f[p][0])以便于计算,但我认为它必须应用于所有三个方向(我有一个 3D 模拟,然后是 x,y ,z)。结果是布料的一半无限地朝向一个方向,一半朝向另一个方向。力值和速度都正确振荡,但问题是顶点的位置继续增加,有些是正值,有些是负值。我不知道如何获得增加的风的效果,但直到一定值,然后保持不变。我读到它的值取决于顶点的位置(我将布料的左右角固定为不会飞走,然后我想风的效果必须在底部更大布),但我没有

在没有风的情况下,我的布料可以想象如下:

在此处输入图像描述

在应用我错误的风效果时,它的行为方式如下:

在此处输入图像描述

我希望我提供了所有信息,否则请不要犹豫。

4

1 回答 1

0

使用弹簧系统,“风”只是向顶点施加一些力并让弹簧系统负责调平力的问题。您不需要明确地平衡力,这就是您编写弹簧系统的目的。“风”不是特定的模拟/公式,它是您输入模拟的数据(作为力)。

于 2021-12-30T17:58:02.830 回答