Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- ===============================================================================
- File: ASEModel.cpp
- Author: Clinton Freeman
- Created: May 8, 2011
- ===============================================================================
- */
- #include <headers/Common.h>
- #include <headers/ASEModel.h>
- #include <iostream>
- #include <fstream>
- #include <vector>
- #include <iterator>
- using namespace E3D;
- using std::vector;
- using std::string;
- using std::iterator;
- static void split(string input, vector<string>& tokens);
- static float parseFloat(vector<string>::iterator& tokenItr);
- static unsigned int parseUInt(vector<string>::iterator& tokenItr);
- static string& parseString(vector<string>::iterator& tokenItr);
- // more complicated structures require passing the structure in to avoid
- // having to allocate a new one in the free store
- static void parseRGB(vector<string>::iterator& tokenItr, RGB& rgb);
- static void parseVector3(vector<string>::iterator& tokenItr, Vector3& v);
- //=============================================================================
- // ASEModel
- //=============================================================================
- ASEModel::ASEModel(string filename)
- {
- string curLine, token;
- vector<string> tokens;
- vector<string>::iterator tokenItr;
- // attempt to read the file, parse it into tokens based on whitespace
- std::ifstream file(filename.c_str());
- if(file.is_open())
- {
- while(file.good())
- {
- getline(file, curLine);
- split(curLine, tokens);
- }
- }
- else
- {
- printf("Unable to open file \"%s\".\n", filename.c_str());
- return;
- }
- tokenItr = tokens.begin();
- lastToken = tokens.end();
- parse(tokenItr);
- file.close();
- }
- void ASEModel::parse(vector<string>::iterator& tokenItr)
- {
- exportVersion = parseUInt(tokenItr);
- comment = parseString(tokenItr);
- scene.parse(tokenItr);
- materialList.parse(tokenItr);
- while(tokenItr != lastToken)
- {
- if(*tokenItr == "*GEOMOBJECT")
- {
- ASEGeomObject go;
- go.parse(tokenItr);
- geomObjects.push_back(go);
- }
- else if(*tokenItr == "*LIGHTOBJECT")
- {
- // do something!
- }
- }
- }
- //=============================================================================
- // ASEScene
- //=============================================================================
- void ASEScene::parse(vector<string>::iterator& tokenItr)
- {
- // consume *SCENE and {
- tokenItr += 2;
- filename = parseString(tokenItr);
- firstFrame = parseUInt(tokenItr);
- lastFrame = parseUInt(tokenItr);
- frameSpeed = parseUInt(tokenItr);
- ticksPerFrame = parseUInt(tokenItr);
- parseRGB(tokenItr, backgroundStatic);
- parseRGB(tokenItr, ambientStatic);
- // consume }
- tokenItr++;
- }
- //=============================================================================
- // ASEMaterialList
- //=============================================================================
- void ASEMaterialList::parse(vector<string>::iterator& tokenItr)
- {
- // consume *MATERIAL_LIST and {
- tokenItr += 2;
- materialCount = parseUInt(tokenItr);
- for(unsigned int i = 0; i < this->materialCount; i++)
- {
- ASEMaterial m;
- m.parse(tokenItr);
- materials.push_back(m);
- }
- // consume }
- tokenItr++;
- }
- //=============================================================================
- // ASEMaterial
- //=============================================================================
- void ASEMaterial::parse(vector<string>::iterator& tokenItr)
- {
- // consume *MATERIAL or *SUBMATERIAL and # and {
- tokenItr += 3;
- name = parseString(tokenItr);
- matClass = parseString(tokenItr);
- parseRGB(tokenItr, ambient);
- parseRGB(tokenItr, diffuse);
- parseRGB(tokenItr, specular);
- shine = parseFloat(tokenItr);
- shineStrength = parseFloat(tokenItr);
- transparency = parseFloat(tokenItr);
- wireSize = parseFloat(tokenItr);
- // potentially parse submaterials
- if(*tokenItr == "*NUMSUBMTLS")
- {
- numSubMtls = parseUInt(tokenItr);
- for(unsigned int j = 0; j < numSubMtls; j++)
- {
- ASEMaterial sm;
- sm.parse(tokenItr);
- subMaterials.push_back(sm);
- }
- shading = "n/a";
- xpFalloff = 0.0;
- selfIllum = 0.0;
- falloff = "n/a";
- xpType = "n/a";
- }
- else
- {
- numSubMtls = 0;
- shading = parseString(tokenItr);
- xpFalloff = parseFloat(tokenItr);
- selfIllum = parseFloat(tokenItr);
- falloff = parseString(tokenItr);
- xpType = parseString(tokenItr);
- // this is a little bit trickier than objects in the ASE file that
- // tell you the count ahead of time. since the maps are located last
- // in the material, we can use the presence of a } after parsing
- // a map as a signal that we've gone through all of them.
- for(;;)
- {
- ASEMap m;
- m.parse(tokenItr);
- maps.push_back(m);
- if(*tokenItr == "}")
- break;
- }
- }
- // consume }
- tokenItr++;
- }
- //=============================================================================
- // ASEMap
- //=============================================================================
- void ASEMap::parse(vector<string>::iterator& tokenItr)
- {
- if(*tokenItr == "*MAP_DIFFUSE")
- mapFunc = MAP_DIFFUSE;
- else if(*tokenItr == "*MAP_SPECULAR")
- mapFunc = MAP_SPECULAR;
- else if(*tokenItr == "*MAP_SHINE")
- mapFunc = MAP_SHINE;
- else if(*tokenItr == "*MAP_SHINESTRENGTH")
- mapFunc = MAP_SHINESTRENGTH;
- else if(*tokenItr == "*MAP_SELFILLUM")
- mapFunc = MAP_SELFILLUM;
- else if(*tokenItr == "*MAP_OPACITY")
- mapFunc = MAP_OPACITY;
- else if(*tokenItr == "*MAP_FILTERCOLOR")
- mapFunc = MAP_FILTERCOLOR;
- else if(*tokenItr == "*MAP_BUMP")
- mapFunc = MAP_BUMP;
- else if(*tokenItr == "*MAP_REFLECT")
- mapFunc = MAP_REFLECT;
- else if(*tokenItr == "*MAP_REFRACT")
- mapFunc = MAP_REFRACT;
- // consume *MAP_____ and {
- tokenItr += 2;
- name = parseString(tokenItr);
- mapClass = parseString(tokenItr);
- subno = parseUInt(tokenItr);
- amount = parseFloat(tokenItr);
- bitmap = parseString(tokenItr);
- type = parseString(tokenItr);
- uvwUOffset = parseFloat(tokenItr);
- uvwVOffset = parseFloat(tokenItr);
- uvwUTiling = parseFloat(tokenItr);
- uvwVTiling = parseFloat(tokenItr);
- uvwAngle = parseFloat(tokenItr);
- uvwBlur = parseFloat(tokenItr);
- uvwBlurOffset = parseFloat(tokenItr);
- uvwNoiseAmt = parseFloat(tokenItr);
- uvwNoiseSize = parseFloat(tokenItr);
- uvwNoiseLevel = parseUInt(tokenItr);
- uvwNoisePhase = parseFloat(tokenItr);
- bitmapFilter = parseString(tokenItr);
- // consume }
- tokenItr++;
- }
- //=============================================================================
- // ASEGeomObject
- //=============================================================================
- void ASEGeomObject::parse(vector<string>::iterator& tokenItr)
- {
- // consume *GEOMOBJECT and {
- tokenItr += 2;
- nodeName = parseString(tokenItr);
- nodeTM.parse(tokenItr);
- mesh.parse(tokenItr);
- propMotionBlur = parseUInt(tokenItr);
- propCastShadow = parseUInt(tokenItr);
- propRecvShadow = parseUInt(tokenItr);
- materialRef = parseUInt(tokenItr);
- // consume }
- tokenItr++;
- }
- //=============================================================================
- // ASEMesh
- //=============================================================================
- void ASEMesh::parse(vector<string>::iterator& tokenItr)
- {
- // consume *MESH and {
- tokenItr += 2;
- timeValue = parseUInt(tokenItr);
- numVertex = parseUInt(tokenItr);
- numFaces = parseUInt(tokenItr);
- // consume *MESH_VERTEX_LIST and {
- tokenItr += 2;
- for(unsigned int i = 0; i < numVertex; i++)
- {
- ASEVertex v;
- v.parse(tokenItr);
- vertexList.push_back(v);
- }
- // consume }
- tokenItr++;
- // consume *MESH_FACE_LIST and {
- tokenItr += 2;
- for(unsigned int i = 0; i < numFaces; i++)
- {
- ASEFace f;
- f.parse(tokenItr);
- faceList.push_back(f);
- }
- // consume }
- tokenItr++;
- numTVertex = parseUInt(tokenItr);
- // consume *MESH_TVERTLIST and {
- tokenItr += 2;
- for(unsigned int i = 0; i < numTVertex; i++)
- {
- ASETVertex v;
- v.parse(tokenItr);
- tVertexList.push_back(v);
- }
- // consume }
- tokenItr++;
- numTVFaces = parseUInt(tokenItr);
- // consume *MESH_TFACELIST and {
- tokenItr += 2;
- for(unsigned int i = 0; i < numTVFaces; i++)
- {
- ASETFace f;
- f.parse(tokenItr);
- tFaceList.push_back(f);
- }
- // consume }
- tokenItr++;
- numCVertex = parseUInt(tokenItr);
- if(numCVertex > 0)
- {
- // consume *MESH_CVERTLIST and {
- tokenItr += 2;
- for(unsigned int i = 0; i < numCVertex; i++)
- {
- ASECVertex c;
- c.parse(tokenItr);
- cVertexList.push_back(c);
- }
- // consume }
- tokenItr++;
- numCVFaces = parseUInt(tokenItr);
- // consume *MESH_CVERTLIST and {
- tokenItr += 2;
- for(unsigned int i = 0; i < numCVFaces; i++)
- {
- ASECFace c;
- c.parse(tokenItr);
- cFaceList.push_back(c);
- }
- // consume }
- tokenItr++;
- }
- // consume *MESH_NORMALS and {
- tokenItr += 2;
- for(unsigned int i = 0; i < numFaces; i++)
- {
- ASENormal fNorm;
- fNorm.parse(tokenItr);
- faceNormals.push_back(fNorm);
- for(int j = 0; j < 3; j++)
- {
- ASENormal vNorm;
- vNorm.parse(tokenItr);
- vertexNormals.push_back(vNorm);
- }
- }
- // consume }
- tokenItr++;
- // consume }
- tokenItr++;
- }
- //=============================================================================
- // ASENodeTM
- //=============================================================================
- void ASENodeTM::parse(vector<string>::iterator& tokenItr)
- {
- // consume *NODE_TM and {
- tokenItr += 2;
- nodeName = parseString(tokenItr);
- parseVector3(tokenItr, inheritPos);
- parseVector3(tokenItr, inheritRot);
- parseVector3(tokenItr, inheritScl);
- parseVector3(tokenItr, tmRow0);
- parseVector3(tokenItr, tmRow1);
- parseVector3(tokenItr, tmRow2);
- parseVector3(tokenItr, tmRow3);
- parseVector3(tokenItr, tmPos);
- parseVector3(tokenItr, tmRotAxis);
- tmRotAngle = parseFloat(tokenItr);
- parseVector3(tokenItr, tmScale);
- parseVector3(tokenItr, tmScaleAxis);
- tmScaleAxisAng = parseFloat(tokenItr);
- // consume }
- tokenItr++;
- }
- //=============================================================================
- // ASEFace
- //=============================================================================
- void ASEFace::parse(vector<string>::iterator& tokenItr)
- {
- // consume *MESH_FACE
- tokenItr++;
- // the id ends with a colon, remove that
- id = atoi(tokenItr->substr(0, tokenItr->size()-1).c_str());
- tokenItr++;
- A = parseUInt(tokenItr);
- B = parseUInt(tokenItr);
- C = parseUInt(tokenItr);
- AB = parseUInt(tokenItr);
- BC = parseUInt(tokenItr);
- CA = parseUInt(tokenItr);
- // if the face doesn't have a smoothing group it will be empty (not 0)
- tokenItr++;
- if(*tokenItr != "*MESH_MTLID")
- {
- meshSmoothing = atoi(tokenItr->c_str());
- tokenItr++;
- }
- else
- meshSmoothing = -1; // flag that it's empty
- meshMtlID = parseUInt(tokenItr);
- }
- //=============================================================================
- // ASETFace
- //=============================================================================
- void ASETFace::parse(vector<string>::iterator& tokenItr)
- {
- // consume *MESH_TFACE or *MESH_CFACE
- tokenItr++;
- id = atoi(tokenItr->c_str());
- tokenItr++;
- A = atoi(tokenItr->c_str());
- tokenItr++;
- B = atoi(tokenItr->c_str());
- tokenItr++;
- C = atoi(tokenItr->c_str());
- tokenItr++;
- }
- //=============================================================================
- // ASEVertex
- //=============================================================================
- void ASEVertex::parse(vector<string>::iterator& tokenItr)
- {
- // consume *MESH_VERTEX or TVERTEX or FACENORMAL, etc.
- tokenItr++;
- id = atoi(tokenItr->c_str());
- tokenItr++;
- coords.x = atof(tokenItr->c_str());
- tokenItr++;
- coords.y = atof(tokenItr->c_str());
- tokenItr++;
- coords.z = atof(tokenItr->c_str());
- tokenItr++;
- }
- //=============================================================================
- // << Operators
- //=============================================================================
- namespace E3D
- {
- std::ostream& operator <<(std::ostream& o, const ASEModel& m)
- {
- o << "ASEModel ========================================================\n";
- o << "Export Version: " << m.exportVersion << "\n";
- o << "Comment: " << m.comment << "\n";
- o << m.scene;
- o << m.materialList;
- for(vector<ASEGeomObject>::const_iterator it = m.geomObjects.begin();
- it != m.geomObjects.end(); ++it)
- {
- o << *it;
- }
- return o;
- }
- std::ostream& operator <<(std::ostream& o, const ASEScene& s)
- {
- o << "ASEScene ========================================================\n";
- o << "Filename: " << s.filename << "\n";
- o << "First Frame: " << s.firstFrame << "\n";
- o << "Last Frame: " << s.lastFrame << "\n";
- o << "Frame Speed: " << s.frameSpeed << "\n";
- o << "Ticks Per Frame: " << s.ticksPerFrame << "\n";
- o << "Background Static: " << s.backgroundStatic << "\n";
- o << "Ambient Static: " << s.ambientStatic << "\n";
- return o;
- }
- std::ostream& operator <<(std::ostream& o, const ASEMaterialList& m)
- {
- o << "ASEMaterialList =================================================\n";
- o << "Material Count: " << m.materialCount << "\n";
- for(vector<ASEMaterial>::const_iterator it = m.materials.begin();
- it != m.materials.end(); ++it)
- {
- o << *it;
- }
- return o;
- }
- std::ostream& operator <<(std::ostream& o, const ASEMaterial& m)
- {
- o << "ASEMaterial =====================================================\n";
- o << "Name: %s\n" << m.name << "\n";
- o << "Class: %s\n" << m.matClass << "\n";
- o << "Ambient: " << m.ambient << "\n";
- o << "Diffuse: " << m.diffuse << "\n";
- o << "Specular: " << m.specular << "\n";
- o << "Shine: " << m.shine << "\n";
- o << "Shine Strength: " << m.shineStrength << "\n";
- o << "Transparency: " << m.transparency << "\n";
- o << "Wire Size: " << m.wireSize << "\n";
- o << "Submaterials ====================================================\n";
- o << "Number of Submaterials: " << m.numSubMtls << "\n";
- for(vector<ASEMaterial>::const_iterator it = m.subMaterials.begin();
- it != m.subMaterials.end(); ++it)
- {
- o << *it;
- }
- o << "=================================================================\n";
- o << "Shading: " << m.shading << "\n";
- o << "XP Falloff: " << m.xpFalloff << "\n";
- o << "Self Illumination; " << m.selfIllum << "\n";
- o << "Falloff: " << m.falloff << "\n";
- o << "XP Type: " << m.xpType << "\n";
- o << "Maps ============================================================\n";
- for(vector<ASEMap>::const_iterator it = m.maps.begin();
- it != m.maps.end(); ++it)
- {
- o << *it;
- }
- o << "=================================================================\n";
- return o;
- }
- std::ostream& operator <<(std::ostream& o, const ASEMap& m)
- {
- o << "ASEMap ==========================================================\n";
- o << "Map Func: " << m.mapFunc << "\n";
- o << "Name: " << m.name << "\n";
- o << "Class: " << m.mapClass << "\n";
- o << "Subno: " << m.subno << "\n";
- o << "Amount: " << m.amount << "\n";
- o << "Bitmap: " << m.bitmap << "\n";
- o << "Type: " << m.type << "\n";
- o << "uvw U Offset: " << m.uvwUOffset << "\n";
- o << "uvw V Offset: " << m.uvwVOffset << "\n";
- o << "uvw U Tiling: " << m.uvwUTiling << "\n";
- o << "uvw V Tiling: " << m.uvwVTiling << "\n";
- o << "uvw Angle: " << m.uvwAngle << "\n";
- o << "uvw Blur: " << m.uvwBlur << "\n";
- o << "uvw Blur Offset: " << m.uvwBlurOffset << "\n";
- o << "uvw Noise Amt: " << m.uvwNoiseAmt << "\n";
- o << "uvw Noise Size: " << m.uvwNoiseSize << "\n";
- o << "uvw Noise Level: " << m.uvwNoiseLevel << "\n";
- o << "uvw Noise Phase: " << m.uvwNoisePhase << "\n";
- o << "Bitmap Filter: " << m.bitmapFilter << "\n";
- return o;
- }
- std::ostream& operator <<(std::ostream& o, const ASEGeomObject& go)
- {
- o << "ASEGeomObject ===================================================\n";
- o << "Node Name: " << go.nodeName << "\n";
- o << go.nodeTM;
- o << go.mesh;
- o << "Motion Blur: " << go.propMotionBlur << "\n";
- o << "Cast Shadow: " << go.propCastShadow << "\n";
- o << "Recieve Shadow: " << go.propRecvShadow << "\n";
- o << "Material Reference: " << go.materialRef << "\n";
- return o;
- }
- std::ostream& operator <<(std::ostream& o, const ASENodeTM& n)
- {
- o << "ASENodeTM =======================================================\n";
- o << "Node Name: " << n.nodeName << "\n";
- o << "Inherit Position: " << n.inheritPos << "\n";
- o << "Inherit Rotation: " << n.inheritRot << "\n";
- o << "Inherit Scale: " << n.inheritScl << "\n";
- o << "TM Row0: " << n.tmRow0 << "\n";
- o << "TM Row1: " << n.tmRow1 << "\n";
- o << "TM Row2: " << n.tmRow2 << "\n";
- o << "TM Row3: " << n.tmRow3 << "\n";
- o << "TM Pos: " << n.tmPos << "\n";
- o << "TM Rot Axis: " << n.tmRotAxis << "\n";
- o << "TM Rot Angle: " << n.tmRotAngle << "\n";
- o << "TM Scale: " << n.tmScale << "\n";
- o << "TM Scale Axis: " << n.tmScaleAxis << "\n";
- o << "TM Scale Axis Angle: " << n.tmScaleAxisAng << "\n";
- return o;
- }
- std::ostream& operator <<(std::ostream& o, const ASEMesh& m)
- {
- o << "ASEMesh =========================================================\n";
- o << "Time Value: " << m.timeValue << "\n";
- o << "Number of Vertices: " << m.numVertex << "\n";
- for(vector<ASEVertex>::const_iterator it = m.vertexList.begin();
- it != m.vertexList.end(); ++it)
- {
- o << *it << "\n";
- }
- o << "Number of Faces: " << m.numFaces << "\n";
- for(vector<ASEFace>::const_iterator it = m.faceList.begin();
- it != m.faceList.end(); ++it)
- {
- o << *it << "\n";
- }
- o << "Number of TVertices: " << m.numTVertex << "\n";
- for(vector<ASETVertex>::const_iterator it = m.tVertexList.begin();
- it != m.tVertexList.end(); ++it)
- {
- o << *it << "\n";
- }
- o << "Number of TFaces: %d\n" << m.numTVFaces << "\n";
- for(vector<ASETFace>::const_iterator it = m.tFaceList.begin();
- it != m.tFaceList.end(); ++it)
- {
- o << *it << "\n";
- }
- o << "Number of CVertices: " << m.numCVertex << "\n";
- // TODO: print cvertex list and cface list
- o << "Normals:\n";
- // TODO: iterators?
- for(unsigned int i = 0; i < m.numFaces; i++)
- {
- o << "Face Normal ";
- o << m.faceNormals.at(i) << "\n";
- for(int j = 0; j < 3; j++)
- {
- o << "Vertex Normal ";
- o << m.vertexNormals.at(i*3+j) << "\n";
- }
- }
- return o;
- }
- std::ostream& operator <<(std::ostream& o, const ASETFace& tf)
- {
- o << tf.id << " " << tf.A << " " << tf.B << " " << tf.C;
- return o;
- }
- std::ostream& operator <<(std::ostream& o, const ASEFace& f)
- {
- o << f.id << " A: " << f.A << " B: " << f.B << " C: " << f.C << " ";
- o << "AB: " << f.AB << " BC: " << f.BC << " CA: " << f.CA << " ";
- o << "Smoothing Group: " << f.meshSmoothing << " ";
- o << "Material ID: " << f.meshMtlID;
- return o;
- }
- std::ostream& operator <<(std::ostream& o, const ASEVertex& v)
- {
- o << v.id << " " << v.coords;
- return o;
- }
- }
- //=============================================================================
- // Parsing helper functions
- //=============================================================================
- /*
- * Convenience function to split an input string into tokens based on
- * whitespace. Perserves quoted string literals.
- */
- static void split(string input, vector<string>& tokens)
- {
- string token;
- std::istringstream iss(input);
- while(iss >> token)
- {
- // if this is the beginning of a quoted string that does not end with
- // a matching quote
- if((token.at(0) == '\"') && (token.at(token.size()-1) != '\"'))
- {
- // create a temp string to accumulate the full quoted string
- string quotedStr(token);
- // begin grabbing subsequent tokens until we find one that has the
- // matching end quote
- while(iss >> token)
- {
- // append a space because presumably that is what caused the
- // break
- quotedStr.append(" ");
- quotedStr.append(token);
- if(token.at(token.size()-1) == '\"')
- break;
- }
- tokens.push_back(quotedStr);
- continue;
- }
- tokens.push_back(token);
- }
- }
- static float parseFloat(vector<string>::iterator& tokenItr)
- {
- tokenItr++;
- float val = atof(tokenItr->c_str());
- tokenItr++;
- return val;
- }
- static unsigned int parseUInt(vector<string>::iterator& tokenItr)
- {
- tokenItr++;
- unsigned int val = atoi(tokenItr->c_str());
- tokenItr++;
- return val;
- }
- static string& parseString(vector<string>::iterator& tokenItr)
- {
- tokenItr++;
- string& s = *tokenItr;
- tokenItr++;
- return s;
- }
- static void parseRGB(vector<string>::iterator& tokenItr, RGB& rgb)
- {
- tokenItr++;
- rgb.r = atof(tokenItr->c_str()); tokenItr++;
- rgb.g = atof(tokenItr->c_str()); tokenItr++;
- rgb.b = atof(tokenItr->c_str()); tokenItr++;
- }
- static void parseVector3(vector<string>::iterator& tokenItr, Vector3& v)
- {
- tokenItr++;
- v.x = atof(tokenItr->c_str()); tokenItr++;
- v.y = atof(tokenItr->c_str()); tokenItr++;
- v.z = atof(tokenItr->c_str()); tokenItr++;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement