Ver Fonte

Add button interaction example;

bjorn há 5 anos atrás
pai
commit
0da09462c0

+ 1 - 5
examples/Interaction/Pointing/main.lua

@@ -6,11 +6,7 @@ function lovr.draw()
     lovr.graphics.setColor(1, 1, 1)
     lovr.graphics.sphere(position, .01)
 
-    if lovr.headset.isDown(hand, 'trigger') then
-      lovr.graphics.setColor(0, 1, 0)
-    else
-      lovr.graphics.setColor(1, 0, 0)
-    end
+    lovr.graphics.setColor(1, 0, 0)
     lovr.graphics.line(position, position + direction * 50)
   end
 end

+ 94 - 0
examples/Interaction/Selecting:_UI/main.lua

@@ -0,0 +1,94 @@
+local function raycast(rayPos, rayDir, planePos, planeDir)
+  local dot = rayDir:dot(planeDir)
+  if math.abs(dot) < .001 then
+    return nil
+  else
+    local distance = (planePos - rayPos):dot(planeDir) / dot
+    if distance > 0 then
+      return rayPos + rayDir * distance
+    else
+      return nil
+    end
+  end
+end
+
+local button = {
+  text = 'Please click me',
+  textSize = .1,
+  position = lovr.math.newVec3(0, 1, -3),
+  width = 1.0,
+  height = .4,
+  hover = false,
+  active = false
+}
+
+local tips = {}
+
+function lovr.update()
+  button.hover, button.active = false, false
+
+  for i, hand in ipairs(lovr.headset.getHands()) do
+    tips[hand] = pointers[hand] or lovr.math.newVec3()
+
+    -- Ray info:
+    local rayPosition = vec3(lovr.headset.getPosition(hand))
+    local rayDirection = vec3(quat(lovr.headset.getOrientation(hand)):direction())
+
+    -- Call the raycast helper function to get the intersection point of the ray and the button plane
+    local hit = raycast(rayPosition, rayDirection, button.position, vec3(0, 0, 1))
+
+    local inside = false
+    if hit then
+      local bx, by, bw, bh = button.position.x, button.position.y, button.width / 2, button.height / 2
+      inside = (hit.x > bx - bw) and (hit.x < bx + bw) and (hit.y > by - bh) and (hit.y < by + bh)
+    end
+
+    -- If the ray intersects the plane, do a bounds test to make sure the x/y position of the hit
+    -- is inside the button, then mark the button as hover/active based on the trigger state.
+    if inside then
+      if lovr.headset.wasPressed(hand, 'trigger') then
+        print('ALERT: The button has been pressed')
+      elseif lovr.headset.isDown(hand, 'trigger') then
+        button.active = true
+      else
+        button.hover = true
+      end
+    end
+
+    -- Set the end position of the pointer.  If the raycast produced a hit position then use that,
+    -- otherwise extend the pointer's ray outwards by 50 meters and use it as the tip.
+    tips[hand]:set(inside and hit or (rayPosition + rayDirection * 50))
+  end
+end
+
+function lovr.draw()
+  -- Button background
+  if button.active then
+    lovr.graphics.setColor(.4, .4, .4)
+  elseif button.hover then
+    lovr.graphics.setColor(.2, .2, .2)
+  else
+    lovr.graphics.setColor(.1, .1, .1)
+  end
+  lovr.graphics.plane('fill', button.position, button.width, button.height)
+
+  -- Button text (add a small amount to the z to put the text slightly in front of button)
+  lovr.graphics.setColor(1, 1, 1)
+  lovr.graphics.print(button.text, button.position + vec3(0, 0, .001), button.textSize)
+
+  -- Pointers
+  for hand, tip in pairs(tips) do
+    local position = vec3(lovr.headset.getPosition(hand))
+
+    lovr.graphics.setColor(1, 1, 1)
+    lovr.graphics.sphere(position, .01)
+
+    if button.active then
+      lovr.graphics.setColor(0, 1, 0)
+    else
+      lovr.graphics.setColor(1, 0, 0)
+    end
+    lovr.graphics.line(position, tip)
+    lovr.graphics.setColor(1, 1, 1)
+  end
+end