Technology Demo

Manual Mouse Picking Demo

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Spot for images

Intro

This tutorial will demonstrate how to manually send out rays to objects to see if the mouse is over them.

Setting Up

Here, we will set up a sphere and a material for it.

self.sphere = luster.display.Entity(luster.resources.Mesh.SPHERE)
self.sphere.scale = .05
self.sphere:setMaterial(luster.resources.Material("Flower"))
self:addChild(self.sphere)

Next, we need to add two booleans to our sphere to make the demo work. MouseEnabled is allows the sphere to be interacted with by the mouse, and the isSphere is a boolean we will use later.

self.sphere.mouseEnabled = true
self.sphere.isSphere = true

All we need to do is add an event listener to complete the set up.

self:addEventListener(luster.display.DisplayObject.MOUSE_MOVE, Function(self, self.onMouseMove))

Manual Mouse Picking

We're going to link our mouse picking to a mouse move.

function Root:onMouseMove(dx,dy)
   local success, results = luster.util.raycast(self, {camera = self.camera})
   if success then
      if results.object.isSphere then
         local sphere = results.object
         sphere:yaw(dx*0.01)
         sphere:pitch(dy*0.01)
      end
   end
end

To do manual mouse picking, we use luster.util.raycast. It takes the scene and a table with options - here, we only supply the camera. If the ray hits something, it will return a boolean (success) and a table of resulting objects that were hit (results).

This is where the isSphere boolean comes in handy. If you have different objects in your scene, you can have each react differently depending on what kind of object it is. Here, we say that if there is a successful interaction and the object is a sphere, then we set a local variable to be the object and roll it depending on the dx and dy of the mouse.

Other options that can further define how the mouse interacts with the objects in the scene are

  • camera: the camera from which to cast the ray
  • position: the point in world global space to cast the ray from
  • direction: the world space direction of the ray cast
  • mask: the query mask to exclude objects from the raycast

Query masks and flags are used similarly to visibility masks and flags. You set the flag of an object and set the mask of the ray to set whether or not an object will count when the ray is sent out. For instance, if there are two cubes and you want one to react and the other to be "invisible" to the ray, set the flags as shown below, and change the options table appropriately.

self.cube.queryFlags = 1

And to set the mask property of the raycast:

local success, results = luster.util.raycast(self, {camera = self.camera, mask = 1})