Pages: [1] 2 3
Author Topic: posing with ofxAssimpModelLoader  (Read 1482 times)
kylemcdonald
View admin
Brooklyn

Posts: 1141

Gravatar


WWW
posing with ofxAssimpModelLoader
« on: October 27, 2011, 08:39:39 AM »

i have a collada file that contains a mesh and a rig for the mesh.

i've loaded it into OF with ofxAssimpModelLoader, and i want to define custom poses for the rig.

i can see inside ofxAssimpModelLoader::updateAnimation() that deforming the mesh involves something like recursively applying matrix transformations that have been defined in the animation.

so i suppose what i want to do is define those transforms myself instead of loading them from the animation?

has anyone done something similar to this, and could you give me pointers?

i feel like it would be nice to have a function in ofxAssimpModelLoader that just lets you specify the orientation for all the bones in the rig.
« Last Edit: October 27, 2011, 10:23:33 AM by kylemcdonald » Logged

arturo
Administrator
barcelona

Posts: 2214

Gravatar


WWW
Re: posing with ofxAssimpModelLoader
« Reply #1 on: October 27, 2011, 09:36:53 AM »

kyle, i was thinking about this some days ago :)  I need to check but i think the problem with assimp is that the returned objects are always const. I think it shouldn't be a problem, though, to get a copy and modify it as long as you don't want to update it later from values in the original model.

The code for that was done by Anton but as far as i understand the animation is defined in key frames so you need to interpolate to get the transformations in between and the bones have some weights that are the amount of that transformation that is applied to each vertex.

Haven't looked into it much further but also interested in doing it.

When doing 007 there was a discussion about how to implement the model loader, Keith started to implement everything with OF objects. In the end we did everything with assimp mainly because of memory management but perhaps it's the time to look into having ofBone. I think it's the only part missing to be able to do this.
Logged
makuz

Posts: 7

Gravatar


Re: posing with ofxAssimpModelLoader
« Reply #2 on: October 27, 2011, 12:28:56 PM »

i did something like this a while ago. what i ended up doing is inherited my own class from ofxAssimpModelLoader with a custom Bone class and rewrote the part of updateAnimation that was dealing with the rigging. the Bone class is similar to ofNode, but it has to deal with the inheritance of orientation, because when you do manual rigging you probably don't want the orientation to be affected by the parent.
Logged
kylemcdonald
View admin
Brooklyn

Posts: 1141

Gravatar


WWW
Re: posing with ofxAssimpModelLoader
« Reply #3 on: October 27, 2011, 12:53:34 PM »

@makuz, what you describe is exactly what i was about to write! would it be possible for you to post that code?

@arturo, i think if what makuz describes really works, then there shouldn't be any issues about const-ness. after all, the animation works, and that's definitely deforming the mesh.
Logged

kylemcdonald
View admin
Brooklyn

Posts: 1141

Gravatar


WWW
Re: posing with ofxAssimpModelLoader
« Reply #4 on: October 27, 2011, 04:52:51 PM »

here's my first shot. it doesn't do anything, and i'm sure i'm completely misunderstanding how things work.

i was thinking that bone->mOffsetMatrix would be the thing i could set to rig the model, but it looks like nothing happens when i do this. i'm initializing all the incoming aiMatrix4x4 with a random orientation so i should see something if this was vaguely right. i do know my mesh has 74 bones so that part is working.

Code:
class RiggedModel : public ofxAssimpModelLoader {
public:
int getNumBones(int which = 0) {
const aiMesh* mesh = modelMeshes[which].mesh;
return mesh->mNumBones;
}
void pose(vector<aiMatrix4x4>& pose, int which = 0) {
const aiMesh* mesh = modelMeshes[which].mesh;
vector<aiMatrix4x4> boneMatrices(mesh->mNumBones);
for(int a = 0; a < mesh->mNumBones; a++) {
const aiBone* bone = mesh->mBones[a];
aiNode* node = scene->mRootNode->FindNode(bone->mName);
boneMatrices[a] = pose[a];//bone->mOffsetMatrix;
const aiNode* tempNode = node;
while(tempNode) {
boneMatrices[a] = tempNode->mTransformation * boneMatrices[a];
tempNode = tempNode->mParent;
}
modelMeshes[which].hasChanged = true;
modelMeshes[which].validCache = false;
}

modelMeshes[which].animatedPos.assign(modelMeshes[which].animatedPos.size(),0);
if(mesh->HasNormals()){
modelMeshes[which].animatedNorm.assign(modelMeshes[which].animatedNorm.size(),0);
}

// loop through all vertex weights of all bones
for(int a = 0; a < mesh->mNumBones; a++) {
const aiBone* bone = mesh->mBones[a];
const aiMatrix4x4& posTrafo = boneMatrices[a];
for( size_t b = 0; b < bone->mNumWeights; b++) {
const aiVertexWeight& weight = bone->mWeights[b];
size_t vertexId = weight.mVertexId;
const aiVector3D& srcPos = mesh->mVertices[vertexId];
modelMeshes[which].animatedPos[vertexId] += weight.mWeight * (posTrafo * srcPos);
}
if(mesh->HasNormals()) {
// 3x3 matrix, contains the bone matrix without the translation, only with rotation and possibly scaling
aiMatrix3x3 normTrafo = aiMatrix3x3( posTrafo);
for( size_t b = 0; b < bone->mNumWeights; b++) {
const aiVertexWeight& weight = bone->mWeights[b];
size_t vertexId = weight.mVertexId;
const aiVector3D& srcNorm = mesh->mNormals[vertexId];
modelMeshes[which].animatedNorm[vertexId] += weight.mWeight * (normTrafo * srcNorm);
}
}
}
}
};
Logged

