How to add texture information in "ccSphere" class?

Any question about the main GUI application (frontend)
daniel
Site Admin
Posts: 7332
Joined: Wed Oct 13, 2010 7:34 am
Location: Grenoble, France
Contact:

Re: How to add texture information in "ccSphere" class?

Post by daniel »

Ok:
- the texture seems rotated of 90 degrees, therefore I guess you should check the roles of A, B, C and D (for a texture, the (0,0) coordinate is the upper left pixel, and (1,1) the lower bottom pixel).

- considering the repetition of the texture pattern, it seems you have also missed the fact that if you want the texture to span once over the whole sphere, the texture coordinates must span from 0 to 1 on the whole sphere. This means that the first 'segment' of the sphere will span from 0 to 1/g_iCol, then the second will span from 1/g_iCol to 2/g_iCol, etc.

Once fixed, can you post your updated code?
Daniel, CloudCompare admin
Jame
Posts: 7
Joined: Wed Jul 20, 2016 2:51 am

Re: How to add texture information in "ccSphere" class?

Post by Jame »

daniel wrote:Ok:
- the texture seems rotated of 90 degrees, therefore I guess you should check the roles of A, B, C and D (for a texture, the (0,0) coordinate is the upper left pixel, and (1,1) the lower bottom pixel).

- considering the repetition of the texture pattern, it seems you have also missed the fact that if you want the texture to span once over the whole sphere, the texture coordinates must span from 0 to 1 on the whole sphere. This means that the first 'segment' of the sphere will span from 0 to 1/g_iCol, then the second will span from 1/g_iCol to 2/g_iCol, etc.

Once fixed, can you post your updated code?
Ok,thanks!
I will try first to solve this problem according to your ideas..
Yeyan
Posts: 7
Joined: Wed Jul 27, 2016 6:58 am

Re: How to add texture information in "ccSphere" class?

Post by Yeyan »

daniel wrote:Ok:
- the texture seems rotated of 90 degrees, therefore I guess you should check the roles of A, B, C and D (for a texture, the (0,0) coordinate is the upper left pixel, and (1,1) the lower bottom pixel).

- considering the repetition of the texture pattern, it seems you have also missed the fact that if you want the texture to span once over the whole sphere, the texture coordinates must span from 0 to 1 on the whole sphere. This means that the first 'segment' of the sphere will span from 0 to 1/g_iCol, then the second will span from 1/g_iCol to 2/g_iCol, etc.

Once fixed, can you post your updated code?
Hello:
I'm Jame's friend, I fix his code, now it can add the texture to the sphere, the code in "ccSphere" like as the flowing:

Code: Select all

