Modding, Mission Design, and Coding > The Scripting Workshop

nuke ass masters 3d point rotation

(1/1)

Nuke:
after 4 articals on the subject, 5 lieters of cola and about 12 headache pills i finally figured out matrix rotation, from scratch :D

i needed a way to rotate normals for my turret modifications, but they could apply to anything from drawing gauges in 3d to writing hud elite. mainly i did it to help me better understand orientations and matricies. so i got 3 usefull functions to play with.

im using a 3*3 matrix for simplicity, in an array 1-9 (or table if you insist upon luas terminology). firs function multiplies one 3x3 with another. the second function multiplies the matrix with a vector (this is what they mean when they apply the matrix). both of those are required by the 3rd function. it creates an x,y,and z matrix, multiplies them together, and applies it tio the normal. i might break it down into 2 funcs, one to create the matrix and the other to rotate with. but for now im happy i finally cracked this nut.

keep in mind this, at least according to what i read, suffers from gimbal lock and is the slow way of doing things. theres actually a better way, but for now this suits my needs. i post the funcs to hopefully help people understand what matricies are all about. also keep in mind this doesnt create an orientation object, and will crash any function that operates on an orientation object if you try to use my matrix instead instead.

--- Code: ---multmat = function(mat1,mat2) --multiply a couple 3x3 matricies
local mat3 = {}

mat3[1] = (mat1[1] * mat2[1]) + (mat1[2] * mat2[4]) + (mat1[3] * mat2[7])
mat3[2] = (mat1[1] * mat2[2]) + (mat1[2] * mat2[5]) + (mat1[3] * mat2[8])
mat3[3] = (mat1[1] * mat2[3]) + (mat1[2] * mat2[6]) + (mat1[3] * mat2[9])
mat3[4] = (mat1[4] * mat2[1]) + (mat1[5] * mat2[4]) + (mat1[6] * mat2[7])
mat3[5] = (mat1[4] * mat2[2]) + (mat1[5] * mat2[5]) + (mat1[6] * mat2[8])
mat3[6] = (mat1[4] * mat2[3]) + (mat1[5] * mat2[6]) + (mat1[6] * mat2[9])
mat3[7] = (mat1[7] * mat2[1]) + (mat1[8] * mat2[4]) + (mat1[9] * mat2[7])
mat3[8] = (mat1[7] * mat2[2]) + (mat1[8] * mat2[5]) + (mat1[9] * mat2[8])
mat3[9] = (mat1[7] * mat2[3]) + (mat1[8] * mat2[6]) + (mat1[9] * mat2[9])

return mat3
end

matxvec = function(mat,vec) --multiply a vextor by a matrix
local x = (mat[1] * vec.x) + (mat[2] * vec.y) + (mat[3] * vec.z)
local y = (mat[4] * vec.x) + (mat[5] * vec.y) + (mat[6] * vec.z)
local z = (mat[7] * vec.x) + (mat[8] * vec.y) + (mat[9] * vec.z)

vec.x,vec.y,vec.z = x,y,z

return vec
end

rotnorm = function(norm,angs) --rotates a normal, in theory
local matx = {1,0,0,0,1,0,0,0,1}
local maty = {1,0,0,0,1,0,0,0,1} --create 3x3 matrix arrays for x y and z and fill it in with an identity matrix
local matz = {1,0,0,0,1,0,0,0,1}

matx[5] = math.cos(angs.x)
matx[6] = math.sin(angs.x)
matx[8] = -math.sin(angs.x)
matx[9] = math.cos(angs.x)

maty[1] = math.cos(angs.y)
maty[3] = -math.sin(angs.y) --fill in the nessicary parts of the matrix for each axis
maty[7] = math.sin(angs.y)
maty[9] = math.cos(angs.y)

matz[1] = math.cos(angs.z)
matz[2] = math.sin(angs.z)
matz[4] = -math.sin(angs.z)
matz[5] = math.cos(angs.z)

local mat = multmat(matx,maty) --multiply our matrixies
mat = multmat(mat,matz) --to get total matrix

norm = matxvec(mat,norm) --apply the matrix

return norm
end

--- End code ---

WMCoolmon:
Given that for indexing the orientation object, the values have to go through the Lua interpreter and grab the values from the C environment, these functions are probably pretty slow. But there's not any alternative builtin to scripting atm, so it's probably just a matter of using them sparingly.

Nuke:
yea, rendering a cobra mk3 (35 or so points, its actually 12 but i had to make duplicates cause the way my draw model function worked) is about 3 times slower than the 9 point paper airplane model in my other example. but i really didnt write it for model rotation, i wrote it for the arbitrary rotation of vectors and normals. though the idea of a 3d hud is a pretty cool concept. im still trying to understand how to use quaternions to do this, aparently it gets rid of gimbal lock and is alot faster. arbitrary point rotations is something id like to see built in functions for.