PDA

View Full Version : Bone Weights

SilentScream
05-11-2011, 01:40 AM
Hey. Sorry if i'm posting in the wrong sub-forum. I didn't found more suitable...

I'm trying to find out how does LightWave output calculating bone weights(if there's no weight map specified for model). To be more certain, i mean how does it calculate bone affect amount for vertex if it's affected by 2 or more bones?

I have hard times finding some certain info about that anythere. I've tried to sum inverse distance of every affecting bone to vertex and taking average, then divide every bones inverse distance by average to get it's multiplier. It's sometime looks close, but sometimes not even close to what i see in LWOutput.

I've digged LWSDK but found nothing about that. Also, i have hard times finding any formula\algorithm example of how everyone does that(not only in LW), maybe wrong keywords? Anyone?

SilentScream
05-11-2011, 08:05 AM
So far i found this pseudocode:

FVEC old, new, tmp, def, dsum;
float dist, weight, weightsum;
int i, j;

for ( i = 0; i < npnts; i++ )
{

old = point[ i ];
dsum = (0, 0, 0);
weightsum = 0.0f;

for ( j = 0; j < nbones; j++ )
{

sub( new, old, bone->restpos ); // new = old - restpos

tmp[ 0 ] = dot( new, bone->rmat[ 0, 1, 2 ] );
tmp[ 1 ] = dot( new, bone->rmat[ 3, 4, 5 ] );
tmp[ 2 ] = dot( new, bone->rmat[ 6, 7, 8 ] ) / bone->restlen;

new[ 0 ] = dot( tmp, bone->omat[ 0, 3, 6 ] ) + bone->opos[ 0 ];
new[ 1 ] = dot( tmp, bone->omat[ 1, 4, 7 ] ) + bone->opos[ 1 ];
new[ 2 ] = dot( tmp, bone->omat[ 2, 5, 8 ] ) + bone->opos[ 2 ];

tmp[ 2 ] /= bone->restlen;
sub( def, new, old ); // def = new - old

dist = bonedist( bone, old, tmp[ 2 ] );
weight = bone->strength / ( pow( dist, falloff_exponent ) + 1.0E-6f );

weightsum += weight;

dsum[ 0 ] += def[ 0 ] * weight;
dsum[ 1 ] += def[ 1 ] * weight;
dsum[ 2 ] += def[ 2 ] * weight;
}

if ( weightsum > 0.0f )
{

point[ i ][ 0 ] += dsum[ 0 ] / weightsum;
point[ i ][ 1 ] += dsum[ 1 ] / weightsum;
point[ i ][ 2 ] += dsum[ 2 ] / weightsum;
}
}

(c) Ernie Wright

But i don't know what bone->rmat, bone->omat, bone->opos are. Author didn't mention that. I just need simple calculation without rest length multiplication.

Update: Ok, that was dumb. bone->rmat, bone->omat, bone->opos are just translation\origin\rotation matrices, i don't need that part. Translation and rotation occurs far later in my program. And if i cut out that part, i can't see any valid weigth calculation.