From 59c543174181f09fdbf1c08feba7d3acc2046ca6 Mon Sep 17 00:00:00 2001 From: Josh Yelon Date: Sun, 28 Oct 2007 17:10:55 +0000 Subject: [PATCH] Working on ARToolKit - not functional yet --- panda/src/grutil/arToolKit.cxx | 143 ++++++++++++++++++++++++++++++++- 1 file changed, 139 insertions(+), 4 deletions(-) diff --git a/panda/src/grutil/arToolKit.cxx b/panda/src/grutil/arToolKit.cxx index 776f0c5550..c84332b123 100644 --- a/panda/src/grutil/arToolKit.cxx +++ b/panda/src/grutil/arToolKit.cxx @@ -22,6 +22,7 @@ #include "pandaNode.h" #include "camera.h" +#include "perspectiveLens.h" #include "config_grutil.h" extern "C" { #include "artools.h" @@ -29,6 +30,56 @@ extern "C" { ARToolKit::PatternTable ARToolKit::_pattern_table; +static void argConvGLcpara2( double cparam[3][4], int width, int height, double gnear, double gfar, double m[16] ) +{ + double icpara[3][4]; + double trans[3][4]; + double p[3][3], q[4][4]; + int i, j; + + if( arParamDecompMat(cparam, icpara, trans) < 0 ) { + printf("gConvGLcpara: Parameter error!!\n"); + exit(0); + } + + for( i = 0; i < 3; i++ ) { + for( j = 0; j < 3; j++ ) { + p[i][j] = icpara[i][j] / icpara[2][2]; + } + } + q[0][0] = (2.0 * p[0][0] / width); + q[0][1] = (2.0 * p[0][1] / width); + q[0][2] = ((2.0 * p[0][2] / width) - 1.0); + q[0][3] = 0.0; + + q[1][0] = 0.0; + q[1][1] = (2.0 * p[1][1] / height); + q[1][2] = ((2.0 * p[1][2] / height) - 1.0); + q[1][3] = 0.0; + + q[2][0] = 0.0; + q[2][1] = 0.0; + q[2][2] = (gfar + gnear)/(gfar - gnear); + q[2][3] = -2.0 * gfar * gnear / (gfar - gnear); + + q[3][0] = 0.0; + q[3][1] = 0.0; + q[3][2] = 1.0; + q[3][3] = 0.0; + + for( i = 0; i < 4; i++ ) { + for( j = 0; j < 3; j++ ) { + m[i+j*4] = q[i][0] * trans[0][j] + + q[i][1] * trans[1][j] + + q[i][2] * trans[2][j]; + } + m[i+3*4] = q[i][0] * trans[0][3] + + q[i][1] * trans[1][3] + + q[i][2] * trans[2][3] + + q[i][3]; + } +} + //////////////////////////////////////////////////////////////////// // Function: ARToolKit::Constructor // Access: Private @@ -36,6 +87,15 @@ ARToolKit::PatternTable ARToolKit::_pattern_table; //////////////////////////////////////////////////////////////////// ARToolKit *ARToolKit:: make(NodePath camera, const Filename ¶mfile) { + + if (AR_DEFAULT_PIXEL_FORMAT != AR_PIXEL_FORMAT_BGRA) { + grutil_cat.error() << + "The copy of ARToolKit that you are using is not compiled " + "for BGRA input. Panda3D cannot use this copy of ARToolKit. " + "Modify the ARToolKit's config file and compile it again.\n"; + return 0; + } + if (camera.is_empty()) { grutil_cat.error() << "ARToolKit: invalid camera nodepath\n"; return 0; @@ -45,6 +105,12 @@ make(NodePath camera, const Filename ¶mfile) { grutil_cat.error() << "ARToolKit: invalid camera nodepath\n"; return 0; } + Camera *cam = DCAST(Camera, node); + Lens *lens = cam->get_lens(); + if (lens->get_type() != PerspectiveLens::get_class_type()) { + grutil_cat.error() << "ARToolKit: supplied camera node must be perspective.\n"; + return 0; + } ARParam wparam; string fn = paramfile.to_os_specific(); @@ -53,6 +119,16 @@ make(NodePath camera, const Filename ¶mfile) { return 0; } + arParamDisp(&wparam); + double m[16]; + argConvGLcpara2(wparam.mat, 640, 480, 10, 1000, m); + cerr << "Panda3D projection mat: " << lens->get_projection_mat() << "\n"; + cerr << "Artoolkit mat: " + << m[ 0] << " " << m[ 1] << " " << m[ 2] << " " << m[ 3] << "\n" + << m[ 4] << " " << m[ 5] << " " << m[ 6] << " " << m[ 7] << "\n" + << m[ 8] << " " << m[ 9] << " " << m[10] << " " << m[11] << "\n" + << m[12] << " " << m[13] << " " << m[14] << " " << m[15] << "\n"; + ARToolKit *result = new ARToolKit(); result->_camera = camera; result->_camera_param = new ARParam; @@ -151,19 +227,78 @@ detach_patterns() { //////////////////////////////////////////////////////////////////// void ARToolKit:: analyze(Texture *tex, double thresh) { - nassertv(tex->get_texture_type() == Texture::TT_2d_texture); + nassertv(tex->has_ram_image()); + nassertv(tex->get_ram_image_compression() == Texture::CM_off); nassertv(tex->get_component_type() == Texture::T_unsigned_byte); - nassertv(tex->get_num_components() >= 3); + nassertv(tex->get_texture_type() == Texture::TT_2d_texture); + + if (tex->get_num_components() != 4) { + grutil_cat.error() << "ARToolKit can only analyze RGBA textures.\n"; + return; + } - int xsize = tex->get_x_size() - tex->get_pad_x_size(); - int ysize = tex->get_y_size() - tex->get_pad_y_size(); + int padx = tex->get_pad_x_size(); + int pady = tex->get_pad_y_size(); + int xsize = tex->get_x_size() - padx; + int ysize = tex->get_y_size() - pady; + int pagesize = xsize * ysize * 4; nassertv((xsize > 0) && (ysize > 0)); ARParam cparam; arParamChangeSize( (ARParam*)_camera_param, xsize, ysize, &cparam ); arInitCparam( &cparam ); + + // Pack the data into a buffer with no padding and invert the video + // vertically (panda's representation is upside down from ARToolKit) + + CPTA_uchar ri = tex->get_ram_image(); + const unsigned char *ram = ri.p(); + unsigned char *data = new unsigned char[xsize * ysize * 4]; + int dstlen = xsize * 4; + int srclen = (xsize + padx) * 4; + for (int y=0; y= conf) { + conf = marker_info[i].cf; + best = i; + } + } + } + if (conf > 0.0) { + cerr << "Marker " << pattern + << " " << int(marker_info[best].vertex[0][0]) << "," << int(marker_info[best].vertex[0][1]) + << " " << int(marker_info[best].vertex[1][0]) << "," << int(marker_info[best].vertex[1][1]) + << " " << int(marker_info[best].vertex[2][0]) << "," << int(marker_info[best].vertex[2][1]) + << " " << int(marker_info[best].vertex[3][0]) << "," << int(marker_info[best].vertex[3][1]) + << "\n"; + } + } + + delete data; }