/*
ccSphere
*/
bool ccSphere::buildUp()
{
	if (m_drawPrecision < MIN_DRAWING_PRECISION)
		return false;

	const unsigned steps = m_drawPrecision;

	//vertices
	ccPointCloud* verts = vertices();
	assert(verts);

	//vertices
	unsigned count = (steps+1)*(steps+1);
	//faces
	unsigned faces = (steps)*(steps)*2;

	if (!init(count,true,faces,0))
	{
		ccLog::Error("[ccSphere::buildUp] Not enough memory");
		return false;
	}

	//then, angular sweep
	PointCoordinateType angle_rad_step = static_cast<PointCoordinateType>(M_PI)/static_cast<PointCoordinateType>(steps);
	CCVector3 N0,N,P;
	{
		for (unsigned j=0; j<=steps; ++j)
		{
			PointCoordinateType theta = static_cast<PointCoordinateType>(j) * angle_rad_step;
			PointCoordinateType cos_theta = cos(theta);
			PointCoordinateType sin_theta = sin(theta);

			N0.x = sin_theta;
			N0.y = 0;
			N0.z = cos_theta;
		
			for (unsigned i=0; i<=steps; ++i)
			{
				PointCoordinateType phi = static_cast<PointCoordinateType>(2*i) * angle_rad_step;
				PointCoordinateType cos_phi = cos(phi);
				PointCoordinateType sin_phi = sin(phi);

				N.x = N0.x*cos_phi;
				N.y = N0.x*sin_phi;
				N.z = N0.z;
				N.normalize();

				P = N * m_radius;

				verts->addPoint(P);
				verts->addNorm(N);
			}
		}
	}

	//faces
	{
		assert(m_triVertIndexes);

		// set vert index
		float TPointIndex[4];
		//slices
		for (unsigned j=1; j<=steps; ++j)
		{
			unsigned shift = steps+1;		
			for (unsigned i=0; i<steps; ++i)
			{
				// 0,1
				// 2,3
				TPointIndex[0] =i+(j-1)*shift;
				TPointIndex[1] =TPointIndex[0] + 1;
				TPointIndex[2] =i+j*shift;
				TPointIndex[3] =TPointIndex[2] + 1;

				// 0,2,1
				addTriangle(TPointIndex[0],TPointIndex[2],TPointIndex[1]);
				// 2,3,1
				addTriangle(TPointIndex[2],TPointIndex[3],TPointIndex[1]);
				
			}
		}
	}

	notifyGeometryUpdate();
	showNormals(true);
	return true;
}
//! Sets an image as texture
bool ccSphere::setAsTexture(QImage image)
{
	if (image.isNull())
	{
		ccLog::Warning("[ccPlane::setAsTexture] Invalid texture image!");
		return false;
	}

	const unsigned steps = m_drawPrecision;
	//vertices
	unsigned count = (steps+1)*(steps+1);

	unsigned faces = steps*steps*2;

	//texture coordinates
	TextureCoordsContainer* texCoords = getTexCoordinatesTable();
	if (!texCoords)
	{
		texCoords = new TextureCoordsContainer();
		if (!texCoords->reserve(count))
		{
			//not enough memory
			ccLog::Warning("[ccSphere::setAsTexture] Not enough memory!");
			delete texCoords;
			return false;
		}

	
		//create default texture coordinates
	
		float TA[2];
		for (int j=0;j<=steps;++j)
		{
			for (int i=0;i<=steps;++i)
			{
				TA[0] = (float)j/steps;
				TA[1] =  (float)i/steps;

				texCoords->addElement(TA);
			}
		}

		setTexCoordinatesTable(texCoords);
	}

	if (!hasPerTriangleTexCoordIndexes())
	{
		if (!reservePerTriangleTexCoordIndexes())
		{
			//not enough memory
			ccLog::Warning("[ccSphere::setAsTexture] Not enough memory!");
			setTexCoordinatesTable(0);
			removePerTriangleMtlIndexes();
			return false;
		}

		// set texture
		{
			assert(m_triVertIndexes);

			// tex vert index
			float TPointIndex[4];
			//slices

			//slices
			for (unsigned j=1; j<=steps; ++j)
			{
				unsigned shift = steps+1;		
				for (unsigned i=0; i<steps; ++i)
				{
					// 0,1
					// 2,3
					TPointIndex[0] =i+(j-1)*shift;
					TPointIndex[1] =TPointIndex[0] + 1;
					TPointIndex[2] =i+j*shift;
					TPointIndex[3] =TPointIndex[2] + 1;

					// 0,2,1
					addTriangleTexCoordIndexes(TPointIndex[0],TPointIndex[2],TPointIndex[1]);
					// 2,3,1
					addTriangleTexCoordIndexes(TPointIndex[2],TPointIndex[3],TPointIndex[1]);

				}
			}
		}

	}

	if (!hasPerTriangleMtlIndexes())
	{
		if (!reservePerTriangleMtlIndexes())
		{
			//not enough memory
			ccLog::Warning("[ccSphere::setAsTexture] Not enough memory!");
			setTexCoordinatesTable(0);
			removePerTriangleTexCoordIndexes();
			return false;
		}

		//set default material indexes
		for (unsigned j=0; j<faces; ++j)
		{
			addTriangleMtlIndex(0);
		}
	}

	//set material
	if (!getMaterialSet())
		setMaterialSet(new ccMaterialSet());
	ccMaterialSet* materialSet = const_cast<ccMaterialSet*>(getMaterialSet());
	assert(materialSet);
	//remove old material (if any)
	materialSet->clear();
	//add new material
	{
		ccMaterial::Shared material(new ccMaterial("texture"));
		material->setTexture(image,QString(),false);
		materialSet->addMaterial(material);
	}

	showMaterials(true);
	return true;
}
but I have some problems:
-1:
-when I add texture, I must rorate the image 270 degrees, it can be right, like this
https://s20.postimg.org/ewebykxzh/zhengque.jpg
if I don‘t rotate ,it will like this,I can’t understand why.
https://s20.postimg.org/gph8mwj65/zhengque1.jpg
I can't understand why it is.
-2:
-I want to do a panoramic view , just like this:http://threejs.org/examples/?q=pano#web ... ectangular,
so I move the 'ccSphere' object to position (100,100,50), and set camera to the same postion (100,100,50), it just like I see it in the sphere center, but when rorate the 'pano', it is wrong, I see the code, the error caulsed by "convertMousePositionToOrientation", it calcuated pp.w value is 0.0 (in "ccIncludeGL.h" 217 line). It is important to me, can you give me some advices to fix it?

