CGTalk Lerp for matrix3 values
 09-21-2010, 10:08 AM #1 JHN maxscript/c# lover   Johan Boekhoven Technical Artist nmtrix.com Netherlands   Join Date: Apr 2002 Posts: 1,714 Lerp for matrix3 values Is there an existing way to lerp between 2 matrix values or do I have to decompose the PRS values, (s)lerp them and rebuilt the matrix each step? Thanks, -Johan __________________ Online: LinkedIn | blog | nmtrix.com Code: mxs+.net | c# | mb-python | php | html+js | mysql | python share quote
 09-21-2010, 11:36 AM #2 JHN maxscript/c# lover   Johan Boekhoven Technical Artist nmtrix.com Netherlands   Join Date: Apr 2002 Posts: 1,714 Found a thread about it : http://forums.cgsociety.org/showthr...p?f=98&t=859470 Thanks, -Johan __________________ Online: LinkedIn | blog | nmtrix.com Code: mxs+.net | c# | mb-python | php | html+js | mysql | python share quote
 09-21-2010, 11:59 AM #3 MatanH Character TD   portfolio Matan Halberstadt Head of Rigging dpt. snowball studios Tel-Aviv, Israel   Join Date: Oct 2002 Posts: 378 Just saw your 2nd post but I'll post my solution anyhow.. Code: ```( fn lerp matArray weights = ( local resMat = matrix3 [0,0,0] [0,0,0] [0,0,0] [0,0,0] for i = 1 to matArray.count do ( local w = weights[i] local intMat = matrix3 [w,0,0] [0,w,0] [0,0,w] [w,w,w] resMat += matArray[i] * intMat ) resMat ) if selection.count == 3 then ( local a = \$[1] local b = \$[2] local c = \$[3] local d = copy a d.transform = lerp #(a.transform, b.transform, c.transform) #(0.5, 0.5, 0.5) ) else messageBox "Please select 3 objects!" )``` __________________ Home:http://cargocollective.com/matan Work: http://www.snowballvfx.com/ share quote
09-21-2010, 12:02 PM   #4
denisT
MAX Doctor

portfolio
Denis Trofimov
CA, USA

Join Date: Jul 2009
Posts: 9,189
Quote:
 Originally Posted by JHN Is there an existing way to lerp between 2 matrix values or do I have to decompose the PRS values, (s)lerp them and rebuilt the matrix each step? Thanks, -Johan

