static void parseKeyFramer( MeshModel *root ){ _log( "KeyFramer" ); enterChunk(); string file_3ds; unsigned short rev,curr_time=0; while( int id=nextChunk() ){ switch( id ){ case 0xb009: //CURR_TIME in.sgetn( (char*)&curr_time,2 ); _log( "CURR_TIME: "+itoa(curr_time) ); break; case 0xb00a: //KFHDR in.sgetn( (char*)&rev,2 ); file_3ds=parseString(); in.sgetn( (char*)&anim_len,2 ); _log( "KFHDR: revision="+itoa(rev)+" 3dsfile="+file_3ds+" anim_len="+itoa(anim_len) ); break; case 0xb002: //object keyframer data... parseMeshInfo( root,curr_time ); break; } } if( !collapse ){ root->setAnimator( d_new Animator( root,anim_len ) ); } leaveChunk(); }
MeshModel *Loader_3DS::load( const string &filename,const Transform &t,int hint ){ conv_tform=t; conv=flip_tris=false; if( conv_tform!=Transform() ){ conv=true; if( conv_tform.m.i.cross(conv_tform.m.j).dot(conv_tform.m.k)<0 ) flip_tris=true; } collapse=!!(hint&MeshLoader::HINT_COLLAPSE); animonly=!!(hint&MeshLoader::HINT_ANIMONLY); if( !in.open( filename.c_str(),ios_base::in|ios_base::binary ) ){ return 0; } MeshModel *root=parseFile(); in.close(); materials_map.clear(); name_map.clear(); id_map.clear(); return root; }
static int nextChunk(){ in.pubseekoff( chunk_end,ios_base::beg ); if( chunk_end==parent_end.back() ) return 0; unsigned short id;int len; in.sgetn( (char*)&id,2 ); in.sgetn( (char*)&len,4 ); chunk_end=(int)in.pubseekoff( 0,ios_base::cur )+len-6; return id; }
int main(){ a.open("target.txt", std::ios::in); d.open("dse.txt", std::ios::in); r.open("relation0.txt", std::ios::in); istream ia(&a), id(&d), ir(&r); string sa, sd, sr; len = 0; arg_num = -1; dse_num = -1; while (getline(ia, sa)){ getline(id, sd); sa = sa.substr(0, sa.size() -1 ); // cout<<sa<<","<<sd<<endl; if (sa.size() <= 1){ memset(ans, 0, sizeof(ans)); while (sr.size() > 1){ string dseID, argID; uint i = sr.find_first_of('\t'); dseID = sr.substr(0, i); argID= sr.substr(i+1, sr.size()-i-2); int x = toDigit(dseID), y = toDigit(argID); for (int i = 0; i < dse[x].size(); i ++) for (int j = 0; j < arg[y].size(); j ++) ans[dse[x][i]][arg[y][j]] = 1; } for (int i = 0; i < len; i ++){ cout<<ans[i][0]; for (int j = 1; j < len; j ++){ cout<<"\t"<<ans[i][j]; } cout<<"\n"; } cout<<"\n"; len = 0; arg_num = -1; dse_num = -1; }else{ // sa = sa.substr(0, sa.size() - 1); sd = sd.substr(0, sd.size() - 1); string token, part, tl, al, dl; uint i = sa.find_last_of('\t'); al = sa.substr(i+1, sa.size()-i-1); i = sd.find_last_of('\t'); dl = sd.substr(i+1, sd.size()-i-1); // cerr<<al<<","<<dl<<","<<endl; if (al == "B"){ arg_num ++; arg[arg_num].clear(); arg[arg_num].push_back(len); } if (dl == "B"){ dse_num ++; dse[dse_num].clear(); dse[dse_num].push_back(len); } if (al == "I"){arg[arg_num].push_back(len);} if (dl == "I"){dse[dse_num].push_back(len);} len ++; } } }
static void parseVertList(){ unsigned short cnt; in.sgetn( (char*)&cnt,2 ); _log( "VertList cnt="+itoa(cnt) ); while( cnt-- ){ Surface::Vertex v; in.sgetn( (char*)&v.coords,12 ); if( conv ) v.coords=conv_tform * v.coords; MeshLoader::addVertex( v ); } }
static void parseFaceMat(){ string name=parseString(); _log( "FaceMat: "+name ); Brush mat=materials_map[name]; unsigned short cnt; in.sgetn( (char*)&cnt,2 ); while( cnt-- ){ unsigned short face; in.sgetn( (char*)&face,2 ); faces[face].brush=mat; } }
int main(){ attitude.open("MPQA2.0_processed/attitude_alignannos.txt", std::ios::in); dse.open("MPQA2.0_processed/dse_alignannos.txt", std::ios::in); target.open("MPQA2.0_processed/target_alignannos.txt", std::ios::in); istream ia(&attitude), id(&dse), it(&target); string sa, sd, st; while (getline(id, sd){ getline(ia, sa); getline(it, st); if (st != "") st += '\t'; int last = 0, targetid = 0; while (st.find("id", last) != -1){ int nxt = st.find("id", last); string tar = ""; for (int j = nxt + 3; j != st.size() && st[j] != '\t'; j ++) tar += st[j]; int } last = 0; int dseid = 0; if (sd != "") sd += '\t'; while (sd.find_first_of('\t', last) != -1){ int nxt = sd.find_first_of('\t', last); string subsd = sd.substr(last, nxt - 1); int loc = subsd.find("attrlink"); loc += 9; string attr = ""; for (int j = loc; j != subsd.length() && subsd[j] != ';'; j ++) attr += subsd[j]; last = nxt + 1; } if (st == "") cout<<"\n"; else{ st = st.substr(0, st.size() - 1); sa = sa.substr(0, sa.size() - 1); sd = sd.substr(0, sd.size() - 1); string token, part, tl, al, dl; uint i = st.find_first_of('\t'); token = st.substr(0, i); uint j = st.find_first_of('\t', i+1); part = st.substr(i+1,j-i-1); //cout << part << endl; i = st.find_last_of('\t'); tl = st.substr(i+1, st.size()-i-1); i = sa.find_last_of('\t'); al = sa.substr(i+1, sa.size()-i-1); i = sd.find_last_of('\t'); dl = sd.substr(i+1, sd.size()-i-1); cout<<token<<"\t"<<part<<"\t"<<tl<<"\t"<<al<<"\t"<<dl<<endl; } } }
static void parseMapList(){ _log( "MapList" ); unsigned short cnt; in.sgetn( (char*)&cnt,2 ); for( int k=0;k<cnt;++k ){ float uv[2]; in.sgetn( (char*)uv,8 ); Surface::Vertex &v=MeshLoader::refVertex( k ); v.tex_coords[0][0]=v.tex_coords[1][0]=uv[0]; v.tex_coords[0][1]=v.tex_coords[1][1]=1-uv[1]; // v->tex_coords[0]=v->tex_coords[1]=Vector( uv[0],1-uv[1],1 ); } }
static Vector parseColor(){ Vector v; unsigned char rgb[3]; enterChunk(); while( int id=nextChunk() ){ switch( id ){ case CHUNK_RGBF: in.sgetn( (char*)&v,12 ); break; case CHUNK_RGBB: in.sgetn( (char*)rgb,3 ); v=Vector( rgb[0]/255.0f,rgb[1]/255.0f,rgb[2]/255.0f ); } } leaveChunk(); return v; }
static void parseTriMesh( MeshModel *mesh ){ _log( "TriMesh" ); enterChunk(); Transform tform; faces.clear(); MeshLoader::beginMesh(); while( int id=nextChunk() ){ switch( id ){ case CHUNK_VERTLIST: if( !animonly ) parseVertList(); break; case CHUNK_MAPLIST: if( !animonly ) parseMapList(); break; case CHUNK_FACELIST: if( !animonly ) parseFaceList(); break; case CHUNK_TRMATRIX: in.sgetn( (char*)&tform,48 ); if( conv ) tform=conv_tform * tform * -conv_tform; break; } } leaveChunk(); //should really do something here... // bool neg_x=tform.m.j.cross(tform.m.k).dot(tform.m.i)<0; int k; mesh->setWorldTform( tform ); if( animonly ){ MeshLoader::endMesh( 0 ); return; } Transform inv_tform=-tform; for( k=0;k<MeshLoader::numVertices();++k ){ Surface::Vertex &v=MeshLoader::refVertex( k ); v.coords=inv_tform * v.coords; } for( k=0;k<faces.size();++k ){ const Face3DS &f=faces[k]; MeshLoader::addTriangle( f.verts,f.brush ); } MeshLoader::endMesh( mesh ); mesh->updateNormals(); faces.clear(); }
static MeshModel *parseFile(){ unsigned short id;int len; in.sgetn( (char*)&id,2 ); in.sgetn( (char*)&len,4 ); if( id!=CHUNK_MAIN ) return 0; chunk_end=(int)in.pubseekoff( 0,ios_base::cur )+len-6; enterChunk(); MeshModel *root=d_new MeshModel(); while( int id=nextChunk() ){ switch( id ){ case CHUNK_SCENE: parseScene( root ); break; case CHUNK_KEYFRAMER: parseKeyFramer( root ); break; } } leaveChunk(); return root; }
static void parseFaceList(){ unsigned short cnt; in.sgetn( (char*)&cnt,2 ); _log( "FaceList cnt="+itoa(cnt) ); while( cnt-- ){ unsigned short v[4]; in.sgetn( (char*)v,8 ); Face3DS face; face.verts[0]=v[0]; face.verts[1]=v[1]; face.verts[2]=v[2]; if( flip_tris ) std::swap( face.verts[1],face.verts[2] ); faces.push_back( face ); } enterChunk(); while( int id=nextChunk() ){ switch( id ){ case CHUNK_FACEMAT: parseFaceMat(); break; } } leaveChunk(); }
filebuf IconvWrapper::convert(const filebuf& input) { size_t ret = 0; char* BUFFER; size_t BUFFSIZE; size_t inbytesleft = 0; size_t outbytesleft = 0; char* input_ptr = 0; char* output_ptr = 0; char* output = 0; // The final result will go here... size_t output_size = 0; // How much data should be put avaiable to iconv? // How about twice as much as input's length? inbytesleft = input.len(); BUFFSIZE = 2 * inbytesleft; outbytesleft = BUFFSIZE; // Get memory to hold our converted data. BUFFER = new char[ BUFFSIZE ]; input_ptr = (char*)input.current; output_ptr = BUFFER; ret = iconv( cd, &input_ptr, &inbytesleft, &output_ptr, &outbytesleft); if (ret == size_t(-1)) { delete[] BUFFER; throw IconvError("While converting..."); } // Got here? So everything went fine. // Copy data to a more memory-efficient location output_size = BUFFSIZE - outbytesleft; output = new char[output_size]; memcpy(output, BUFFER, output_size); delete[] BUFFER; return filebuf(output, output_size); }
filebuf decompress(filebuf data) { /* This code is based on zLib's usage example, available * at http://www.zlib.net/zlib_how.html */ // Zlib stuff int ret; z_stream strm; unsigned int have; // Outputing stuff size_t OUTBUF_LEN = DECOMPRESS_RESERVE; char outbuf[OUTBUF_LEN]; std::vector<char> accbuf; // accumulator buffer accbuf.reserve(DECOMPRESS_RESERVE); if (data.len() == 0) { // Empty filebufs result in empty filebufs. return filebuf(); } /* allocate inflate state */ const int windowBits = 15 + 16; /* 15 is the default value for * windownBits in inflateInit(). * * Bits+16 means "use gzip" in * zlib >= 1.2. Use 32 instead * of 16 to force automatic header * detection for gzip/zlib. */ strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.avail_in = data.len(); strm.next_in = Z_NULL; ret = inflateInit2(&strm, windowBits); if (ret != Z_OK){ throw ZLibException("in inflateInit2", ret); } strm.avail_in = data.len(); strm.next_in = (unsigned char*) data.current; /* decompress until deflate stream ends or an error happens */ do { /* Remember: all input data _is_ available! All we can and * must do is loop until zlib reports that it has * finished or an error occurs. */ /* run inflate() on input until output buffer not full */ do { strm.avail_out = OUTBUF_LEN; strm.next_out = (unsigned char*) outbuf; ret = inflate(&strm, Z_NO_FLUSH); // make sure state not clobbered if (ret == Z_STREAM_ERROR) { throw ZLibException("in inflate", ret); } switch (ret) { case Z_NEED_DICT: ret = Z_DATA_ERROR; // and fall through case Z_DATA_ERROR: case Z_MEM_ERROR: (void)inflateEnd(&strm); throw ZLibException("in inflate", ret); } have = OUTBUF_LEN - strm.avail_out; accbuf.insert( accbuf.end(), outbuf, &outbuf[have]); } while (strm.avail_out == 0); /* done when inflate() says it's done */ } while(ret != Z_STREAM_END); /* clean up */ (void)inflateEnd(&strm); /* Ugly and lazy copy to an array */ char* final_buffer = new char[accbuf.size()]; std::copy(accbuf.begin(), accbuf.end(), final_buffer); return filebuf(final_buffer, accbuf.size()); }
inline void swap(filebuf& x, filebuf& y) { x.swap(y); }
int eof(){ return buf->sgetc()==EOF; }
int write( const char *buff,int size ){ return buf->sputn( (char*)buff,size ); }
int avail(){ return buf->in_avail(); }
int read( char *buff,int size ){ return buf->sgetn( (char*)buff,size ); }
static void parseAnimKeys( Animation *anim,int type ){ int cnt=0; short t_flags; in.sgetn( (char*)&t_flags,2 ); in.pubseekoff( 8,ios_base::cur ); in.sgetn( (char*)&cnt,2 ); in.pubseekoff( 2,ios_base::cur ); _log( "ANIM_TRACK: frames="+itoa( cnt ) ); Vector pos,axis,scale; float angle; Quat quat; for( int k=0;k<cnt;++k ){ int time; short flags; in.sgetn( (char*)&time,4 ); in.sgetn( (char*)&flags,2 ); float tens=0,cont=0,bias=0,ease_to=0,ease_from=0; if( flags & 1 ) in.sgetn( (char*)&tens,4 ); if( flags & 2 ) in.sgetn( (char*)&cont,4 ); if( flags & 4 ) in.sgetn( (char*)&bias,4 ); if( flags & 8 ) in.sgetn( (char*)&ease_to,4 ); if( flags & 16 ) in.sgetn( (char*)&ease_from,4 ); switch( type ){ case 0xb020: //POS_TRACK_TAG in.sgetn( (char*)&pos,12 ); if( conv ) pos=conv_tform*pos; // _log( "POS_KEY: time="+itoa(time)+" pos="+ftoa( pos.x )+","+ftoa( pos.y )+","+ftoa( pos.z ) ); if( time<=anim_len ) anim->setPositionKey( time,pos ); break; case 0xb021: //ROT_TRACK_TAG in.sgetn( (char*)&angle,4 ); in.sgetn( (char*)&axis,12 ); // _log( "ROT_KEY: time="+itoa(time)+" angle="+ftoa(angle)+" axis="+ftoa(axis.x)+","+ftoa(axis.y)+","+ftoa(axis.z) ); if( axis.length()>EPSILON ){ if( flip_tris ) angle=-angle; if( conv ) axis=conv_tform.m*axis; quat=Quat( cosf( angle/2 ),axis.normalized()*sinf( angle/2 ) )*quat; quat.normalize(); } if( time<=anim_len ) anim->setRotationKey( time,quat ); break; case 0xb022: //SCL_TRACK_TAG in.sgetn( (char*)&scale,12 ); if( conv ) scale=conv_tform.m*scale; // scale.x=fabs(scale.x);scale.y=fabs(scale.y);scale.z=fabs(scale.z); _log( "SCL_KEY: time="+itoa(time)+" scale="+ftoa( scale.x )+","+ftoa( scale.y )+","+ftoa( scale.z ) ); if( time<=anim_len ) anim->setScaleKey( time,scale ); break; } } }
static string parseString(){ string t; while( int c=in.sbumpc() ) t+=char(c); return t; }
static void parseMeshInfo( MeshModel *root,float curr_time ){ _log( "OBJECT_NODE_TAG" ); enterChunk(); string name,inst; Vector pivot; Animation anim; unsigned short id=65535,parent=65535,flags1,flags2; Box box( (Vector()),(Vector()) ); Vector box_centre; while( int chunk_id=nextChunk() ){ switch( chunk_id ){ case 0xb030: //NODE_ID in.sgetn( (char*)&id,2 ); _log( "NODE_ID: "+itoa(id) ); break; case 0xb010: //NODE_HDR name=parseString(); in.sgetn( (char*)&flags1,2 ); in.sgetn( (char*)&flags2,2 ); in.sgetn( (char*)&parent,2 ); _log( "NODE_HDR: name="+name+" parent="+itoa(parent) ); break; case 0xb011: //INSTANCE NAME inst=parseString(); _log( "INSTANCE_NAME: "+inst ); break; case 0xb013: //PIVOT in.sgetn( (char*)&pivot,12 ); if( conv ) pivot=conv_tform * pivot; _log( "PIVOT: "+ftoa(pivot.x)+","+ftoa(pivot.y)+","+ftoa(pivot.z) ); break; case 0xb014: //BOUNDBOX in.sgetn( (char*)&box.a,12 ); in.sgetn( (char*)&box.b,12 ); box_centre=box.centre(); if( conv ) box_centre=conv_tform * box_centre; _log( "BOUNDBOX: min="+ftoa(box.a.x)+","+ftoa(box.a.y)+","+ftoa(box.a.z)+" max="+ftoa(box.b.x)+","+ftoa(box.b.y)+","+ftoa(box.b.z) ); break; case 0xb020: //POS_TRACK_TAG case 0xb021: //ROT_TRACK_TAG case 0xb022: //SCALE_TRACK_TAG if( !collapse ) parseAnimKeys( &anim,chunk_id ); break; } } leaveChunk(); MeshModel *p=root; if( parent!=65535 ){ map<int,MeshModel*>::const_iterator it=id_map.find( parent ); if( it==id_map.end() ) return; p=it->second; } MeshModel *mesh=0; if( name=="$$$DUMMY" ){ mesh=d_new MeshModel(); mesh->setName( inst ); mesh->setParent( p ); }else{ map<string,MeshModel*>::const_iterator it=name_map.find( name ); if( it==name_map.end() ) return; mesh=it->second; name_map.erase( name ); if( pivot!=Vector() ){ mesh->transform( -pivot ); } Transform t= mesh->getWorldTform(); mesh->setParent( p ); mesh->setWorldTform( t ); } mesh->setAnimation( anim ); if( id!=65535 ) id_map[id]=mesh; }
static void enterChunk(){ parent_end.push_back( chunk_end ); chunk_end=(int)in.pubseekoff( 0,ios_base::cur ); }