so I've been working with alot of common interfaces and the typical layout for this data seems to follow:
- LRS (Loc, Rot, Scale) >( calculated to )> 3x4 transform matrix (Parent Relation)
- 3x4 local-bind matrix (Parent relation)
- 3x4 inverse-bind matrix (Inverse-World Relation)

the most important matrix is the transform matrix, which should be the same as either the local-bind matrix, or in some cases, the world-bind matrix
the inverse-bind matrix is usually not needed, but is usually pre-calculated to save processing power.

and then there's the world-bind matrix which is usually dynamically calculated by multiplying the local-bind matrix with the parent world-bind matrix.
(inverting this creates the inverse bind matrix)

so what I want to know is:
how do I check that the supplied data (unknown relation) matches these standards??

extra info: (for noobs)
Q: what do all of these matrices do exactly
well, the LRS is added to the animation's current-frame transformations before being calculated into a local-bind matrix.
this is multiplied with the inverse bind before being weighted and added to an influence matrix specified by a weight group to transform a given vector by.

the vertices are multiplied by the full 3x4 influence matrix, while the normals are only multiplied by a 3x3 rotation matrix (stripping the location from the influence matrix (not certain about the scale))

anyone else know how to verify bone data??

I probably should mention this is for a program that converts models from games rather than a game itself

if anyone wants to know, here's my current code I never finished before asking: (python)

``````def __VerifyBoneTree(BID,Data,children,wpbind,wptransform):
BoneName, BDL, (l,r,s), Res, Bind, Inv_Bind, PBID, PrBID, CBID, NBID = Data

default = __rr.Matrix44(DM) # default (same as identity)

transform = __rr.Matrix44.from_scale(s) * __rr.Matrix44.from_eulers(r) * __rr.Matrix44.from_translation(l) # Local Transform
bind = __rr.Matrix44(Bind) # Local Bind
inverse = __rr.Matrix44(Inv_Bind) # World Inverse Bind

wtransform = __rr.matrix44.multiply(transform,wptransform) # World Transform
wbind = __rr.matrix44.multiply(bind,wpbind) # World Bind

# validate inverse (world location)
if (default == inverse).all(): # inverse should almost never be defaulted (unless root)
if (default != transform).all() and (default != bind).all():
inverse = __rr.matrix33.inverse(wbind)
else:
inverse = __rr.matrix33.inverse(wpbind)

if (transform == bind).all():
if (default == bind).all(): # possible problem (this may be the proper local location)
if (default != inverse).all(): # this may not be the proper locations
wbind = __rr.matrix33.inverse(inverse)
transform, bind = [ wbind * __rr.matrix33.inverse(wpbind) ]*2

else: # (not defaulted) make sure the bind matches the inverse
if (bind != inverse).all(): # this is obviousely wrong
inverse = __rr.matrix33.inverse(wbind)

else: # warning, no match
t = __rr.matrix33.inverse(wpbind*inverse)
if (default == bind).all():
if (t == transform).all():

elif (default == transform).all():
if (t == bind).all():

else: # neither are default

if BID in children: # if this bone has any children
for CID in children[BID]:
__VerifyBoneTree(CID,Data,children,wbind,wtransform)
``````

I wanted to make sure I was doing my crap right

EDIT:
import pyrr as __rr

ok, I think I might be onto something with this:

``````def __VerifyBoneTree(BID,Data,children,wpbind,wptransform):
BoneName, BDL, (l,r,s), Res, Bind, Inv_Bind, PBID, PrBID, CBID, NBID = Data

transform = __rr.Matrix44.from_scale(s) * __rr.Matrix44.from_eulers(r) * __rr.Matrix44.from_translation(l) # Local Transform
bind = __rr.Matrix44(Bind) # Local Bind
inverse = __rr.Matrix44(Inv_Bind) # World Inverse Bind

# gather matrix types
_DE = __rr.Matrix44(DM)

_LT = transform*__rr.matrix33.inverse(wpbind)
_WT = transform*wpbind
_RT = transform

_LB = bind*__rr.matrix33.inverse(wpbind)
_WB = bind*wpbind
_RB = bind

_LI = inverse*__rr.matrix33.inverse(wpbind)
_WI = inverse*wpbind
_RI = inverse

# inverses
_ILT, _IWT, _IRT, _ILB, _IWB, _IRB, _ILI, _IWI, _IRI = [__rr.matrix33.inverse(mtx) for mtx in [_LT, _WT, _RT, _LB, _WB, _RB, _LI, _WI, _RI]]

# comparisons (should gather AT LEAST 4 types [ default, transform, bind, inverse(, other) ]
_comps = { mtx.__str__():None for mtx in [_DE, _LT, _WT, _RT, _LB, _WB, _RB, _LI, _WI, _RI, _ILT, _IWT, _IRT, _ILB, _IWB, _IRB, _ILI, _IWI, _IRI] }

# now find relations and test for inverse relation and apply

wtransform = transform*wptransform # World Transform
wbind = bind*wpbind # World Bind

if BID in children: # if this bone has any children
for CID in children[BID]:
__VerifyBoneTree(CID,Data,children,wbind,wtransform)
``````

relation is given as supplied and could be given improperly

edit to the last part of that code:

``````# comparisons (should gather AT LEAST 4 types [ default, transform, bind, inverse(, other) ]
matrices = [ eval(cmtx) for cmtx in { mtx.__str__():None for mtx in [_DE, _LT, _WT, _RT, _LB, _WB, _RB, _LI, _WI, _RI, _ILT, _IWT, _IRT, _ILB, _IWB, _IRB, _ILI, _IWI, _IRI] } ]
``````

so now that I've got 1 of each individual matrix, what can I do to find out which is the correct matrix and properly reassign or recalculate what's needed??

well, I see I'm getting nowhere with this, so I've scrapped this and went on with a more-static method, changing my internal format to keep track of the supplied matrix relation as well as what's defaulted.

thanks for the help everyone