Exemple #1
0
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)));
}
Exemple #2
0
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);
}
Exemple #3
0
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();
}
Exemple #4
0
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);
}
Exemple #5
0
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;
}