translating objects with cursor

Started by
3 comments, last by Uthman 18 years, 6 months ago
this isn't really an opengl question perse which is why i am posting it here as opposed to say in the opengl forums; nevertheless, i am currently using the opengl api... i have a 3d model for the x,y,z axes. this model is drawn in the screen and using a selection technique, i figure out which axes the user currently has the mouse on. my goal is to have it so that if the user clicks and moves the mouse, the axes will translate depending on which one was clicked. my technique is to unproject the screen coordinates @ mousex, height-mousey and at the z coordinate of the axes. with the resulting 3d point, adjust the position. this method does not work, however. the axes jump all over the place. any suggestions?
"a low level aho master like you couldn't kill me even if I let you"
Advertisement
Just a couple of questions. What do you mean by 'translate' the axes? Or are you perhaps trying to rotate them? Also, when you say you pass in the 'z coordinate of the axes', what do you mean exactly?

Actually, you might just post the relevant code - it'll probably answer the above questions as well as others that might come up.
double dX,dY,dZ;

gluUnProject ((double)mousePnt.x, (double)(tehHeight-mousePnt.y), (double)axes.z, mvmatrix, projmatrix, viewport, &dX, &dY, &dZ);

if(xAxisSelected) axes.x = dX;
if(yAxisSelected) axes.y = dY;
if(zAxisSelected) axes.z = dZ;

axes is a point3d. the unit axes arrows originate out of this point and are directed in the x, y and z directions respectively.

when the user, say, clicks and drags on the y axis, i want point3d axes to translate up in the y direction.
"a low level aho master like you couldn't kill me even if I let you"
Quote:double dX,dY,dZ;

gluUnProject ((double)mousePnt.x, (double)(tehHeight-mousePnt.y), (double)axes.z, mvmatrix, projmatrix, viewport, &dX, &dY, &dZ);

if(xAxisSelected) axes.x = dX;
if(yAxisSelected) axes.y = dY;
if(zAxisSelected) axes.z = dZ;

axes is a point3d. the unit axes arrows originate out of this point and are directed in the x, y and z directions respectively.

when the user, say, clicks and drags on the y axis, i want point3d axes to translate up in the y direction.
Ok, some follow-up questions. I assume some code is missing there since we don't see where the 'AxisSelected' variables are created or set. Can you post that part? Also, I'd recommend renaming 'axes' to 'origin'. That would be less confusing, for me at least. When I read 'axes' I think of, for example, a struct holding three vectors which are the axes of a coordinate system. From there, 'axes.x' looks like the x axis of this system. I understand it's a point, but it just doesn't parse when you're trying to read it.

