Fuses: Matrix4()

User avatar
Midgardsormr
Fusionista
Posts: 858
Joined: Wed Nov 26, 2014 8:04 pm
Location: Los Angeles, CA, USA
Been thanked: 4 times
Contact:

Fuses: Matrix4()

#1

Post by Midgardsormr » Fri Sep 14, 2018 5:58 pm

Anyone have any experience with or insight into the Matrix4() and related functions in a Fuse? I'm trying to improve the Redshift Camera Extractor to enable it to handle 3DS Max's right-handed Z-up coordinate system. While I could probably brute-force a solution by doing the matrix multiplication myself like I did the first time around, I'd really prefer to get my head around the built-in matrix handling functions.

Right now, I'm just trying to get data into and out of a matrix.

If I do this:

  1.         testMatrix = Matrix4()
  2.         testTable = testMatrix:GetTable()
  3.         dump(testTable)
  4.         newMatrix = Matrix4(testTable)

Lines 1 and 2 work as expected. A Matrix4 object is created, and it pulls the identity matrix values out to the table. But trying to put those values back into a new matrix fails with this error:

Code: Select all

[string "FFI Script"]:5446: bad argument #16 to 'ffi_Matrix4__newNums' (cannot convert 'nil' to 'double')
stack traceback:
	[C]: in function 'ffi_Matrix4__newNums'
	[string "FFI Script"]:5446: in function 'Matrix4'
	...xe\BlackMagic\fusion9\fuses\Fuses\RSCameraExtractor.fuse:80: in function <...xe\BlackMagic\fusion9\fuses\Fuses\RSCameraExtractor.fuse:50>

I thought perhaps it was a matter of table indices starting at 1 instead of 0, but shifting the indices didn't help, nor did adding an extra entry to the end of the table or putting another argument in directly.

I'm working from the (likely obsolete) hints described here: https://www.steakunderwater.com/VFXPedi ... es/Matrix4

User avatar
Midgardsormr
Fusionista
Posts: 858
Joined: Wed Nov 26, 2014 8:04 pm
Location: Los Angeles, CA, USA
Been thanked: 4 times
Contact:

Re: Fuses: Matrix4()

#2

Post by Midgardsormr » Thu Dec 13, 2018 4:32 pm

I've come back to this problem, and I still can't figure out how to read into a Matrix4. I'm becoming suspicious that the function is actually broken. It works fine for creating the identity matrix, and I all of the manipulations of that matrix work fine, but I can't for the life of me create a matrix from a table, as described in the 'docs.'

So failing that, I suspect I need to learn a bit more about matrices. I managed to muddle through with v1 of the RSCameraExtractor, but now I need to sort out converting Max's Z-up, right-handed matrix, as expressed by Redshift, into the Y-up, left-handed matrix that the Fuse is using. So, can anyone recommend any reading? Or hand-hold me through the problem?

User avatar
bfloch
Fusioneer
Posts: 84
Joined: Wed Aug 06, 2014 4:25 pm

Re: Fuses: Matrix4()

#3

Post by bfloch » Thu Dec 13, 2018 9:54 pm

Back when you posted this I also tried various ways and I also believe the lua binding is broken on that one.
The matrices work well in the SDK afaik.

User avatar
Midgardsormr
Fusionista
Posts: 858
Joined: Wed Nov 26, 2014 8:04 pm
Location: Los Angeles, CA, USA
Been thanked: 4 times
Contact:

Re: Fuses: Matrix4()

#4

Post by Midgardsormr » Fri Dec 14, 2018 7:15 am

Good to know I'm not just misunderstanding it. It's probably good for me, though, to be forced to actually learn the math instead of leaning on the algorithms.

User avatar
Midgardsormr
Fusionista
Posts: 858
Joined: Wed Nov 26, 2014 8:04 pm
Location: Los Angeles, CA, USA
Been thanked: 4 times
Contact:

Re: Fuses: Matrix4()

#5

Post by Midgardsormr » Fri Dec 14, 2018 5:53 pm

This is like trying to solve an invisible Rubik's Cube. I wound up writing some column major matrix manipulation functions of my own, but I still haven't quite solved the Fuse. If anyone's interested:

Code: Select all

function MatrixMult(m1, m2)

	m = {}
	m[1] = m1[1] * m2[1] + m1[5] * m2[2] + m1[9] * m2[3] + m1[13] * m2[4]
	m[2] = m1[2] * m2[1] + m1[6] * m2[2] + m1[10] * m2[3] + m1[14] * m2[4]
	m[3] = m1[3] * m2[1] + m1[7] * m2[2] + m1[11] * m2[3] + m1[15] * m2[4]
	m[4] = m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3] + m1[16] * m2[4]

	m[5] = m1[1] * m2[5] + m1[5] * m2[6] + m1[9] * m2[7] + m1[13] * m2[8]
	m[6] = m1[2] * m2[5] + m1[6] * m2[6] + m1[10] * m2[7] + m1[14] * m2[8]
	m[7] = m1[3] * m2[5] + m1[7] * m2[6] + m1[11] * m2[7] + m1[15] * m2[8]
	m[8] = m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7] + m1[16] * m2[8]

	m[9] = m1[1] * m2[9] + m1[5] * m2[10] + m1[9] * m2[11] + m1[13] * m2[12]
	m[10] = m1[2] * m2[9] + m1[6] * m2[10] + m1[10] * m2[11] + m1[14] * m2[12]
	m[11] = m1[3] * m2[9] + m1[7] * m2[10] + m1[11] * m2[11] + m1[15] * m2[12]
	m[12] = m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11] + m1[16] * m2[12]

	m[13] = m1[1] * m2[13] + m1[5] * m2[14] + m1[9] * m2[15] + m1[13] * m2[16]
	m[14] = m1[2] * m2[13] + m1[6] * m2[14] + m1[10] * m2[15] + m1[14] * m2[16]
	m[15] = m1[3] * m2[13] + m1[7] * m2[14] + m1[11] * m2[15] + m1[15] * m2[16]
	m[16] = m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15] + m1[16] * m2[16]


	return m
end


function rotateX(matrix, angle)

	rotx = { 1,0,0,0, 0,math.cos(math.rad(angle)),-math.sin(math.rad(angle)),0, 0,math.sin(math.rad(angle)),math.cos(math.rad(angle)),0, 0,0,0,1 }

	m = MatrixMult(matrix, rotx)

	return m

end


function rotateY(matrix, angle)

	roty = { math.cos(math.rad(angle)),0,math.sin(math.rad(angle)),0, 0,1,0,0, -math.sin(math.rad(angle)),0,math.cos(math.rad(angle)),0, 0,0,0,1 }

	m = MatrixMult(matrix, roty)

	return m
end


function rotateZ(matrix, angle)

	rotz = { math.cos(math.rad(angle)),-math.sin(math.rad(angle)),0,0, math.sin(math.rad(angle)),math.cos(math.rad(angle)),0,0, 0,0,0,1 }

	m = MatrixMult(matrix, rotz)

	return m

end

I think that's all correct, but I haven't done any real testing.