Sign in to follow this  
Hassanbasil

object free rotation

Recommended Posts

Hello, everyone I'm confused trying to apply free rotation for my objects, i've done it for my cameras, but i dont know how should i do it with objects, at the moment i have:
void hxObject::Yaw ( float angle )
{
	yaw += angle;
	while ( yaw > 360 )
		yaw -= 360;
	while ( yaw < 0 )
		yaw += 360;
	angle = D3DXToRadian ( angle );
	D3DXMATRIX T;
	D3DXMatrixRotationAxis(&T, &up, angle);

	// rotate _right and _look around _up or y-axis
	D3DXVec3TransformCoord(&right,&right, &T);
	D3DXVec3TransformCoord(&look,&look, &T);
}
void hxObject::Pitch ( float angle )
{
	pitch += angle;
	while ( pitch > 360 )
		pitch -= 360;
	while ( pitch < 0 )
		pitch += 360;
	angle = D3DXToRadian ( angle );
	D3DXMATRIX T;
	D3DXMatrixRotationAxis(&T, &right, angle);

	// rotate _up and _look around _right vector
	D3DXVec3TransformCoord(&up,&up, &T);
	D3DXVec3TransformCoord(&look,&look, &T);
}
void hxObject::Roll ( float angle )
{
	roll += angle;
	while ( roll > 360 )
		roll -= 360;
	while ( roll < 0 )
		roll += 360;
	angle = D3DXToRadian ( angle );
	D3DXMATRIX T;
	D3DXMatrixRotationAxis(&T, &look, angle);

	// rotate _up and _right around _look vector
	D3DXVec3TransformCoord(&right,&right, &T);
	D3DXVec3TransformCoord(&up,&up, &T);
}
void hxObject::Move ( float units )
{
	units /= 10;
	pos += look * units;
}
void hxObject::Strafe ( float units )
{
	units /= 10;
	pos += right * units;
}
void hxObject::Fly ( float units )
{
	units /= 10;
	pos += up * units;
}

i think this code is right isn't it? well, i don't know how to render it, i have the following variables to describe the object's location/angle:
	D3DXMATRIX WorldMatrix;

	D3DXVECTOR3 up;
	D3DXVECTOR3 right;
	D3DXVECTOR3 look;
	D3DXVECTOR3 pos;

	float yaw, pitch, roll;

how should i make the world transformation for the object? thanks in advance -Hassan

Share this post


Link to post
Share on other sites
i have the following render now:

D3DXMATRIX mpos, scale, mx, my, mz;
float posfactor = 10;
if ( scaleFactor == 2000 )
posfactor = 0.5;
D3DXMatrixTranslation ( &mpos, pos.x/posfactor, pos.y/posfactor, pos.z/posfactor );
D3DXMatrixRotationX ( &mx, D3DXToRadian ( pitch ) );
D3DXMatrixRotationY ( &my, D3DXToRadian ( yaw ) );
D3DXMatrixRotationZ ( &mz, D3DXToRadian ( roll ) );
D3DXMatrixScaling ( &scale, fScale/scaleFactor, fScale/scaleFactor, fScale/scaleFactor );
WorldMatrix = scale * (mz*mx*my) * mpos;

MainCore->GetDevice()->SetTransform ( D3DTS_WORLD, &WorldMatrix );



but the look/right/up vectors messes up sometimes

Share this post


Link to post
Share on other sites
You can use D3DXMatrixRotationYawPitchRoll to build your matrix out of angles.
http://msdn.microsoft.com/en-us/library/bb205361(VS.85).aspx

Or if your camera class is using right/look/up vectors, use that but an inversed view matrix makes it world.

Share this post


Link to post
Share on other sites
Quote:

Or if your camera class is using right/look/up vectors, use that but an inversed view matrix makes it world.


what do you mean? also, i'm trying to get object free rotation, not camera, if i use yawpitchroll, i can't have right/up/look vectors, which means i cant make functions such as move/fly/strafe.

Share this post


Link to post
Share on other sites
Maybe you should rotate you matrix as you wish, and keep track of global world space vectors like this
D3DXVec3TransformCoord(&globalRight,&VECTOR3(1,0,0), &objectMatrix);

Then strafe your matrix position along that vector.

About the camera, if you are already using a camera which is working with vectors, use that for your objects, but inverse the view matrix to make it world space.

Share this post


Link to post
Share on other sites
works weird,

my source:

//render
D3DXMATRIX mpos, scale, rot;
float posfactor = 10;
if ( scaleFactor == 2000 )
posfactor = 10;
D3DXMatrixTranslation ( &mpos, pos.x/posfactor, pos.y/posfactor, pos.z/posfactor );
D3DXMatrixRotationYawPitchRoll ( &rot, D3DXToRadian ( yaw ), D3DXToRadian ( pitch ), D3DXToRadian ( roll ) );
D3DXMatrixScaling ( &scale, fScale/scaleFactor, fScale/scaleFactor, fScale/scaleFactor );
WorldMatrix = scale * rot * mpos;

MainCore->GetDevice()->SetTransform ( D3DTS_WORLD, &WorldMatrix );