Code: Select all

     
	//The result normalizes between -1 and 1
		if (Pp.w == 0.0)
		{
			assert(false);
			return false;
		}

Code: Select all


/*
	Rorate image 270 angles
*/
	ccSphere* pPano =  new ccSphere(100);
	pPano->setDrawingPrecision(48);
	QImage image;
	
	// load image
	image.load("E:\\04_Data\\pano.jpg");   
	
	// rorate image
	QMatrix matrix;
	matrix.rotate(270);
	
	// set texture
	pPano->setAsTexture(image.transformed(matrix));
	
	// move the pPano to position (100,100,50)
	CCVector3 r1(1,0,0);
	CCVector3 r2(0,1,0);
	CCVector3 r3(0,0,1);
	CCVector3 t2(100,100,50);
	ccGLMatrix trans1(r1,r2,r3,t2);
	pPano->setGLTransformation(trans1);
	pPano->applyGLTransformation_recursive();
	
	//  set camera to position (100,100,50)
	CCVector3d pos(100,100,50);
	ccGLWindow *child = MainWindow::GetActiveGLWindow();
	child->blockSignals(true);
	child->setCameraPos(pos);
	child->blockSignals(false);
	child->redraw();
daniel
Site Admin
Posts: 7332
Joined: Wed Oct 13, 2010 7:34 am
Location: Grenoble, France
Contact:

Re: How to add texture information in "ccSphere" class?

Post by daniel »

1 - if you need to rotate your image, then your texture coordinates are probably inverted (you'll have to invert X and Y typically)

2 - to do a panoramic view, you'll need to switch to perspective mode. Moreover, it may be easier to use the 'bubble view mode'. To activate it, you'll simply need to define a fake sensor (ccCameraSensor for instance) and place it at the center of your sphere.
Daniel, CloudCompare admin
Yeyan
Posts: 7
Joined: Wed Jul 27, 2016 6:58 am

Re: How to add texture information in "ccSphere" class?

Post by Yeyan »

daniel wrote:1 - if you need to rotate your image, then your texture coordinates are probably inverted (you'll have to invert X and Y typically)

2 - to do a panoramic view, you'll need to switch to perspective mode. Moreover, it may be easier to use the 'bubble view mode'. To activate it, you'll simply need to define a fake sensor (ccCameraSensor for instance) and place it at the center of your sphere.
OK! THANK YOU!
Post Reply