ruby-processing でNyAR4psg を使ったら drawBackground でこける

NyAR4psg のサンプルを ruby-processing で書き直してみた。

nyar.rb

require 'lib/NyARToolkit.jar'
require 'lib/NyAR4psg.jar'
load_library :video

include_package "processing.video"

module NyAR4psg
	include_package 'jp.nyatla.nyar4psg'
end

def setup
	size 640, 480, P3D
	colorMode RGB, 100
	@cam = Capture.new(self, width, height)
	@nya = NyAR4psg::MultiMarker.new(self, width, height, "camera_para.dat")
	@nya.addARMarker "patt.hiro", 80
end

def draw
	return unless @cam.available?
	@cam.read
	@nya.detect @cam
	background 0
	@nya.draw_background @cam
	return unless @nya.isExistMarker(0)
	@nya.beginTransform 0
	fill 0, 0, 255
	translate 0, 0, 20
	box 40
	@nya.endTransform
end

実行には、NyARToolkit.jar と NyAR4psg.jar が必要なので、nyar.rb と同じ階層のフォルダにlibフォルダを作り、両jarファイルを保存する。
また、コマンドラインには-d32 を指定する必要がある。

% rp5 run nyar.rb -d32

ところが @nya.drawBackground のところで、Method missing エラーが出る。
調べると、drawBackground は MultiMarker の親である仮想クラス NyARPsgBaseClass で定義されている。
Processing では同様のコードは何の問題もなく動作するが、ruby-processing では、確かに @nya.public_methods は親クラスのメソッドを持っていない。

JRuby固有の問題もあるかもしれないと思ったが、ふとSwing のJButton クラスの public_methods をのぞいたら、親仮想クラス AbstractButton のメソッドをちゃんと持っている。

そこでピンと来て調べたら案の定。
AbstractButton は public abstract だが、NyARPsgBaseClass はただの abstract だ。
public 指定がないためにパッケージ内可視となって、そのせいで JRuby から見えないのだ。

というわけでクラス宣言に public を追加してNyAR4psg を再コンパイルした。
Makefile の類はついていなかったので、コマンドラインを手打ちする。

% cd ~/workspace/nyar4psg-1.2.0/src
% mkdir class
% javac -encoding utf-8 -d class -classpath ../../kinect/nyar4psg/library/NyARToolkit.jar:/Applications/Processing.app/Contents/Resources/Java/core.jar jp/nyatla/nyar4psg/*.java
% cd class
% jar cf NyAR4psg.jar jp

こうして作ったNyAR4psg.jar を、nyar.rb のあるフォルダのlib にコピーしたら、期待通り動作して、マーカー上に青の立方体が表示できた。