- Joined
- Jul 29, 2007
- Messages
- 5,174
Because I like being graveyard'ed.
This is useful (if it wasn't made before) for people who want to make some 3d transformations.
Don't ask me why any sane human will use this in Warcraft (aside from the one I made this for).
Basically what you can do with this is easily rotate 3d points around whatever you want.
Do notice (if there's any insane human that wants to use this) that EVERY ANGLE IS IN RADIANS.
There's an example of usage below the code.
Here's an example of making a plane (a simple square) and rotating it around the Z axis, which is the same as unit facing in Warcraft.
This is useful (if it wasn't made before) for people who want to make some 3d transformations.
Don't ask me why any sane human will use this in Warcraft (aside from the one I made this for).
Basically what you can do with this is easily rotate 3d points around whatever you want.
Do notice (if there's any insane human that wants to use this) that EVERY ANGLE IS IN RADIANS.
There's an example of usage below the code.
JASS:
globals
// just for the lulz
// can this even compile? :)
constant real PI = 3.1415926535897932384626433832795
constant real deg2Rad = 0.01745329251994329576923690768488
constant real rad2Deg = 57.2957795130823208767981548141052
endglobals
//****************************************************************
// struct vec3 represents a 3d vector
//
// members:
// real x - x coordinate of the vector
// real y - y coordinate of the vector
// real z - z coordinate of the vector
//
// methods:
// setv takes real x,real y,real z returns nothing
// sets self to the given values respectively
//
// squaredLength takes nothing returns real
// returns the squared length of the vector
//
// normalize takes nothing returns nothing
// sets the length of the vector to one (unit vector)
//
// add takes vec3 v returns vec3
// adds v to self and returns the solution
//
// sub takes vec3 v returns vec3
// substracts v from self and returns the solution
//
// scale takes real s returns nothing
// scales the vector by s
//
// dot takes vec3 v returns real
// returns the dot value of v with self
//****************************************************************
struct vec3
real x
real y
real z
method setv takes real x,real y,real z returns nothing
set .x = x
set .y = y
set .z = z
endmethod
method squaredLength takes nothing returns real
return (.x * .x) + (.y * .y) + (.z * .z)
endmethod
method normalize takes nothing returns nothing
local real length = .squaredLength()
if length > 1 then // to avoid unnecessary square roots
set length = SquareRoot(length)
set .x = .x / length
set .y = .y / length
set .z = .z / length
elseif length > 0 then
set length = SquareRoot(length)
set .x = .x * (1 / length)
set .y = .y * (1 / length)
set .z = .z * (1 / length)
else // any unit vector will do, might as well pick the X axis
set .x = 1
set .y = 0
set .z = 0
endif
endmethod
method add takes vec3 v returns vec3
local vec3 ret = vec3.create()
set ret.x = .x + v.x
set ret.y = .y + v.y
set ret.z = .z + v.z
return ret
endmethod
method sub takes vec3 v returns vec3
local vec3 ret = vec3.create()
set ret.x = .x - v.x
set ret.y = .y - v.y
set ret.z = .z - v.z
return ret
endmethod
method scale takes real s returns nothing
set .x = .x * s
set .y = .y * s
set .z = .z * s
endmethod
method dot takes vec3 v returns real
return (.x * v.x) + (.y * v.y) + (.z * v.z)
endmethod
endstruct
//****************************************************************
// struct mat3 represents a 3x3 matrix
//
// members:
// real m[9] - all the 9 indexes of the matrix
//
// methods:
// multVector takes vec3 v returns vec3
// returns v multiplied by self
//
// multMatrix takes mat3 m returns mat3
// returns m multiplied by self
//
// rotationAxis takes real radians, vec3 axis returns nothing
// creates a rotation matrix around axis
//
// rotationX takes real radians returns nothing
// creates a rotation matrix around the X axis
//
// rotationY takes real radians returns nothing
// creates a rotation matrix around the Y axis
//
// rotationZ takes real radians returns nothing
// creates a rotation matrix around the Z axis
//****************************************************************
struct mat3
real array m[9]
method multVector takes vec3 v returns vec3
local vec3 ret = vec3.create()
set ret.x = .m[0] * v.x + .m[1] * v.y + .m[2] * v.z
set ret.y = .m[3] * v.x + .m[4] * v.y + .m[5] * v.z
set ret.z = .m[6] * v.x + .m[7] * v.y + .m[8] * v.z
return ret
endmethod
method multMatrix takes mat3 m returns mat3
local mat3 ret = mat3.create()
local integer row = 0
local integer col = 0
local integer i
loop
exitwhen row == 3
set i = 3 * row
loop
exitwhen col == 3
set ret.m[i + col] = .m[i] * m.m[col] + .m[i + 1] * m.m[3 + col] + .m[i + 2] * m.m[6 + col]
set col = col + 1
endloop
set row = row + 1
set col = 0
endloop
return ret
endmethod
method rotationAxis takes real radians, vec3 axis returns nothing
local real fcos = Cos(radians)
local real fsin = Sin(radians)
local real foneMinusCos = 1.0 - fcos
local real fx2 = axis.x * axis.x
local real fy2 = axis.y * axis.y
local real fz2 = axis.z * axis.z
local real fxym = axis.x * axis.y * foneMinusCos
local real fxzm = axis.x * axis.z * foneMinusCos
local real fyzm = axis.y * axis.z * foneMinusCos
local real fxSin = axis.x * fsin
local real fySin = axis.y * fsin
local real fzSin = axis.z * fsin
set .m[0] = fx2 * foneMinusCos + fcos
set .m[1] = fxym - fzSin
set .m[2] = fxzm + fySin
set .m[3] = fxym + fzSin
set .m[4] = fy2 * foneMinusCos + fcos
set .m[5] = fyzm - fxSin
set .m[6] = fxzm - fySin
set .m[7] = fyzm + fxSin
set .m[8] = fz2 * foneMinusCos + fcos
endmethod
method rotationX takes real radians returns nothing
local real fcos = Cos(radians)
local real fsin = Sin(radians)
set .m[0] = 1
set .m[1] = 0
set .m[2] = 0
set .m[3] = 0
set .m[4] = fcos
set .m[5] = fsin
set .m[6] = -fsin
set .m[7] = fcos
set .m[8] = 0
endmethod
method rotationY takes real radians returns nothing
local real fcos = Cos(radians)
local real fsin = Sin(radians)
set .m[0] = fcos
set .m[1] = 0
set .m[2] = -fsin
set .m[3] = 0
set .m[4] = 1
set .m[5] = 0
set .m[6] = fsin
set .m[7] = 0
set .m[8] = fcos
endmethod
method rotationZ takes real radians returns nothing
local real fcos = Cos(radians)
local real fsin = Sin(radians)
set .m[0] = fcos
set .m[1] = fsin
set .m[2] = 0
set .m[3] = -fsin
set .m[4] = fcos
set .m[5] = 0
set .m[6] = 0
set .m[7] = 0
set .m[8] = 1
endmethod
endstruct
Here's an example of making a plane (a simple square) and rotating it around the Z axis, which is the same as unit facing in Warcraft.
JASS:
globals
vec3 a = vec3.create()
vec3 b = vec3.create()
vec3 c = vec3.create()
vec3 d = vec3.create()
endglobals
function InitPlane takes nothing returns nothing
set a.setv(-1, 0, 1) // left-top corner
set b.setv( 1, 0, 1) // right-top corner
set c.setv( 1, 0,-1) // right-bottom corner
set d.setv(-1, 0,-1) // left-bottom corner
endfunction
function RotatePlaneZ takes real radians returns nothing
local mat3 m = mat3.create()
call m.rotationZ(radians)
set a = m.multVector(a)
set b = m.multVector(b)
set c = m.multVector(c)
set d = m.multVector(d)
endfunction
Last edited: