Ejemplo n.º 1
0
// The thread in charge of creating and updating the GUI windows.
void CStereoOdometryEstimator::thread_gui()
{
	VERBOSE_LEVEL(1) << "[CStereoOdometryEstimator::thread_gui] Thread alive.\n";

	mrpt::gui::CDisplayWindow3DPtr  win;
	CPose3D current_pose(0,0,0,DEG2RAD(-90),DEG2RAD(0),DEG2RAD(-100) );

	try
	{
		// Initialize a 3D view with 2 panels for L & R images:
		win = mrpt::gui::CDisplayWindow3D::Create("Stereo Odometry",1200,465);

		// Subscribe to key events:
		TObserverWindowEvents my_observer( m_win_keyhit );
		my_observer.observeBegin(*win);

		vector<COpenGLViewportPtr>  gl_views(3);
		{
			COpenGLScenePtr &theScene = win->get3DSceneAndLock();
			gl_views[0] = theScene->getViewport("main");
			ASSERT_(gl_views[0])
			gl_views[1] = theScene->createViewport("right_image");
			ASSERT_(gl_views[1])
			gl_views[2] = theScene->createViewport("pose3D");

			// Assign sizes:
			gl_views[0]->setViewportPosition(  0, 0, .33,1.);
			gl_views[1]->setViewportPosition(.33, 0, .33,1.);
			gl_views[2]->setViewportPosition(.66, 0, .33,1.);

			// Prepare 3D view
			CSetOfObjectsPtr cam = stock_objects::BumblebeeCamera();
			cam->setPose(CPose3D());
			cam->setName("bumblebee");

			CSetOfLinesPtr path = CSetOfLines::Create();
			path->setName("path");
			path->setColor(0,1,0);
			path->appendLine(0,0,0,0,0,0);

			gl_views[2]->insert( stock_objects::CornerXYZ() );
			gl_views[2]->insert( CGridPlaneXY::Create(-100,100,-100,100) );
			gl_views[2]->insert( cam );
			gl_views[2]->insert( path );

			theScene->enableFollowCamera(true);

			// IMPORTANT!!! IF NOT UNLOCKED, THE WINDOW WILL NOT BE UPDATED!
			win->unlockAccess3DScene();
		}

		mrpt::system::TTimeStamp  last_timestamp = INVALID_TIMESTAMP;

		// Main loop in this GUI thread
		while (!m_threads_must_close)
		{
			// Check if we have new stuff to show:
			m_gui_info_cs.enter();

			if (m_gui_info->timestamp==last_timestamp || m_gui_info->timestamp==INVALID_TIMESTAMP)
			{	// Not a new or valid structure, keep waiting.
				m_gui_info_cs.leave();
				mrpt::system::sleep(2);
				continue;
			}
			last_timestamp = m_gui_info->timestamp;

			// We have new stuff:
			// Firstly, make a quick copy of the data to release the critical section ASAP and without
			// letting any chance of raising an exception in the way:
			TInfoForTheGUI  info;
			info.swap(*m_gui_info);
			m_gui_info_cs.leave();
			// From now on, we can safely work on our copy "info"
			//----------------------------------------------------

            // Set the image to color mode
            // ----------------------------------------------------
			info.img_left.colorImageInPlace();
			info.img_right.colorImageInPlace();

			// Update camera position
			current_pose += info.inc_pose;

			// Draw optional stuff on the base images:
			// ----------------------------------------------------
			m_profiler.enter("gui.draw_lr_pairings");
			if (!info.draw_pairings_all.empty())
			{
				const size_t nFeats = info.draw_pairings_all.size();

				static TColor colors[8] = {
					TColor(0xFF,0x00,0x00),
					TColor(0xFF,0xFF,0x00),
					TColor(0x00,0x00,0xFF),
					TColor(0x00,0xFF,0xFF),
					TColor(0x00,0x00,0x00),
					TColor(0xFF,0xFF,0xFF),
					TColor(0xFF,0x00,0xFF),
					TColor(0xFF,0x80,0x80)
				};

				const int rect_w = 2;
				for(size_t i=0;i<nFeats;++i)
				{
					// (X,Y) coordinates in the left/right images for this pairing:
					const TPixelCoord &ptL = info.draw_pairings_all[i].first;
					const TPixelCoord &ptR = info.draw_pairings_all[i].second;

					TColor thisColor;
					if( params_detect.detect_method == TDetectParams::dmORB )
                        thisColor = colors[info.draw_pairings_ids[i]&0x07];
                    else
                        thisColor = colors[i&0x07];

					info.img_left.rectangle( ptL.x-rect_w, ptL.y-rect_w, ptL.x+rect_w, ptL.y+rect_w, thisColor );
					info.img_right.rectangle( ptR.x-rect_w, ptR.y-rect_w, ptR.x+rect_w, ptR.y+rect_w, thisColor );
				}
			}
			m_profiler.leave("gui.draw_lr_pairings");

			// Draw tracked feats as lines in L/R
			m_profiler.enter("gui.draw_tracking");
			if (!info.stats_tracked_feats.empty())
			{
				static TColor colors[8] = {
					TColor(0xFF,0x00,0x00),
					TColor(0xFF,0xFF,0x00),
					TColor(0x00,0x00,0xFF),
					TColor(0x00,0xFF,0xFF),
					TColor(0x00,0x00,0x00),
					TColor(0xFF,0xFF,0xFF),
					TColor(0xFF,0x00,0xFF),
					TColor(0xFF,0x80,0x80)
				};

				const size_t N = info.stats_tracked_feats.size();
				for (size_t i=0;i<N;i++)
				{
					info.img_left.line(
						info.stats_tracked_feats[i].px_pL.x,
						info.stats_tracked_feats[i].px_pL.y,
						info.stats_tracked_feats[i].px_cL.x,
						info.stats_tracked_feats[i].px_cL.y,
						colors[i&0x07] );

					info.img_right.line(
						info.stats_tracked_feats[i].px_pR.x,
						info.stats_tracked_feats[i].px_pR.y,
						info.stats_tracked_feats[i].px_cR.x,
						info.stats_tracked_feats[i].px_cR.y,
						colors[i&0x07] );
				}
			}
			m_profiler.leave("gui.draw_tracking");

			// ------------------------------------------------------------
			// LOCK 3D scene & update images & text labels:
			m_profiler.enter("gui.locked-update");
			win->get3DSceneAndLock();

			gl_views[0]->setImageView_fast(info.img_left);   // "_fast()" has "move semantics" and destroy origin objects
			gl_views[1]->setImageView_fast(info.img_right);
            CRenderizablePtr obj = gl_views[2]->getByName("bumblebee");
            if(obj)
            {
                CSetOfObjectsPtr bb = static_cast<CSetOfObjectsPtr>(obj);
                bb->setPose( current_pose ); // Update camera position:

                CCamera &theCam = gl_views[2]->getCamera();
                theCam.setPointingAt( bb->getPoseX(), bb->getPoseY(), bb->getPoseZ() );
            }
			
			obj = gl_views[2]->getByName("path");
            if(obj)
            {
				CSetOfLinesPtr p = static_cast<CSetOfLinesPtr>(obj);
				p->appendLineStrip( current_pose.x(), current_pose.y(), current_pose.z() ); // Update camera path
            }

			// Text:
			win->addTextMessage(
					5,5,
					mrpt::system::dateTimeLocalToString(info.timestamp),
					TColorf(1,1,1),"mono",10, mrpt::opengl::FILL, 1
					);

			// Text:
			/** /
			{
				string sStatsFeats = string("Raw FAST features per octave: ");
				string sThresholds;
				for (size_t i=0;i<info.stats_feats_per_octave.size();i++) {
					sStatsFeats += mrpt::format("%u/",static_cast<unsigned int>(info.stats_feats_per_octave[i]) );
					sThresholds += mrpt::format("%i/",static_cast<int>(info.stats_FAST_thresholds_per_octave[i]) );
				}
				sStatsFeats += string(" | Thresholds: ") + sThresholds;

				win->addTextMessage(
						5,5+1*15,
						sStatsFeats,
						TColorf(1,1,1),"mono",10, mrpt::opengl::FILL, 2
						);
			}
			/ * */
			// Text:
			win->addTextMessage(
					5,5+1*15,
					"Detected features: " + info.text_msg_from_detect + "\n",
					TColorf(1,1,1),"mono",10, mrpt::opengl::FILL, 2
					);
			// Text:
			win->addTextMessage(
					5,5+2*15,
					info.text_msg_from_lr_match,
					TColorf(1,1,1),"mono",10, mrpt::opengl::FILL, 3
					);
			// Text:
			win->addTextMessage(
					5,5+3*15,
					info.text_msg_from_conseq_match,
					TColorf(1,1,1),"mono",10, mrpt::opengl::FILL, 4
					);

            // Text:
			win->addTextMessage(
					5,5+5*15,
					mrpt::format("Current pose (x,y,z,yaw,pitch,roll) = (%.2f,%.2f,%.2f,%.1fd,%.1fd,%.1fd)",
                        current_pose.x(), current_pose.y(), current_pose.z(),
                        RAD2DEG(current_pose.yaw()), RAD2DEG(current_pose.pitch()), RAD2DEG(current_pose.roll()))
                        + info.text_msg_from_optimization,
					TColorf(1,1,1),"mono",10, mrpt::opengl::FILL, 5
					);

			win->unlockAccess3DScene();
			m_profiler.leave("gui.locked-update");
			win->repaint();
		} // end while() main loop
	}
	catch(std::exception &e)
	{
		cerr << "[CStereoOdometryEstimator::thread_gui] Thread exit for exception:\n" << e.what() << endl;
	}

	if (win) {
		win.clear();
		mrpt::system::sleep(20); // Leave time to the wxWidgets thread to clean up
	}
	VERBOSE_LEVEL(1) << "[CStereoOdometryEstimator::thread_gui] Thread closed.\n";
}
Ejemplo n.º 2
0
void CSkeletonTracker::processPreviewNone()
{
		using namespace mrpt::opengl;

	// show laser scan
	if( m_showPreview )
	{
		if( !m_win )
		{
			string caption = string("Preview of ") + m_sensorLabel;
			m_win = mrpt::gui::CDisplayWindow3D::Create( caption, 800, 600 );
			
			COpenGLScenePtr & scene = m_win->get3DSceneAndLock();
			scene->insert( CGridPlaneXZ::Create(-3,3,0,5,-1.5 ) );
		
			// set camera parameters
			m_win->setCameraElevationDeg(-90);
			m_win->setCameraAzimuthDeg(90);
			m_win->setCameraZoom(4);
			m_win->setCameraPointingToPoint(0,0,0);
			
			// insert initial body
			CSetOfObjectsPtr body = CSetOfObjects::Create();
			body->setName("body");
			for(int i = 0; i < NUM_JOINTS; ++i)
			{
				CSpherePtr sph = CSphere::Create(0.03);
				sph->setColor(0,1,0);
				sph->setName( jointNames[i] );
				body->insert(sph);
			}
			
			// insert initial lines
			CSetOfLinesPtr lines = CSetOfLines::Create();
			lines->setName("lines");
			lines->setColor(0,0,1);
			body->insert(lines);
			
			scene->insert(body);
			m_win->unlockAccess3DScene();
		}

		if( m_win && m_win->isOpen() )
		{
			COpenGLScenePtr & scene = m_win->get3DSceneAndLock();
			{
				// update joints positions
				CSetOfObjectsPtr body = static_cast<CSetOfObjectsPtr>( scene->getByName("body") );
				ASSERT_( body )
							
				for(int i = 0; i < NUM_JOINTS; ++i)
				{
					CSpherePtr s = static_cast<CSpherePtr>( body->getByName( jointNames[i] ) );
					CPoint3D sphPos;
					if( i == 0 )
						sphPos = CPoint3D(0,0,0);
					else
					{
						m_joint_theta[i] += M_2PI/(10*(NUM_JOINTS-1));
						sphPos.x( 0.5*cos( m_joint_theta[i] ) );
						sphPos.y( 0.5*sin( m_joint_theta[i] ) );
						sphPos.z( 0.0 );
					}
					s->setPose( sphPos );
					s->setColor( 1, 0, 0 );
					s->setRadius( i == 0 ? 0.07 : 0.03 );
				} // end-for
			} // end-get3DSceneAndLock
			m_win->unlockAccess3DScene();
			m_win->forceRepaint();
		} // end if
	} // end if
Ejemplo n.º 3
0
/*-------------------------------------------------------------
					processPreviewNone
-------------------------------------------------------------*/
void CSkeletonTracker::processPreviewNone()
{
	using namespace mrpt::opengl;

	// show skeleton data
	if( m_showPreview )
	{
		if( !m_win )
		{
			string caption = string("Preview of ") + m_sensorLabel;
			m_win = mrpt::gui::CDisplayWindow3D::Create( caption, 800, 600 );
			
			COpenGLScenePtr & scene = m_win->get3DSceneAndLock();
			scene->insert( CGridPlaneXZ::Create(-3,3,0,5,-1.5 ) );
		
			// set camera parameters
			m_win->setCameraElevationDeg(-90);
			m_win->setCameraAzimuthDeg(90);
			m_win->setCameraZoom(4);
			m_win->setCameraPointingToPoint(0,0,0);
			
			// insert initial body
			CSetOfObjectsPtr body = CSetOfObjects::Create();
			body->setName("body");
			for(int i = 0; i < NUM_JOINTS; ++i)
			{
				CSpherePtr sph = CSphere::Create(0.03f);
				sph->setColor(0,1,0);
				sph->setName( jointNames[i] );
				body->insert(sph);
			}
			
			// insert initial lines
			CSetOfLinesPtr lines = CSetOfLines::Create();
			lines->setName("lines");
			lines->setColor(0,0,1);
			body->insert(lines);
			
			scene->insert(body);
			m_win->unlockAccess3DScene();
		}

		if( m_win && m_win->isOpen() )
		{
			COpenGLScenePtr & scene = m_win->get3DSceneAndLock();
			{
				m_win->addTextMessage( 0.35, 0.9,
					"Please, adopt this position",
					TColorf(1,1,1),"mono",10, mrpt::opengl::FILL, 
					0);

				// insert translucid dummy and help text (it will go away when measurements are taken)
				if( !scene->getByName("dummy") ) 
				{
					const double SCALE			= 0.8;
					const double BODY_RADIUS	= 0.22*SCALE;
					const double BODY_LENGTH	= 0.8*SCALE;
					const double ARM_RADIUS		= 0.05*SCALE;
					const double ARM_LENGTH		= 0.4*SCALE;
					const double LEG_RADIUS		= 0.1*SCALE;
					const double LEG_LENGTH		= 0.8*SCALE;
					const double HEAD_RADIUS	= 0.15*SCALE;
					const double ALPHA_CH		= 0.8;
					
					CSetOfObjectsPtr dummy = CSetOfObjects::Create();
					dummy->setName("dummy");
					dummy->setPose(math::TPose3D(0,0,0,0,0,DEG2RAD(-90)));
					{
						// head
						CSpherePtr   part = CSphere::Create(HEAD_RADIUS);
						part->setColor(1,1,1,ALPHA_CH);
						part->setPose(math::TPose3D(0,0,0.5*BODY_LENGTH+HEAD_RADIUS,0,0,0));
						dummy->insert(part);
					}
					{
						// body
						CCylinderPtr part = CCylinder::Create(BODY_RADIUS,BODY_RADIUS,BODY_LENGTH);
						part->setColor(1,1,1,ALPHA_CH);
						part->setPose(math::TPose3D(0,0,-BODY_LENGTH/2,0,0,0));
						dummy->insert(part);
					}
					{
						// left arm 0
						CCylinderPtr part = CCylinder::Create(ARM_RADIUS,ARM_RADIUS,ARM_LENGTH);
						part->setColor(1,1,1,ALPHA_CH);
						part->setPose(math::TPose3D(-BODY_RADIUS,0,0.5*BODY_LENGTH-ARM_RADIUS,0,DEG2RAD(-90),0));
						dummy->insert(part);
					}
					{
						// left arm 1
						CCylinderPtr part = CCylinder::Create(ARM_RADIUS,ARM_RADIUS,ARM_LENGTH);
						part->setColor(1,1,1,ALPHA_CH);
						part->setPose(math::TPose3D(-BODY_RADIUS-ARM_LENGTH+ARM_RADIUS,0,0.5*BODY_LENGTH-ARM_RADIUS,0,0,0));
						dummy->insert(part);
					}
					{
						// right arm 0
						CCylinderPtr part = CCylinder::Create(ARM_RADIUS,ARM_RADIUS,ARM_LENGTH);
						part->setColor(1,1,1,ALPHA_CH);
						part->setPose(math::TPose3D(BODY_RADIUS,0,0.5*BODY_LENGTH-ARM_RADIUS,0,DEG2RAD(90),0));
						dummy->insert(part);
					}
					{
						// right arm 1
						CCylinderPtr part = CCylinder::Create(ARM_RADIUS,ARM_RADIUS,ARM_LENGTH);
						part->setColor(1,1,1,ALPHA_CH);
						part->setPose(math::TPose3D(BODY_RADIUS+ARM_LENGTH-ARM_RADIUS,0,0.5*BODY_LENGTH-ARM_RADIUS,0,0,0));
						dummy->insert(part);
					}
									{
						// left leg
						CCylinderPtr part = CCylinder::Create(LEG_RADIUS,LEG_RADIUS,LEG_LENGTH);
						part->setColor(1,1,1,ALPHA_CH);
						part->setPose(math::TPose3D(-BODY_RADIUS+LEG_RADIUS,0,-(0.5*BODY_LENGTH+LEG_LENGTH),0,0,0));
						dummy->insert(part);
					}
					{
						// right leg
						CCylinderPtr part = CCylinder::Create(LEG_RADIUS,LEG_RADIUS,LEG_LENGTH);
						part->setColor(1,1,1,ALPHA_CH);
						part->setPose(math::TPose3D(BODY_RADIUS-LEG_RADIUS,0,-(0.5*BODY_LENGTH+LEG_LENGTH),0,0,0));
						dummy->insert(part);
					}
					scene->insert(dummy);
				} // end-if
				else
				{
					CSetOfObjectsPtr dummy = static_cast<CSetOfObjectsPtr>( scene->getByName("dummy") );
					dummy->setVisibility(true);
				}

				// update joints positions
				CSetOfObjectsPtr body = static_cast<CSetOfObjectsPtr>( scene->getByName("body") );
				ASSERT_( body )
							
				for(int i = 0; i < NUM_JOINTS; ++i)
				{
					CSpherePtr s = static_cast<CSpherePtr>( body->getByName( jointNames[i] ) );
					CPoint3D sphPos;
					if( i == 0 )
						sphPos = CPoint3D(0,0,0);
					else
					{
						m_joint_theta[i] += M_2PI/(10*(NUM_JOINTS-1));
						sphPos.x( 0.5*cos( m_joint_theta[i] ) );
						sphPos.y( 0.5*sin( m_joint_theta[i] ) );
						sphPos.z( 0.0 );
					}
					s->setPose( sphPos );
					s->setColor( 1, 0, 0 );
					s->setRadius( i == 0 ? 0.07 : 0.03 );
				} // end-for
			} // end-get3DSceneAndLock
			m_win->unlockAccess3DScene();
			m_win->forceRepaint();
		} // end if
	} // end if
Ejemplo n.º 4
0
/*---------------------------------------------------------------
					RobotPioneer
  ---------------------------------------------------------------*/
CSetOfObjectsPtr stock_objects::RobotPioneer()
{
	CSetOfObjectsPtr	ret = CSetOfObjects::Create();

	ret->setName("theRobot");

	CSetOfTrianglesPtr obj = CSetOfTriangles::Create();

	// Add triangles:
	CSetOfTriangles::TTriangle	trian;

	trian.r[0]=trian.r[1]=trian.r[2]= 1;
	trian.g[0]=trian.g[1]=trian.g[2]= 0;
	trian.b[0]=trian.b[1]=trian.b[2]= 0;
	trian.a[0]=trian.a[1]=trian.a[2]= 1;

	trian.x[0] = 0.10f; trian.x[1] =-0.20f; trian.x[2] =-0.20f;
	trian.y[0] =-0.10f; trian.y[1] = 0.10f; trian.y[2] =-0.10f;
	trian.z[0] = 0.20f; trian.z[1] = 0.25f; trian.z[2] = 0.25f;
	obj->insertTriangle( trian );	// 0
	trian.x[0] = 0.10f; trian.x[1] = 0.10f; trian.x[2] =-0.20f;
	trian.y[0] =-0.10f; trian.y[1] = 0.10f; trian.y[2] = 0.10f;
	trian.z[0] = 0.20f; trian.z[1] = 0.20f; trian.z[2] = 0.25f;
	obj->insertTriangle( trian );	// 1

	//trian.r = 0.9f; trian.g = 0; trian.b = 0; trian.a = 1;

	trian.x[0] = 0.10f; trian.x[1] = 0.10f; trian.x[2] = 0.10f;
	trian.y[0] =-0.10f; trian.y[1] =-0.10f; trian.y[2] = 0.10f;
	trian.z[0] = 0.05f; trian.z[1] = 0.20f; trian.z[2] = 0.20f;
	obj->insertTriangle( trian );	// 2
	trian.x[0] = 0.10f; trian.x[1] = 0.10f; trian.x[2] = 0.10f;
	trian.y[0] =-0.10f; trian.y[1] = 0.10f; trian.y[2] = 0.10f;
	trian.z[0] = 0.05f; trian.z[1] = 0.05f; trian.z[2] = 0.20f;
	obj->insertTriangle( trian );	// 3

	trian.x[0] =-0.20f; trian.x[1] =-0.20f; trian.x[2] =-0.20f;
	trian.y[0] =-0.10f; trian.y[1] =-0.10f; trian.y[2] = 0.10f;
	trian.z[0] = 0.05f; trian.z[1] = 0.25f; trian.z[2] = 0.25f;
	obj->insertTriangle( trian );	// 2b
	trian.x[0] =-0.20f; trian.x[1] =-0.20f; trian.x[2] =-0.20f;
	trian.y[0] =-0.10f; trian.y[1] = 0.10f; trian.y[2] = 0.10f;
	trian.z[0] = 0.05f; trian.z[1] = 0.05f; trian.z[2] = 0.25f;
	obj->insertTriangle( trian );	// 3b

	//trian.r = 0.8f; trian.g = 0; trian.b = 0; trian.a = 1;
	trian.x[0] = 0.10f; trian.x[1] =-0.20f; trian.x[2] =-0.20f;
	trian.y[0] =-0.10f; trian.y[1] =-0.10f; trian.y[2] =-0.10f;
	trian.z[0] = 0.20f; trian.z[1] = 0.25f; trian.z[2] = 0.05f;
	obj->insertTriangle( trian );	// 4
	trian.x[0] = 0.10f; trian.x[1] = 0.10f; trian.x[2] =-0.20f;
	trian.y[0] =-0.10f; trian.y[1] =-0.10f; trian.y[2] =-0.10f;
	trian.z[0] = 0.20f; trian.z[1] = 0.05f; trian.z[2] = 0.05f;
	obj->insertTriangle( trian );	// 5

	trian.x[0] = 0.10f; trian.x[1] =-0.20f; trian.x[2] =-0.20f;
	trian.y[0] = 0.10f; trian.y[1] = 0.10f; trian.y[2] = 0.10f;
	trian.z[0] = 0.20f; trian.z[1] = 0.25f; trian.z[2] = 0.05f;
	obj->insertTriangle( trian );	// 6
	trian.x[0] = 0.10f; trian.x[1] = 0.10f; trian.x[2] =-0.20f;
	trian.y[0] = 0.10f; trian.y[1] = 0.10f; trian.y[2] = 0.10f;
	trian.z[0] = 0.20f; trian.z[1] = 0.05f; trian.z[2] = 0.05f;
	obj->insertTriangle( trian );	// 7

	trian.r[0]=trian.r[1]=trian.r[2]= 0.05f;
	trian.g[0]=trian.g[1]=trian.g[2]= 0.05f;
	trian.b[0]=trian.b[1]=trian.b[2]= 0.05f;
	trian.a[0]=trian.a[1]=trian.a[2]= 1;

	trian.x[0] = 0.00f; trian.x[1] = 0.00f; trian.x[2] = 0.05f;
	trian.y[0] = 0.11f; trian.y[1] = 0.11f; trian.y[2] = 0.11f;
	trian.z[0] = 0.00f; trian.z[1] = 0.10f; trian.z[2] = 0.05f;
	obj->insertTriangle( trian );	// 8
	trian.x[0] = 0.00f; trian.x[1] = 0.00f; trian.x[2] = -0.05f;
	trian.y[0] = 0.11f; trian.y[1] = 0.11f; trian.y[2] = 0.11f;
	trian.z[0] = 0.00f; trian.z[1] = 0.10f; trian.z[2] = 0.05f;
	obj->insertTriangle( trian );	// 9

	trian.x[0] = 0.00f; trian.x[1] = 0.00f; trian.x[2] = 0.05f;
	trian.y[0] =-0.11f; trian.y[1] =-0.11f; trian.y[2] =-0.11f;
	trian.z[0] = 0.00f; trian.z[1] = 0.10f; trian.z[2] = 0.05f;
	obj->insertTriangle( trian );	// 10
	trian.x[0] = 0.00f; trian.x[1] = 0.00f; trian.x[2] = -0.05f;
	trian.y[0] =-0.11f; trian.y[1] =-0.11f; trian.y[2] =-0.11f;
	trian.z[0] = 0.00f; trian.z[1] = 0.10f; trian.z[2] = 0.05f;
	obj->insertTriangle( trian );	// 11

	ret->insert( obj );

	return ret;
}