pane.lua 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. m = {} -- floating pane as anchor for 2D and 3D graphical content
  2. m.__index = m
  3. m.colors = {
  4. background = 0x231e18,
  5. active = 0xd35c5c,
  6. disabled = 0x242424,
  7. }
  8. local defaultFont = lovr.graphics.newFont('ubuntu-mono.ttf', 30)
  9. defaultFont:setPixelDensity(1)
  10. m.new = function(width, height, handleSide)
  11. local self = setmetatable({
  12. width = width, -- meters
  13. height = height,
  14. canvasSize = 1600,
  15. canvas = nil, -- lazily created in drawCanvas
  16. material = lovr.graphics.newMaterial(),
  17. font = defaultFont,
  18. handleSide = handleSide or 'left',
  19. transform = lovr.math.newMat4(.1,1.6,-1.3, 1,1,1, 0, 0,1,0)
  20. }, m)
  21. self.ortho = lovr.math.newMat4():orthographic(0, self.canvasSize, 0, -self.canvasSize, -100, 100),
  22. self.material:setTransform(0, 1-height, width, height)
  23. self.font:setPixelDensity(1)
  24. self.fontWidth = self.font:getWidth(' ')
  25. self.fontHeight = self.font:getHeight()
  26. return self
  27. end
  28. function m:center()
  29. local x,y,z, angle, ax,ay,az = lovr.headset.getPose('head')
  30. local headTransform = mat4(x,y,z, angle, ax,ay,az)
  31. local headPosition = vec3(headTransform:mul(0,0,0))
  32. local panePosition = vec3(headTransform:mul(0,0,-0.8))
  33. self.transform:target(panePosition, headPosition)
  34. end
  35. function m:draw(isActive, drawFunction, ...)
  36. -- oriented towards -z so that mat4.lookAt() works as expected
  37. lovr.graphics.push()
  38. lovr.graphics.transform(self.transform)
  39. lovr.graphics.setColor(0x1e1a15)
  40. local margin = 0.02
  41. lovr.graphics.plane('fill', 0,0,0.005, self.width + margin, self.height + margin, math.pi, 0,1,0)
  42. lovr.graphics.setColor(1,1,1)
  43. if self.canvas then
  44. lovr.graphics.plane(self.material, 0,0,0, -self.width, self.height, 0*math.pi, 0,0,0)
  45. end
  46. lovr.graphics.setColor(isActive and self.colors.active or self.colors.disabled)
  47. local thickness = 0.02
  48. local handleX = self.handleSide == 'right' and -self.width/2 - thickness or self.width/2 + thickness
  49. local handleY = 0
  50. lovr.graphics.box('fill', handleX, handleY, 0, thickness, self.height * 0.8, thickness)
  51. if drawFunction then
  52. -- make all content drawn in xy range -1 to 1 meters fit onto the pane
  53. local scaling = math.min(self.width, self.height) / 2
  54. lovr.graphics.scale(-scaling, scaling, -scaling)
  55. drawFunction(...)
  56. -- within drawFunction, x and y lie on pane and +z is in front of pane
  57. end
  58. lovr.graphics.pop()
  59. end
  60. function m:drawCanvas(drawFunction, ...)
  61. if not self.canvas then
  62. self.canvas = lovr.graphics.newCanvas(self.canvasSize, self.canvasSize, {stereo=false, depth=false})
  63. end
  64. lovr.graphics.push()
  65. lovr.graphics.origin()
  66. lovr.graphics.setShader()
  67. lovr.graphics.setCanvas(self.canvas)
  68. lovr.graphics.setViewPose(1, mat4())
  69. lovr.graphics.setProjection(1, self.ortho)
  70. drawFunction(...)
  71. lovr.graphics.setCanvas()
  72. lovr.graphics.pop()
  73. self.material:setTexture(self.canvas:getTexture())
  74. end
  75. function m:drawText(text, col, row)
  76. lovr.graphics.setFont(self.font)
  77. local x = col * self.fontWidth
  78. local y = -row * self.fontHeight
  79. lovr.graphics.print(text, x,y,0, 1, 0, 1,0,0, 0, 'left','top')
  80. end
  81. function m:drawTextRectangle(col, row, width)
  82. -- rectangle in text-coordinates
  83. width = width * self.fontWidth
  84. local x = col * self.fontWidth
  85. local y = -row * self.fontHeight
  86. local height = self.fontHeight
  87. lovr.graphics.plane('fill', x + width/2, y - height/2, -10, width, height)
  88. end
  89. return m