Archived

This topic is now archived and is closed to further replies.

Reverse Weighted Deformation

This topic is 5500 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm trying to find a way to compute the reverse deformation of a weighted envelope. Lets say I have a point on a deformed mesh, deformation that is the result of several bones transformation, each of them receiving a weight. I want to be able to retrieve the position of that point as if it was undeformed. In my understanding of a weighted deformation ( but I'm may be wrong ) the forward deformation can be written as: (Vs*[Tr1])*W1 + (Vs*[Tr2])*W2 + ... = Vt where: Vs: is the position of the undeformed point, represented as a vector. Vt: is the position of the deformed point. Tr1: transformation of the bone #1 W1: weight of the bone #1 The same question can be formulated as: Knowing Vt, how could I compute Vs ? I've tried: Vt = Vs * Inverse[Tr1*W1 + Tr2*W2] without success, but it might be my implementation wich is wrong. In: (Vs*[Tr1])*W1 I understand that the vector Vs is transformed with the Tr1 transformation, wich give a vector, then this vector is scaled by the scalar value W1. So I'm not sure if we can write: Vs * ( [Tr1]*W1 + [Tr2]*W2 + ... ) = Vt Well, for now I have no clue how to compute this 'reverse' deformation. Any help would be greatly apreciated. Thanks a lot in advance. [edited by - smedic on November 18, 2002 2:17:46 AM]

Share this post


Link to post
Share on other sites
I''m interested too.

If you have vertices in world coordinates as the default pose, and they
have vertex weights, you need to transform them back first before you
start animating, right?

What are the steps needed to do this correctly?

Share this post


Link to post
Share on other sites
taking the Vs out:
Vs * ( [Tr1]*W1 + [Tr2]*W2 + ... ) = Vt
is fine since matrix multiplication is distributive

one thing that might catch you up here though is that order matters, if in your code your actually doing
([Tr1]*Vs)*W1 + ([Tr2]*Vs)*W2 + ... = Vt
i.e. post multiplying then you should post multply by Vs
( [Tr1]*W1 + [Tr2]*W2 + ... ) * Vs = Vt
in which case
Vs = Inv([Tr1]*W1 + [Tr2]*W2 + ...) * Vt

it all depends on how you've implemented your vector-matrix multiply, with the vector as a row (you post-multiply the transformation matrix) or column (pre-multiply) matrix


btw
and all the weights for a vertex should add up to 1. you probably already realize this but just thought i'd mention it



[edited by - joanusdmentia on November 19, 2002 2:27:09 AM]

[edited by - joanusdmentia on November 19, 2002 2:28:00 AM]

Share this post


Link to post
Share on other sites
Hi,

first thanks for answering, I''m having hard time to find any help about this.

[joanusdmentia]
>Vs * ( [Tr1]*W1 + [Tr2]*W2 + ... ) = Vt
>is fine since matrix multiplication is distributive
>../..
>one thing that might catch you up here though is that order >matters, if in your code your actually doing
>([Tr1]*Vs)*W1 + ([Tr2]*Vs)*W2 + ... = Vt
>../..

I think most of my problem is all about this:
( Vs * [Tr1] ) * W1
can''t be written as
Vs * ( [Tr1] * W1 )

because Vs * [Tr1] means transform a vector, and that operation gives a Vector.

Lets say that:
Vt1 = Vs * [Tr1]
so
Vt1 * W1 is simply a matter of wheighting a position, and in:
( Vt1 * W1 ) + ( Vt2 * W2 ) + ... = Vt
order doesn''t matter because Vector addition is commutative.

That''s the all point.

That''s why I said that I''m not sure if
(Vs*[Tr1])*W1
can be written as
Vs * ([Tr1]*W1)
and now I''m pretty sure I cant.

So may be all the problem is in my bad writting/interpretation of it.

What I''m 100% sure is that:
(Vs*[Tr1])*W1 + (Vs*[Tr2])*W2 + ... = Vt
can be written as
(Vs*[Tr2])*W2 + (Vs*[Tr1])*W1 + ... = Vt
because each operation gives a vector and vector addition is commutative.

May there is another way to ''write'' it, a more accurate or mahtematical way ?

I''m starting to become crazy with this :/

Thanks for any help.

Share this post


Link to post
Share on other sites
When it comes down to it, Vs*Tr1 is just a matrix multiply (vectors are just a specialised matrix), so if Vs is a row matrix you have a 1x4 matrix by a 4x4, giving you a 1x4 matrix (your vector) as the result

Now, lets say we''ve got
M = (A*B + A*C)
where M,A,B,C are matricies, it''s perfectly valid to say
M = A*(B+C)
since matrix multiplication is distributive

So with your problem, saying
Vs * (Tr1*W1 + Tr2*W2 + ...) = Vt
is mathematically correct

how are you implementing your vector*matrix? it can be looked at as finding the dot product of the vector with either the rows or columns of the matrix, so which are you doing? if your dotting with the columns then your doing Vs*Tr1 as expected, but if your dotting with the rows your actually doing Tr1*Vs, which _isn''t_ the same

Share this post


Link to post
Share on other sites
Ok,

the problem is that I'm using built-in functions from my host application. I didn't implemented the Math libraries, I'm using scripting from this host that is using those Math functions, and they are named 'transform', so I don't really know what's happening 'inside'.

I'll have to go down lower and may be use low level fonction or even recreate some basic math library to see where the problem come from.

So now that I have the theorical 'solution', I'll have to see what's wrong with the implementation.

Thanks a lot.

ps: Are you aware about some existing code that do this kind of reverse deformation calculation ?

[edited by - smedic on November 20, 2002 6:17:19 PM]

Share this post


Link to post
Share on other sites
nope, don''t know any code that already does it

just to be sure i just threw it into matlab and it worked so the maths is _definately_ right. heres some things that you could check:

- do you use your own inverse()? if so, it can be easy to screw up, especially if your using 4x4 matricies (which i''m assuming you are)
- see if the library has a generic vector-matrix multiply rather than the ''transform'' function and see if that makes a difference
- you can see whether the library uses pre or post multiplying by looking at a translate matrix, if it''s post multiplying the translation vector will be in the bottom row, if it''s pre multiplying it''ll be in the right column. i''d guess it uses post-multiplying, since i''m assuming your doing the same in other parts of your code and it works there

and if all that fails, as you said you could throw together your own basic math functions and try that

Share this post


Link to post
Share on other sites