Esempio n. 1
0
  void run() {
    vsx_mesh* p = mesh_in->get_addr();
    if (!p)
    {
      mesh_empty.timestamp = (int)(engine->real_vtime*1000.0f);
      mesh_out->set_p(mesh_empty);
      prev_timestamp = 0xFFFFFFFF;
      return;
    }

    debug = false;
    bool newMeshLoaded = false;


    //after a mesh change clone the mesh
    if (p && (prev_timestamp != p->timestamp)) {
      prev_timestamp = p->timestamp;
      mesh.data->vertices.reset_used(0);
      mesh.data->vertex_normals.reset_used(0);
      mesh.data->vertex_tex_coords.reset_used(0);
      mesh.data->vertex_colors.reset_used(0);
      mesh.data->faces.reset_used(0);

      for (unsigned int i = 0; i < p->data->vertices.size(); i++)
      {
        mesh.data->vertices[i] = p->data->vertices[i] + v;
        verticesSpeed[i] = vsx_vector(0, 0, 0);
      }

      for (unsigned int i = 0; i < p->data->vertex_normals.size(); i++) mesh.data->vertex_normals[i] = p->data->vertex_normals[i];
      for (unsigned int i = 0; i < p->data->vertex_tangents.size(); i++) mesh.data->vertex_tangents[i] = p->data->vertex_tangents[i];
      for (unsigned int i = 0; i < p->data->vertex_tex_coords.size(); i++) mesh.data->vertex_tex_coords[i] = p->data->vertex_tex_coords[i];
      for (unsigned int i = 0; i < p->data->vertex_colors.size(); i++) mesh.data->vertex_colors[i] = p->data->vertex_colors[i];
      for (unsigned int i = 0; i < p->data->faces.size(); i++) mesh.data->faces[i] = p->data->faces[i];

      //calc and store original face lengths
      faceLengths.reset_used();
      vsx_vector normal;
      vsx_vector len;
      vsx_vector hypVec;
      for (unsigned int i = 0; i < p->data->faces.size(); i++) {
        vsx_face& f = mesh.data->faces[i];
        vsx_vector& v0 = mesh.data->vertices[f.a];
        vsx_vector& v1 = mesh.data->vertices[f.b];
        vsx_vector& v2 = mesh.data->vertices[f.c];
        //calc face area
        normal.assign_face_normal(&v0, &v1, &v2);
        float area = normal.length() / 2.0f;
        faceAreas[i] = area;
        //facelengths a, b, c stored in vector x, y, z
        len.x = (v1 - v0).length();
        len.y = (v2 - v1).length();
        len.z = (v0 - v2).length();
        faceLengths.push_back(len);
      }
      mesh.timestamp++;
      param_updates = 0;

      newMeshLoaded = true;
      dtimeRest = 0.0f;
    }

    float stepSize = step_size->get();
    //float stepsPerSecond = steps_per_second->get();
    float gasExpansionFactor = gas_expansion_factor->get();
    float gridStiffnessFactor = grid_stiffness_factor->get();
    float dampingFactor =  damping_factor->get();
    float materialWeight = material_weight->get();
    float lowerBoundary = lower_boundary->get();

    //use engine->dtime; and dtimeRest
    //to repeat the calculation several times ((dtime + rest) * stepsPerSecond)



    //calculate volume
    float volume = 0.0f;
    vsx_face* face_p = mesh.data->faces.get_pointer();
    vsx_vector* vertex_p = mesh.data->vertices.get_pointer();
    vsx_vector* faces_length_p = faceLengths.get_pointer();

    verticesSpeed.allocate(mesh.data->vertices.size());
    vsx_vector* vertices_speed_p = verticesSpeed.get_pointer();

    float onedivsix = (1.0f / 6.0f);
    for(unsigned int i = 0; i < mesh.data->faces.size(); i++) {
      vsx_face& f = face_p[i];//mesh.data->faces[i];
      vsx_vector& v0 = vertex_p[f.a];
      vsx_vector& v2 = vertex_p[f.b];
      vsx_vector& v1 = vertex_p[f.c];

      volume += (v0.x * (v1.y - v2.y) +
           v1.x * (v2.y - v0.y) +
           v2.x * (v0.y - v1.y)) * (v0.z + v1.z + v2.z) * onedivsix;

    }

    //default gas_amount to volume of a new mesh i.e. no pressure
    if(newMeshLoaded) {
      gas_amount->set(volume);
    }
    float pressure = (gas_amount->get() - volume) / volume;

    //mesh.data->face_normals.reset_used(0);
    //mesh.data->vertex_normals.reset_used(0);


    //calculate face areas, normals, forces and add to speed
    for(unsigned int i = 0; i < mesh.data->faces.size(); i++) {
      vsx_face& f = face_p[i];//mesh.data->faces[i];
      vsx_vector& v0 = vertex_p[f.a];//mesh.data->vertices[f.a];
      vsx_vector& v1 = vertex_p[f.b];//mesh.data->vertices[f.b];
      vsx_vector& v2 = vertex_p[f.c];//mesh.data->vertices[f.c];

              printVector("v0", i, v0);
              printVector("v1", i, v1);
              printVector("v2", i, v2);

      //vsx_vector normal = mesh.data->get_face_normal(i);
      vsx_vector a = vertex_p[face_p[i].b] - vertex_p[face_p[i].a];
      vsx_vector b = vertex_p[face_p[i].c] - vertex_p[face_p[i].a];
      vsx_vector normal;
      normal.cross(a,b);



              printVector("normal", i, normal);

      //float len = normal.length();
      //float area = len / 2;

              printFloat("length", i, len);
              printFloat("area", i, len);

      vsx_vector edgeA = (v1 - v0);
      vsx_vector edgeB = (v2 - v1);
      vsx_vector edgeC = (v0 - v2);

              printVector("edgeA", i, edgeA);
              printVector("edgeB", i, edgeB);
              printVector("edgeC", i, edgeC);

      float lenA = edgeA.length();
      float lenB = edgeB.length();
      float lenC = edgeC.length();

              printFloat("lenA", i, lenA);
              printFloat("lenB", i, lenB);
              printFloat("lenC", i, lenC);


      float edgeForceA = (faces_length_p[i].x - lenA) / faces_length_p[i].x;
      float edgeForceB = (faces_length_p[i].y - lenB) / faces_length_p[i].y;
      float edgeForceC = (faces_length_p[i].z - lenC) / faces_length_p[i].z;

              printFloat("edgeForceA", i, edgeForceA);
              printFloat("edgeForceB", i, edgeForceB);
              printFloat("edgeForceC", i, edgeForceC);

      float edgeAccA = edgeForceA / lenA;
      float edgeAccB = edgeForceB / lenB;
      float edgeAccC = edgeForceC / lenC;

              printFloat("edgeAccA", i, edgeAccA);
              printFloat("edgeAccB", i, edgeAccB);
              printFloat("edgeAccC", i, edgeAccC);

      vsx_vector accA = edgeA * edgeAccA;
      vsx_vector accB = edgeB * edgeAccB;
      vsx_vector accC = edgeC * edgeAccC;

              printVector("accA", i, accA);
              printVector("accB", i, accB);
              printVector("accC", i, accC);

      vertices_speed_p[f.a] -= (accA - accC) * gridStiffnessFactor;
      vertices_speed_p[f.b] -= (accB - accA) * gridStiffnessFactor;
      vertices_speed_p[f.c] -= (accC - accB) * gridStiffnessFactor;

      //applying pressure to areas of faces
      vsx_vector pressureAcc = normal * pressure * gasExpansionFactor;
      vertices_speed_p[f.a] -= pressureAcc;
      vertices_speed_p[f.b] -= pressureAcc;
      vertices_speed_p[f.c] -= pressureAcc;

      //apply material weight
      float gravityAcc = materialWeight;
      vertices_speed_p[f.a].y -= gravityAcc;
      vertices_speed_p[f.b].y -= gravityAcc;
      vertices_speed_p[f.c].y -= gravityAcc;

    }

    //apply speeds to vertices
    for(unsigned int i = 0; i < mesh.data->vertices.size(); i++) {
      vertex_p[i] += vertices_speed_p[i] * stepSize;
      if(vertex_p[i].y < lowerBoundary) {
        vertex_p[i].y = lowerBoundary;
      }
      vertices_speed_p[i] = vertices_speed_p[i] * dampingFactor;
    }


    mesh.data->vertex_normals.allocate(mesh.data->vertices.size());
    mesh.data->vertex_normals.memory_clear();
    vsx_vector* vertex_normals_p = mesh.data->vertex_normals.get_pointer();
    /*for(unsigned int i = 0; i < mesh.data->vertices.size(); i++) {
      mesh.data->vertex_normals[i] = vsx_vector(0, 0, 0);
    }*/

    //TODO: create vertex normals, for rendering... should be a separate module...
    for(unsigned int i = 0; i < mesh.data->faces.size(); i++) {
      vsx_vector a = vertex_p[face_p[i].b] - vertex_p[face_p[i].a];
      vsx_vector b = vertex_p[face_p[i].c] - vertex_p[face_p[i].a];
      vsx_vector normal;
      normal.cross(a,b);

      //vsx_vector normal = mesh.data->get_face_normal(i);
      normal = -normal;
      normal.normalize();
      vertex_normals_p[face_p[i].a] += normal;
      vertex_normals_p[face_p[i].b] += normal;
      vertex_normals_p[face_p[i].c] += normal;
    }

    volume_out->set(volume);

    //printf("***************Pressure %f     ", pressure);
    //printf(" Volume %f\n", volume);

    mesh_out->set_p(mesh);
  }
