From ffe2fe1d921be5180f41765cef1ea7e221e939b4 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 20 Apr 2011 15:08:42 -0400 Subject: [PATCH] load materials into Material objects --- WFObj.cc | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- WFObj.h | 20 +++++++++++++ 2 files changed, 104 insertions(+), 3 deletions(-) diff --git a/WFObj.cc b/WFObj.cc index 8f163f1..1c43d3b 100644 --- a/WFObj.cc +++ b/WFObj.cc @@ -122,6 +122,7 @@ void WFObj::clear() for (int i = 0; i < sizeof(m_vertices)/sizeof(m_vertices[0]); i++) m_vertices[i].clear(); m_faces.clear(); + m_materials.clear(); m_valid = false; m_path = ""; m_current_material_name = ""; @@ -192,8 +193,7 @@ string WFObj::getLine(const Buffer & buff, size_t idx, size_t *update_idx) void WFObj::processInputLine(const std::string & input) { - string line = input; - vector tokens = tokenize(line); + vector tokens = tokenize(input); if (tokens.size() == 0) return; @@ -329,7 +329,88 @@ WFObj::VertexRef WFObj::readVertexRef(const std::string ref) void WFObj::loadMaterial(const std::string & name) { - /* TODO */ + Buffer buff; + if (!m_loadfile(name.c_str(), &buff)) + { + cerr << "WFObj: error: couldn't open material file '" << name << "'" + << endl; + return; + } + + size_t idx = 0; + string mat_name; + while (idx < buff.length) + { + string input = trimString(getLine(buff, idx, &idx)); + if (input.size() == 0 || input[0] == '#') + continue; + vector tokens = tokenize(input); + if (tokens.size() < 2) + continue; + if (tokens[0] == "newmtl") + { + mat_name = tokens[1]; + m_materials[mat_name] = Material(); + } + else if (mat_name == "") + { + cerr << "WFObj: error: material directive" + " with no 'newmtl' statement" << endl; + } + else if (tokens[0] == "Ns") + { + m_materials[mat_name].shininess = atof(tokens[1].c_str()); + m_materials[mat_name].flags |= Material::MAT_SHININESS; + } + else if (tokens[0] == "Ka") + { + if (tokens.size() >= 4) + { + for (int i = 0; i < 3; i++) + m_materials[mat_name].ambient[i] = + atof(tokens[i + 1].c_str()); + m_materials[mat_name].flags |= Material::MAT_AMBIENT; + } + else + cerr << "WFObj: error: 'Ka' material directive requires" + " 3 parameters" << endl; + } + else if (tokens[0] == "Kd") + { + if (tokens.size() >= 4) + { + for (int i = 0; i < 3; i++) + m_materials[mat_name].diffuse[i] = + atof(tokens[i + 1].c_str()); + m_materials[mat_name].flags |= Material::MAT_DIFFUSE; + } + else + cerr << "WFObj: error: 'Kd' material directive requires" + " 3 parameters" << endl; + } + else if (tokens[0] == "Ks") + { + if (tokens.size() >= 4) + { + for (int i = 0; i < 3; i++) + m_materials[mat_name].specular[i] = + atof(tokens[i + 1].c_str()); + m_materials[mat_name].flags |= Material::MAT_SPECULAR; + } + else + cerr << "WFObj: error: 'Ks' material directive requires" + " 3 parameters" << endl; + } + else if (tokens[0] == "Ni" || tokens[0] == "d" || tokens[0] == "illum") + { + /* ignore these parameters */ + } + else + { + cerr << "WFObj: error: unrecognized material directive: '" + << tokens[0] << "'" << endl; + } + } } bool WFObj::loadfile(const char *path, Buffer *buff) diff --git a/WFObj.h b/WFObj.h index 3d44a03..927773a 100644 --- a/WFObj.h +++ b/WFObj.h @@ -60,6 +60,25 @@ protected: VertexRef vertices[3]; }; + class Material + { + public: + enum { + MAT_SHININESS = 0x01, + MAT_AMBIENT = 0x02, + MAT_DIFFUSE = 0x04, + MAT_SPECULAR = 0x08, + MAT_TEXTURE = 0x10 + }; + Material() : flags(0) {} + float shininess; + float ambient[3]; + float diffuse[3]; + float specular[3]; + std::string texture; + int flags; + }; + /* methods */ void clear(); void processInputLine(const std::string & input); @@ -74,6 +93,7 @@ protected: /* variables */ std::vector m_vertices[VERTEX_TYPES]; std::map< std::string, std::vector< Face > > m_faces; + std::map< std::string, Material > m_materials; float m_aabb[6]; std::string m_path; loadfile_t m_loadfile;