[Python] How export and use bone data for cpp

Discussão em 'Python' iniciado por Stack, Agosto 14, 2025.

  1. Stack

    Stack Membro Participativo

    Everythings work fine with assimp skeletal animation, but i wanted import from blender directly without assimp. Exporting static mesh was fully succesfull (well i think so. Model is in T-pose and rotating bone by id that can be found with bone name rotates it around central world axis). But offset matrix to spin bone around its joint have some problems. I cant manage get reasonable data from blender.

    Using basic code to make xyz point with visualizer (creating plot) show something correct data as skelet form. But it seems i calculate it wrong in my cpp code side for final transformation matrix.

    Code to calculate transform (offset exported with bonemap):

    void readNodes(NodeData *node,char * buffer,unsigned int * fileindex) {
    //some read before parsing transformation
    glm::vec3 pos;
    glm::quat rot;
    glm::vec3 scale;

    //I read data like this because i dont know glm order
    memcpy(&pos.x, &buffer[*fileindex], 4);
    *fileindex+=4;
    memcpy(&pos.y, &buffer[*fileindex], 4);
    *fileindex+=4;
    memcpy(&pos.z, &buffer[*fileindex], 4);
    *fileindex+=4;

    //rotation
    memcpy(&rot.z, &buffer[*fileindex], 4);
    *fileindex+=4;
    memcpy(&rot.y, &buffer[*fileindex], 4);
    *fileindex+=4;
    memcpy(&rot.x, &buffer[*fileindex], 4);
    *fileindex+=4;
    memcpy(&rot.w, &buffer[*fileindex], 4);
    *fileindex+=4;

    //scale
    memcpy(&scale.x, &buffer[*fileindex], 4);
    *fileindex+=4;
    memcpy(&scale.y, &buffer[*fileindex], 4);
    *fileindex+=4;
    memcpy(&scale.z, &buffer[*fileindex], 4);
    *fileindex+=4;

    //calculate transformation
    node->transformation=glm::mat4(1.0f);
    node->transformation=glm::translate(node->transformation,pos);
    node->transformation*=glm::toMat4(rot);
    node->transformation=glm::scale(node->transformation,scale);

    //read other data from node end and recursivle read other child nodes
    }
    }


    Code to export bonedata:

    def write_bone_node(self, file, bone):
    """Write one bone and all its children recursively."""
    bone_id = self.armature_obj.data.bones.find(bone.name)
    name_bytes = bone.name.encode('ascii', errors="ignore")[:255]
    # Name length + name
    file.write(struct.pack("B", len(name_bytes)))
    file.write(name_bytes)

    # Bone ID
    file.write(struct.pack("B", bone_id))

    # Inverse bind matrix (offset)
    offset_matrix = (self.armature_obj.matrix_world @ bone.matrix_local).inverted()

    loc, rot, scale = offset_matrix.decompose()
    file.write(struct.pack("3f", *loc))
    file.write(struct.pack("4f", *rot))
    file.write(struct.pack("3f", *scale))

    # Write children
    children = bone.children
    file.write(struct.pack("B", len(children)))
    for child in children:
    self.write_bone_node(file, child)


    Struggled several days changing parametrs order and etc. But don't tried using final bone location from blender (bone.head data exported correctly but it is static location if i am not wrong) because i don't know how pass transformed bone rotation to child with it. Do i should use final bone position from bone.head from blender instead calculation inverse matrix and rotating around this point?

    Final calculation is:

    //Passing arm or root node with basic rotation or glm::mat(1.0f) to get reversed bind pose (i dont know how it should look)
    void CalculateBasicBoneTransform(const NodeData* node, glm::mat4 parentTransform)
    {
    std::string nodeName = node->name;
    std::cout<<nodeName<<"\n";
    glm::mat4 nodeTransform = node->transformation;
    glm::mat4 globalTransformation = parentTransform*nodeTransform;
    m_FinalBoneMatrices[node->bone_id] = globalTransformation;

    for (int i = 0; i < node->childrenCount; i++)
    CalculateBasicBoneTransform(&node->children, globalTransformation);
    }


    what it should like (like t pose joints but i didn't found good tool to visualize it)

    what i get even when changing calculation steps and order

    Continue reading...

Compartilhe esta Página