model.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #include <iostream>
  2. #include <fstream>
  3. #include <sstream>
  4. #include "model.h"
  5. Model::Model(const char *filename) : verts_(), faces_(), norms_(), uv_(), diffusemap_(), normalmap_(), specularmap_() {
  6. std::ifstream in;
  7. in.open (filename, std::ifstream::in);
  8. if (in.fail()) return;
  9. std::string line;
  10. while (!in.eof()) {
  11. std::getline(in, line);
  12. std::istringstream iss(line.c_str());
  13. char trash;
  14. if (!line.compare(0, 2, "v ")) {
  15. iss >> trash;
  16. Vec3f v;
  17. for (int i=0;i<3;i++) iss >> v[i];
  18. verts_.push_back(v);
  19. } else if (!line.compare(0, 3, "vn ")) {
  20. iss >> trash >> trash;
  21. Vec3f n;
  22. for (int i=0;i<3;i++) iss >> n[i];
  23. norms_.push_back(n);
  24. } else if (!line.compare(0, 3, "vt ")) {
  25. iss >> trash >> trash;
  26. Vec2f uv;
  27. for (int i=0;i<2;i++) iss >> uv[i];
  28. uv_.push_back(uv);
  29. } else if (!line.compare(0, 2, "f ")) {
  30. std::vector<Vec3i> f;
  31. Vec3i tmp;
  32. iss >> trash;
  33. while (iss >> tmp[0] >> trash >> tmp[1] >> trash >> tmp[2]) {
  34. for (int i=0; i<3; i++) tmp[i]--; // in wavefront obj all indices start at 1, not zero
  35. f.push_back(tmp);
  36. }
  37. faces_.push_back(f);
  38. }
  39. }
  40. std::cerr << "# v# " << verts_.size() << " f# " << faces_.size() << " vt# " << uv_.size() << " vn# " << norms_.size() << std::endl;
  41. load_texture(filename, "_diffuse.tga", diffusemap_);
  42. load_texture(filename, "_nm_tangent.tga", normalmap_);
  43. load_texture(filename, "_spec.tga", specularmap_);
  44. }
  45. Model::Model():verts_(), faces_(), norms_(), uv_(), diffusemap_(), normalmap_(), specularmap_()
  46. {
  47. }
  48. void Model::setDiffuseTextureFromData(unsigned char* textureImage,int textureWidth,int textureHeight)
  49. {
  50. diffusemap_ = TGAImage(textureWidth, textureHeight, TGAImage::RGB);
  51. for (int i=0;i<textureWidth;i++)
  52. {
  53. for (int j=0;j<textureHeight;j++)
  54. {
  55. TGAColor color;
  56. color.bgra[0] = textureImage[(i+j*textureWidth)*3+0];
  57. color.bgra[1] = textureImage[(i+j*textureWidth)*3+1];
  58. color.bgra[2] = textureImage[(i+j*textureWidth)*3+2];
  59. color.bgra[3] = 255;
  60. color.bytespp = 3;
  61. diffusemap_.set(i,j,color);
  62. }
  63. }
  64. diffusemap_.flip_vertically();
  65. }
  66. void Model::loadDiffuseTexture(const char* relativeFileName)
  67. {
  68. diffusemap_.read_tga_file(relativeFileName);
  69. }
  70. void Model::reserveMemory(int numVertices, int numIndices)
  71. {
  72. verts_.reserve(numVertices);
  73. norms_.reserve(numVertices);
  74. uv_.reserve(numVertices);
  75. faces_.reserve(numIndices);
  76. }
  77. void Model::addVertex(float x,float y,float z, float normalX, float normalY, float normalZ, float u, float v)
  78. {
  79. verts_.push_back(Vec3f(x,y,z));
  80. norms_.push_back(Vec3f(normalX,normalY,normalZ));
  81. uv_.push_back(Vec2f(u,v));
  82. }
  83. void Model::addTriangle(int vertexposIndex0, int normalIndex0, int uvIndex0,
  84. int vertexposIndex1, int normalIndex1, int uvIndex1,
  85. int vertexposIndex2, int normalIndex2, int uvIndex2)
  86. {
  87. std::vector<Vec3i> f;
  88. f.push_back(Vec3i(vertexposIndex0, normalIndex0, uvIndex0));
  89. f.push_back(Vec3i(vertexposIndex1, normalIndex1, uvIndex1));
  90. f.push_back(Vec3i(vertexposIndex2, normalIndex2, uvIndex2));
  91. faces_.push_back(f);
  92. }
  93. Model::~Model() {}
  94. int Model::nverts() {
  95. return (int)verts_.size();
  96. }
  97. int Model::nfaces() {
  98. return (int)faces_.size();
  99. }
  100. std::vector<int> Model::face(int idx) {
  101. std::vector<int> face;
  102. for (int i=0; i<(int)faces_[idx].size(); i++) face.push_back(faces_[idx][i][0]);
  103. return face;
  104. }
  105. Vec3f Model::vert(int i) {
  106. return verts_[i];
  107. }
  108. Vec3f Model::vert(int iface, int nthvert) {
  109. return verts_[faces_[iface][nthvert][0]];
  110. }
  111. void Model::load_texture(std::string filename, const char *suffix, TGAImage &img) {
  112. std::string texfile(filename);
  113. size_t dot = texfile.find_last_of(".");
  114. if (dot!=std::string::npos) {
  115. texfile = texfile.substr(0,dot) + std::string(suffix);
  116. std::cerr << "texture file " << texfile << " loading " << (img.read_tga_file(texfile.c_str()) ? "ok" : "failed") << std::endl;
  117. img.flip_vertically();
  118. }
  119. }
  120. TGAColor Model::diffuse(Vec2f uvf) {
  121. if (diffusemap_.get_width() && diffusemap_.get_height())
  122. {
  123. Vec2i uv(uvf[0]*diffusemap_.get_width(), uvf[1]*diffusemap_.get_height());
  124. return diffusemap_.get(uv[0], uv[1]);
  125. }
  126. return TGAColor(255,255,255,255);
  127. }
  128. Vec3f Model::normal(Vec2f uvf) {
  129. Vec2i uv(uvf[0]*normalmap_.get_width(), uvf[1]*normalmap_.get_height());
  130. TGAColor c = normalmap_.get(uv[0], uv[1]);
  131. Vec3f res;
  132. for (int i=0; i<3; i++)
  133. res[2-i] = (float)c[i]/255.f*2.f - 1.f;
  134. return res;
  135. }
  136. Vec2f Model::uv(int iface, int nthvert) {
  137. return uv_[faces_[iface][nthvert][1]];
  138. }
  139. float Model::specular(Vec2f uvf) {
  140. Vec2i uv(uvf[0]*specularmap_.get_width(), uvf[1]*specularmap_.get_height());
  141. return specularmap_.get(uv[0], uv[1])[0]/1.f;
  142. }
  143. Vec3f Model::normal(int iface, int nthvert) {
  144. int idx = faces_[iface][nthvert][2];
  145. return norms_[idx].normalize();
  146. }