Jump to content
  • Advertisement
Sign in to follow this  
VitaliBR

Control Of Bone

This topic is 2861 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts


Good job. It appears that the bone's local Y axis is pointing out of the screen - the rotation is clockwise with increasing angle.

For the model, what do you set for the world transform when you render it? The equations you're using assume the model is rendered with an identity world matrix. You need to use the same world matrix for D3DXVec3Project as you do when you render it, to ensure that the projected bone location is in screen space with the mouse location.

I.e., if you render the model something like:

dev->SetTransform(D3DTS_WORLD, &modelWorld);
// draw the model

then you need to use the same modelWorld in the D3DXVec3Project call:

D3DXVec3Project(&boneLocation,&boneLocation,&m_vp,&m_pm,&m_vm,&modelWorld);



[font="arial, sans-serif"]But not sure how I'm doing using the identity matrix?[/font]
[font="arial, sans-serif"]D3DXMATRIX ident;
D3DXMatrixIdentity(&ident);
D3DXMATRIX final = bone->TransformationMatrix*(*parentMatrix);
D3DXVECTOR3 boneLocation(final._41,final._42,final._43);
D3DXVec3Project(&boneLocation,&boneLocation,&m_vp,&m_pm,&m_vm,&ident); // use YOUR viewport, projection and view matrices in this call
D3DXVECTOR3 dir = mouseLocation - boneLocation;

[/font]

Share this post


Link to post
Share on other sites
Advertisement
The last parameter in the D3DXVec3Project call should be the world matrix for the vector you want projected. If you render the mesh with a world matrix other than the identity matrix, substitute the mesh's world matrix as shown in my post.

Share this post


Link to post
Share on other sites
[font="arial, sans-serif"]Ok, I did as you said, the arm responds to the mouse, but moves very little, not totally in sync with the cursor[/font]
D3DXMATRIX ident;
D3DXMATRIX modelWorld;
D3DXMatrixIdentity(&ident);
m_pDevice->SetTransform(D3DTS_WORLD, &modelWorld);
D3DXMATRIX final = bone->TransformationMatrix*(*parentMatrix);
D3DXVECTOR3 boneLocation(final._41,final._42,final._43);
D3DXVec3Project(&boneLocation,&boneLocation,&m_vp,&m_pm,&m_vm,&modelWorld); // use YOUR viewport, projection and view matrices in this call
D3DXVECTOR3 dir = mouseLocation - boneLocation;

float offset = D3DX_PI/2.0f;
float angle = offset - atan2(dir.y,dir.x); // change this when you rotate the model
D3DXMATRIX rot;
D3DXMatrixRotationY(&rot,angle);
bone->CombinedTransformationMatrix = rot*final;

Share this post


Link to post
Share on other sites
You need to really try to get a better understanding of what you're trying to do. In your code, you don't set the modelWorld matrix to a valid value. You should be using the same world transform that you use when you render the mesh.

Answer for yourself: what world transform is set when the mesh is rendered? For instance, if you're using a shader, what world transform is used by the shader when the mesh is rendered. Use that same transform in the D3DXVec3Project call.

Share this post


Link to post
Share on other sites
[font=arial, sans-serif]I do not know if these data shall go help on something, but I did as follows:[/font] D3DXMATRIX ident;
D3DXMATRIX modelWorld;
D3DXMatrixIdentity(&ident);
m_pDevice->SetTransform(D3DTS_WORLD, &modelWorld);
D3DXMATRIX final = bone->TransformationMatrix*(*parentMatrix);
D3DXVECTOR3 boneLocation(final._41,final._42,final._43);
D3DXVec3Project(&boneLocation,&boneLocation,&m_vp,&m_pm,&m_vm,&modelWorld); // use YOUR viewport, projection and view matrices in this call
Logging->LogMessage(MSG_INFO,"boneLocation.x ",boneLocation.x);
Logging->LogMessage(MSG_INFO,"boneLocation.y ",boneLocation.y);
Logging->LogMessage(MSG_INFO,"boneLocation.z ",boneLocation.z);
D3DXVECTOR3 dir = mouseLocation - boneLocation;