D3DXVec3TransformCoord ( &right, &D3DXVECTOR3 ( 1, 0, 0 ), &WorldMatrix );
D3DXVec3TransformCoord ( &up, &D3DXVECTOR3 ( 0, 1, 0 ), &WorldMatrix );
D3DXVec3TransformCoord ( &look, &D3DXVECTOR3 ( 0, 0, 1 ), &WorldMatrix );
//------
void hxObject::Yaw ( float angle )
{
yaw+= angle;
while ( yaw > 360 )
yaw -= 360;
while ( yaw < 0 )
yaw += 360;
}
void hxObject::Pitch ( float angle )
{
pitch += angle;
while ( pitch > 360 )
pitch -= 360;
while ( pitch < 0 )
pitch += 360;
}
void hxObject::Roll ( float angle )
{
roll += angle;
while ( roll > 360 )
roll -= 360;
while ( roll < 0 )
roll += 360;
}
void hxObject::Move ( float units )
{
pos += look * units;
}
void hxObject::Strafe ( float units )
{
pos += right * units;
}
void hxObject::Fly ( float units )
{
pos += up * units;
}





first off, if i use D3DXMatrixRotationYawPitchRoll, it works right ONLY if i yaw, pitch then roll in order, but if my object, for example, rolls before turning, the rotation goes wrong, so turning does not work at all

and moving is even worse, my object moves in the same curve whether i strafe, move or fly, and it cant move to positive positions ( curve is from 0 to -[INFINITY] )

i suppose my code is wrong? please correct me if it's wrong

also, i think i'll try that inverse thing, so i should use the exact same code as my camera for objects, but inverse the fine (view) matrix?

Share this post


Link to post
Share on other sites
I'm glad you got it working.
The up,right and front vectors are part of the first 3x3 submatrix of your 4x4 matrix.
Now, out of curiosity, instead of inverting the view matrix of your camera class and apply that as a world matrix to your object, just transpose it, not invert it. [smile]
Could be faster tahn inverting to my understanding.
Assuming, you are not using non-uniform scaling.

Share this post


Link to post
Share on other sites
oh well, i'm happy with it now, works fine with scaling and stuff, this is what i have now, someone might find that of some use

void hxObject::Yaw ( float angle )
{
yaw += angle;
while ( yaw > 360 )
yaw -= 360;
while ( yaw < 0 )
yaw += 360;
angle = D3DXToRadian ( angle );
D3DXMATRIX T;
D3DXMatrixRotationAxis(&T, &up, angle);

// rotate _right and _look around _up or y-axis
D3DXVec3TransformCoord(&right,&right, &T);
D3DXVec3TransformCoord(&look,&look, &T);
}
void hxObject::Pitch ( float angle )
{
pitch += angle;
while ( pitch > 360 )
pitch -= 360;
while ( pitch < 0 )
pitch += 360;
angle = D3DXToRadian ( angle );
D3DXMATRIX T;
D3DXMatrixRotationAxis(&T, &right, angle);

// rotate _up and _look around _right vector
D3DXVec3TransformCoord(&up,&up, &T);
D3DXVec3TransformCoord(&look,&look, &T);
}
void hxObject::Roll ( float angle )
{
roll += angle;
while ( roll > 360 )
roll -= 360;
while ( roll < 0 )
roll += 360;
angle = D3DXToRadian ( angle );
D3DXMATRIX T;
D3DXMatrixRotationAxis(&T, &look, angle);

// rotate _up and _right around _look vector
D3DXVec3TransformCoord(&right,&right, &T);
D3DXVec3TransformCoord(&up,&up, &T);
}
void hxObject::Move ( float units )
{
units /= 10;
pos += look * units;
}
void hxObject::Strafe ( float units )
{
units /= 10;
pos += right * units;
}
void hxObject::Fly ( float units )
{
units /= 10;
pos += up * units;
}

//render
//adjust vectors
D3DXVec3Normalize(&look, &look);

D3DXVec3Cross(&up, &look, &right);
D3DXVec3Normalize(&up, &up);

D3DXVec3Cross(&right, &up, &look);
D3DXVec3Normalize(&right, &right);

//we calculate the view matrix then inverse it
//to get the world matrix, code from camera.cpp

//calculate view matrix
float x = -D3DXVec3Dot(&right, &pos);
float y = -D3DXVec3Dot(&up, &pos);
float z = -D3DXVec3Dot(&look, &pos);

float posfactor = 10;
if ( scaleFactor == 2000 )
posfactor = 0.5;

x /= posfactor;
y /= posfactor;
z /= posfactor;

(WorldMatrix)(0,0) = right.x; (WorldMatrix)(0, 1) = up.x; (WorldMatrix)(0, 2) = look.x; (WorldMatrix)(0, 3) = 0.0f;
(WorldMatrix)(1,0) = right.y; (WorldMatrix)(1, 1) = up.y; (WorldMatrix)(1, 2) = look.y; (WorldMatrix)(1, 3) = 0.0f;
(WorldMatrix)(2,0) = right.z; (WorldMatrix)(2, 1) = up.z; (WorldMatrix)(2, 2) = look.z; (WorldMatrix)(2, 3) = 0.0f;
(WorldMatrix)(3,0) = x; (WorldMatrix)(3, 1) = y; (WorldMatrix)(3, 2) = z; (WorldMatrix)(3, 3) = 1.0f;

//world matrix is the view matrix's inverse
D3DXMatrixInverse ( &WorldMatrix, NULL, &WorldMatrix );

D3DXMATRIX scale;
D3DXMatrixScaling ( &scale, fScale/scaleFactor, fScale/scaleFactor, fScale/scaleFactor );
WorldMatrix *= scale;

MainCore->GetDevice()->SetTransform ( D3DTS_WORLD, &WorldMatrix );





[Edited by - Hassanbasil on March 23, 2010 9:09:05 AM]

Share this post


Link to post
Share on other sites
sorry for bumping this, but it's not worth making a new topic for this little question:

the D3DLIGHT9::Direction can be considered as "the look vector of the light"? so i can use it the same way i use look (or forward) vectors?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this