Exemplo n.º 1
0
  void declare_params(vsx_module_param_list& in_parameters, vsx_module_param_list& out_parameters)
  {
    mesh_in = (vsx_module_param_mesh*)in_parameters.create(VSX_MODULE_PARAM_ID_MESH,"mesh_in");

    steps_per_second = (vsx_module_param_float*)in_parameters.create(VSX_MODULE_PARAM_ID_FLOAT, "steps_per_second");
    step_size = (vsx_module_param_float*)in_parameters.create(VSX_MODULE_PARAM_ID_FLOAT, "step_size");
    gas_amount = (vsx_module_param_float*)in_parameters.create(VSX_MODULE_PARAM_ID_FLOAT, "gas_amount");
    gas_expansion_factor = (vsx_module_param_float*)in_parameters.create(VSX_MODULE_PARAM_ID_FLOAT, "gas_expansion_factor");
    grid_stiffness_factor = (vsx_module_param_float*)in_parameters.create(VSX_MODULE_PARAM_ID_FLOAT, "grid_stiffness_factor");
    damping_factor = (vsx_module_param_float*)in_parameters.create(VSX_MODULE_PARAM_ID_FLOAT, "damping_factor");
    material_weight = (vsx_module_param_float*)in_parameters.create(VSX_MODULE_PARAM_ID_FLOAT, "material_weight");
    lower_boundary = (vsx_module_param_float*)in_parameters.create(VSX_MODULE_PARAM_ID_FLOAT, "lower_boundary");


    steps_per_second->set(100.0f);
    step_size->set(0.01f);
    gas_amount->set(1.0f);
    gas_expansion_factor->set(1.0f);
    grid_stiffness_factor->set(1.0f);
    damping_factor->set(0.98f);
    material_weight->set(0.00f);
    lower_boundary->set(-150.00f);


    loading_done = true;
    mesh_out = (vsx_module_param_mesh*)out_parameters.create(VSX_MODULE_PARAM_ID_MESH,"mesh_out");
    mesh_out->set_p(mesh);
    volume_out = (vsx_module_param_float*)out_parameters.create(VSX_MODULE_PARAM_ID_FLOAT,"volume_out");
    volume_out->set(0.0f);
  }
Exemplo n.º 2
0
void declare_params(vsx_module_param_list& in_parameters, vsx_module_param_list& out_parameters)
{
  loading_done = false;
  filename = (vsx_module_param_resource*)in_parameters.create(VSX_MODULE_PARAM_ID_RESOURCE,"filename");
  filename->set("");
  current_filename = "";

  result = (vsx_module_param_mesh*)out_parameters.create(VSX_MODULE_PARAM_ID_MESH,"mesh");
  result->set_p(mesh);
  first_run = true;
}
Exemplo n.º 3
0
Arquivo: main.cpp Projeto: Who828/vsxu
  void run() {
    int l_grid_size = (int)floor(grid_size->get());
    if (i_grid_size != l_grid_size) {
      balls.SetGridSize(l_grid_size);
      i_grid_size = l_grid_size;
    }
    if (engine->dtime != 0.0f) {
      float dd = engine->dtime;
      if (dd < 0) dd = 0;
    vsx_timer timer;
    timer.start();
    balls.Update(dd);

      //printf("update took: %f s\n", timer.dtime());
    timer.start();
    balls.Render();

    //printf("render took: %f s\n", timer.dtime());
    mesh->timestamp++;
    }
    result->set_p(mesh);
  }
Exemplo n.º 4
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);
  }
Exemplo n.º 5
0
Arquivo: main.cpp Projeto: 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);
  }