Logging->LogMessage(MSG_INFO,"mouseLocation.x ",mouseLocation.x);
Logging->LogMessage(MSG_INFO,"mouseLocation.y ",mouseLocation.y);
Logging->LogMessage(MSG_INFO,"mouseLocation.z ",mouseLocation.z);
Logging->LogMessage(MSG_INFO,"dir.x ",dir.x);
Logging->LogMessage(MSG_INFO,"dir.y ",dir.y);
Logging->LogMessage(MSG_INFO,"dir.z ",dir.z);

float offset = D3DX_PI/2.0f;
float angle = offset - atan2(dir.y,dir.x); // change this when you rotate the model
D3DXMATRIX rot;
D3DXMatrixRotationY(&rot,angle);
bone->CombinedTransformationMatrix = rot*final;


Look the data:
INFO: boneLocation.x -60.4733
INFO: boneLocation.y 853.739
INFO: boneLocation.z 0.947493
INFO: mouseLocation.x -56
INFO: mouseLocation.y 74
INFO: mouseLocation.z 0
INFO: dir.x 4.47333
INFO: dir.y -779.739
INFO: dir.z -0.947493
INFO: boneLocation.x -60.4733
INFO: boneLocation.y 853.739
INFO: boneLocation.z 0.947493
INFO: mouseLocation.x -105
INFO: mouseLocation.y 174
INFO: mouseLocation.z 0
INFO: dir.x -44.5267
INFO: dir.y -679.739
INFO: dir.z -0.947493
INFO: boneLocation.x -60.4733
INFO: boneLocation.y 853.739
INFO: boneLocation.z 0.947493
INFO: mouseLocation.x -115
INFO: mouseLocation.y 225
INFO: mouseLocation.z 0
INFO: dir.x -54.5267
INFO: dir.y -628.739
INFO: dir.z -0.947493
INFO: boneLocation.x -60.4733
INFO: boneLocation.y 853.739
INFO: boneLocation.z 0.947493
INFO: mouseLocation.x -99
INFO: mouseLocation.y 225
INFO: mouseLocation.z 0
INFO: dir.x -38.5267
INFO: dir.y -628.739
INFO: dir.z -0.947493
INFO: boneLocation.x -60.4733
INFO: boneLocation.y 853.739
INFO: boneLocation.z 0.947493
INFO: mouseLocation.x 159
INFO: mouseLocation.y 79
INFO: mouseLocation.z 0
INFO: dir.x 219.473
INFO: dir.y -774.739
INFO: dir.z -0.947493
INFO: boneLocation.x -60.4734
INFO: boneLocation.y 853.739
INFO: boneLocation.z 0.947493
INFO: mouseLocation.x 427
INFO: mouseLocation.y 65
INFO: mouseLocation.z 0
INFO: dir.x 487.473
INFO: dir.y -788.739
INFO: dir.z -0.947493
INFO: boneLocation.x -60.4734
INFO: boneLocation.y 853.739
INFO: boneLocation.z 0.947493
INFO: mouseLocation.x 586
INFO: mouseLocation.y 106
INFO: mouseLocation.z 0
INFO: dir.x 646.473
INFO: dir.y -747.739
INFO: dir.z -0.947493[/quote]

Share this post


Link to post
Share on other sites
As I mentioned before:
In your code, you don't set the modelWorld matrix to a valid value. You should be using the same world transform that you use when you render the mesh.[/quote]

Share this post


Link to post
Share on other sites

As I mentioned before:
In your code, you don't set the modelWorld matrix to a valid value. You should be using the same world transform that you use when you render the mesh.

[/quote]


[font="arial, sans-serif"]Sorry by my ignorance, but if I'm not doing correctly, how about it?[/font]

Share this post


Link to post
Share on other sites
When you render the mesh, how do you set the world transform, the dev->SetRenderState(D3DTS_WORLD,...) call? Post the code you use to render the mesh.

In your code, you have

D3DXMATRIX modelWorld;

You don't set the value of that variable before you call D3DXVec3Project(..., &modelWorld).

