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); }
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; }
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; }
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); }
//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; }
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; }
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"); }
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++; }
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; } }