/* \brief free skin bone object */ GLHCKAPI unsigned int glhckSkinBoneFree(glhckSkinBone *object) { if (!glhckInitialized()) return 0; CALL(FREE_CALL_PRIO(object), "%p", object); assert(object); /* there is still references to this object alive */ if (--object->refCounter != 0) goto success; /* free the weights */ glhckSkinBoneInsertWeights(object, NULL, 0); /* remove from world */ _glhckWorldRemove(skinBone, object, glhckSkinBone*); /* free */ NULLDO(_glhckFree, object); success: RET(FREE_RET_PRIO(object), "%u", object?object->refCounter:0); return object?object->refCounter:0; }
static glhckBone* processBones(const struct aiNode *boneNd, const struct aiNode *nd, const struct aiMesh *mesh, glhckBone **bones, glhckSkinBone **skinBones, unsigned int *numBones) { kmMat4 matrix, transposed; glhckBone *bone = NULL, *child; glhckSkinBone *skinBone = NULL; const struct aiBone *assimpBone; unsigned int i; assert(boneNd && nd); assert(mesh); assert(numBones); /* something went wrong */ if (!numBones || *numBones >= ASSIMP_BONES_MAX) goto fail; /* don't allow duplicates */ for (i = 0; i != *numBones; ++i) if (!strcmp(glhckBoneGetName(bones[i]), boneNd->mName.data)) goto fail; /* create new bone */ if (!(bone = glhckBoneNew()) || !(skinBone = glhckSkinBoneNew())) goto fail; /* set bone to list */ bones[*numBones] = bone; skinBones[*numBones] = skinBone; *numBones = *numBones+1; /* store bone name */ glhckBoneName(bone, boneNd->mName.data); glhckSkinBoneBone(skinBone, bone); /* skip this part by creating dummy bone, if this information is not found */ if ((assimpBone = findBone(mesh, bone->name))) { /* get offset matrix */ matrix.mat[0] = assimpBone->mOffsetMatrix.a1; matrix.mat[1] = assimpBone->mOffsetMatrix.a2; matrix.mat[2] = assimpBone->mOffsetMatrix.a3; matrix.mat[3] = assimpBone->mOffsetMatrix.a4; matrix.mat[4] = assimpBone->mOffsetMatrix.b1; matrix.mat[5] = assimpBone->mOffsetMatrix.b2; matrix.mat[6] = assimpBone->mOffsetMatrix.b3; matrix.mat[7] = assimpBone->mOffsetMatrix.b4; matrix.mat[8] = assimpBone->mOffsetMatrix.c1; matrix.mat[9] = assimpBone->mOffsetMatrix.c2; matrix.mat[10] = assimpBone->mOffsetMatrix.c3; matrix.mat[11] = assimpBone->mOffsetMatrix.c4; matrix.mat[12] = assimpBone->mOffsetMatrix.d1; matrix.mat[13] = assimpBone->mOffsetMatrix.d2; matrix.mat[14] = assimpBone->mOffsetMatrix.d3; matrix.mat[15] = assimpBone->mOffsetMatrix.d4; /* get weights */ glhckVertexWeight weights[assimpBone->mNumWeights]; memset(weights, 0, sizeof(weights)); for (i = 0; i != assimpBone->mNumWeights; ++i) { weights[i].vertexIndex = assimpBone->mWeights[i].mVertexId; weights[i].weight = assimpBone->mWeights[i].mWeight; } /* assimp is row-major, kazmath is column-major */ kmMat4Transpose(&transposed, &matrix); glhckSkinBoneOffsetMatrix(skinBone, &transposed); glhckSkinBoneInsertWeights(skinBone, weights, assimpBone->mNumWeights); } /* get transformation matrix */ matrix.mat[0] = boneNd->mTransformation.a1; matrix.mat[1] = boneNd->mTransformation.a2; matrix.mat[2] = boneNd->mTransformation.a3; matrix.mat[3] = boneNd->mTransformation.a4; matrix.mat[4] = boneNd->mTransformation.b1; matrix.mat[5] = boneNd->mTransformation.b2; matrix.mat[6] = boneNd->mTransformation.b3; matrix.mat[7] = boneNd->mTransformation.b4; matrix.mat[8] = boneNd->mTransformation.c1; matrix.mat[9] = boneNd->mTransformation.c2; matrix.mat[10] = boneNd->mTransformation.c3; matrix.mat[11] = boneNd->mTransformation.c4; matrix.mat[12] = boneNd->mTransformation.d1; matrix.mat[13] = boneNd->mTransformation.d2; matrix.mat[14] = boneNd->mTransformation.d3; matrix.mat[15] = boneNd->mTransformation.d4; /* assimp is row-major, kazmath is column-major */ kmMat4Transpose(&transposed, &matrix); glhckBoneTransformationMatrix(bone, &transposed); /* process children bones */ for (i = 0; i != boneNd->mNumChildren; ++i) { child = processBones(findNode(nd, boneNd->mChildren[i]->mName.data), nd, mesh, bones, skinBones, numBones); if (child) glhckBoneParentBone(child, bone); } return bone; fail: IFDO(glhckBoneFree, bone); IFDO(glhckSkinBoneFree, skinBone); return RETURN_FAIL; }