int MemPool::SelfTest() { Log::printf("Testing MemPool...\n"); void* allocated[2][MEMPOOL_TABLE_SIZE]; for (int size=1;size<MEMPOOL_TABLE_SIZE;size++) { allocated[0][size]=getSingleton()->malloc(size); allocated[1][size]=getSingleton()->malloc(size); } for (int size=1;size<MEMPOOL_TABLE_SIZE;size++) { getSingleton()->free(size,allocated[1][size]); getSingleton()->free(size,allocated[0][size]); } for (int size=1;size<MEMPOOL_TABLE_SIZE;size++) { void* temp1=getSingleton()->malloc(size); void* temp2=getSingleton()->malloc(size); XgeReleaseAssert(temp1==allocated[0][size]); XgeReleaseAssert(temp2==allocated[1][size]); } return 0; }
void Archive::Pop(std::string name) { if (bTextMode) { XgeReleaseAssert(xml_objects.top().name==name); xml_objects.pop(); } }
void Plasm::convertOldXml(char* infilename,char* outfilename,char* prefix) { ::prefix=std::string(prefix); TiXmlDocument doc; unsigned long filesize; unsigned char* buff=FileSystem::ReadFile(infilename,filesize,true); if (!doc.Parse((const char*)buff)) { MemPool::getSingleton()->free(filesize,buff); Utils::Error(HERE,"Failed to open XML fle %s [%d] %s",infilename,doc.ErrorRow(),doc.ErrorDesc()); } MemPool::getSingleton()->free(filesize,buff); TiXmlNode* xnode=doc.FirstChild(); const char* xname=xnode->Value(); XgeReleaseAssert(!strcmpi(xname,"mesh")); //geometry std::map<int, SmartPointer<Vector > > arrays; TiXmlNode* xgeometry=getChild(xnode,"arrays"); for (TiXmlNode* xchild= xgeometry->FirstChild(); xchild != 0; xchild = xchild->NextSibling()) { XgeReleaseAssert(!strcmpi(xchild->Value(),"array")); int id =atoi(getAttribute(xchild,"id" )->Value()); int size =atoi(getAttribute(xchild,"size")->Value()); SmartPointer<Vector> arr(new Vector(size)); Vector::parse(size,arr->mem(),xchild->FirstChild()->Value(),(char*)"%e"); arrays[id]=arr; } SmartPointer<Hpc> hpc=openXmlNode(getChild(xnode,"node"),arrays); Log::printf("Opened XML file %s\n",infilename); Plasm::save(hpc,outfilename); }
int Archive::ReadInt(std::string name) { int value; if (bTextMode) { TiXmlElement* xml_element=CURNODE->ToElement(); const char* bOk=xml_element->Attribute(name.c_str(),&value); XgeReleaseAssert(bOk); } else InnerRead((char*)&value,sizeof(int)); return value; }
unsigned int Archive::ReadUint(std::string name) { unsigned int value; if (bTextMode) { int ivalue; TiXmlElement* element=CURNODE->ToElement(); const char* bOk=element->Attribute(name.c_str(),&ivalue); XgeReleaseAssert(bOk); value=(unsigned int)ivalue; } else InnerRead((char*)&value,sizeof(unsigned int)); return value; }
void Archive::InnerRead(void* buffer,int memsize) { if (bTextMode) { TiXmlNode* xml_child=CURNODE->IterateChildren("data",(TiXmlNode*)xml_objects.top().second); xml_objects.top().second=xml_child; const char* encoded_data=xml_child->ToElement()->GetText(); Decoder decoder(encoded_data); decoder.ReadRaw(memsize,(unsigned char*)buffer); } else { for (int ndone=0,nread=0;ndone!=memsize;ndone+=nread) { nread=(int)(gzfile?gzread((gzFile)gzfile,(char*)buffer+ndone,memsize-ndone):fread((char*)buffer+ndone,1,memsize-ndone,file)); XgeReleaseAssert(nread); } } }
void Texture::uploadIfNeeded(GLCanvas& gl) { if (this->gpu) return; juce::OpenGLContext* context=(juce::OpenGLContext*)gl.getGLContext(); unsigned int texid; glGenTextures(1,&texid);XgeReleaseAssert(texid); glPixelStorei (GL_UNPACK_ALIGNMENT, 1); glBindTexture (GL_TEXTURE_2D, texid); float maxsize; glGetFloatv(GL_MAX_TEXTURE_SIZE,&maxsize); XgeDebugAssert (this->width<=maxsize && this->height<=maxsize); unsigned int format=(this->bpp==24)?GL_RGB:(this->bpp==32?GL_RGBA:GL_LUMINANCE); unsigned int type=GL_UNSIGNED_BYTE; gluBuild2DMipmaps(GL_TEXTURE_2D,this->bpp/8,this->width, this->height,format, type, this->buffer); this->gpu=SmartPointer<Texture::Gpu>(new Texture::Gpu(texid)); }
void Archive::InnerWrite(void* buffer,int memsize) { if (bTextMode) { Encoder encoder; encoder.WriteRaw(memsize,(unsigned char*)buffer); const char* encoded_data=(const char*)encoder.c_str(); TiXmlElement * xml_binary_element = new TiXmlElement("data"); TiXmlText * xml_base64_content = new TiXmlText(encoded_data); xml_binary_element->LinkEndChild( xml_base64_content); CURNODE->LinkEndChild(xml_binary_element); } else { for (int ndone=0,nwrite=0;ndone!=memsize;ndone+=nwrite) { nwrite=(int)(gzfile?gzwrite((gzFile)gzfile,(char*)buffer+ndone,memsize-ndone):fwrite((char*)buffer+ndone,1,memsize-ndone,file)); XgeReleaseAssert(nwrite); } } }
//______________________________________________________________________________ static SmartPointer<Hpc> openXmlNode(TiXmlNode* xnode,std::map<int, SmartPointer<Vector> >& arrays) { XgeReleaseAssert(!strcmpi(xnode->Value(),"node")); SmartPointer<Hpc> node(new Hpc); SmartPointer<Batch> batch(new Batch()); //parse attributees for (TiXmlAttribute* att=((TiXmlElement*)xnode)->FirstAttribute();att;att=att->Next()) { const char* att_name=att->Name(); if (!strcmp("name",att_name)) { if (!node->prop) node->prop.reset(new PropertySet); (*node->prop)[HPC_PROP_NAME]=std::string(att->Value()); continue; } if (!strcmp("pointdim",att_name)) { node->pointdim=atoi(att->Value()); continue; } if (!strcmp("spacedim",att_name)) { node->spacedim=atoi(att->Value()); continue; } if (!strcmp("vmat",att_name)) { node->vmat.reset(new Matf(node->spacedim)); Vector::parse((node->spacedim+1)*(node->spacedim+1),(float*)node->vmat->mem,att->Value(),(char*)"%e"); node->hmat.reset(new Matf(node->vmat->invert())); continue; } if (!strcmp("gltype",att_name)) { batch->primitive=atoi(att->Value()); continue; } if (!strcmp("VRMLmaterial" ,att_name)) { if (!node->prop) node->prop.reset(new PropertySet); (*node->prop)[HPC_PROP_VRML_MATERIAL]=att->Value(); continue; } if (!strcmp("VRMLtexture" ,att_name)) continue; if (!strcmp("geometry" ,att_name)) continue; if (!strcmp("vertices" ,att_name)) { batch->vertices=arrays[atoi(att->Value())]; continue; } if (!strcmp("normals" ,att_name)) { batch->normals=arrays[atoi(att->Value())]; continue; } if (!strcmp("skin",att_name)) { batch->texture0=Texture::open(att->Value()); if (batch->texture0->filename[0]!=':') batch->texture0->filename=prefix + batch->texture0->filename; continue; } if (!strcmp("skincoords" ,att_name)) { batch->texture0coords=arrays[atoi(att->Value())]; continue; } if (!strcmp("light" ,att_name)) { batch->texture1=Texture::open(att->Value()); if (batch->texture1->filename[0]!=':') batch->texture1->filename=prefix + batch->texture1->filename; continue; } if (!strcmp("lightcoords" ,att_name)) { batch->texture1coords=arrays[atoi(att->Value())]; continue; } //unknown node type XgeReleaseAssert(false); } if (batch->primitive>=0) node->batches.push_back(batch); //sub nodes for (TiXmlNode* xchild = xnode->FirstChild(); xchild != 0; xchild = xchild->NextSibling()) { //other old format! if (!strcmpi("compiled" ,xchild->Value())) { SmartPointer<Batch> batch(new Batch); for (TiXmlAttribute* att=((TiXmlElement*)xchild)->FirstAttribute();att;att=att->Next()) { if (!strcmp("primitive",att->Name())) { batch->primitive=atoi(att->Value()); continue; } if (!strcmp("vertices" ,att->Name())) { batch->vertices=arrays[atoi(att->Value())]; continue; } if (!strcmp("normals" ,att->Name())) { batch->normals=arrays[atoi(att->Value())]; continue; } if (!strcmp("texture0" ,att->Name())) { batch->texture0=Texture::open(att->Value()); if (batch->texture0->filename[0]!=':') batch->texture0->filename=prefix + batch->texture0->filename; continue; } if (!strcmp("texture0coords" ,att->Name())) { batch->texture0coords=arrays[atoi(att->Value())]; continue; } if (!strcmp("texture1" ,att->Name())) { batch->texture1=Texture::open(att->Value()); if (batch->texture1->filename[0]!=':') batch->texture1->filename=prefix + batch->texture1->filename; continue; } if (!strcmp("texture1coords" ,att->Name())) { batch->texture1coords=arrays[atoi(att->Value())]; continue; } } node->batches.push_back(batch); } else { node->childs.push_back(openXmlNode(xchild,arrays)); } } return node; }
// ------------------------------------------------------------------------- // ------------------------------------------------------------------------- void Batch::saveObj(std::string filename,std::vector<SmartPointer<Batch> > batches) { FILE* file=fopen(FileSystem::FullPath(filename).c_str(),"wt"); XgeReleaseAssert(file); Box3f box; for (int I=0;I<(int)batches.size();I++) { SmartPointer<Batch> batch=batches[I]; box.add(batch->getBox()); } Mat4f ToUnitBox= Mat4f::scale(1.0f/box.size().x,1.0f/box.size().y,1.0f/box.size().z) * Mat4f::translate(-box.p1.x,-box.p1.y,-box.p1.z); int Cont=1; for (int I=0;I<(int)batches.size();I++) { SmartPointer<Batch> batch=batches[I]; //TODO: all other cases XgeReleaseAssert(batch->primitive==Batch::TRIANGLES); Mat4f matrix=batch->matrix; matrix=ToUnitBox * matrix; Mat4f inv=matrix.invert(); /*XgeReleaseAssert(batch->texture1); XgeReleaseAssert(batch->texture1->width==batch->texture1->height); int texturedim=batch->texture1->width;*/ int nv=batch->vertices->size()/3; int nt=nv/3; XgeReleaseAssert(batch->vertices); XgeReleaseAssert(batch->normals); //XgeReleaseAssert(batch->texture1coords); float* vertex = batch->vertices->mem(); float* normal = batch->normals ->mem(); //float* lightcoord = batch->texture1coords->mem(); for (int i=0;i<nt;i++,vertex+=9,normal+=9) { Vec3f v0(vertex[0],vertex[1],vertex[2]) ; v0=matrix * v0; Vec3f v1(vertex[3],vertex[4],vertex[5]) ; v1=matrix * v1; Vec3f v2(vertex[6],vertex[7],vertex[8]) ; v2=matrix * v2; Vec4f _n0(normal[0],normal[1],normal[2],0.0); _n0=_n0 * inv; Vec3f n0=Vec3f(_n0.x,_n0.y,_n0.z).normalize(); Vec4f _n1(normal[3],normal[4],normal[5],0.0); _n1=_n1 * inv; Vec3f n1=Vec3f(_n1.x,_n1.y,_n1.z).normalize(); Vec4f _n2(normal[6],normal[7],normal[8],0.0); _n2=_n2 * inv; Vec3f n2=Vec3f(_n2.x,_n2.y,_n2.z).normalize(); /*float s0=lightcoord[i*6+0],t0=lightcoord[i*6+1]; float s1=lightcoord[i*6+2],t1=lightcoord[i*6+3]; float s2=lightcoord[i*6+4],t2=lightcoord[i*6+5];*/ // force the regeneration of float values (seems perfect for opengl/ renderman scan line conversion!) /*s0=(0.5f/(float)texturedim)+(((int)(s0*(float)texturedim))/(float)texturedim);t0=(0.5f/(float)texturedim)+(((int)(t0*(float)texturedim))/(float)texturedim); s1=(0.5f/(float)texturedim)+(((int)(s1*(float)texturedim))/(float)texturedim);t1=(0.5f/(float)texturedim)+(((int)(t1*(float)texturedim))/(float)texturedim); s2=(0.5f/(float)texturedim)+(((int)(s2*(float)texturedim))/(float)texturedim);t2=(0.5f/(float)texturedim)+(((int)(t2*(float)texturedim))/(float)texturedim); */ fprintf(file,Utils::Format("v %e %e %e\n",v0.x,v0.y,v0.z).c_str()); fprintf(file,Utils::Format("v %e %e %e\n",v1.x,v1.y,v1.z).c_str()); fprintf(file,Utils::Format("v %e %e %e\n",v2.x,v2.y,v2.z).c_str()); //fprintf(file,Utils::Format("vt %e %e\n",s0,t0).c_str()); //fprintf(file,Utils::Format("vt %e %e\n",s1,t1).c_str()); //fprintf(file,Utils::Format("vt %e %e\n",s2,t2).c_str()); fprintf(file,Utils::Format("vn %e %e %e\n",n0.x,n0.y,n0.z).c_str()); fprintf(file,Utils::Format("vn %e %e %e\n",n1.x,n1.y,n1.z).c_str()); fprintf(file,Utils::Format("vn %e %e %e\n",n2.x,n2.y,n2.z).c_str()); fprintf(file,Utils::Format("f %d//%d %d//%d %d//%d\n", Cont+0,Cont+0, Cont+1,Cont+1, Cont+2,Cont+2).c_str()); /*fprintf(file,Utils::Format("f %d/%d/%d %d/%d/%d %d/%d/%d\n", Cont+0,Cont+0,Cont+0, Cont+1,Cont+1,Cont+1, Cont+2,Cont+2,Cont+2).c_str());*/ Cont+=3; } } fclose(file); }
// ------------------------------------------------------------------------- // ------------------------------------------------------------------------- std::vector<SmartPointer<Batch> > Batch::openObj(std::string filename) { char buf[2048]; filename=FileSystem::FullPath(filename); //open the Text obj file FILE* file=fopen(filename.c_str(),"rt"); if (!file) return std::vector<SmartPointer<Batch> >(); std::vector<float> vertices; std::vector<float> normals; std::vector<float> texcoords; std::vector<int> vertices_indices; std::vector<int> normals_indices; std::vector<int> texcoords_indices; int nline=0; while (fscanf(file, "%s", buf) != EOF) { switch (buf[0]) { case 'v': /* vertex! */ { if (!buf[1]) { float X,Y,Z; fscanf(file, "%e %e %e", &X, &Y, &Z); vertices.push_back(X); vertices.push_back(Y); vertices.push_back(Z); } else if (buf[1]=='n') { float NX,NY,NZ; fscanf(file, "%e %e %e", &NX, &NY, &NZ); normals.push_back(NX); normals.push_back(NY); normals.push_back(NZ); } else if (buf[1]=='t') { float TX, TY; fscanf(file, "%e %e", &TX, &TY); texcoords.push_back(TX); texcoords.push_back(TY); } nline++; break; } case 'f': /* face */ { int c; int V,N,T; for (int i=0;i<3;i++) { fscanf(file,"%d",&V); if (V<0) V=((int)vertices.size()/3)+V; else V--; XgeReleaseAssert(V>=0 && V<((int)vertices.size()/3)); vertices_indices.push_back(V*3+0); vertices_indices.push_back(V*3+1); vertices_indices.push_back(V*3+2); /* v/t/n */ if (normals.size() && texcoords.size()) { c=fgetc(file); XgeReleaseAssert(c=='/'); fscanf(file,"%d",&T); if (T<0) V=((int)texcoords.size()/2)+T; else T--; XgeReleaseAssert(T>=0 && T<((int)texcoords.size()/2)); texcoords_indices.push_back(T*2+0); texcoords_indices.push_back(T*2+1); c=fgetc(file); XgeReleaseAssert(c=='/'); fscanf(file,"%d",&N); if (N<0) N=((int)normals.size()/3)+N; else N--; XgeReleaseAssert(N>=0 && N<((int)normals.size()/3)); normals_indices.push_back(N*3+0); normals_indices.push_back(N*3+1); normals_indices.push_back(N*3+2); } else if (normals.size()) /* v//n */ { c=fgetc(file); XgeReleaseAssert(c=='/'); c=fgetc(file); XgeReleaseAssert(c=='/'); fscanf(file,"%d",&N); if (N<0) N=((int)normals.size()/3)+N; else N--; XgeReleaseAssert(N>=0 && N<((int)normals.size()/3)); normals_indices.push_back(N*3+0); normals_indices.push_back(N*3+1); normals_indices.push_back(N*3+2); } else if (texcoords.size()) { c=fgetc(file); XgeReleaseAssert(c=='/'); fscanf(file,"%d",&T); if (T<0) V=((int)texcoords.size()/2)+T; else T--; XgeReleaseAssert(T>=0 && T<((int)texcoords.size()/2)); texcoords_indices.push_back(T*2+0); texcoords_indices.push_back(T*2+1); c=fgetc(file); if (c!='/') ungetc(c,file); } if (i<2) { c=fgetc(file); XgeReleaseAssert(c==' '); } } nline++; break; } default: /* skip the line */ { skipLine(file); nline++; break; } } } fclose(file); SmartPointer<Batch> batch(new Batch); batch->primitive=Batch::TRIANGLES; if (!vertices.size() || !vertices_indices.size()) return std::vector<SmartPointer<Batch> >(); batch->vertices.reset(new Vector(vertices_indices,vertices)); if (normals_indices .size() && normals.size()) { batch->normals.reset(new Vector(normals_indices,normals)); } else { //automatic calculation of normals normals.clear(); int nt=batch->vertices->size()/9; float* t=batch->vertices->mem(); for (int i=0;i<nt;i++,t+=9) { Vec3f p0(t[0],t[1],t[2]); Vec3f p1(t[3],t[4],t[5]); Vec3f p2(t[6],t[7],t[8]); Vec3f n=((p1-p0).cross(p2-p0)).normalize(); normals.push_back(n.x);normals.push_back(n.y);normals.push_back(n.z); normals.push_back(n.x);normals.push_back(n.y);normals.push_back(n.z); normals.push_back(n.x);normals.push_back(n.y);normals.push_back(n.z); } batch->normals.reset(new Vector(normals)); } if (texcoords_indices.size() && texcoords.size()) batch->texture0coords.reset(new Vector(texcoords_indices,texcoords)); std::vector<SmartPointer<Batch> > ret; ret.push_back(batch); return ret; }