Esempio n. 2
0
File: main.cpp Progetto: Who828/vsxu
  void output(vsx_module_param_abs* param) {
    mesh = in_mesh->get_addr();

    if (mesh && (*mesh)->data->vertices.size())
    {
      if (prev_num_vertices != (unsigned long)mesh_id_count->get())
      {
        // remove all the old ones
        for (unsigned long i = prev_num_vertices; i < (unsigned long)mesh_id_count->get(); ++i)
        {
          //printf("allocating %d\n", i);
          //if (i == prev_num_vertices)
            //printf("allocating again\n");
          gr[i] = new gravity_strip;
          gr[i]->init();
          gr[i]->init_strip();
        }
        prev_num_vertices = (int)mesh_id_count->get();
      }
      //printf("mesh_id_start: %d\n", (int)mesh_id_start->get());
      size_t mesh_index = (size_t)mesh_id_start->get() % (*mesh)->data->vertices.size();

      vsx_matrix* matrix_result = modelview_matrix->get_addr();
      if (!matrix_result)
      {
        matrix_result = &modelview_matrix_no_connection;
        glGetFloatv(GL_MODELVIEW_MATRIX, modelview_matrix_no_connection.m);
      }


      //printf("in-mesh vertex count: %d\n", mesh->data->vertices.size());
      if (param == render_result)
      {
        for (unsigned long i = 0; i < prev_num_vertices; ++i)
        {
          //gr[i].length = 0.0f;
          gr[i]->width = ribbon_width->get();
          //gr[i].masses[1].mass = gr[i].masses[0].mass + ribbon_width->get();
          gr[i]->length = length->get();
          gr[i]->friction = friction->get();
          //float tt = ((*particles->particles)[i].time/(*particles->particles)[i].lifetime);
          //if (tt < 0.0f) tt = 0.0f;
          //if (tt > 1.0f) tt = 1.0f;
          gr[i]->color0[0] = color0->get(0);
          gr[i]->color0[1] = color0->get(1);
          gr[i]->color0[2] = color0->get(2);
          gr[i]->color0[3] = color0->get(3);

          gr[i]->color1[0] = color1->get(0);
          gr[i]->color1[1] = color1->get(1);
          gr[i]->color1[2] = color1->get(2);
          gr[i]->step_freq = 10.0f * step_length->get();
          //if (last_update != engine->vtime) {
          if (reset_pos->get() > 0.0f)
          {
            gr[i]->reset_pos(
              (*mesh)->data->vertices[mesh_index].x,
              (*mesh)->data->vertices[mesh_index].y,
              (*mesh)->data->vertices[mesh_index].z
            );
          } else
          {
            gr[i]->update(
              engine->dtime,
              (*mesh)->data->vertices[mesh_index].x,
              (*mesh)->data->vertices[mesh_index].y,
              (*mesh)->data->vertices[mesh_index].z
            );
          }
          gr[i]->render();
              //(*(particles->particles))[i].pos.x, (*(particles->particles))[i].pos.y, (*(particles->particles))[i].pos.z);
            //last_upd ate = engine->vtime;
          //}
          //printf("%f, %f, %f\n", (*particles->particles)[i].pos.x, (*particles->particles)[i].pos.y, (*particles->particles)[i].pos.z);
      //    printf("%d %d;;; %d\n",__LINE__,i, particles->particles->size());
          // add the delta-time to the time of the particle
          /*(*particles->particles)[i].pos.x += px*engine->dtime;
          (*particles->particles)[i].pos.y += py*engine->dtime;
          (*particles->particles)[i].pos.z += pz*engine->dtime;*/
          mesh_index++;
          mesh_index = mesh_index % (*mesh)->data->vertices.size();
        }
      }
      else
      {
        float ilength = length->get();
        if (ilength > 1.0f) ilength = 1.0f;
        if (ilength < 0.01f) ilength = 0.01f;

        int num2 = BUFF_LEN * (int)(ilength * 8.0f * (float)prev_num_vertices);

        //printf("num2: %d\n", num2);
        // allocate mesh memory for all parts
        mesh_out->data->faces.allocate(num2);
        mesh_out->data->vertices.allocate(num2);
        mesh_out->data->vertex_normals.allocate(num2);
        mesh_out->data->vertex_tex_coords.allocate(num2);
        //printf("mesh: %d\n", __LINE__);
        mesh_out->data->faces.reset_used(num2);
        mesh_out->data->vertices.reset_used(num2);
        mesh_out->data->vertex_normals.reset_used(num2);
        mesh_out->data->vertex_tex_coords.reset_used(num2);
        //printf("mesh: %d\n", __LINE__);

        vsx_face*      fs_d = mesh_out->data->faces.get_pointer();
        vsx_vector*    vs_d = mesh_out->data->vertices.get_pointer();
        vsx_vector*    ns_d = mesh_out->data->vertex_normals.get_pointer();
        vsx_tex_coord* ts_d = mesh_out->data->vertex_tex_coords.get_pointer();
        int generated_vertices = 0;
        int generated_faces = 0;
        //printf("mesh: %d\n", __LINE__);

        generated_faces = 0;
        generated_vertices = 0;
        generated_vertices = 0;
        generated_vertices = 0;
        vsx_vector upv;
        upv.x = upvector->get(0);
        upv.y = upvector->get(1);
        upv.z = upvector->get(2);
        for (unsigned long i = 0; i < prev_num_vertices; ++i)
        {
          gr[i]->width = ribbon_width->get();
          gr[i]->length = length->get();
          gr[i]->friction = friction->get();
          gr[i]->color0[0] = color0->get(0);
          gr[i]->color0[1] = color0->get(1);
          gr[i]->color0[2] = color0->get(2);
          gr[i]->color0[3] = color0->get(3);

          gr[i]->color1[0] = color1->get(0);
          gr[i]->color1[1] = color1->get(1);
          gr[i]->color1[2] = color1->get(2);
          gr[i]->step_freq = 10.0f * step_length->get();

          //printf("mesh: %d %d\n", __LINE__, mesh_index);
          if (reset_pos->get() > 0.0f)
          {
            gr[i]->reset_pos(
              (*mesh)->data->vertices[mesh_index].x,
              (*mesh)->data->vertices[mesh_index].y,
              (*mesh)->data->vertices[mesh_index].z
            );
          } else
          {
            gr[i]->update(
              engine->dtime,
              (*mesh)->data->vertices[mesh_index].x,
              (*mesh)->data->vertices[mesh_index].y,
              (*mesh)->data->vertices[mesh_index].z
            );
          }
          //printf("%d\n", (int)i);

          gr[i]->generate_mesh(*mesh_out,fs_d, vs_d, ns_d, ts_d, matrix_result, &upv, generated_vertices, generated_faces);
          mesh_index++;
          mesh_index = mesh_index % (*mesh)->data->vertices.size();
        }

//        printf("generated faces: %d\n", generated_faces);
        //printf("generated vertices: %d\n", generated_vertices);
        mesh_out->data->faces.reset_used(generated_faces);
        mesh_out->data->vertices.reset_used(generated_vertices);
        mesh_out->data->vertex_normals.reset_used(generated_vertices);
        mesh_out->data->vertex_tex_coords.reset_used(generated_vertices);
        //printf("mesh: %d\n", __LINE__);

        mesh_result->set_p(mesh_out);
      }
      //printf("done drawing\n");
    }
  render_result->set(1);
  }