Saturday, April 24, 2010

Component Mouse Events

Now that I've got mouse-picking all figured out things are moving swiftly forward. I have created a new "bounding" package in sgine to support hit testing for mouse events and collision detection in the future. One of the awesome things about Scala's mix-ins is that I can modularize functionality down to a few traits that make up specific functionality to allow users of the engine to take on as much or as little of the system as they want. To this end I've created two classes: MatrixPropertyContainer (name to change to MatrixObject) and BoundingObject. MatrixPropertyContainer represents an immutable property "matrix" that returns a mutable Matrix4 and BoundingObject similarly contains an immutable property "bounding" that returns a Bounding instance.

In RenderableScene I listen for events on Mouse, walk through the NodeView for my scene matching Nodes that have both of these traits and then do a hit-test with them. The result is shown in the test below:

package org.sgine.ui

import org.sgine.core.Resource

import org.sgine.event.EventHandler

import org.sgine.input.event.MouseEvent

import org.sgine.render.Renderer
import org.sgine.render.scene.RenderableScene

import org.sgine.scene.GeneralNodeContainer

object TestMousePicking {
 def main(args: Array[String]): Unit = {
  // Create the Renderer
  val r = Renderer.createFrame(1024, 768, "Test Mouse Picking")
  // Create a mutable scene
  val scene = new GeneralNodeContainer()
  // Create an image to show the puppies
  val component = new Image()
  component.location.x := -200.0
  component.location.z := -500.0
  component.scale.x := 1.5
  component.rotation.y := Math.Pi / -4.0
  component.source := Resource("resource/puppies.jpg")   // 700x366
  scene += component
  // Add our scene to the renderer
  r.renderable := RenderableScene(scene, false)
  // Add a listener to listen to all mouse events to the picture
  component.listeners += EventHandler(mouseEvent)
 // The method that is invoked when a mouse event occurs on the picture
 private def mouseEvent(evt: MouseEvent) = {
  println("MouseEvent: " + evt)

Though adding a listener to mouse events is a one-line call the underlying functionality remains modular and optional to rendering functionality in the application giving the benefits of simple functionality in classes that make use of it, and trimmed down explicit functionality in those classes that do not. The mouse event system dispatches "press", "release", "move", and "wheel" events. I have on my todo to incorporate "over" and "out" events as well.

No comments:

Post a Comment

Scala Engine for high-performance interactive applications.