openframeworks / openFrameworks

openFrameworks is a community-developed cross platform toolkit for creative coding in C++.
http://openframeworks.cc
Other
9.93k stars 2.55k forks source link

get mesh positions in ofxassimploader #2980

Open minusplusminus opened 10 years ago

minusplusminus commented 10 years ago

Hi,

I've mentioned that Assimp model loader doesn't have positions of meshes. I've seen that the data is available in the Assimp library, but not interpreted in the addon.

I've allready made a start, but couldn't get the positions right.

 //-------------------------------------------
 ofPoint ofxAssimpModelLoader::getMeshPosition(int num){
ofPoint pos;
if((int)scene->mNumMeshes<=num){
    ofLogError("ofxAssimpModelLoader") << "getMesh(): mesh id " << num
    << " out of range for total num meshes: " << scene->mNumMeshes;
    return pos;
}

aiVector3D* verticles = scene->mMeshes[num]->mVertices;

ofPoint pt = ofPoint(verticles->x*normalizedScale,
                     verticles->y*normalizedScale ,
                     verticles->z*normalizedScale );

pt.rotate(-90, ofVec3f(1,0,0));
return pt;

}

minusplusminus commented 10 years ago

I've figured it out:

   typedef struct
   {
       ofVec3f scale;
       ofVec3f rotation;
       ofVec3f position;
   } meshTranslation;

     meshTranslation ofxAssimpModelLoader::getMeshTranslation(int meshIndex)
{
    meshTranslation translation;
    aiMatrix4x4 childTransformation = scene->mRootNode->mChildren[meshIndex]->mTransformation;

    aiVector3t<float> scaling;
    aiQuaterniont<float> rotation;
    aiVector3t<float> position;

    childTransformation.Decompose(scaling, rotation,position);

    translation.position.set(position.x,position.y,position.z);
    translation.position = translation.position*normalizedScale;
    translation.scale.set(scaling.x, scaling.y,scaling.z);
    translation.rotation.set(rotation.x,rotation.y,rotation.z);

    return translation;
}
bilderbuchi commented 10 years ago

pinging @openframeworks/2d-3d @arturoc

arturoc commented 10 years ago

probably what we need is to internally represent ofxAssimpModelLoader meshes using an of3dPrimitive which already includes a node so you can easily query for it's position, rotation... also it will probably make the code cleaner

minusplusminus commented 10 years ago
 of3dPrimitive ofxAssimpModelLoader::getMeshTranslation(int meshIndex)
 {
     of3dPrimitive translation;
     if( scene->mRootNode != NULL && meshIndex < scene->mRootNode->mNumChildren)
     {
         meshIndex = ofClamp(meshIndex,0, scene->mRootNode->mNumChildren);

         aiMatrix4x4 childTransformation = scene->mRootNode->mChildren[meshIndex]->mTransformation;

         aiVector3t<float> scaling;
         aiQuaterniont<float> rotation;
         aiVector3t<float> position;

    childTransformation.Decompose(scaling, rotation,position);

         ofQuaternion q;
         q.set(rotation.w, rotation.x, rotation.y, rotation.z);

         translation.setPosition(position.x,position.y,position.z);
         translation.setPosition(translation.getPosition()*normalizedScale);
         translation.setScale(scaling.x, scaling.y,scaling.z);
         translation.rotateAround(q, ofPoint(rotation.x,rotation.y,rotation.z));
     }
     return translation;
 }

I'm unsure about the rotation. What do you think @arturoc ?

arturoc commented 10 years ago

mmh, no that doesn't make much sense, an of3dPrimitive is an object that has a mesh and an ofNode so it can represent a geometry and it's transformations. what i was saying is that ofxAssimpModelLoader could use of3dPrimitives instead of ofMesh to reprensent the different meshes and at the same time the transformations for each of those meshes, then a function like the one you propose would just need to call getPosition/Rotation... on the corresponding primitive.

it's kind of a big change and if we are going to do that it's probably worth looking into porting the addon to use assimp 3