kylemcdonald
View admin
Brooklyn

Posts: 1141

Gravatar


WWW
Re: posing with ofxAssimpModelLoader
« Reply #5 on: October 28, 2011, 01:46:56 AM »

so i forgot to add updateGLResources(); to the end of that. then i got something. except was all stretched out like an alien.

so i changed the line where i set the pose to multiply by the mOffsetMatrix first:

Code:
boneMatrices[a] = pose[a] * bone->mOffsetMatrix;

and now i get something that is scaled correctly, but not accumulating.


* alien.png (43.18 KB, 684x616 - viewed 10 times.)

* non-accumulating.png (75.84 KB, 534x557 - viewed 246 times.)
Logged

kylemcdonald
View admin
Brooklyn

Posts: 1141

Gravatar


WWW
Re: posing with ofxAssimpModelLoader
« Reply #6 on: October 28, 2011, 02:20:36 AM »

ok, here's a technique that works for me.

it's admittedly the wrong approach. but i don't really understand how the animation is setting the bones without breaking constness.

http://pastebin.com/Lmra7zvA

any insight on how the animation works normally would be very much appreciated.


* ouch.png (45.15 KB, 500x546 - viewed 237 times.)
« Last Edit: October 28, 2011, 02:22:33 AM by kylemcdonald » Logged

arturo
Administrator
barcelona

Posts: 2214

Gravatar


WWW
Re: posing with ofxAssimpModelLoader
« Reply #7 on: October 28, 2011, 02:24:57 AM »

usually it doesn't break constness because it's just doing a copy of the original mesh transformed with the bones matrices, the used meshes are in the mesh helpers, in modelMeshes. That is the data that gets uploaded to the vbos not the originals
Logged
arturo
Administrator
barcelona

Posts: 2214

Gravatar


WWW
Re: posing with ofxAssimpModelLoader
« Reply #8 on: October 28, 2011, 02:28:32 AM »

and yes, that looks pretty correct to me. What i meant with the constness is that you cannot add bones to the model but you can apply transformations like you are doing without problem
Logged
arturo
Administrator
barcelona

Posts: 2214

Gravatar


WWW
Re: posing with ofxAssimpModelLoader
« Reply #9 on: October 28, 2011, 03:05:52 AM »

not completely sure but from what i understand each key frame defines a translation, rotation and scaling (actually several in a node hierarchy)

When you pass the time it interpolates between 2 key frames to calculate the transformations at that time and then with those it creates a transformation matrix.

The bones weights tells you how much of that transformation has to be applied to each vertex in the mesh

I guess you could pass nodes instead of matrices for the transformations then the rest of the code you have seems pretty much correct
Logged
kylemcdonald
View admin
Brooklyn

Posts: 1141

Gravatar


WWW
Re: posing with ofxAssimpModelLoader
« Reply #10 on: October 28, 2011, 04:29:13 AM »

Logged

makuz

Posts: 7

Gravatar


Re: posing with ofxAssimpModelLoader
« Reply #11 on: October 28, 2011, 10:56:24 AM »

kyle, i'm afraid i am not allowed to post the code, because it's client work, but i see you managed well without it. if you have any more questions or need any help, just let me know.
Logged
arturo
Administrator
barcelona

Posts: 2214

Gravatar


WWW
Re: posing with ofxAssimpModelLoader
« Reply #12 on: October 28, 2011, 11:43:23 AM »

wow, is it just random poses?
Logged
kylemcdonald
View admin
Brooklyn

Posts: 1141

Gravatar


WWW
Re: posing with ofxAssimpModelLoader
« Reply #13 on: October 28, 2011, 12:13:18 PM »

yes, a +/- 45 degree angle on a random axis:

Code:
ofMatrix4x4 randomRotation(float amt = 180) {
ofQuaternion quat;
ofMatrix4x4 mat;
ofVec3f axis(ofRandomf(), ofRandomf(), ofRandomf());
axis.normalize();
quat.makeRotate(ofRandom(-amt, amt), axis);
quat.get(mat);
return mat;
}

void testApp::randomPose() {
Pose pose = model.getPose();
for(Pose::iterator i = pose.begin(); i != pose.end(); i++) {
aiMatrix4x4& cur = i->second;
ofMatrix4x4 mat = randomRotation(45);
cur.a1 = mat(0, 0);
cur.a2 = mat(0, 1);
cur.a3 = mat(0, 2);
cur.b1 = mat(1, 0);
cur.b2 = mat(1, 1);
cur.b3 = mat(1, 2);
cur.c1 = mat(2, 0);
cur.c2 = mat(2, 1);
cur.c3 = mat(2, 2);
}
model.pose(pose);
curRotation = randomRotation();
}

this really destroys some things, like the jaw. but for most things it works fine.

i'm definitely interested in glitch vs the body... i want to explore this style a little more.

but i really got started with this because i'm thinking about implementing the algorithm behind the skeleton tracker on xbox/ms sdk.
Logged

arturo
Administrator
barcelona

Posts: 2214

Gravatar


WWW
Re: posing with ofxAssimpModelLoader
« Reply #14 on: October 28, 2011, 05:13:16 PM »

i need to take into account the orientation, but i think this can do to find the skeleton in a model:

https://github.com/arturoc/ofxAssimpSkeleton


I'm finding bounding boxes for all the vertexes that have weights for each bone


* Pantallazo del 2011-10-28 18:07:21.png (27.27 KB, 1024x750 - viewed 10 times.)
Logged
Pages: [1] 2 3
 
Jump to:  

Powered by SMF 1.1.15 | SMF © 2011, Simple Machines
kinect

viagra priser