Logo   Home Table of Contents    News  Dev Blogs  Gallery  Timeline  Legend  Tags  Sponsors 
Join us on... 
Banner

Current: Month Day, Year

9.1.10 Code of opengl/bone.py

obj3d/bone provides all methods to deal with bones. The file contains 2 classes:

Class cBone

This class is used to work with a single bone.

Variables

These variables are all preset by __init__.
namedescription
glob reference to global object.
parentname name of the parent bone or None.
name name of the bone.
skeleton reference to skeleton.
children a list of children bones.
reference a list of reference bones used for copying weights.
weightref reference to weights, preset with None.
level bone level (0 = root bone) + 1 for each child.
head list of vertices for head.
tail list of vertices for tail.
localplane rotation plane for bone. (0 if not existing)
headPos Numpy array of 3 elements for bone head position (default).
tailPos Numpy array of 3 elements for bone tail position (default).
poseheadPos Numpy array of 3 elements for bone head position (pose mode).
posetailPos Numpy array of 3 elements for bone tail position (pose mode).
matRestGlobal rest pose, global position 4x4 Matrix of bone object.
invRestGlobal inverse global Matrix (to do less calculation).
matRestLocal rest Pose, relative (local) position 4x4 Matrix of bone object.
matPoseGlobal global pose matrix.
matPoseLocal relative pose matrix, preset with 4x4 identity.
matPoseVerts result of matRestLocal X matPoseLocal X inv(matRestGlobal).
length length of bone

Methods:

nameparametersreturnsdescription
debugMats NoneNone A simple function to print matRestGlobal, matRestLocal.
getRestLocalRotQVector Nonequaternion vector yields the rotation for bones.
getPoseLocalRotQVector Nonequaternion vector yields the local rotation for bones in pose mode
getPoseGlobalRotQVector Nonequaternion vector yields the global rotation for bones in pose mode. Used for gltf exporter.
getRestLocalTransVector Nonetransition vector return first 3 elements of last column of local rest matrix (transition vector)
getRestGlobalTransVector Nonetransition vector return first 3 elements of last column of global rest matrix (transition vector)
getPoseLocalTransVector Nonetransition vector return first 3 elements of last column of local pose matrix (transition vector)
getPoseGlobalTransVector Nonetransition vector return first 3 elements of last column of global pose matrix (transition vector). Used for gltf exporter.
getPoseRelParentRotQVector Nonequaternion vector yields the global rotation for bones in pose mode relatively to parent bone. Used for gltf exporter.
getBindMatrix orientation
rotAxis
offset
4x4 bindmat
4x4 bindinv
calculates the transformed rest matrix, then bindinv by transposing the rest matrix and calculating the inverse matrix from it. Last column is set to 0, 0, 0, 1 for gltf.
getTransformedRestMatrix orientation
rotAxis
offset
4x4 restmatrix calculates the rest matrix with changeOrientation() function.
getRelativeCorrection NoneNone calculates the relative correction by multiplying matRestGlobal, matPoseLocal, invRestGlobal
getNormal NoneNone Should calculate the normal, if a localplane is given as a string, the normals are calculated by skeleton getNormal. If no normal can be calculated or normals are close to zeros, normal is the y vector.
assignJointPos head
tail
None sets headPos, tailPos
getJointPos Nonehead, tail Calculates head and tail position by mean values.
setJointPos NoneNone sets headPos, tailPos by calculation of mean position of head and tail.
calcLocalRestMat normalrest matrix Calculates the local rest matrix by first calculating a normalize bone vector. For the orthonormal base, perpendicular vector to normal / bone_direction needed (cross-product). The missing axis x is calculated by using bone_direction and z_axis by cross product and calculating the norm. These values can now calculate the orthonormal base.
calcRestMatFromSkeleton Nonematrix calculation failed (bool) First get the own normal and calculate local rest matrix from that normal. Assign this to matRestGlobal and calculate inverse global rest matrix. If that does not work, return with error (non singular matrix). To calculate local rest matrix, do a dot product of parent global rest matrix and own global restmatrix. For no parent bone the local and global matrices are equal.
restPose NoneNone set local pose matrix to identity.
calcLocalPoseMat poseMatNone Set local pose matrix to a 4x4 identity and copy posemat to matPoseLocal, then calculate the dot product of invRestGlobal .matPoseLocal, and the result again as a dot product of matRestGlobal, then add the translations from original bone (translations must be calculated with dot product and invRestGlobal.
calcGlobalPoseMat NoneNone matPoseGlobal is calculated by dot product of matRestLocal, matPoseLocal when no parent bone is available, otherwise parent bones matPoseGlobal must be used as second dot product. matPoseVerts are calculated by dot product of matPoseGlobal and invRestGlobal.
poseBone NoneNone poseheadPos and posetailPos are calculated by transposing headPos or tailPos and using this with a dot product of matPoseVerts and then transposing it back.

Class boneWeights

This class is used to support work with bone weights

Variables

These variables are all preset by __init__.
namedescription
glob reference to global object.
env reference to environment object.
default_skeleton reference to default skeleton.
root reference to root of default skeleton.
bWeights dictionary of weights, initialized empty.
mesh reference to the mesh

Methods:

nameparametersreturnsdescription
createWeightsPerBone wdictNone Calculate the sums of normalize weights per bone, put these in verts and weights arrays The weights are sorted by index filter for values higher that 0.001. All what is not found is assigned to root bone. In this case a warning is given.
sortWeights weightsweights when using a custom skeleton, one bone may contain more than one bone of the default skeleton. sortWeights is needed, since deduplication is only working on sorted array.
deDuplicateWeights weightsweights weight arrays must be sorted before, for assets weights are calculated using 3 values from the base mesh, this means that values are used multiple times the skinning algorithm expects them once. This procedure is doing that by using np.unique to get occurences.
approxWeights asset
base
None create bone weights from base, recalculate the input in case of mesh loaded in binary form for easier calculation (tested). form is: vertex_num: baseskeleton: [(vertexnum_asset, weight), (...) ]. In the end the weights must be deduplicated.
transferWeights customskeletonweights if custom skeleton is not default skeleton, weights must be transfered. Then collect which bones of standard-skeleton are referenced by a bone. If bone is found in default, test "weights_reference". If available sum these up to one bone otherwise simply "copy" the weights. It is possible to define the same name for another bone but in this case reference must have 0 elements. The missing vertices must be distributed. This is done a by a parent chain reference, until a bone is found. (e.g. eyes will be transfered to head if no eye-bones) The values are sorted and deduplicated.
loadJSON pathsuccess (bool) Loads JSON file and sets attributes, checks if "weights" are a value and creates weights per bone.