# Crate Rotate: an experiment with RotationRate (Codea 1.5)

`RotationRate` is a new feature in Codea version 1.5, for iPad 2s and above. The code below is based on code where @Andrew_Stacey assisted greatly with the coding of the mathematics of the rotation.

``````
--
-- Crate Rotate
-- For Codea 1.5 (or above)
--

supportedOrientations(LANDSCAPE_LEFT)
function setup()
if deviceMetrics().platformName == "iPad 1G" then
print("This code needs a gyroscope."..
" An iPad 1 does not have one.")
else
print("Rotate the Viewer about the crate.")
end
local size = math.min(HEIGHT, WIDTH) / 2
d = size * 3
m = cubeMesh(size)
dirz = vec3(0, 0, 1)
diry = vec3(0, 1, 0)
dirx = vec3(1, 0, 0)
fill(255)
end

function draw()
background(0)
perspective()
local mat = matrix()
local dxa = RotationRate.x
local dya = RotationRate.y
local dza = RotationRate.z
mat = mat:rotate(dza, dirz.x, dirz.y, dirz.z)
mat = mat:rotate(dya, diry.x, diry.y, diry.z)
mat = mat:rotate(dxa, dirx.x, dirx.y, dirx.z)
dirx = mult(mat, dirx)
diry = mult(mat, diry)
dirz = mult(mat, dirz)
local x = dirz.x * d
local y = dirz.y * d
local z = dirz.z * d
camera(x, y, z, 0, 0, 0, diry.x, diry.y, diry.z)
m:draw()
end

function cubeMesh(size)
local v = {}
for i = 0, 7 do
local x = (i % 2) * 2 - 1
local y = (math.floor(i / 2) % 2) * 2 - 1
local z = (math.floor(i / 4) % 2) * 2 - 1
v[i] = vec3(x, y, z) * size / 2
end
local ver = {}
for v1 = 1, 3 do
local v2 = v1 * 3 % 7
local v3 = 7 - v1
local v4 = 7 - v2
local vt = {v[0], v[v1], v[v2],
v[0], v[v3], v[v4],
v[7], v[v2], v[v1],
v[7], v[v4], v[v3]}
for i = 1, #vt do
ver[(v1 - 1) * #vt + i] = vt[i]
end
end
local uv = {
vec2(0.5, 0), vec2(0, 0), vec2(0, 0.5),
vec2(0.5, 0), vec2(1, 0.5), vec2(1, 0),
vec2(0.5, 0.5), vec2(1, 0.5), vec2(1, 0),
vec2(0.5, 0.5), vec2(0, 0), vec2(0, 0.5),
vec2(0.5, 0), vec2(0.5, 0.5), vec2(1, 0.5),
vec2(0.5, 0.5), vec2(1, 1), vec2(1, 0.5),
vec2(0.5, 0.5), vec2(0, 0.5), vec2(0, 1),
vec2(0.5, 0.5), vec2(1, 0), vec2(0.5, 0),
vec2(0.5, 0), vec2(0, 0.5), vec2(0.5, 0.5),
vec2(0.5, 0.5), vec2(0.5, 1), vec2(1, 1),
vec2(0.5, 0.5), vec2(0, 1), vec2(0.5, 1),
vec2(0.5, 0.5), vec2(0.5, 0), vec2(0, 0)}
local m = mesh()
m.texture = texture()
m.vertices = ver
m.texCoords = uv
return m
end

function texture()
local img = image(214, 214)
pushStyle()
pushMatrix()
resetStyle()
resetMatrix()
setContext(img)
background(45, 11, 23)
textAlign(CENTER)
spriteMode(CORNER)
sprite("Cargo Bot:Title Large Crate 2", 1, 1)
sprite("Cargo Bot:Title Large Crate 2", 108, 1)
sprite("Cargo Bot:Title Large Crate 1", 1, 108)
sprite("Cargo Bot:Title Large Crate 1", 108, 108)
fill(201, 186, 25)
text("THIS\
WAY\
UP", 53, 53)
text("USE\
NO\
HOOKS", 160, 53)
text("THIS\
SIDE\
UP", 53, 160)
text("OTHER\
SIDE\
UP", 160, 160)
setContext()
popStyle()
popMatrix()
return img
end

function mult(mat, vec)
local v1 = mat[1] * vec.x + mat[5] * vec.y + mat[9]  * vec.z
local v2 = mat[2] * vec.x + mat[6] * vec.y + mat[10] * vec.z
local v3 = mat[3] * vec.x + mat[7] * vec.y + mat[11] * vec.z
return vec3(v1, v2, v3)
end

``````

I love the text render-to-texture you’ve done to customise the crate. That’s a really cool demo.