there is no lerp for matrices. use lerp for rotation (in quaternions), and average for position and scale.

 09-21-2010, 12:22 PM #5 JHN maxscript/c# lover   Johan Boekhoven Technical Artist nmtrix.com Netherlands   Join Date: Apr 2002 Posts: 1,714 @ Matan : Thanks, I'm using something else since I just need to blend between 2 matrices (making a pose tool for CAT). Will test you code as it looks more compact. @ Denis : I'm using a slightly modified variant on your code Code: ```fn blendMatrix m1: m2: weight:0.5 = ( fn dotQuat q q_prev = ( (q.w * q_prev.w + q.x * q_prev.x + q.y * q_prev.y + q.z * q_prev.z) < 0 ) r1 = m1.rotationpart r2 = m2.rotationpart if (dotQuat r1 r2) do r1 *=-1 r = slerp (normalize r1) (normalize r2) weight t = m1.translationpart + (m2.translationpart - m1.translationpart) * weight s = m1.scalepart + (m2.scalepart - m1.scalepart) * weight translate (rotate (scale (matrix3 1) s true) r) t -- ignores scale ) ``` I added the scale averaging, and encapsulated the dotQuat fn. Thanks! -Johan __________________ Online: LinkedIn | blog | nmtrix.com Code: mxs+.net | c# | mb-python | php | html+js | mysql | python share quote
 09-21-2010, 12:53 PM #6 JHN maxscript/c# lover   Johan Boekhoven Technical Artist nmtrix.com Netherlands   Join Date: Apr 2002 Posts: 1,714 @Matan, does it work between 2 transforms. I tried: Code: ``` for i = 1 to 10 do point transform:(lerpM #(\$[1].transform, \$[2].transform) #((i/10.), (1 - (i/10))))``` Between 2 objects that are transformed differently, but the results are not good. How does your function work with 2 matrices? Thanks, -Johan __________________ Online: LinkedIn | blog | nmtrix.com Code: mxs+.net | c# | mb-python | php | html+js | mysql | python share quote
 09-21-2010, 12:59 PM #7 MatanH Character TD   portfolio Matan Halberstadt Head of Rigging dpt. snowball studios Tel-Aviv, Israel   Join Date: Oct 2002 Posts: 378 it won't work correct if the weights don't sum up to exactly 1.0 here is an example of what you tried to do: Code: ```local a = \$[1] local b = \$[2] local n = 10 for i = 1 to n - 1 do ( local c = copy a local w = 1.0 * i / n c.transform = lerp #(a.transform, b.transform) #(w, 1.0 - w) )``` EDIT: just playing around with it, here is another nice test: Code: ```( fn lerp matArray weights = ( local resMat = matrix3 [0,0,0] [0,0,0] [0,0,0] [0,0,0] for i = 1 to matArray.count do ( local w = weights[i] local intMat = matrix3 [w,0,0] [0,w,0] [0,0,w] [w,w,w] resMat += matArray[i] * intMat ) resMat ) local a = teapot transform:(matrix3 [0.543478,1.19095,-0.738627] [-1.22502,0.788501,0.370005] [1.21654,0.836836,2.24443] [204.994,154.378,224.798]) wirecolor:red local b = teapot transform:(matrix3 [1,0,0] [0,1,0] [0,0,1] [122.507,3.13654,0]) wirecolor:green local c = teapot transform:(matrix3 [1.06301,0.5229,0.250736] [-0.301877,-0.31541,1.93761] [0.425891,-0.832628,-0.0691843] [288.803,-141.283,52.8861]) wirecolor:blue local n = 10 for j = 0 to n do ( local w1 = 1.0 * j / n for i = 0 to n do ( local d = copy a local w2 = (1.0 - w1) * i / n local w3 = 1.0 - w1 - w2 d.transform = lerp #(a.transform, b.transform, c.transform) #(w1, w2, w3) d.wireColor = a.wireColor * w1 + b.wireColor * w2 + c.wireColor * w3 ) ) )``` __________________ Home:http://cargocollective.com/matan Work: http://www.snowballvfx.com/ Last edited by MatanH : 09-21-2010 at 01:18 PM. share quote
 09-21-2010, 01:31 PM #8 JHN maxscript/c# lover   Johan Boekhoven Technical Artist nmtrix.com Netherlands   Join Date: Apr 2002 Posts: 1,714 I went wrong because my code produced an integer as weight instead of a float. But still your solution is not as good because the scale of the matrix is not avaraged, but get's distorted. So I'm sticking with my (Denis' actually) code. But there's some nice motion design effects to be made with your code! Thanks, -Johan __________________ Online: LinkedIn | blog | nmtrix.com Code: mxs+.net | c# | mb-python | php | html+js | mysql | python share quote
 09-22-2010, 02:53 PM #9 eek Fixer   portfolio Charles Looker Snr Technical Artist Electronic Arts Vancouver, Canada   Join Date: Feb 2002 Posts: 4,221 Code: ``` local matrices = #((matrix3 1), ((eulerangles 0 45 32) as matrix3), (transMatrix [50,40,10])) local mc = for each in matrices collect each local tmp = #() local t = 0.5 while mc.count > 1 do ( for i = 1 to (mc.count-1) do ( append tmp ((slerp mc[i].rotation mc[i+1].rotation t) as matrix3 * transMatrix((1-t) * mc[i].row4 + mc[i+1].row4 * t)) ) mc = tmp tmp = #() ) mc[1] ``` This is a quadratic form of blending between multiple matrices roughly. __________________ Disclaimer: My opinions are not those of my employer. share quote
 09-22-2010, 02:53 PM #10 CGTalk Moderation Lord of the posts   Join Date: Sep 2003 Posts: 1,066,481 Thread automatically closed This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum. __________________ CGTalk Policy/Legalities Note that as CGTalk Members, you agree to the terms and conditions of using this website. share quote