Esempio n. 1
0
// begin arcball rotation
void arcball_start(int mx, int my)
{
  // saves a copy of the current rotation for comparison
  quatcopy(ab_last,ab_quat);
  if(ab_planar) ab_start = planar_coords((GLdouble)mx,(GLdouble)my);
  else ab_start = sphere_coords((GLdouble)mx,(GLdouble)my);
}
Esempio n. 2
0
// update current arcball rotation
void arcball_move(int mx, int my)
{
  if(ab_planar)
  {
    ab_curr = planar_coords((GLdouble)mx,(GLdouble)my);
    if(ab_curr.equals(ab_start)) return;
    
    // d is motion since the last position
    vec d = ab_curr - ab_start;
    
    GLfloat angle = d.length() * 0.5;
    GLfloat cosa = cos( angle );
    GLfloat sina = sin( angle );
    // p is perpendicular to d
    vec p = ((ab_out*d.x)-(ab_up*d.y)).unit() * sina;

    quaternion(ab_next,p.x,p.y,p.z,cosa);
    quatnext(ab_quat,ab_last,ab_next);
    // planar style only ever relates to the last point
    quatcopy(ab_last,ab_quat);
    ab_start = ab_curr;
    
  } else {

    ab_curr = sphere_coords((GLdouble)mx,(GLdouble)my);
    if(ab_curr.equals(ab_start))
    { // avoid potential rare divide by tiny
      quatcopy(ab_quat,ab_last);
      return;
    }

    // use a dot product to get the angle between them
    // use a cross product to get the vector to rotate around
    GLfloat cos2a = ab_start*ab_curr;
    GLfloat sina = sqrt((1.0 - cos2a)*0.5);
    GLfloat cosa = sqrt((1.0 + cos2a)*0.5);
    vec cross = (ab_start^ab_curr).unit() * sina;
    quaternion(ab_next,cross.x,cross.y,cross.z,cosa);

    // update the rotation matrix
    quatnext(ab_quat,ab_last,ab_next);
  }
}
Esempio n. 3
0
int PoserCharlesSlow( SurviveObject * so, PoserData * pd )
{
	PoserType pt = pd->pt;
	SurviveContext * ctx = so->ctx;
	DummyData * dd = so->PoserData;

	if( !dd ) so->PoserData = dd = malloc( sizeof( DummyData ) );

	switch( pt )
	{
	case POSERDATA_IMU:
	{
		PoserDataIMU * imu = (PoserDataIMU*)pd;
		//printf( "IMU:%s (%f %f %f) (%f %f %f)\n", so->codename, imu->accel[0], imu->accel[1], imu->accel[2], imu->gyro[0], imu->gyro[1], imu->gyro[2] );
		break;
	}
	case POSERDATA_LIGHT:
	{
		PoserDataLight * l = (PoserDataLight*)pd;
		//printf( "LIG:%s %d @ %f rad, %f s (AC %d) (TC %d)\n", so->codename, l->sensor_id, l->angle, l->length, l->acode, l->timecode );
		break;
	}
	case POSERDATA_FULL_SCENE:
	{
		PoserDataFullScene * fs = (PoserDataFullScene*)pd;



		int p;
		FLT * hmd_points  = so->sensor_locations;

		for( p = 0; p < so->nr_locations; p++ )
		{
			printf( "%f %f %f\n", hmd_points[p*3+0], hmd_points[p*3+1], hmd_points[p*3+2] );
		}


		int lh, cycle;
		FLT dz, dy, dx;
		for( lh = 0; lh < 2; lh++ )
		{
			FLT beste = 1e20;

			FLT LighthousePos[3];
			FLT LighthouseQuat[4];

			LighthousePos[0] = 0;
			LighthousePos[1] = 0;
			LighthousePos[2] = 0;
			LighthouseQuat[0] = 1;
			LighthouseQuat[1] = 0;
			LighthouseQuat[2] = 0;
			LighthouseQuat[3] = 0;

			FLT bestxyz[3];
			memcpy( bestxyz, LighthousePos, sizeof( LighthousePos ) );

			//STAGE1 1: Detemine vectoral position from lighthouse to target.  Does not determine lighthouse-target distance.
			//This also is constantly optimizing the lighthouse quaternion for optimal spotting.
			FLT fullrange = 5; //Maximum search space for positions.  (Relative to HMD)
	

			//Sweep whole area 30 times
			for( cycle = 0; cycle < 30; cycle ++ )
			{

				//Adjust position, one axis at a time, over and over until we zero in.
				{
					FLT bestxyzrunning[3];
					beste = 1e20;

					FILE * f;
					if( cycle == 0 )
					{
						char filename[1024];
						sprintf( filename, "calinfo/%d_lighthouse.dat", lh );
						f = fopen( filename, "wb" );
					}

					//We split the space into this many groups (times 2) and
					//if we're on the first cycle, we want to do a very linear
					//search.  As we refine our search we can then use a more
					//binary search technique.
					FLT splits = 4;
					if( cycle == 0 ) splits = 32;
					if( cycle == 1 ) splits = 13;
					if( cycle == 2 ) splits = 10;
					if( cycle == 3 ) splits = 8;
					if( cycle == 4 ) splits = 5;

					//Wwe search throug the whole space.
					for( dz = -fullrange; dz < fullrange; dz += fullrange/splits )
					for( dy = -fullrange; dy < fullrange; dy += fullrange/splits )
					for( dx = -fullrange; dx < fullrange; dx += fullrange/splits )
					{
						//Specificially adjust one axis at a time, searching for the best.
						memcpy( LighthousePos, bestxyz, sizeof( LighthousePos ) );
						LighthousePos[0] += dx;  //These are adjustments to the "best" from last frame.
						LighthousePos[1] += dy;
						LighthousePos[2] += dz;

						FLT ft;
						//Try refining the search for the best orientation several times.
						ft = RunOpti(so, fs, lh, 0, LighthousePos, LighthouseQuat);
						if( cycle == 0 )
						{
							FLT sk = ft*10.;
							if( sk > 1 ) sk = 1;
							uint8_t cell = (uint8_t)((1.0 - sk) * 255);
							FLT epsilon = 0.1;

							if( dz == 0 ) { /* Why is dz special? ? */
							  if ( dx > -epsilon && dx < epsilon )
								cell =  255;
							  if ( dy > -epsilon && dy < epsilon )
				                                    cell = 128;
							}

							fprintf( f, "%c", cell );
						}

						if( ft < beste ) { beste = ft; memcpy( bestxyzrunning, LighthousePos, sizeof( LighthousePos ) ); }
					}

					if( cycle == 0 )
					{
						fclose( f );
					}
					memcpy( bestxyz, bestxyzrunning, sizeof( bestxyz ) );

					//Print out the quality of the lock this time.
					FLT dist = sqrt(bestxyz[0]*bestxyz[0] + bestxyz[1]*bestxyz[1] + bestxyz[2]*bestxyz[2]);
					printf( "%f %f %f (%f) = %f\n", bestxyz[0], bestxyz[1], bestxyz[2], dist, beste );
				}

				//Every cycle, tighten up the search area.
				fullrange *= 0.25;
			}

			if( beste > 0.1 )
			{
				//Error too high
				SV_ERROR( "LH: %d / Best E %f Error too high\n", lh, beste );
				return -1;
			}

			RunOpti(so, fs, lh, 1, LighthousePos, LighthouseQuat);

			ctx->bsd[lh].PositionSet = 1;
			copy3d( ctx->bsd[lh].Pose.Pos, LighthousePos );
			quatcopy( ctx->bsd[lh].Pose.Rot, LighthouseQuat );			
#define ALT_COORDS
#ifdef ALT_COORDS
			so->FromLHPose[lh].Pos[0] = LighthousePos[0];
			so->FromLHPose[lh].Pos[1] = LighthousePos[1];
			so->FromLHPose[lh].Pos[2] = LighthousePos[2];
			so->FromLHPose[lh].Rot[0] =-LighthouseQuat[0];
			so->FromLHPose[lh].Rot[1] = LighthouseQuat[1];
			so->FromLHPose[lh].Rot[2] = LighthouseQuat[2];
			so->FromLHPose[lh].Rot[3] = LighthouseQuat[3];

			quatrotatevector( so->FromLHPose[lh].Pos, so->FromLHPose[lh].Rot, so->FromLHPose[lh].Pos );
#else
			so->FromLHPose[lh].Pos[0] = LighthousePos[0];
			so->FromLHPose[lh].Pos[1] = LighthousePos[1];
			so->FromLHPose[lh].Pos[2] = LighthousePos[2];
			so->FromLHPose[lh].Rot[0] = LighthouseQuat[0];
			so->FromLHPose[lh].Rot[1] = LighthouseQuat[1];
			so->FromLHPose[lh].Rot[2] = LighthouseQuat[2];
			so->FromLHPose[lh].Rot[3] = LighthouseQuat[3];
#endif
		}

		return 0;
	}
	case POSERDATA_DISASSOCIATE:
	{
		free( dd );
		so->PoserData = 0;
		//printf( "Need to disassociate.\n" );
		break;
	}
	}
	return -1;
}