Exemplo n.º 6
0
void run() {
  if (filename->get() != current_filename) {
   	if (!verify_filesuffix(filename->get(),"obj")) {
   		filename->set(current_filename);
   		message = "module||ERROR! This is not a OBJ mesh file!";
   		return;
   	} else message = "module||ok";

    current_filename = filename->get();
    vsxf_handle *fp;
    //printf("a\n");
    if ((fp = engine->filesystem->f_open(current_filename.c_str(), "r")) == NULL)
    {
      return;
    }
    
    char buf[65535];
    vsx_string line;
    vsx_array<vsx_vector> vertices; //vertices.set_allocation_increment(15000);
    vsx_array<vsx_vector> normals; //normals.set_allocation_increment(15000);
    vsx_array<vsx_tex_coord> texcoords; //texcoords.set_allocation_increment(15000);
    //mesh->data->vertex_tex_coords.reset_used();
    mesh->data->clear();
    //mesh->data->vertices.set_allocation_increment(15000);
    //mesh->data->vertex_normals.set_allocation_increment(15000);
    //mesh->data->vertex_tex_coords.set_allocation_increment(15000);
    //mesh->data->faces.set_allocation_increment(15000);

    int face_cur = 0;
    //printf("b\n");
    bool found_normals = false;
    bool found_texcoords = false;
    if (preserve_uv_coords->get()) {
      mesh->data->vertices.reset_used();
      mesh->data->vertex_tex_coords.reset_used();
      mesh->data->vertex_normals.reset_used();
      mesh->data->faces.reset_used();

	    while (engine->filesystem->f_gets(buf,65535,fp)) {
	      line = buf;
	      if (line[line.size()-1] == 0x0A) line.pop_back();
	      if (line[line.size()-1] == 0x0D) line.pop_back();
	      //printf("reading line: %s\n",line.c_str());
	      //printf("c\n");
	      if (line.size()) {
	        vsx_avector<vsx_string> parts;
	        vsx_string deli = " ";
	        explode(line, deli, parts);
	        if (parts[0] == "v") {
	        	//printf("v\n");
	          //mesh->data->vertices.push_back(vsx_vector(s2f(parts[1]),s2f(parts[2]),s2f(parts[3])));
	          vertices.push_back(vsx_vector(s2f(parts[1]),s2f(parts[2]),s2f(parts[3])));
	        } else
	        if (parts[0] == "vt") {
	        	//printf("vt\n");
	          vsx_tex_coord a;
	          a.s = (s2f(parts[1]));
	          a.t = (s2f(parts[2]));
	          //printf("%f  ::   %f\n",a.s,a.t);
	          texcoords.push_back(a);
	          //vsx_vector__(s2f(parts[1]),s2f(parts[2]),s2f(parts[3])));
	          found_texcoords = true;

	        } else
	        if (parts[0] == "vn") {
	        	//printf("vn\n");
	          //printf("normal\n");
	          normals.push_back(vsx_vector(s2f(parts[1]),s2f(parts[2]),s2f(parts[3])));
	          found_normals = true;
	          //mesh->data->vertex_normals.push_back(vsx_vector__(s2f(parts[1]),s2f(parts[2]),s2f(parts[3])));
	        } else
	        if (parts[0] == "f") {
	        	//printf("f1\n");
	          //printf("face\n");
	          //if (parts.size() == 4) {
	            //printf("num texcoords %d\n",texcoords.size());
	            vsx_face ff;
	//            vsx_avector<vsx_string> parts2;
	            vsx_string deli2 = "/";

	/*            explode(parts[1], deli2, parts2);
	            ff.c = s2i(parts2[0])-1;
	            mesh->data->vertex_normals[ff.c] = normals[s2i(parts2[1])-1];
	            mesh->data->vertex_tex_coords[ff.c] = texcoords[s2i(parts2[1])-1];

	            explode(parts[2], deli2, parts2);
	            ff.b = s2i(parts2[0])-1;
	            mesh->data->vertex_normals[ff.b] = normals[s2i(parts2[1])-1];
	            mesh->data->vertex_tex_coords[ff.b] = texcoords[s2i(parts2[1])-1];

	            explode(parts[3], deli2, parts2);
	            ff.a = s2i(parts2[0])-1;
	            mesh->data->vertex_normals[ff.a] = normals[s2i(parts2[1])-1];
	            mesh->data->vertex_tex_coords[ff.a] = texcoords[s2i(parts2[1])-1];*/


	            vsx_avector<vsx_string> parts2;
	            explode(parts[1], deli2, parts2);
	            vsx_avector<vsx_string> parts3;
	            explode(parts[2], deli2, parts3);
	            vsx_avector<vsx_string> parts4;
	            explode(parts[3], deli2, parts4);

	            ff.c = face_cur;   //s2i(parts2[0])-1;
	            ff.b = face_cur+1; //s2i(parts3[0])-1;
	            ff.a = face_cur+2; //s2i(parts4[0])-1;

              
	            //printf("f2\n");
              //printf("reading line: %s\n",line.c_str());
              int id;
              id = s2i(parts2[0])-1; if (id < 0) id=0;
	            mesh->data->vertices[ff.a] = vertices[id];
              id = s2i(parts3[0])-1; if (id < 0) id=0;
              mesh->data->vertices[ff.b] = vertices[id];
              id = s2i(parts4[0])-1; if (id < 0) id=0;
	            mesh->data->vertices[ff.c] = vertices[id];

	            if (found_texcoords && found_normals) {
                if (parts2[1] != "") {
                  mesh->data->vertex_tex_coords[ff.a] = texcoords[s2i(parts2[1])-1];
                  mesh->data->vertex_tex_coords[ff.b] = texcoords[s2i(parts3[1])-1];
                  mesh->data->vertex_tex_coords[ff.c] = texcoords[s2i(parts4[1])-1];
                }
	              if (parts2[2] != "") {
                  mesh->data->vertex_normals[ff.a] = normals[s2i(parts2[2])-1];
                  mesh->data->vertex_normals[ff.b] = normals[s2i(parts3[2])-1];
                  mesh->data->vertex_normals[ff.c] = normals[s2i(parts4[2])-1];
                }
	            } else
	            if (found_normals) {
                if (parts2[2] != "") {
                  mesh->data->vertex_normals[ff.a] = normals[s2i(parts2[2])-1];
                  mesh->data->vertex_normals[ff.b] = normals[s2i(parts3[2])-1];
                  mesh->data->vertex_normals[ff.c] = normals[s2i(parts4[2])-1];
                }
	            } else
	            if (found_texcoords) {
                if (parts2[1] != "") {
                  mesh->data->vertex_tex_coords[ff.a] = texcoords[s2i(parts2[1])-1];
                  mesh->data->vertex_tex_coords[ff.b] = texcoords[s2i(parts3[1])-1];
                  mesh->data->vertex_tex_coords[ff.c] = texcoords[s2i(parts4[1])-1];
                }
	            }


						  //printf("%d  ",s2i(parts2[1]));
						  //printf("%d  ",s2i(parts3[1]));
						  //printf("%d\n",s2i(parts4[1]));
						  //printf("f3\n");

	            /*printf("ida: %d\n",s2i(parts2[1]));
	            printf("orig coords: %f %f\n",texcoords[s2i(parts2[1])-1].s,texcoords[s2i(parts2[1])-1].t);
	            printf("texcoord s: %f   %f\n",mesh->data->vertex_tex_coords[ff.a].s,mesh->data->vertex_tex_coords[ff.a].t);

	            printf("idb: %d\n",s2i(parts3[1]));
	            printf("orig coords: %f %f\n",texcoords[s2i(parts3[1])-1].s,texcoords[s2i(parts3[1])-1].t);
	            printf("texcoord s: %f   %f\n",mesh->data->vertex_tex_coords[ff.a].s,mesh->data->vertex_tex_coords[ff.a].t);

	            printf("idc: %d\n",s2i(parts4[1]));
	            printf("orig coords: %f %f\n",texcoords[s2i(parts4[1])-1].s,texcoords[s2i(parts4[1])-1].t);
	            printf("texcoord s: %f   %f\n",mesh->data->vertex_tex_coords[ff.a].s,mesh->data->vertex_tex_coords[ff.a].t);
	*/
	            face_cur += 3;
	            mesh->data->faces.push_back(ff);
	            //printf("f4\n");
	          //}
	        }

	      }
	    }
    } else {

	    while (engine->filesystem->f_gets(buf,65535,fp)) {
	      line = buf;
	      if (line[line.size()-1] == 0x0A) line.pop_back();
	      if (line[line.size()-1] == 0x0D) line.pop_back();
	      if (line.size()) {
	        vsx_avector<vsx_string> parts;
	        vsx_string deli = " ";
	        explode(line, deli, parts);
	        if (parts[0] == "v") {
	        	mesh->data->vertices.push_back(vsx_vector(s2f(parts[1]),s2f(parts[2]),s2f(parts[3])));
	        } else
	        if (parts[0] == "f") {
	            vsx_face ff;
	            vsx_string deli2 = "/";

	            vsx_avector<vsx_string> parts2;
	            explode(parts[1], deli2, parts2);
	            vsx_avector<vsx_string> parts3;
	            explode(parts[2], deli2, parts3);
	            vsx_avector<vsx_string> parts4;
	            explode(parts[3], deli2, parts4);

	            ff.c = s2i(parts2[0])-1;
	            ff.b = s2i(parts3[0])-1;
	            ff.a = s2i(parts4[0])-1;

	            //printf("face %d %d %d %d\n", mesh->data->faces.size(), ff.a, ff.b, ff.c);

	            mesh->data->faces.push_back(ff);
	        }

	      }
	    }
    }

    engine->filesystem->f_close(fp);
    loading_done = true;
    mesh->timestamp = (int)(engine->real_vtime*1000.0f);
    #ifdef VSXU_DEBUG
      //printf("mesh timestamp: %d\n", (int)mesh->timestamp);
    #endif
  }
  result->set_p(mesh);
}