Exemplo n.º 1
0
MenuServeur::MenuServeur() :
  mWindow(sf::VideoMode(430, 430, 32), "Tic-Tac-Toe en SFML!"),
  mXTexture(),
  mOTexture(),
  mShapes(),
  mGrid(),
  mPlayer(X_PLAYER),
  mOutcome(UNFINISHED),
  mBoard()
{
  if (!mXTexture.loadFromFile("assets/cross.png"))
  {
    std::cerr << "ERROR : Image not found !" << std::endl;
  }
  if (!mOTexture.loadFromFile("assets/circle.png"))
  {
    std::cerr << "ERROR : Image not found !" << std::endl;
  }

  sf::RectangleShape vert1(sf::Vector2f(5, 410));
  vert1.setFillColor(sf::Color::Black);
  vert1.setPosition(140,10);
  mGrid.push_back(vert1);

  sf::RectangleShape vert2(sf::Vector2f(5, 410));
  vert2.setFillColor(sf::Color::Black);
  vert2.setPosition(285,10);
  mGrid.push_back(vert2);

  sf::RectangleShape hori1(sf::Vector2f(410, 5));
  hori1.setFillColor(sf::Color::Black);
  hori1.setPosition(10,140);
  mGrid.push_back(hori1);

  sf::RectangleShape hori2(sf::Vector2f(410, 5));
  hori2.setFillColor(sf::Color::Black);
  hori2.setPosition(10,285);
  mGrid.push_back(hori2);
}
Exemplo n.º 2
0
bool Loader_obj::load_model_data(Model& mdl, QString path){
    QStringList pathlist = path.split("/",QString::KeepEmptyParts); //KeepEmptyParts
    QString model_name = pathlist.last();

    //LOAD MESH DATA
    QFile file(path);
    if (!file.open (QIODevice::ReadOnly))
    {
        qDebug("        Model import: Error 1: Model file could not be loaded...");
        return false;
    }
    QTextStream stream ( &file );
    QString line;

    QString mtllib;


    QString current_mesh;
    QMap<QString,QVector<int> >mesh_faces;
    QMap<QString,QString> mesh_mtl;
    QMap<QString,Material* > mtln_mtl;
    QVector<Vector3> model_vertices;
    QVector<Vector3> model_vertex_normals;
    QVector<Vector3> model_vertex_texture_coordinates;

    while( !stream.atEnd() ) {
        line = stream.readLine();
        QStringList list = line.split(QRegExp("\\s+"),QString::SkipEmptyParts); //SkipEmptyParts

        if(!list.empty()){
            if(list.first() == "mtllib"){
                mtllib = list.last();
            }

            else if(list.first() == "v"){
                model_vertices.append(Vector3(  list.value(1).toFloat(),
                                                  list.value(2).toFloat(),
                                                  list.value(3).toFloat()));
            }
            else if(list.first() == "vn"){
                model_vertex_normals.append(Vector3(  list.value(1).toFloat(),
                                                        list.value(2).toFloat(),
                                                        list.value(3).toFloat()));
            }
            else if(list.first() == "vt"){
                model_vertex_texture_coordinates.append(Vector3(  list.value(1).toFloat(),
                                                                    list.value(2).toFloat(),
                                                                    list.value(3).toFloat()));
            }
            else if(list.first() == "g"){
                current_mesh = list.value(1);
            }
            else if(list.first() == "usemtl"){
                mesh_mtl[current_mesh] = list.value(1);
            }
            else if(list.first() == "f"){
                QStringList face_part_1_list = list.value(1).split("/",QString::SkipEmptyParts); //SkipEmptyParts
                QStringList face_part_2_list = list.value(2).split("/",QString::SkipEmptyParts); //SkipEmptyParts
                QStringList face_part_3_list = list.value(3).split("/",QString::SkipEmptyParts); //SkipEmptyParts
                mesh_faces[current_mesh].append(face_part_1_list.value(0).toInt());
                mesh_faces[current_mesh].append(face_part_1_list.value(1).toInt());
                mesh_faces[current_mesh].append(face_part_1_list.value(2).toInt());

                mesh_faces[current_mesh].append(face_part_2_list.value(0).toInt());
                mesh_faces[current_mesh].append(face_part_2_list.value(1).toInt());
                mesh_faces[current_mesh].append(face_part_2_list.value(2).toInt());

                mesh_faces[current_mesh].append(face_part_3_list.value(0).toInt());
                mesh_faces[current_mesh].append(face_part_3_list.value(1).toInt());
                mesh_faces[current_mesh].append(face_part_3_list.value(2).toInt());

            }
        }

    }
    file.close();


    //LOAD MTL DATA

    pathlist.removeAt(pathlist.length()-1);
    QString mtl_path = pathlist.join("/") + "/" + mtllib;
    QString tex_path = pathlist.join("/") + "/";

    QFile mtlfile(mtl_path);
    if (!mtlfile.open (QIODevice::ReadOnly))
    {
        qDebug("        Model import: Error 2: Model material file could not be loaded...");
        return false;
    }
    QTextStream mtlstream ( &mtlfile );
    QString mtlline;


    QString current_mtl;
    QMap<QString,Vector3> mtl_ambient_c;          //Ka
    QMap<QString,Vector3> mtl_diffuse_c;          //Kd
    QMap<QString,Vector3> mtl_specular_c;         //Ks
    QMap<QString,float>     mtl_specular_ns;        //Ns
    QMap<QString,float>     mtl_transparency_d;     //d
    QMap<QString,float>     mtl_transparency_tr;    //Tr
    QMap<QString,Vector3> mtl_transparency_tf;    //Tf
    QMap<QString,QString>   mtl_ambient_map;        //map_Ka
    QMap<QString,QString>   mtl_diffuse_map;        //map_Kd
    QMap<QString,QString>   mtl_specular_map;       //map_Ks
    QMap<QString,QString>   mtl_bump_map;           //map_bump
    QMap<QString,int>       mtl_illumination;       //illum

    //stream
    while( !mtlstream.atEnd() ) {
        mtlline = mtlstream.readLine();
        QStringList list = mtlline.split(QRegExp("\\s+"),QString::SkipEmptyParts); //SkipEmptyParts
        if(!list.empty()){
            if(list.first() == "newmtl"){
                current_mtl = list.last();
            }
            else if(list.first() == "Ka"){
                mtl_ambient_c[current_mtl] = Vector3(list.value(1).toFloat(),
                                                       list.value(2).toFloat(),
                                                       list.value(3).toFloat());
            }
            else if(list.first() == "Kd"){
                mtl_diffuse_c[current_mtl] = Vector3(list.value(1).toFloat(),
                                                       list.value(2).toFloat(),
                                                       list.value(3).toFloat());
            }
            else if(list.first() == "Ks"){
                mtl_specular_c[current_mtl] = Vector3(list.value(1).toFloat(),
                                                        list.value(2).toFloat(),
                                                        list.value(3).toFloat());
            }
            else if(list.first() == "Ns"){
                mtl_specular_ns[current_mtl] = list.value(1).toFloat();

            }
            else if(list.first() == "d"){
                mtl_transparency_d[current_mtl] = list.value(1).toFloat();

            }
            else if(list.first() == "Tr"){
                mtl_transparency_tr[current_mtl] = list.value(1).toFloat();

            }
            else if(list.first() == "Tf"){
                mtl_transparency_tf[current_mtl] = Vector3(list.value(1).toFloat(),
                                                             list.value(2).toFloat(),
                                                             list.value(3).toFloat());
            }
            else if(list.first() == "map_Ka"){
                mtl_ambient_map[current_mtl] = list.value(1).split("\\",QString::SkipEmptyParts).last().toUtf8();
            }
            else if(list.first() == "map_Kd"){
                mtl_diffuse_map[current_mtl] = list.value(1).split("\\",QString::SkipEmptyParts).last().toUtf8();
            }
            else if(list.first() == "map_Ks"){
                mtl_specular_map[current_mtl] = list.value(1).split("\\",QString::SkipEmptyParts).last().toUtf8();
            }
            else if((list.first() == "map_bump") || (list.first() == "bump")){
                mtl_bump_map[current_mtl] = list.value(1).split("\\",QString::SkipEmptyParts).last().toUtf8();
            }
            else if(list.first() == "illum"){
                mtl_illumination[current_mtl] = list.value(1).toInt();
            }
        }
    }
    //stream end



    //CREATE MTLS (if needed...)

    //using diffues mat cause its the major map used (other maps are optional)...

    QList<QString> mtl_names = mtl_diffuse_c.keys();
    for(int i = 0; i < mtl_names.length(); i++){
        Material* mtl = new Material(mtl_names.value(i),tex_path);
        mtl->set_ambient_c(mtl_ambient_c[mtl_names.value(i)]);
        mtl->set_diffuse_c(mtl_diffuse_c[mtl_names.value(i)]);
        mtl->set_specular_c(mtl_specular_c[mtl_names.value(i)]);
        mtl->set_specular_ns(mtl_specular_ns[mtl_names.value(i)]);
        mtl->set_transparency_d(mtl_transparency_d[mtl_names.value(i)]);
        mtl->set_transparency_tr(mtl_transparency_tr[mtl_names.value(i)]);
        mtl->set_transparency_tf(mtl_transparency_tf[mtl_names.value(i)]);
        mtl->set_ambient_map_name(mtl_ambient_map[mtl_names.value(i)]);
        mtl->set_diffuse_map_name(mtl_diffuse_map[mtl_names.value(i)]);
        mtl->set_specular_map_name(mtl_specular_map[mtl_names.value(i)]);
        mtl->set_bump_map_name(mtl_bump_map[mtl_names.value(i)]);
        mtl->set_illumination(mtl_illumination[mtl_names.value(i)]);

        //init texture maps

        //as this function gets called in a thread we need to do this in main...
        /*
        mtl->load_ambient_map(tex_path + mtl_ambient_map[mtl_names.value(i)]);
        mtl->load_diffuse_map(tex_path + mtl_diffuse_map[mtl_names.value(i)]);
        mtl->load_specular_map(tex_path + mtl_specular_map[mtl_names.value(i)]);
        mtl->load_bump_map(tex_path + mtl_bump_map[mtl_names.value(i)]);
        */

        mtl->set_ambient_map_path(tex_path + mtl_ambient_map[mtl_names.value(i)]);
        mtl->set_diffuse_map_path(tex_path + mtl_diffuse_map[mtl_names.value(i)]);
        mtl->set_specular_map_path(tex_path + mtl_specular_map[mtl_names.value(i)]);
        mtl->set_bump_map_path(tex_path + mtl_bump_map[mtl_names.value(i)]);

        mtl->loadData();

        /*
        qDebug("        MTL ambient m:   " + mtl->get_ambient_map_name().toUtf8());
        qDebug("        MTL diffuse m:   " + mtl->get_diffuse_map_name().toUtf8());
        qDebug("        MTL specular m:  " + mtl->get_specular_map_name().toUtf8());
        qDebug("        MTL bump m:      " + mtl->get_bump_map_name().toUtf8());
        */

        mtln_mtl[mtl_names.value(i)] = mtl;
    }



    //CREATE MESHS (if needed...)
    //QMap<QString,QVector<QVector3D> > mesh_faces;
    //QMap<QString,QString> mesh_mtl;
    //QVector<QVector3D> model_vertices;
    //QVector<QVector3D> model_vertex_normals;
    //QVector<QVector3D> model_vertex_texture_coordinates;

    //using mesh_mtl to iterate ...
    QList<QString> mesh_names = mesh_mtl.keys();
    for(int i = 0; i < mesh_names.length(); i++){

        //min/max vertex pos on all 3 axis
        GLfloat v_min_x = 0.0f;
        GLfloat v_max_x = 0.0f;

        GLfloat v_min_y = 0.0f;
        GLfloat v_max_y = 0.0f;

        GLfloat v_min_z = 0.0f;
        GLfloat v_max_z = 0.0f;


        int triangle_count = mesh_faces[mesh_names.value(i)].size() / 3 / 3;
        //qDebug("        Triangles: %i",triangle_count);
        GLfloat* vertices = new GLfloat[mesh_faces[mesh_names.value(i)].size()];
        GLfloat* texcoords = new GLfloat[mesh_faces[mesh_names.value(i)].size()]; //should be wrong ... 108/3*2 is right ...
        GLfloat* normals = new GLfloat[mesh_faces[mesh_names.value(i)].size()];

        //qDebug("Mesh...");

        for(int j = 0; j < mesh_faces[mesh_names.value(i)].size(); j+=9){
            //  1 v/vt/vn   2 v/vt/vn   3 v/vt/vn

            //  v
            Vector3 vertex1 =  model_vertices.value(mesh_faces[mesh_names.value(i)].value(j)  -1);
            vertices[j]     = (GLfloat) vertex1.x();
            vertices[j+1]   = (GLfloat) vertex1.y();
            vertices[j+2]   = (GLfloat) vertex1.z();

            Vector3 vertex2 =  model_vertices.value(mesh_faces[mesh_names.value(i)].value(j+3)-1);
            vertices[3+j]   = (GLfloat) vertex2.x();
            vertices[3+j+1] = (GLfloat) vertex2.y();
            vertices[3+j+2] = (GLfloat) vertex2.z();

            Vector3 vertex3 =  model_vertices.value(mesh_faces[mesh_names.value(i)].value(j+6)-1);
            vertices[6+j]   = (GLfloat) vertex3.x();
            vertices[6+j+1] = (GLfloat) vertex3.y();
            vertices[6+j+2] = (GLfloat) vertex3.z();

            //get the min/max vertex pos on all 3 axis
            //x axis
            v_min_x = min_value(v_min_x,vertex1.x());
            v_min_x = min_value(v_min_x,vertex2.x());
            v_min_x = min_value(v_min_x,vertex3.x());

            v_max_x = max_value(v_max_x,vertex1.x());
            v_max_x = max_value(v_max_x,vertex2.x());
            v_max_x = max_value(v_max_x,vertex3.x());

            //y axis
            v_min_y = min_value(v_min_y,vertex1.y());
            v_min_y = min_value(v_min_y,vertex2.y());
            v_min_y = min_value(v_min_y,vertex3.y());

            v_max_y = max_value(v_max_y,vertex1.y());
            v_max_y = max_value(v_max_y,vertex2.y());
            v_max_y = max_value(v_max_y,vertex3.y());

            //z axis
            v_min_z = min_value(v_min_z,vertex1.z());
            v_min_z = min_value(v_min_z,vertex2.z());
            v_min_z = min_value(v_min_z,vertex3.z());

            v_max_z = max_value(v_max_z,vertex1.z());
            v_max_z = max_value(v_max_z,vertex2.z());
            v_max_z = max_value(v_max_z,vertex3.z());




            //  vt  (t value inverted)
            Vector3 texcoord1 = model_vertex_texture_coordinates.value(mesh_faces[mesh_names.value(i)].value(j+1)-1);
            texcoords[j]     = (GLfloat) texcoord1.x();
            texcoords[j+1]   = (GLfloat) -texcoord1.y();
            texcoords[j+2]   = (GLfloat) texcoord1.z();

            Vector3 texcoord2 = model_vertex_texture_coordinates.value(mesh_faces[mesh_names.value(i)].value(j+4)-1);
            texcoords[3+j]   = (GLfloat) texcoord2.x();
            texcoords[3+j+1] = (GLfloat) -texcoord2.y();
            texcoords[3+j+2] = (GLfloat) texcoord2.z();

            Vector3 texcoord3 = model_vertex_texture_coordinates.value(mesh_faces[mesh_names.value(i)].value(j+7)-1);
            texcoords[6+j]   = (GLfloat) texcoord3.x();
            texcoords[6+j+1] = (GLfloat) -texcoord3.y();
            texcoords[6+j+2] = (GLfloat) texcoord3.z();


            //  vn
            Vector3 normal1 = model_vertex_normals.value(mesh_faces[mesh_names.value(i)].value(j+2)-1);
            normal1.normalize();

            //normalize
            normals[j]     = (GLfloat) normal1.x();
            normals[j+1]   = (GLfloat) normal1.y();
            normals[j+2]   = (GLfloat) normal1.z();


            Vector3 normal2 = model_vertex_normals.value(mesh_faces[mesh_names.value(i)].value(j+5)-1);
            normal2.normalize();

            //normalize
            normals[3+j]   = (GLfloat) normal2.x();
            normals[3+j+1] = (GLfloat) normal2.y();
            normals[3+j+2] = (GLfloat) normal2.z();


            Vector3 normal3 = model_vertex_normals.value(mesh_faces[mesh_names.value(i)].value(j+8)-1);
            normal3.normalize();

            //normalize
            normals[6+j]   = (GLfloat) normal3.x();
            normals[6+j+1] = (GLfloat) normal3.y();
            normals[6+j+2] = (GLfloat) normal3.z();


        }



        Vector3 vert1(v_min_x, v_min_y, v_min_z);
        Vector3 vert2(v_max_x, v_max_y, v_max_z);

        Vector3 bounding_sphere_pos((v_min_x + v_max_x)/2.0f, (v_min_y + v_max_y)/2.0f, (v_min_z + v_max_z)/2.0f);
        double bounding_sphere_radius = vert1.distance(vert2) / 2.0f;


        //bounding_sphere_radius = 10.0;

        //Create Mesh and add it to the Mesh-list of the model.
        Mesh* mesh = new Mesh(mesh_names.value(i), triangle_count, vertices, texcoords, normals,
                              mtln_mtl.value(mesh_mtl.value(mesh_names.value(i))));

        mesh->setBoundingSpherePos(bounding_sphere_pos);
        mesh->setBoundingSphereRadius(bounding_sphere_radius);

        //meshs.append(mesh);
        mdl.add_mesh(mesh);

    }

    mdl.set_path(path);
    return true;
}
Exemplo n.º 3
0
Mesh*
Extrude::createMesh(){
	cout<<isConvex()<<" - True = "<<true<<endl;
	
	Mesh* m = new Mesh(isConvex()); //empty mesh
	vector<vec3> polygon_top(polygon);	//a copy of polygon
	
	
	//inserts polygon to mesh
	//so for polygon the index is k
	for(int j = 0; j< sides; j++){
		m->addVertex(polygon[j]);
	}
	//add y coordinate to polygon_top and inserts it to mesh
	//so for top polygon the index is k+sides
	for(int i = 0; i<sides; i++){
		polygon_top[i][1] = distance;
		m->addVertex(polygon_top[i]);
	}
	for(int k = 0; k<sides; k++){
		if(k<(sides-1)){
			//finds normal for face that is going to be inserted to the mesh
			vec4 vert1(polygon[k][0],polygon[k][1],polygon[k][2],1);
			vec4 vert2(polygon[k+1][0],polygon[k+1][1],polygon[k+1][2],1);
			vec4 vert3(polygon_top[k+1][0],polygon_top[k+1][1],polygon_top[k+1][2],1);
			vec4 n = getNormal(vert1,vert2,vert3);
			vec3 normal(n[0],n[1],n[2]);

			
			/*std::cout<<"--------\nNormal x = "<<normal[0]<<std::endl;
			std::cout<<"Normal y = "<<normal[1]<<std::endl;
			std::cout<<"Normal z = "<<normal[2]<<std::endl;*/
			m->addNormal(normal);
			//creates the faces, normal index is = k, always have 4 vertices for a face
			vec2 f1((double)k,(double)k);
			vec2 f2((double)k+1,(double)k);
			vec2 f3((double)sides+k+1,(double)k);
			vec2 f4((double)sides+k,(double)k);
			std::vector<vec2> face;
			face.push_back(f1);
			face.push_back(f2);
			face.push_back(f3);
			face.push_back(f4);
			m->addFace(face);
		}

		//case: need to do last one too
		if(k == (sides-1)){
			vec4 vert1L(polygon[k][0],polygon[k][1],polygon[k][2],1);
			vec4 vert2L(polygon[0][0],polygon[0][1],polygon[0][2],1);
			vec4 vert3L(polygon_top[0][0],polygon_top[0][1],polygon_top[0][2],1);
			vec4 nL = getNormal(vert1L,vert2L,vert3L);
			vec3 normalL(nL[0],nL[1],nL[2]);
			m->addNormal(normalL);
			//creates the faces, normal index is = k, always have 4 vertices for a face
			vec2 f1L((double)k,(double)k);
			vec2 f2L((double)0,(double)k);
			vec2 f3L((double)sides,(double)k);
			vec2 f4L((double)sides+k,(double)k);
			std::vector<vec2> faceL;
			faceL.push_back(f1L);
			faceL.push_back(f2L);
			faceL.push_back(f3L);
			faceL.push_back(f4L);
			m->addFace(faceL);
		}

	}

	//check if convex to cap or not
	if(isConvex()){
		std::vector<vec2> cap;
		std::vector<vec2> cap_top;
		//add the two normals at side and side+1
		vec4 vert1(polygon[0][0],polygon[0][1],polygon[0][2],1);
		vec4 vert2(polygon[1][0],polygon[1][1],polygon[1][2],1);
		vec4 vert3(polygon[2][0],polygon[2][1],polygon[2][2],1);
		vec4 n = getNormal(vert1,vert2,vert3);
		n = n*(-1);
		vec3 normal(n[0],n[1],n[2]);
		m->addNormal(normal);
		vec4 vert1_top(polygon_top[0][0],polygon_top[0][1],polygon_top[0][2],1);
		vec4 vert2_top(polygon_top[1][0],polygon_top[1][1],polygon_top[1][2],1);
		vec4 vert3_top(polygon_top[2][0],polygon_top[2][1],polygon_top[2][2],1);
		vec4 n_top = getNormal(vert1_top,vert2_top,vert3_top);
		vec3 normal_top(n_top[0],n_top[1],n_top[2]);
		m->addNormal(normal_top);
		//adds the faces, vertices for bottom cap = polygon(i)
		//for top cap = polygon_top(i+side)
		for(int i = 0; i<sides; i++){
			vec2 f((double)i,(double)sides);
			cap.push_back(f);
			vec2 f_top((double)i+sides,(double)sides+1);
			cap_top.push_back(f_top);
		}
		m->addFace(cap);
		m->addFace(cap_top);
	}
	
	return m;

}
Exemplo n.º 4
0
void BasicPrimitiveMeshHelper::SolidSphere(float radius, int slices, int stacks) {
  bool normals = true;
  float nsign = 1.0f;
  float drho = kPi / stacks;
  float dtheta = 2.0f * kPi / slices;

  int imin = 0;
  int imax = stacks;

  //triangle strip를 묶어서 vertex/index list로 재구성하기
  DrawCmdData<vec3> cmd;
  cmd.draw_mode = kDrawTriangles;
  vector<vec3> &vert_list = cmd.vertex_list;
  vector<unsigned short> &index_list = cmd.index_list;

  // draw intermediate stacks as quad strips
  for (int i = imin; i < imax; i++) {
    float rho = i * drho;

    //quad strip로 구성된 vertex 목록 구성하기
    vector<vec3> tmp_vert_list;
    float s = 0.0f;
    for (int j = 0; j <= slices; j++) {
      float theta = (j == slices) ? 0.0f : j * dtheta;
      float x = -sin(theta) * sin(rho);
      float y = cos(theta) * sin(rho);
      float z = nsign * cos(rho);

      vec3 vert1(x * radius, y * radius, z * radius);
      tmp_vert_list.push_back(vert1);

      x = -sin(theta) * sin(rho + drho);
      y = cos(theta) * sin(rho + drho);
      z = nsign * cos(rho + drho);

      vec3 vert2(x * radius, y * radius, z * radius);
      tmp_vert_list.push_back(vert2);
    }

    //DrawCmdData<vec3> cmd;
    //cmd.draw_mode = kDrawTriangleStrip;
    //quad strip -> triangle strip
    //cmd.vertex_list = vert_list;
    //this->cmd_list_->push_back(cmd);
    int base_vert_list_size = vert_list.size();
    std::copy(tmp_vert_list.begin(), tmp_vert_list.end(), back_inserter(vert_list));
    
    for(int i = 0 ; i < (int)tmp_vert_list.size()-2 ; ++i) {
      unsigned short idx1, idx2, idx3;
      if(i % 2 == 1) {
        idx1 = i;
        idx2 = i + 2;
        idx3 = i + 1;
      } else {
        idx1 = i;
        idx2 = i + 1;
        idx3 = i + 2;
      }
      index_list.push_back(base_vert_list_size + idx1);
      index_list.push_back(base_vert_list_size + idx2);
      index_list.push_back(base_vert_list_size + idx3);
    }
  }

  this->cmd_list_->push_back(cmd);
}
Exemplo n.º 5
0
//creates a Mesh with the appropriate values and returns its pointer
//calculates the rotation
Mesh*
Surfrev::createMesh() {
    Mesh* m = new Mesh(); //empty mesh
    float degrees = 360/slices;
    float angle = 0;
    vec3 Y(0,1,0);
    //inserts all points doing the rotation around the y-axis
    for(int i=0; i<slices; i++) {
        for(int j=0; j<points; j++) {
            vec3 v = rotation3D(Y,angle)*polyline[j];
            //cout<<"X = "<<v[0]<<" Y = "<<v[1] <<" Z = "<< v[2]<<endl;
            m->addVertex(v);
        }
        angle += degrees;
    }
    for(int i=0; i<(slices*points)-1; i++) {
        //finds normal for face that is going to be inserted to the mesh
        if(i<((slices*points)-(points+1))) {
            int mod = (1+i)%points;
            if(mod != 0) {
                /*cout<<"--------\nPoint: "<<i<<endl;
                cout<<"i+1: "<<i+1<<endl;
                cout<<"i+1+points: "<<i+1+points<<endl;
                cout<<"i+points: "<<i+points<<"\n"<<endl;
                cout<<(mod)<<" = Mod\n\n";*/
            }

            vec4 vert1(m->getVertex(i)[0],m->getVertex(i)[1],m->getVertex(i)[2],1);
            vec4 vert2(m->getVertex(i+1)[0],m->getVertex(i+1)[1],m->getVertex(i+1)[2],1);
            vec4 vert3(m->getVertex(i+points+1)[0],m->getVertex(i+points+1)[1],m->getVertex(i+points+1)[2],1);
            //check for final point that has  x = 0: triangle not square
            if(((i+2)%points) == 0 && m->getVertex(i+1)[0] == 0) {
                vert3[0] = m->getVertex(i+points)[0];
                vert3[1] = m->getVertex(i+points)[1];
                vert3[2] = m->getVertex(i+points)[2];
            }


            vec4 n = getNormal(vert1,vert2,vert3);
            vec3 normal(n[0],n[1],n[2]);

            if(mod != 0) {
                /*std::cout<<"Normal x = "<<normal[0]<<std::endl;
                std::cout<<"Normal y = "<<normal[1]<<std::endl;
                std::cout<<"Normal z = "<<normal[2]<<std::endl;*/
            }
            m->addNormal(normal);
            ////creates the faces, normal index is = i, always have 4 vertices for a face
            vec2 f1((double)i,(double)i);
            vec2 f2((double)i+1,(double)i);
            vec2 f3((double)points+i+1,(double)i);
            vec2 f4((double)points+i,(double)i);
            std::vector<vec2> face;
            face.push_back(f2);
            face.push_back(f1);
            face.push_back(f4);
            face.push_back(f3);


            if(mod != 0) {
                //cout<<"add face: "<<i<<endl;
                m->addFace(face);
            }
        }
        //case: do last face
        else {
            int mod = (1+i)%points;
            int k = (points*slices);
            /*cout<<"Else Point: "<<i<<endl;
            cout<<"i+1: "<<i+1<<endl;
            cout<<"i+1+points: "<<i+1+points-k<<endl;
            cout<<"i+points: "<<i+points-k<<"\n"<<endl;
            cout<<(mod)<<" = Mod\n\n";*/

            vec4 vert1L(m->getVertex(i)[0],m->getVertex(i)[1],m->getVertex(i)[2],1);
            vec4 vert2L(m->getVertex(i+1)[0],m->getVertex(i+1)[1],m->getVertex(i+1)[2],1);
            vec4 vert3L(m->getVertex(i+points+1-k)[0],m->getVertex(i+points+1-k)[1],m->getVertex(i+points+1-k)[2],1);
            if(((i+2)%points) == 0 && m->getVertex(i+1)[0] == 0) {
                vert3L[0] = m->getVertex(i+points-k)[0];
                vert3L[1] = m->getVertex(i+points-k)[1];
                vert3L[2] = m->getVertex(i+points-k)[2];
            }
            vec4 nL = getNormal(vert1L,vert2L,vert3L);
            vec3 normalL(nL[0],nL[1],nL[2]);

            /*std::cout<<"--------\nNormal x = "<<normal[0]<<std::endl;
            std::cout<<"Normal y = "<<normal[1]<<std::endl;
            std::cout<<"Normal z = "<<normal[2]<<std::endl;*/
            m->addNormal(normalL);
            //creates the faces, normal index is = i, always have 4 vertices for a face
            vec2 f1L((double)i,(double)i);
            vec2 f2L((double)i+1,(double)i);
            vec2 f3L((double)points+i+1-k,(double)i);
            vec2 f4L((double)points+i-k,(double)i);
            std::vector<vec2> faceL;
            faceL.push_back(f2L);
            faceL.push_back(f1L);
            faceL.push_back(f4L);
            faceL.push_back(f3L);


            if(mod != 0) {
                //cout<<"add face: "<<i<<endl;
                m->addFace(faceL);
            }
        }
    }
    //check if there is an opening at the top or bottom to cap or not
    if(polyline[0][0] != 0) {	//cap the bottom
        /*cout<<"X1 = "<<m->getVertex(0)[0]<<"  Y1 = "<<m->getVertex(0)[1]<<"  Z1 = "<<m->getVertex(points-1)[2]<<endl;
        cout<<"X2 = "<<m->getVertex((points))[0]<<"  Y2 = "<<m->getVertex((points))[1]<<"  Z2 = "<<m->getVertex((points))[2]<<endl;
        cout<<"X3 = "<<m->getVertex((points*2))[0]<<"  Y3 = "<<m->getVertex((points*2))[1]<<"  Z3 = "<<m->getVertex((points*2))[2]<<"\n"<<endl;*/

        vec4 vert1(m->getVertex(0)[0],m->getVertex(0)[1],m->getVertex(0)[2],1);
        vec4 vert2(m->getVertex(points)[0],m->getVertex(points)[1],m->getVertex(points)[2],1);
        vec4 vert3(m->getVertex(points*2)[0],m->getVertex(points*2)[1],m->getVertex(points*2)[2],1);
        vec4 n = getNormal(vert1,vert2,vert3);
        vec3 normal(n[0],n[1],n[2]);

        m->addNormal(normal);
        std::vector<vec2> face;
        for(int k=0; k<slices; k++) {
            vec2 f((double)points*k,(double)m->lastNorm());
            face.push_back(f);
        }
        m->addFace(face);
    }

    if(polyline[points-1][0] != 0) {	//cap the top
        /*cout<<"Top\nX1 = "<<m->getVertex(points-1)[0]<<"  Y1 = "<<m->getVertex(points-1)[1]<<"  Z1 = "<<m->getVertex(points-1)[2]<<endl;
        cout<<"X2 = "<<m->getVertex((points*2)-1)[0]<<"  Y2 = "<<m->getVertex((points*2)-1)[1]<<"  Z2 = "<<m->getVertex((points*2)-1)[2]<<endl;
        cout<<"X3 = "<<m->getVertex((points*3)-1)[0]<<"  Y3 = "<<m->getVertex((points*3)-1)[1]<<"  Z3 = "<<m->getVertex((points*3)-1)[2]<<"\n"<<endl;*/

        vec4 vert1(m->getVertex(points-1)[0],m->getVertex(points-1)[1],m->getVertex(points-1)[2],1);
        vec4 vert2(m->getVertex((points*2)-1)[0],m->getVertex((points*2)-1)[1],m->getVertex((points*2)-1)[2],1);
        vec4 vert3(m->getVertex((points*3)-1)[0],m->getVertex((points*3)-1)[1],m->getVertex((points*3)-1)[2],1);
        vec4 n = getNormal(vert1,vert2,vert3);
        n = n * (-1);
        vec3 normal(n[0],n[1],n[2]);

        m->addNormal(normal);
        std::vector<vec2> face;
        for(int k=1; k<slices+1; k++) {
            vec2 f((double)(points*k)-1,(double)m->lastNorm());
            face.push_back(f);
        }
        m->addFace(face);
    }


    return m;

}
Exemplo n.º 6
0
void ImplicitSampler::init()  {
	surface_area = 0;
	pi_over_2 = 0.5*acos(-1);
	vector<TriIndex> all_tris;
	BasicTriMesh* mc_mesh = surface->isosurface(64,256,0.01);
	ll_bound = Vector3(1e10,1e10,1e10);
	ur_bound = Vector3(-1e10,-1e10,-1e10);

	for(int t = 0; t < mc_mesh->n_faces(); t++)  {
		BasicTriMesh::FaceVertexIter fv_it = mc_mesh->fv_iter(OpenMesh::FaceHandle(t));
		BasicTriMesh::VertexHandle v0 = fv_it.handle();
		BasicTriMesh::VertexHandle v1 = (++fv_it).handle();
		BasicTriMesh::VertexHandle v2 = (++fv_it).handle();

		BasicTriMesh::Point p0 = mc_mesh->point(v0), p1 = mc_mesh->point(v1), p2 = mc_mesh->point(v2);
		BasicTriMesh::Point raw_normal = (p1-p0) % (p2-p0);
		double tri_area = 0.5*raw_normal.length();

		Vector3 vert0(p0[0],p0[1],p0[2]);
		Vector3 vert1(p1[0],p1[1],p1[2]);
		Vector3 vert2(p2[0],p2[1],p2[2]);
		sampler_tris.push_back(SamplerTri(vert0,vert1,vert2));
		ll_bound.expand_min_bound(vert0); ur_bound.expand_max_bound(vert0);
		ll_bound.expand_min_bound(vert1); ur_bound.expand_max_bound(vert1);
		ll_bound.expand_min_bound(vert2); ur_bound.expand_max_bound(vert2);

		if(p0 == p1 || p0 == p2 || p1 == p2 || tri_area < 1e-9)
			continue;
		all_tris.push_back(TriIndex(tri_area, t));
		surface_area += tri_area;
	}
	std::sort(all_tris.begin(),all_tris.end());
	global_radius = 2.5*sqrt(surface_area / ((double)num_points));

	vector<TriIndex> cum_tris;
	for(unsigned t = 0; t < all_tris.size(); t++)  {
		TriIndex next_tri = all_tris[t];
		if(t == 0)
			cum_tris.push_back(next_tri);
		else  {
			TriIndex prev_tri = cum_tris[t-1];
			double cum_area = next_tri.area + prev_tri.area;
			cum_tris.push_back(TriIndex(cum_area, next_tri.tri));
		}
	}

	time_t cur_time;
	time(&cur_time);
	srand(cur_time);
	for(int i = 0; i < 20; i++)
		rand();

	sampled_pts = new GridPoint[num_points];
	double total_area = cum_tris[cum_tris.size()-1].area;
	for(int s = 0; s < num_points; s++)  {
		double rand_unit = (double)rand() / (double)RAND_MAX;
		double rand_area = rand_unit*total_area;
		int rand_ind = this->tri_search(&cum_tris, rand_area, 0, cum_tris.size()-1);
		TriIndex rand_tri_index = cum_tris[rand_ind];

		SamplerTri rand_tri = sampler_tris[rand_tri_index.tri];
		double r1 = (double)rand() / (double)RAND_MAX;
		double r2 = (double)rand() / (double)RAND_MAX;
		double r1_sqrt = sqrt(r1);
		Vector3 rand_pt = rand_tri.v1*(1.0-r1_sqrt) + rand_tri.v2*(r1_sqrt*(1.0-r2)) + rand_tri.v3*(r1_sqrt*r2);

		sampled_pts[s] = GridPoint(rand_pt, s);
	}

	grid_res_x = (ur_bound.x-ll_bound.x)/global_radius;
	grid_res_y = (ur_bound.y-ll_bound.y)/global_radius;
	grid_res_z = (ur_bound.z-ll_bound.z)/global_radius;
	grid_res_x = grid_res_x > 300 ? 300 : grid_res_x;
	grid_res_y = grid_res_y > 300 ? 300 : grid_res_y;
	grid_res_z = grid_res_z > 300 ? 300 : grid_res_z;
	cout << "grid res: " << grid_res_x << " : " << grid_res_y << " : " << grid_res_z << endl;

	delete mc_mesh;
}
Exemplo n.º 7
0
int main(int argc,char** argv)
{

	setCameraDistance(30.f);

#define TRISIZE 10.f
#ifdef DEBUG_MESH
	SimdVector3 vert0(-TRISIZE ,0,TRISIZE );
	SimdVector3 vert1(TRISIZE ,10,TRISIZE );
	SimdVector3 vert2(TRISIZE ,0,-TRISIZE );
	meshData.AddTriangle(vert0,vert1,vert2);
	SimdVector3 vert3(-TRISIZE ,0,TRISIZE );
	SimdVector3 vert4(TRISIZE ,0,-TRISIZE );
	SimdVector3 vert5(-TRISIZE ,0,-TRISIZE );
	meshData.AddTriangle(vert3,vert4,vert5);
#else
#ifdef ODE_MESH
	SimdVector3 Size = SimdVector3(15.f,15.f,12.5f);
	
  gVertices[0][0] = -Size[0];
  gVertices[0][1] = Size[2];
  gVertices[0][2] = -Size[1];
  
  gVertices[1][0] = Size[0];
  gVertices[1][1] = Size[2];
  gVertices[1][2] = -Size[1];
  
  gVertices[2][0] = Size[0];
  gVertices[2][1] = Size[2];
  gVertices[2][2] = Size[1];  

  gVertices[3][0] = -Size[0];
  gVertices[3][1] = Size[2];
  gVertices[3][2] = Size[1];
  
  gVertices[4][0] = 0;
  gVertices[4][1] = 0;
  gVertices[4][2] = 0;
  
  gIndices[0] = 0;
  gIndices[1] = 1;
  gIndices[2] = 4;
  
  gIndices[3] = 1;
  gIndices[4] = 2;
  gIndices[5] = 4;
  
  gIndices[6] = 2;
  gIndices[7] = 3;
  gIndices[8] = 4;
  
  gIndices[9] = 3;
  gIndices[10] = 0;
  gIndices[11] = 4;

  int vertStride = sizeof(SimdVector3);
  int indexStride = 3*sizeof(int);

	TriangleIndexVertexArray* indexVertexArrays = new TriangleIndexVertexArray(NUM_TRIANGLES,
		gIndices,
		indexStride,
		NUM_VERTICES,(float*) &gVertices[0].x(),vertStride);

	//shapePtr[4] = new TriangleMeshShape(indexVertexArrays);
	shapePtr[4] = new BvhTriangleMeshShape(indexVertexArrays);
#else

	int vertStride = sizeof(SimdVector3);
	int indexStride = 3*sizeof(int);

	const int NUM_VERTS_X = 50;
	const int NUM_VERTS_Y = 50;
	const int totalVerts = NUM_VERTS_X*NUM_VERTS_Y;
	
	const int totalTriangles = 2*(NUM_VERTS_X-1)*(NUM_VERTS_Y-1);

	SimdVector3*	gVertices = new SimdVector3[totalVerts];
	int*	gIndices = new int[totalTriangles*3];

	int i;

	for ( i=0;i<NUM_VERTS_X;i++)
	{
		for (int j=0;j<NUM_VERTS_Y;j++)
		{
			gVertices[i+j*NUM_VERTS_X].setValue((i-NUM_VERTS_X*0.5f)*10.f,2.f*sinf((float)i)*cosf((float)j),(j-NUM_VERTS_Y*0.5f)*10.f);
		}
	}

	int index=0;
	for ( i=0;i<NUM_VERTS_X-1;i++)
	{
		for (int j=0;j<NUM_VERTS_Y-1;j++)
		{
			gIndices[index++] = j*NUM_VERTS_X+i;
			gIndices[index++] = j*NUM_VERTS_X+i+1;
			gIndices[index++] = (j+1)*NUM_VERTS_X+i+1;

			gIndices[index++] = j*NUM_VERTS_X+i;
			gIndices[index++] = (j+1)*NUM_VERTS_X+i+1;
			gIndices[index++] = (j+1)*NUM_VERTS_X+i;
		}
	}
	
	TriangleIndexVertexArray* indexVertexArrays = new TriangleIndexVertexArray(totalTriangles,
		gIndices,
		indexStride,
		totalVerts,(float*) &gVertices[0].x(),vertStride);

	//shapePtr[4] = new TriangleMeshShape(indexVertexArrays);
	shapePtr[4] = new BvhTriangleMeshShape(indexVertexArrays);
#endif

	

#endif//DEBUG_MESH


//	GLDebugDrawer	debugDrawer;

	//ConstraintSolver* solver = new SimpleConstraintSolver;
	ConstraintSolver* solver = new OdeConstraintSolver;

	CollisionDispatcher* dispatcher = new	CollisionDispatcher();
		
	BroadphaseInterface* broadphase = new SimpleBroadphase();


	physicsEnvironmentPtr = new CcdPhysicsEnvironment(dispatcher,broadphase);
	

	physicsEnvironmentPtr->setGravity(-1,-10,1);
	PHY_ShapeProps shapeProps;
	
	shapeProps.m_do_anisotropic = false;
	shapeProps.m_do_fh = false;
	shapeProps.m_do_rot_fh = false;
	shapeProps.m_friction_scaling[0] = 1.;
	shapeProps.m_friction_scaling[1] = 1.;
	shapeProps.m_friction_scaling[2] = 1.;

	shapeProps.m_inertia = 1.f;
	shapeProps.m_lin_drag = 0.95999998f;
	shapeProps.m_ang_drag = 0.89999998f;
	shapeProps.m_mass = 1.0f;
	
	PHY_MaterialProps materialProps;
	materialProps.m_friction = 0.f;// 50.5f;
	materialProps.m_restitution = 0.1f;

	CcdConstructionInfo ccdObjectCi;
	ccdObjectCi.m_friction = 0.f;//50.5f;

	ccdObjectCi.m_linearDamping = shapeProps.m_lin_drag;
	ccdObjectCi.m_angularDamping = shapeProps.m_ang_drag;

	SimdTransform tr;
	tr.setIdentity();

	
	for (i=0;i<numObjects;i++)
	{
		if (i>0)
			shapeIndex[i] = 1;//2 = tetrahedron
		else
			shapeIndex[i] = 4;
	}
	for (i=0;i<numObjects;i++)
	{
		shapeProps.m_shape = shapePtr[shapeIndex[i]];

		bool isDyna = i>0;
		
		if (!i)
		{
			//SimdQuaternion orn(0,0,0.1*SIMD_HALF_PI);
			//ms[i].setWorldOrientation(orn.x(),orn.y(),orn.z(),orn[3]);
			//ms[i].setWorldPosition(0,-10,0);
		} else
		{
				ms[i].setWorldPosition(10,i*15-10,0);
		}
		
//either create a few stacks, to show several islands, or create 1 large stack, showing stability
		//ms[i].setWorldPosition((i*5) % 30,i*15-10,0);
		

		ccdObjectCi.m_MotionState = &ms[i];
		ccdObjectCi.m_gravity = SimdVector3(0,0,0);
		ccdObjectCi.m_localInertiaTensor =SimdVector3(0,0,0);
		if (!isDyna)
		{
			shapeProps.m_mass = 0.f;
			ccdObjectCi.m_mass = shapeProps.m_mass;
		}
		else
		{
			shapeProps.m_mass = 1.f;
			ccdObjectCi.m_mass = shapeProps.m_mass;
		}

		
		SimdVector3 localInertia;
		if (shapeProps.m_mass>0.f)
		{
			shapePtr[shapeIndex[i]]->CalculateLocalInertia(shapeProps.m_mass,localInertia);
		} else
		{
			localInertia.setValue(0.f,0.f,0.f);

		}
		ccdObjectCi.m_localInertiaTensor = localInertia;

		ccdObjectCi.m_collisionShape = shapePtr[shapeIndex[i]];


		physObjects[i]= new CcdPhysicsController( ccdObjectCi);
		physicsEnvironmentPtr->addCcdPhysicsController( physObjects[i]);

/*		if (i==0)
		{
			physObjects[i]->SetAngularVelocity(0,0,-2,true);
			physObjects[i]->GetRigidBody()->setDamping(0,0);
		}
*/
		//for the line that represents the AABB extents
//	physicsEnvironmentPtr->setDebugDrawer(&debugDrawer);

		
	}
	return glutmain(argc, argv,640,480,"Static Concave Mesh Demo");
}
Exemplo n.º 8
0
int b3GpuNarrowPhase::registerConcaveMeshShape(b3AlignedObjectArray<b3Vector3>* vertices, b3AlignedObjectArray<int>* indices,b3Collidable& col, const float* scaling1)
{


	b3Vector3 scaling(scaling1[0],scaling1[1],scaling1[2]);

	m_data->m_convexData->resize(m_data->m_numAcceleratedShapes+1);
	m_data->m_convexPolyhedra.resize(m_data->m_numAcceleratedShapes+1);
	
    
	b3ConvexPolyhedronCL& convex = m_data->m_convexPolyhedra.at(m_data->m_convexPolyhedra.size()-1);
	convex.mC = b3Vector3(0,0,0);
	convex.mE = b3Vector3(0,0,0);
	convex.m_extents= b3Vector3(0,0,0);
	convex.m_localCenter = b3Vector3(0,0,0);
	convex.m_radius = 0.f;
	
	convex.m_numUniqueEdges = 0;
	int edgeOffset = m_data->m_uniqueEdges.size();
	convex.m_uniqueEdgesOffset = edgeOffset;
	
	int faceOffset = m_data->m_convexFaces.size();
	convex.m_faceOffset = faceOffset;
	
	convex.m_numFaces = indices->size()/3;
	m_data->m_convexFaces.resize(faceOffset+convex.m_numFaces);
	m_data->m_convexIndices.reserve(convex.m_numFaces*3);
	for (int i=0;i<convex.m_numFaces;i++)
	{
		if (i%256==0)
		{
			//printf("i=%d out of %d", i,convex.m_numFaces);
		}
		b3Vector3 vert0(vertices->at(indices->at(i*3))*scaling);
		b3Vector3 vert1(vertices->at(indices->at(i*3+1))*scaling);
		b3Vector3 vert2(vertices->at(indices->at(i*3+2))*scaling);

		b3Vector3 normal = ((vert1-vert0).cross(vert2-vert0)).normalize();
		b3Scalar c = -(normal.dot(vert0));

		m_data->m_convexFaces[convex.m_faceOffset+i].m_plane[0] = normal.getX();
		m_data->m_convexFaces[convex.m_faceOffset+i].m_plane[1] = normal.getY();
		m_data->m_convexFaces[convex.m_faceOffset+i].m_plane[2] = normal.getZ();
		m_data->m_convexFaces[convex.m_faceOffset+i].m_plane[3] = c;
		int indexOffset = m_data->m_convexIndices.size();
		int numIndices = 3;
		m_data->m_convexFaces[convex.m_faceOffset+i].m_numIndices = numIndices;
		m_data->m_convexFaces[convex.m_faceOffset+i].m_indexOffset = indexOffset;
		m_data->m_convexIndices.resize(indexOffset+numIndices);
		for (int p=0;p<numIndices;p++)
		{
			int vi = indices->at(i*3+p);
			m_data->m_convexIndices[indexOffset+p] = vi;//convexPtr->m_faces[i].m_indices[p];
		}
	}
    
	convex.m_numVertices = vertices->size();
	int vertexOffset = m_data->m_convexVertices.size();
	convex.m_vertexOffset =vertexOffset;
	m_data->m_convexVertices.resize(vertexOffset+convex.m_numVertices);
	for (int i=0;i<vertices->size();i++)
	{
		m_data->m_convexVertices[vertexOffset+i] = vertices->at(i)*scaling;
	}

	(*m_data->m_convexData)[m_data->m_numAcceleratedShapes] = 0;
	
  
	return m_data->m_numAcceleratedShapes++;
}
Exemplo n.º 9
0
void mesh::calculateTangents() {
	std::vector<float> tans(3*vertCount, 0);
	std::vector<float> bitans(3*vertCount, 0);
	tangents.resize(4 * vertCount);

	//calculate tentative tangents and bitangents for each triangle
	for (int i = 0; i < triCount; i++) {
		//find the vertices of the current triangle, and their UV coords
		int vi1 = triangles[3*i];
		int vi2 = triangles[3*i + 1];
		int vi3 = triangles[3*i + 2];

		glm::vec3 vert0(vertices[3*vi1], vertices[3*vi1 + 1], vertices[3*vi1 + 2]);
		glm::vec3 vert1(vertices[3*vi2], vertices[3*vi2 + 1], vertices[3*vi2 + 2]);
		glm::vec3 vert2(vertices[3*vi3], vertices[3*vi3 + 1], vertices[3*vi3 + 2]);

		glm::vec2 uv0(texCoords[2*vi1], texCoords[2*vi1 + 1]);
		glm::vec2 uv1(texCoords[2*vi2], texCoords[2*vi2 + 1]);
		glm::vec2 uv2(texCoords[2*vi3], texCoords[2*vi3 + 1]);

		//differences in position and UV coords
		glm::vec3 dPos1 = vert1 - vert0;
		glm::vec3 dPos2 = vert2 - vert0;

		glm::vec2 dUV1 = uv1 - uv0;
		glm::vec2 dUV2 = uv2 - uv0;

		//calculate and store the tangent and bitangent
		float coeff = 1.0f / (dUV1.x * dUV2.y - dUV1.y * dUV2.x);

		glm::vec3 tan = dPos1 * dUV2.y - dPos2 * dUV1.y;
		glm::vec3 bitan = dPos2 * dUV1.x  - dPos1 * dUV2.x;
		tan *= coeff;
		bitan *= coeff;

		tans[3*vi1] += tan.x;
		tans[3*vi1 + 1] += tan.y;
		tans[3*vi1 + 2] += tan.z;

		tans[3*vi2] += tan.x;
		tans[3*vi2 + 1] += tan.y;
		tans[3*vi2 + 2] += tan.z;

		tans[3*vi3] += tan.x;
		tans[3*vi3 + 1] += tan.y;
		tans[3*vi3 + 2] += tan.z;

		bitans[3*vi1] += bitan.x;
		bitans[3*vi1 + 1] += bitan.y;
		bitans[3*vi1 + 2] += bitan.z;

		bitans[3*vi2] += bitan.x;
		bitans[3*vi2 + 1] += bitan.y;
		bitans[3*vi2 + 2] += bitan.z;

		bitans[3*vi3] += bitan.x;
		bitans[3*vi3 + 1] += bitan.y;
		bitans[3*vi3 + 2] += bitan.z;
	}

	//find the final tangent (and bitangent) for each vertex
	for (int j = 0; j < vertCount; j++) {
		glm::vec3 normal (normals[3*j], normals[3*j + 1], normals[3*j + 2]);
		glm::vec3 tangent (tans[3*j], tans[3*j + 1], tans[3*j + 2]);
		glm::vec3 bitangent (bitans[3*j], bitans[3*j + 1], bitans[3*j + 2]);

		glm::normalize(tangent);
		glm::normalize(bitangent);

		//orthagonalize
		glm::vec3 tangent_orth(normal);
		tangent_orth *= glm::dot(normal, tangent);
		tangent_orth = tangent - tangent_orth;
		glm::normalize(tangent_orth);

		//compute handedness
		float handedness = 1.0f;
		glm::vec3 nCrossT = glm::cross(normal, tangent_orth);
		
		if(glm::dot(nCrossT, bitangent) > 0) {
			handedness = 1.0f;
		} else {
			handedness = -1.0f;
		}

		//store the orthagonalized tangent and handedness
		tangents[4*j] = tangent_orth.x;
		tangents[4*j + 1] = tangent_orth.y;
		tangents[4*j + 2] = tangent_orth.z;
		tangents[4*j + 3] = handedness;
	}

}