打开“ARToolKit\examples\paddleInteraction”下的“paddleInteractionTest.sln(Visual Studio的解决方案文件,它通常包含一个项目中所有的工程文件信息)”文件,我用的是VS2010,当然也也可以用别的版本打开,建议用2003以上的版本。
这个例子中的交互方法是基于paddle的,原理:首先检测到交互实现的平面,跟基础的MarkerDetect一样,检测到Marker(标识)来获得坐标系,在这里我们将这个平面叫做plane,并在这个plane上设置target的位置(实际就等于把一个button(按钮)位置定下来)。交互的工具paddle是另一个用一个Marker(标识)来表示,识别到这个Marker(标识)就找到了paddle,然后定位标识的中心,并通过坐标转换投射到plane的坐标上,比较paddle的坐标和target的坐标,当距离非常近时,则触发交互的事件。
这个程序中的定位plane(交互平面)的Marker(标识)是“ARToolKit\patterns”中的pattMulti,里面有6个Marker(标识)。为了使交互事件更明显,我稍微修改了一下代码,下面来看一下paddleInteractionTest.c中的代码。
(1)代码中加载摄像机信息和一些基本变量设置。37-43行定义了交互target的信息,58-60行定义了交互工具paddle的信息,66-73行是对函数的声明。第54行config_name在Data/multi/marker.dat中,里面包含了6个标识的信息。第60行paddle_name 在Data/paddle_data中,里面包含了交互工具paddle的标识信息。
#ifdef _WIN32
# include
#endif
#include
#include
#include
#include
#ifndef __APPLE__ # include
#else # include
#endif #include
#include
#include
#include
#include
#include
#define TOUCHED 1 #define NOT_TOUCHED -1 #define TARGET_NUM 5 #include "paddle.h" /* set up the video format globals */ #ifdef _WIN32 char *vconf = "Data\\WDM_camera_flipV.xml"; //摄像机默认参数 #else char *vconf = ""; #endif /* define a target struct for the objects that are to be touched */ //定义交互模型的信息 typedef struct { int id; //模型的ID int state; //模型的状态:TOUCHED或者UN_TOUCHED,TOUCHED时表示触发状态 float pos[3]; //模型在交互平面plane坐标系中的三维坐标 } targetInfo; targetInfo myTarget[TARGET_NUM]; //用结构体类型的一维数组来存放5个模型的信息 int draw_paddle( ARPaddleInfo *paddleInfo );//绘制交互工具paddle int xsize, ysize;//窗口xy尺寸 int thresh = 100;//二值化闸值 int count = 0; char *cparam_name = "Data/camera_para.dat";//摄像机参数的信息 ARParam cparam; char *config_name = "Data/multi/marker.dat";//多个标识的信息 ARMultiMarkerInfoT *config; /* paddle information 交互工具paddle的信息*/ int marker_flag[AR_SQUARE_MAX]; ARPaddleInfo *paddleInfo; char *paddle_name = "Data/paddle_data"; //交互工具paddle的标识信息 GLfloat light_position[] = {100.0,-200.0,200.0,0.0}; GLfloat ambi[] = {0.1, 0.1, 0.1, 0.1}; GLfloat lightZeroColor[] = {0.9, 0.9, 0.9, 0.1}; static void init(void); static void cleanup(void); static void keyEvent( unsigned char key, int x, int y); static void mainLoop(void); static void draw( targetInfo myTarget, double BaseTrans[3][4]);//绘制模型 int drawGroundGrid( double trans[3][4], int divisions, float x, float y, float height);//绘制平面网格 static int checkCollision(float Pos1[],float Pos2[], float range);//检查Paddle的位置和target的位置是否发生碰撞 static void findPaddlePosition(float curPaddlePos[], double card_trans[3][4],double base_trans[3][4]);//检测出paddle在plane坐标系中的3D坐标
#the number of patterns to be recognized
6
#marker 1
Data/multi/patt.a
40.0
0.0 0.0
1.0000 0.0000 0.0000 0.0000
0.0000 1.0000 0.0000 0.0000
0.0000 0.0000 1.0000 0.0000
#marker 2
Data/multi/patt.b
40.0
0.0 0.0
1.0000 0.0000 0.0000 100.0000
0.0000 1.0000 0.0000 0.0000
0.0000 0.0000 1.0000 0.0000
#marker 3
Data/multi/patt.c
40.0
0.0 0.0
1.0000 0.0000 0.0000 200.0000
0.0000 1.0000 0.0000 0.0000
0.0000 0.0000 1.0000 0.0000
#marker 4
Data/multi/patt.d
40.0
0.0 0.0
1.0000 0.0000 0.0000 0.0000
0.0000 1.0000 0.0000 -100.0000
0.0000 0.0000 1.0000 0.0000
#marker 5
Data/multi/patt.g
40.0
0.0 0.0
1.0000 0.0000 0.0000 100.0000
0.0000 1.0000 0.0000 -100.0000
0.0000 0.0000 1.0000 0.0000
#marker 6
Data/multi/patt.f
40.0
0.0 0.0
1.0000 0.0000 0.0000 200.0