Share this post


Link to post
Share on other sites
[font="arial, sans-serif"]No, I'm not calling [color="#1C2837"][font="arial, verdana, tahoma, sans-serif"]dev->SetRenderState(D3DTS_WORLD,...) [/font]when rendering the mesh [/font]huh.gif

[color="#000000"][font="arial, sans-serif"]My code to render the mesh is:[/font]
[color="#000000"][font="arial, sans-serif"]void SKINNEDMESH::Render(BONE *bone, float scale)
{
if(bone == NULL)bone = (BONE*)m_pRootBone;

// Setup world matrix
D3DXMATRIXA16 matWorld,matWorld2;
// set the rotation matrix
D3DXMatrixRotationYawPitchRoll(&matWorld2,rotation.x,rotation.y,rotation.z);

D3DXMatrixScaling(&matWorld,scale,scale,scale);
D3DXMatrixMultiply(&matWorld,&matWorld,&matWorld2);

D3DXMatrixTranslation( &matWorld2, vPos.x, vPos.y,vPos.z );

D3DXMatrixMultiply(&matWorld,&matWorld,&matWorld2);

m_pDevice->SetTransform( D3DTS_WORLD, &matWorld );

//If there is a mesh to render..
if(bone->pMeshContainer != NULL)
{
BONEMESH *boneMesh = (BONEMESH*)bone->pMeshContainer;

if (boneMesh->pSkinInfo != NULL)
{
// set up bone transforms
int numBones = boneMesh->pSkinInfo->GetNumBones();
for(int i=0;i < numBones;i++)
D3DXMatrixMultiply(&boneMesh->currentBoneMatrices,
&boneMesh->boneOffsetMatrices,
boneMesh->boneMatrixPtrs);

//Update the skinned mesh
BYTE *src = NULL, *dest = NULL;
boneMesh->OriginalMesh->LockVertexBuffer(D3DLOCK_READONLY, (VOID**)&src);
boneMesh->MeshData.pMesh->LockVertexBuffer(0, (VOID**)&dest);

boneMesh->pSkinInfo->UpdateSkinnedMesh(boneMesh->currentBoneMatrices, NULL, src, dest);

boneMesh->MeshData.pMesh->UnlockVertexBuffer();
boneMesh->OriginalMesh->UnlockVertexBuffer();

//Render the mesh
for(int i=0;i < boneMesh->NumAttributeGroups;i++)
{
int mtrlIndex = boneMesh->attributeTable.AttribId;
m_pDevice->SetMaterial(&(boneMesh->materials[mtrlIndex]));
m_pDevice->SetTexture(0, boneMesh->textures[mtrlIndex]);
boneMesh->MeshData.pMesh->DrawSubset(mtrlIndex);
}
}
}


if(bone->pFrameSibling != NULL)Render((BONE*)bone->pFrameSibling, scale);
if(bone->pFrameFirstChild != NULL)Render((BONE*)bone->pFrameFirstChild, scale);
}

[/font]
[color="#000000"][font="arial, sans-serif"] [/font][color="#000000"][font="arial, sans-serif"] [/font][color="#888888"][font="arial, sans-serif"]
[color="#1C2837"][font="arial, verdana, tahoma, sans-serif"]You don't set the value of that variable before you call D3DXVec3Project(..., &modelWorld)[/quote][/font][/font][color="#888888"][font="arial, sans-serif"][color="#1C2837"][font="arial, verdana, tahoma, sans-serif"][color="#000000"][font="arial, sans-serif"]And what are the values that I set for example?[/font][/font][/font][color="#888888"][font="arial, sans-serif"] [/font]

Share this post


Link to post
Share on other sites
I'm not calling dev->SetRenderState(D3DTS_WORLD,...) when rendering the mesh[/quote]
Ouch! My mistake. I intended dev->SetTransform(D3DTS_WORLD,...).

In the code you just posted, you calculate matWorld and call m_pDevice->SetTransform(D3DTS_WORLD, &matWorld).

That matWorld matrix value, as you have calculated it, should be used in the D3DXVec3Project call.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!