local ctx = {t = 0, currentPronoun = '', lastPeriod = -1} function lovr.load() lovr.graphics.setBackgroundColor(0.0, 0.0, 0.0, 0.0) -- must seed rng etc math.randomseed(os.time()) end local PRONOUNCES = { 'he/him', 'she/her', 'they/them', 'it/its', 'fae/faer', } function lovr.update(dt) -- runs every frame ctx.t = ctx.t + dt -- calculate which 30-second period we're in local currentPeriod = math.floor(ctx.t / 30) -- if we've entered a new period, select a new random pronoun if currentPeriod > ctx.lastPeriod then ctx.currentPronoun = PRONOUNCES[math.random(#PRONOUNCES)] ctx.lastPeriod = currentPeriod end end function textOpacity(controllerPosition) local headsetPose = mat4(lovr.headset.getPose('head')) local headsetPosition = vec3(headsetPose:getPosition()) local textPosition = vec3(controllerPosition:getPosition()) -- Get the forward direction of the text plane (negative z-axis after transformations) local rawControllerPosition = {controllerPosition:unpack(true)} local textForward = vec3( -rawControllerPosition[9], -- -m[3][1] -rawControllerPosition[10], -- -m[3][2] -rawControllerPosition[11] -- -m[3][3] ):normalize() -- Calculate direction from text to headset local toHeadset = vec3( headsetPosition.x - textPosition.x, headsetPosition.y - textPosition.y, headsetPosition.z - textPosition.z ):normalize() -- Calculate dot product between text forward and direction to headset local dotProduct = textForward:dot(toHeadset) if dotProduct >= -0.5 then return 0 end return 0.5 * ((-dotProduct) - 0.5) / 0.5 end function lovr.draw(pass) pass:setColor(1, 0.3, 0.3, 0.5) local controllerPosition = mat4(lovr.headset.getPose('hand/right')) -- put it 5cm above hand controllerPosition:translate(0.05, 0, 0) -- put it some cm separate from my normal watch controllerPosition:translate(0, 0.05, 0) -- rotate such that it faces the hmd controllerPosition:rotate(math.pi/2, 0, 1, 0) controllerPosition:rotate(math.pi/2, 0, 0, 1) controllerPosition:rotate(math.pi/6, 0, 0, 1) -- scale down so its not the size of the hand controllerPosition = controllerPosition:scale(0.1, 0.1, 0.1) -- prevent z fighting with plane controllerPosition:translate(0,0,0.0001) -- scale down text controllerPosition = controllerPosition:scale(0.3, 0.3, 0.3) local textOpacity = textOpacity(controllerPosition) pass:setColor(1, 0.5, 0.5, textOpacity) pass:text(ctx.currentPronoun, controllerPosition) end