Beyond that I'm still not quite sure how the system is supposed to work, but more code or further explanation will probably clear that up.
void PushColor(int index, bool select){	if(!select || index<1 || index>24) return;	int theColor;	glFeatures[0] = glIsEnabled( GL_TEXTURE_2D );	glFeatures[1] = glIsEnabled( GL_DITHER );	glFeatures[2] = glIsEnabled( GL_BLEND );	glFeatures[3] = glIsEnabled( GL_LIGHTING );	glFeatures[4] = glIsEnabled( GL_FOG );	glDisable(GL_TEXTURE_2D);	glDisable(GL_DITHER);	glDisable(GL_BLEND);	glDisable(GL_LIGHTING);	glDisable(GL_FOG);	if(index<9)	// 1-8	{		theColor = index*32-1;		glColor3ub(theColor,0,0);	}else if(index<17) //9-16	{		theColor = (index-8)*32-1;		glColor3ub(0,theColor,0);	}else if(index<25) //17-24	{		theColor = (index-16)*32-1;		glColor3ub(0,0,theColor);	}}void PopColor(){	if(glFeatures[0]) glEnable( GL_TEXTURE_2D );	if(glFeatures[1]) glEnable( GL_DITHER );	if(glFeatures[2]) glEnable( GL_BLEND );	if(glFeatures[3]) glEnable( GL_LIGHTING );	if(glFeatures[4]) glEnable( GL_FOG );	glColor3ub(1,1,1);}void SelectionArrows(bool selectionMode){	// on a per view basis	int NSJ = yourMap.getNumSelectedJoints();	if(NSJ>3)	{		/*			if reset- get the straight line vector of curJoint to oldJoint					- position points A & D at the ends					- position points B & C at the 25% and 75% positions respectively along the AD vector		*/		MapJoint old = yourMap.getOldMapJoint(), cur = yourMap.getCurMapJoint();		Vector3D dir = cur.pos_c - old.pos_c;		// first control point		if(reset) translators[0] = old.pos_c + dir*0.25f;	// 25% CP		{			glColor3f(1,0.73f,0.25f);		PushColor(1,selectionMode);	DrawDebugCube(translators[0]);	PopColor();			glColor4f(0,0,1,1);				PushColor(2,selectionMode);	DrawArrow(translators[0], 0, 0, 0, 0);	PopColor();			glBlendFunc(GL_SRC_ALPHA,GL_ONE);			glColor4f(0,1,0,1);	glColor4f(0.5f,0.5f,0.5f,0.5f);		PushColor(3,selectionMode);	DrawArrow(translators[0], 90, 1, 0, 0);	PopColor();			glColor4f(0,0,1,1);	glColor4f(0.5f,0.5f,0.5f,0.5f);		PushColor(4,selectionMode);	DrawArrow(translators[0], 270, 0, 0, 1);	PopColor();			glBlendFunc(GL_ONE,GL_ZERO);		}		// second control point		if(reset) translators[1] = old.pos_c + dir*0.75f;	// 75% CP		{			glColor3f(1,0.73f,0.25f);		PushColor(5,selectionMode);	DrawDebugCube(translators[1]);	PopColor();			glColor4f(0,0,1,1);				PushColor(6,selectionMode);	DrawArrow(translators[1], 0, 0, 0, 0);	PopColor();			glBlendFunc(GL_SRC_ALPHA,GL_ONE);			glColor4f(0,1,0,1);	glColor4f(0.5f,0.5f,0.5f,0.5f);		PushColor(7,selectionMode);	DrawArrow(translators[1], 90, 1, 0, 0);	PopColor();			glColor4f(0,0,1,1);	glColor4f(0.5f,0.5f,0.5f,0.5f);		PushColor(8,selectionMode);	DrawArrow(translators[1], 270, 0, 0, 1);	PopColor();			glBlendFunc(GL_ONE,GL_ZERO);		}		reset = false;	}	else		reset = true;	glColor4f(1,1,1,1);}void ColorSelectionTechnique(int params){	if(kbd[SDLK_LCTRL] || kbd[SDLK_RCTRL]) return;	if(yourMap.getNumSelectedJoints()<4) return;	InputStat mousePnt = tehScreen.getMouseState();	params	= -params;	SetView(params);	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	SelectionArrows(true);	GLubyte pixel[3];	glReadPixels((int)mousePnt.x,(int)(tehHeight-mousePnt.y),1,1, GL_RGB,GL_UNSIGNED_BYTE,(void *)pixel);	int theIndex=0;	if(pixel[0]>0)		theIndex = (pixel[0]+1)/32;	else if(pixel[1]>0)		theIndex = (pixel[1]+1)/32+8;	else if(pixel[2]>0)		theIndex = (pixel[2]+1)/32+16;	// Unproject the correct point to get more correct points...	double dX,dY,dZ;	if(theIndex<5)		gluUnProject ((double)mousePnt.x, (double)(tehHeight-mousePnt.y), (double)translators[0].z, views[params].vi.mvmatrix, views[params].vi.projmatrix, views[params].vi.viewport, &dX, &dY, &dZ);		else if(theIndex<9)		gluUnProject ((double)mousePnt.x, (double)(tehHeight-mousePnt.y), (double)translators[1].z, views[params].vi.mvmatrix, views[params].vi.projmatrix, views[params].vi.viewport, &dX, &dY, &dZ);		switch(theIndex)	{		case 1:	break;		case 2:				translators[0].y = dY;			break;		case 3:	break;		case 4:	break;		case 5:	break;		case 6:			translators[1].y = dY;			break;		case 7:	break;		case 8:	break;	}	printf("%d %f\n", theIndex, (float)dY);		// If there is any velocity on the mouse, update the eye's location accordingly		/*		Do any math that needs to be done on the selected tile geometry			- calculate the velocity of the slope per unit of change around any specific point			- starting from the LOWER (closer to root node) point:				- add that slope to the angle of each point				- find the end point and use kinematics to move the next point's end point to that point's end point				- check to make sure the next points angles remain within bounds				- if not, move it towards the smallest direction that will make it within bounds			ON nsj change, reset!		*/}





i know that the arrow selection code works because i've couted the index and they all came out perfect. the error is in the part where i do the actual translation of the axes.

the selected joints are colored orange in the picture. there are two axes which i call 'translators' in the code. it ie defines as Point3D translators[2]. My 3D model is just one of the arrows. i rotate it before drawing them so that they point out in the correct axis direction. the final objective is to be able to translate the joints segements using a beizer curve, but for now, i just need to be able to move the axes.


further notes:

when a few (>3) joints are selected, the dir vector is the straight line from the first selected to the last selected. the two 'axes' points are 25% and 75% from either end. the original position of these axes is reset whenever the number of selected joints is changed (hence the rest bool). as for the switch statement, the indices are defined when the arrows are drawn. so for example, 1 would be the actual point of the axes (the orange box in the picture). 2 would be the y axis sticking straight up. three would be like the x and four would be the z. the same goes for the other one. five would be the cube, six would be straight up, and so on.
"a low level aho master like you couldn't kill me even if I let you"

This topic is closed to new replies.

Advertisement