Box2i Pixel_Data::proxy_scale(const Box2i & in, Pixel_Data_Info::PROXY proxy) { const int scale = proxy_scale(proxy); return Box2i( Math::ceil(in.x / static_cast<double>(scale)), Math::ceil(in.y / static_cast<double>(scale)), Math::ceil(in.size.x / static_cast<double>(scale)), Math::ceil(in.size.y / static_cast<double>(scale))); }
Box2i Frame::frame_geom() const { const Box2i & geom = this->geom(); const int margin = frame_size(); return Box2i( geom.x + margin, geom.y + margin, geom.w - margin * 2, geom.h - margin * 2); }
void Util::quad(const Pixel_Data_Info & in) { double u [] = { 0, 0 }, v [] = { 0, 0 }; u[! in.mirror.x] = in.size.x; v[! in.mirror.y] = in.size.y; const V2f uv [] = { V2f(u[0], v[0]), V2f(u[0], v[1]), V2f(u[1], v[1]), V2f(u[1], v[0]) }; glBegin(GL_QUADS); Gl_Util::draw_box(Box2i(in.size), uv); glEnd(); }
Box2i dataWindowForTile (const TileDescription &tileDesc, int minX, int maxX, int minY, int maxY, int dx, int dy, int lx, int ly) { V2i tileMin = V2i (minX + dx * tileDesc.xSize, minY + dy * tileDesc.ySize); V2i tileMax = tileMin + V2i (tileDesc.xSize - 1, tileDesc.ySize - 1); V2i levelMax = dataWindowForLevel (tileDesc, minX, maxX, minY, maxY, lx, ly).max; tileMax = V2i (std::min (tileMax[0], levelMax[0]), std::min (tileMax[1], levelMax[1])); return Box2i (tileMin, tileMax); }
Box2i scale( const Box2i& b, float sx, float sy) { return Box2i( V2i( Math<float>::floor( b.min.x * sx), Math<float>::floor( b.min.y * sy)), V2i( Math<float>::ceil( b.max.x * sx), Math<float>::ceil( b.max.y * sy))); }
std::vector< SmartPointer<Batch> > Unwrapper::Unwrap(Mat4f _T1,SmartPointer<Batch> source_batch) { std::vector< SmartPointer<Batch> > ret; //return the batch I cannot handle untouched if (source_batch->primitive!=Batch::TRIANGLES || !source_batch->vertices || !source_batch->vertices->size()) { ret.push_back(source_batch); return ret; } //second transformation matrix Mat4f Matrix= _T1 * source_batch->matrix; //create a perfect copy and leave the source batch untouched SmartPointer<Batch> batch(new Batch(*source_batch)); //overwrite texture1 coordinates int ntriangles=batch->vertices->size()/9; batch->texture1coords.reset(new Array(ntriangles*6)); batch->texture1.reset(); float* vertices = (float*)batch -> vertices -> c_ptr(); float* lightcoord = (float*)batch -> texture1coords -> c_ptr(); //***************************************************************************** // step 1: triangleProject and rotate GL_TRIANGLES so the longest edge is horizontal and the top vertex is above the horizontal line //****************************************************************************** //LOG("projecting %d triangles\n",ntriangles); for (int T=0;T<ntriangles;T++,vertices+=9) { //apply transformation matrix Vec3f v0 = Matrix * Vec3f(vertices+0); Vec3f v1 = Matrix * Vec3f(vertices+3); Vec3f v2 = Matrix * Vec3f(vertices+6); Triangle2i triangle=triangleProject(texturedim,factor,v0,v1,v2); //NOTE: for now on I have integer coordinates stored! (*lightcoord++)=triangle.p0.x; (*lightcoord++)=triangle.p0.y; (*lightcoord++)=triangle.p1.x; (*lightcoord++)=triangle.p1.y; (*lightcoord++)=triangle.p2.x; (*lightcoord++)=triangle.p2.y; } //****************************************************************************** // step 2: sort the triangle by decreasing height (this is for good placement of GL_TRIANGLES) //****************************************************************************** std::vector<int> order(ntriangles); for (int T=0;T<ntriangles;T++) order[T]=T; std::sort(order.begin(),order.end(),TriangleSort(batch->texture1coords)); //****************************************************************************** // step3: pack continous segment //****************************************************************************** std::vector<int> cur_indices; std::vector<int> prv_indices; lightcoord = (float*)batch -> texture1coords -> c_ptr(); for (int Torder=0;Torder<ntriangles;Torder++) { int T=order[Torder]; // get the integer texture coordinates as Vec2i Triangle2i triangle ( Vec2i(lightcoord[T*6+0],lightcoord[T*6+1]), Vec2i(lightcoord[T*6+2],lightcoord[T*6+3]), Vec2i(lightcoord[T*6+4],lightcoord[T*6+5]) ); //not valid!= since the projection failed if (!triangle.p0.x && !triangle.p0.y && !triangle.p1.x && !triangle.p1.y && !triangle.p2.x && !triangle.p2.y) continue; //give a random color Color4f color=Color4f::randomRGB(); while (true) { //try with the current texture if (cur.rgb && triangleFits(triangle,cur.rgb,cur.alpha,cur.queue,color)) { lightcoord[T*6+0]=(float)triangle.p0.x;lightcoord[T*6+1]=(float)triangle.p0.y; lightcoord[T*6+2]=(float)triangle.p1.x;lightcoord[T*6+3]=(float)triangle.p1.y; lightcoord[T*6+4]=(float)triangle.p2.x;lightcoord[T*6+5]=(float)triangle.p2.y; cur_indices.push_back(T*3+0); //here I put indices of vertices (each triangle has 3 vertices) cur_indices.push_back(T*3+1); cur_indices.push_back(T*3+2); break; } //try to fitTriangle2i with the previous texture (seems to be better to do here!) if (prv.rgb && triangleFits(triangle,prv.rgb,prv.alpha,prv.queue,color)) { lightcoord[T*6+0]=(float)triangle.p0.x;lightcoord[T*6+1]=(float)triangle.p0.y; lightcoord[T*6+2]=(float)triangle.p1.x;lightcoord[T*6+3]=(float)triangle.p1.y; lightcoord[T*6+4]=(float)triangle.p2.x;lightcoord[T*6+5]=(float)triangle.p2.y; prv_indices.push_back(T*3+0); prv_indices.push_back(T*3+1); prv_indices.push_back(T*3+2); break; } //cannot fitTriangle2i in prev or current. New texture needed, drop previous one if (prv_indices.size()) { ret.push_back(batch->getTriangles(prv_indices)); ret[ret.size()-1]->texture1=prv.rgb; } //the previous becames the current one prv=cur; prv_indices=cur_indices; //allocate new texture cur.rgb .reset(new Texture(texturedim,texturedim,24,0)); cur.alpha.reset(new Texture(texturedim,texturedim, 8,0)); cur.rgb->filename=""; if (texture_template.length()) cur.rgb->filename=Utils::Format(texture_template.c_str(),(int)new_light_textures.size()).c_str(); new_light_textures.push_back(cur.rgb); //LOG("New texture %d\n",(int)new_light_textures.size()); cur.queue.clear(); cur.queue.insert(Box2i(Vec2i(1,1),Vec2i(texturedim-2,texturedim-2),0)); //this is the working area cur_indices.clear(); } //while true } //for each triangle //****************************************************************************** // step4: flush residual //****************************************************************************** if (prv_indices.size()) { ret.push_back(batch->getTriangles(prv_indices)); ret[ret.size()-1]->texture1=prv.rgb; } if (cur_indices .size()) { ret.push_back(batch->getTriangles(cur_indices)); ret[ret.size()-1]->texture1=cur.rgb; } //****************************************************************************** //convert back to integer coordinates //****************************************************************************** for (std::vector<SmartPointer<Batch> >::iterator ct=ret.begin();ct!=ret.end();ct++) { XgeDebugAssert((*ct)->primitive==Batch::TRIANGLES); float* t= (float*)(*ct)->texture1coords->c_ptr(); for (int i=0;i<(int)(*ct)->texture1coords->size();i++) { int ival=(int)(*t); float fval=(float)(0.5f/texturedim+ival/(float)texturedim); //robust conversion from int to float *t++=fval; } } ntriangles_done+=ntriangles; //#ifdef _DEBUG //LOG("RibBake:: GL_TRIANGLES done %2d (ntextures %d)\n",ntriangles_done,(int)this->new_light_textures.size()); //#endif return ret; }