Example #1
0
/**
 * \brief Horizontal move of point position
 * This function uses an algorithm for an oblate spheroid earth model.
 * The algorithm is described here: 
 * http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf
 */
int nmea_move_horz_ellipsoid(
    const nmeaPOS *start_pos,   /**< Start position in radians */
    nmeaPOS *end_pos,           /**< (O) Result position in radians */
    double azimuth,             /**< Azimuth in radians */
    double distance,            /**< Distance (km) */
    double *end_azimuth         /**< (O) Azimuth at end position in radians */
    )
{
    /* Variables */
    double f, a, b, sqr_a, sqr_b;
    double phi1, tan_U1, sin_U1, cos_U1, s, alpha1, sin_alpha1, cos_alpha1;
    double sigma1, sin_alpha, sqr_cos_alpha, sqr_u, A, B;
    double sigma_initial, sigma, sigma_prev, sin_sigma, cos_sigma, cos_2_sigmam, sqr_cos_2_sigmam, delta_sigma;
    int remaining_steps;
    double tmp1, phi2, lambda, C, L;
    
    /* Check input */
    NMEA_ASSERT(start_pos != 0);
    NMEA_ASSERT(end_pos != 0);
    
    if (fabs(distance) < 1e-12)
    { /* No move */
        *end_pos = *start_pos;
        if ( end_azimuth != 0 ) *end_azimuth = azimuth;
        return ! (NMEA_POSIX(isnan)(end_pos->lat) || NMEA_POSIX(isnan)(end_pos->lon));
    } /* No move */

    /* Earth geometry */
    f = NMEA_EARTH_FLATTENING;
    a = NMEA_EARTH_SEMIMAJORAXIS_M;
    b = (1 - f) * a;
    sqr_a = a * a;
    sqr_b = b * b;
    
    /* Calculation */
    phi1 = start_pos->lat;
    tan_U1 = (1 - f) * tan(phi1);
    cos_U1 = 1 / sqrt(1 + tan_U1 * tan_U1);
    sin_U1 = tan_U1 * cos_U1;
    s = distance;
    alpha1 = azimuth;
    sin_alpha1 = sin(alpha1);
    cos_alpha1 = cos(alpha1);
    sigma1 = atan2(tan_U1, cos_alpha1);
    sin_alpha = cos_U1 * sin_alpha1;
    sqr_cos_alpha = 1 - sin_alpha * sin_alpha;
    sqr_u = sqr_cos_alpha * (sqr_a - sqr_b) / sqr_b; 
    A = 1 + sqr_u / 16384 * (4096 + sqr_u * (-768 + sqr_u * (320 - 175 * sqr_u)));
    B = sqr_u / 1024 * (256 + sqr_u * (-128 + sqr_u * (74 - 47 * sqr_u)));
    
    /* Initialize iteration */
    sigma_initial = s / (b * A);
    sigma = sigma_initial;
    sin_sigma = sin(sigma);
    cos_sigma = cos(sigma);
    cos_2_sigmam = cos(2 * sigma1 + sigma);
    sqr_cos_2_sigmam = cos_2_sigmam * cos_2_sigmam;
    delta_sigma = 0;
    sigma_prev = 2 * NMEA_PI;
    remaining_steps = 20;

    while ((fabs(sigma - sigma_prev) > 1e-12) && (remaining_steps > 0))
    { /* Iterate */
        cos_2_sigmam = cos(2 * sigma1 + sigma);
        sqr_cos_2_sigmam = cos_2_sigmam * cos_2_sigmam;
        sin_sigma = sin(sigma);
        cos_sigma = cos(sigma);
        delta_sigma = B * sin_sigma * ( 
             cos_2_sigmam + B / 4 * ( 
             cos_sigma * (-1 + 2 * sqr_cos_2_sigmam) - 
             B / 6 * cos_2_sigmam * (-3 + 4 * sin_sigma * sin_sigma) * (-3 + 4 * sqr_cos_2_sigmam)
             ));
        sigma_prev = sigma;
        sigma = sigma_initial + delta_sigma;
        remaining_steps --;
    } /* Iterate */
    
    /* Calculate result */
    tmp1 = (sin_U1 * sin_sigma - cos_U1 * cos_sigma * cos_alpha1);
    phi2 = atan2(
            sin_U1 * cos_sigma + cos_U1 * sin_sigma * cos_alpha1,
            (1 - f) * sqrt(sin_alpha * sin_alpha + tmp1 * tmp1)
            );
    lambda = atan2(
            sin_sigma * sin_alpha1,
            cos_U1 * cos_sigma - sin_U1 * sin_sigma * cos_alpha1
            );
    C = f / 16 * sqr_cos_alpha * (4 + f * (4 - 3 * sqr_cos_alpha));
    L = lambda -
        (1 - C) * f * sin_alpha * (
        sigma + C * sin_sigma *
        (cos_2_sigmam + C * cos_sigma * (-1 + 2 * sqr_cos_2_sigmam))
        );
    
    /* Result */
    end_pos->lon = start_pos->lon + L;
    end_pos->lat = phi2;
    if ( end_azimuth != 0 )
    {
        *end_azimuth = atan2(
            sin_alpha, -sin_U1 * sin_sigma + cos_U1 * cos_sigma * cos_alpha1
            );
    }
    return ! (NMEA_POSIX(isnan)(end_pos->lat) || NMEA_POSIX(isnan)(end_pos->lon));
}
Example #2
0
/*
===============
CG_CalcViewValues

Sets cg.refdef view values
===============
*/
static int CG_CalcViewValues( void ) {
	playerState_t   *ps;
	static vec3_t oldOrigin = {0,0,0};

	memset( &cg.refdef, 0, sizeof( cg.refdef ) );

	// strings for in game rendering
	// Q_strncpyz( cg.refdef.text[0], "Park Ranger", sizeof(cg.refdef.text[0]) );
	// Q_strncpyz( cg.refdef.text[1], "19", sizeof(cg.refdef.text[1]) );

	// calculate size of 3D view
	CG_CalcVrect();

	ps = &cg.predictedPlayerState;

	if ( cg.cameraMode ) {
		vec3_t origin, angles;
		float fov = 90;
		float x;

		if ( trap_getCameraInfo( CAM_PRIMARY, cg.time, &origin, &angles, &fov ) ) {
			VectorCopy( origin, cg.refdef.vieworg );
			angles[ROLL] = 0;
			angles[PITCH] = -angles[PITCH];     // (SA) compensate for reversed pitch (this makes the game match the editor, however I'm guessing the real fix is to be done there)
			VectorCopy( angles, cg.refdefViewAngles );
			AnglesToAxis( cg.refdefViewAngles, cg.refdef.viewaxis );

			x = cg.refdef.width / tan( fov / 360 * M_PI );
			cg.refdef.fov_y = atan2( cg.refdef.height, x );
			cg.refdef.fov_y = cg.refdef.fov_y * 360 / M_PI;
			cg.refdef.fov_x = fov;

			// RF, had to disable, sometimes a loadgame to a camera in the same position
			// can cause the game to not know where the camera is, therefore snapshots
			// dont show the correct entities
			//if(VectorCompare(origin, oldOrigin))
			//	return 0;

			VectorCopy( origin, oldOrigin );
			trap_SendClientCommand( va( "setCameraOrigin %f %f %f", origin[0], origin[1], origin[2] ) );
			return 0;

		} else {
			cg.cameraMode = qfalse;                 // camera off in cgame
			trap_Cvar_Set( "cg_letterbox", "0" );
			trap_SendClientCommand( "stopCamera" );    // camera off in game
			trap_stopCamera( CAM_PRIMARY );           // camera off in client

			CG_Fade( 0, 0, 0, 255, 0, 0 );                // go black
			CG_Fade( 0, 0, 0, 0, cg.time + 200, 1500 );   // then fadeup
		}
	}

	// intermission view
	if ( ps->pm_type == PM_INTERMISSION ) {
		VectorCopy( ps->origin, cg.refdef.vieworg );
		VectorCopy( ps->viewangles, cg.refdefViewAngles );
		AnglesToAxis( cg.refdefViewAngles, cg.refdef.viewaxis );
		return CG_CalcFov();
	}

	cg.bobcycle = ( ps->bobCycle & 128 ) >> 7;
	cg.bobfracsin = fabs( sin( ( ps->bobCycle & 127 ) / 127.0 * M_PI ) );
	cg.xyspeed = sqrt( ps->velocity[0] * ps->velocity[0] +
					   ps->velocity[1] * ps->velocity[1] );


	VectorCopy( ps->origin, cg.refdef.vieworg );
	VectorCopy( ps->viewangles, cg.refdefViewAngles );

	// add error decay
	if ( cg_errorDecay.value > 0 ) {
		int t;
		float f;

		t = cg.time - cg.predictedErrorTime;
		f = ( cg_errorDecay.value - t ) / cg_errorDecay.value;
		if ( f > 0 && f < 1 ) {
			VectorMA( cg.refdef.vieworg, f, cg.predictedError, cg.refdef.vieworg );
		} else {
			cg.predictedErrorTime = 0;
		}
	}

	// Ridah, lock the viewangles if the game has told us to
	if ( ps->viewlocked ) {

		/*
		if (ps->viewlocked == 4)
		{
			centity_t *tent;
			tent = &cg_entities[ps->viewlocked_entNum];
			VectorCopy (tent->currentState.apos.trBase, cg.refdefViewAngles);
		}
		else
		*/
		BG_EvaluateTrajectory( &cg_entities[ps->viewlocked_entNum].currentState.apos, cg.time, cg.refdefViewAngles );

		if ( ps->viewlocked == 2 ) {
			cg.refdefViewAngles[0] += crandom();
			cg.refdefViewAngles[1] += crandom();
		}
	}
	// done.

	if ( cg.renderingThirdPerson ) {
		// back away from character
		CG_OffsetThirdPersonView();
	} else {
		// offset for local bobbing and kicks
		CG_OffsetFirstPersonView();

		// Ridah, lock the viewangles if the game has told us to
		if ( ps->viewlocked == 4 ) {
			vec3_t fwd;
			AngleVectors( cg.refdefViewAngles, fwd, NULL, NULL );
			VectorMA( cg_entities[ps->viewlocked_entNum].currentState.pos.trBase, 16, fwd, cg.refdef.vieworg );
		} else if ( ps->viewlocked )     {
			vec3_t fwd;
			float oldZ;
			// set our position to be behind it
			oldZ = cg.refdef.vieworg[2];
			AngleVectors( cg.refdefViewAngles, fwd, NULL, NULL );
			VectorMA( cg_entities[ps->viewlocked_entNum].currentState.pos.trBase, -34, fwd, cg.refdef.vieworg );
			cg.refdef.vieworg[2] = oldZ;
		}
		// done.
	}

	// position eye reletive to origin
	AnglesToAxis( cg.refdefViewAngles, cg.refdef.viewaxis );

	if ( cg.hyperspace ) {
		cg.refdef.rdflags |= RDF_NOWORLDMODEL | RDF_HYPERSPACE;
	}

	// field of view
	return CG_CalcFov();
}
Example #3
0
static int CG_CalcFov( void ) {
	static float lastfov = 90;      // for transitions back from zoomed in modes
	float x;
	float phase;
	float v;
	int contents;
	float fov_x, fov_y;
	float zoomFov;
	float f;
	int inwater;
	qboolean dead;

	CG_Zoom();

	if ( cg.predictedPlayerState.stats[STAT_HEALTH] <= 0 ) {
		dead = qtrue;
		cg.zoomedBinoc = qfalse;
		cg.zoomTime = 0;
		cg.zoomval = 0;
	} else {
		dead = qfalse;
	}

	if ( cg.predictedPlayerState.pm_type == PM_INTERMISSION ) {
		// if in intermission, use a fixed value
		fov_x = 90;
	} else {
		// user selectable
		if ( cgs.dmflags & DF_FIXED_FOV ) {
			// dmflag to prevent wide fov for all clients
			fov_x = 90;
		} else {
			fov_x = cg_fov.value;
			if ( fov_x < 1 ) {
				fov_x = 1;
			} else if ( fov_x > 160 ) {
				fov_x = 160;
			}
		}

		// account for zooms
		if ( cg.zoomval ) {
			zoomFov = cg.zoomval;   // (SA) use user scrolled amount

			if ( zoomFov < 1 ) {
				zoomFov = 1;
			} else if ( zoomFov > 160 ) {
				zoomFov = 160;
			}
		} else {
			zoomFov = lastfov;
		}

		// do smooth transitions for the binocs
		if ( cg.zoomedBinoc ) {        // binoc zooming in
			f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME;
			if ( f > 1.0 ) {
				fov_x = zoomFov;
			} else {
				fov_x = fov_x + f * ( zoomFov - fov_x );
			}
			lastfov = fov_x;
		} else if ( cg.zoomval ) {    // zoomed by sniper/snooper
			fov_x = cg.zoomval;
			lastfov = fov_x;
		} else {                    // binoc zooming out
			f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME;
			if ( f > 1.0 ) {
				fov_x = fov_x;
			} else {
				fov_x = zoomFov + f * ( fov_x - zoomFov );
			}
		}
	}

	// DHM - Nerve :: zoom in for Limbo or Spectator
	if ( cgs.gametype == GT_WOLF ) {
		if ( cg.snap->ps.pm_flags & PMF_FOLLOW && cg.snap->ps.weapon == WP_SNIPERRIFLE ) {
			fov_x = cg_zoomDefaultSniper.value;
		}
	}
	// dhm - end

	if ( !dead && ( cg.weaponSelect == WP_SNOOPERSCOPE ) ) {
		cg.refdef.rdflags |= RDF_SNOOPERVIEW;
	} else {
		cg.refdef.rdflags &= ~RDF_SNOOPERVIEW;
	}

	if ( cg.snap->ps.persistant[PERS_HWEAPON_USE] ) {
		fov_x = 55;
	}

	x = cg.refdef.width / tan( fov_x / 360 * M_PI );
	fov_y = atan2( cg.refdef.height, x );
	fov_y = fov_y * 360 / M_PI;

	// warp if underwater
	contents = CG_PointContents( cg.refdef.vieworg, -1 );
	if ( contents & ( CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA ) ) {
		phase = cg.time / 1000.0 * WAVE_FREQUENCY * M_PI * 2;
		v = WAVE_AMPLITUDE * sin( phase );
		fov_x += v;
		fov_y -= v;
		inwater = qtrue;
		cg.refdef.rdflags |= RDF_UNDERWATER;
	} else {
		cg.refdef.rdflags &= ~RDF_UNDERWATER;
		inwater = qfalse;
	}

	contents = CG_PointContents( cg.refdef.vieworg, -1 );
	if ( contents & ( CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA ) ) {
		cg.refdef.rdflags |= RDF_UNDERWATER;
	} else {
		cg.refdef.rdflags &= ~RDF_UNDERWATER;
	}

	// set it
	cg.refdef.fov_x = fov_x;
	cg.refdef.fov_y = fov_y;

	if ( !cg.zoomedBinoc ) {
		// NERVE - SMF - fix for zoomed in/out movement bug
		if ( cg.zoomval ) {
			if ( cg.snap->ps.weapon == WP_SNOOPERSCOPE ) {
				cg.zoomSensitivity = 0.3f * ( cg.zoomval / 90.f );  // NERVE - SMF - changed to get less sensitive as you zoom in;
			}
//				cg.zoomSensitivity = 0.2;
			else {
				cg.zoomSensitivity = 0.6 * ( cg.zoomval / 90.f );   // NERVE - SMF - changed to get less sensitive as you zoom in
			}
//				cg.zoomSensitivity = 0.1;
		} else {
			cg.zoomSensitivity = 1;
		}
		// -NERVE - SMF
	} else {
		cg.zoomSensitivity = cg.refdef.fov_y / 75.0;
	}

	return inwater;
}
Example #4
0
//@Jkent: Is there a way to get access to R_customheight/width and/or r_height/width? (Get the newer height-dependant FOV rather than width-dependant as 1.1 widescreens actually have smaller FOVs)
static int CG_CalcFov( void )
{
  float     x;
  float     phase;
  float     v;
  int       contents;
  float     fov_x, fov_y;
  float     zoomFov;
  float     f;
  int       inwater;
  int       attribFov;
  usercmd_t cmd;
  int       cmdNum;

  cmdNum = trap_GetCurrentCmdNumber( );
  trap_GetUserCmd( cmdNum, &cmd );

  if( cg.predictedPlayerState.pm_type == PM_INTERMISSION ||
      ( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR ) )
  {
    // if in intermission, use a fixed value
    fov_x = 90;
  }
  else
  {
    // don't lock the fov globally - we need to be able to change it
    attribFov = BG_FindFovForClass( cg.predictedPlayerState.stats[ STAT_PCLASS ] );
    fov_x = attribFov;

    if ( fov_x < 1 )
      fov_x = 1;
    else if ( fov_x > 160 )
      fov_x = 160;

    if( cg.spawnTime > ( cg.time - FOVWARPTIME ) &&
        BG_ClassHasAbility( cg.predictedPlayerState.stats[ STAT_PCLASS ], SCA_FOVWARPS ) )
    {
      float temp, temp2;

      temp = (float)( cg.time - cg.spawnTime ) / FOVWARPTIME;
      temp2 = ( 170 - fov_x ) * temp;

      //Com_Printf( "%f %f\n", temp*100, temp2*100 );

      fov_x = 170 - temp2;
    }

    // account for zooms
    zoomFov = BG_FindZoomFovForWeapon( cg.predictedPlayerState.weapon );
    if ( zoomFov < 1 )
      zoomFov = 1;
    else if ( zoomFov > attribFov )
      zoomFov = attribFov;

    // only do all the zoom stuff if the client CAN zoom
    // FIXME: zoom control is currently hard coded to BUTTON_ATTACK2
    if( BG_WeaponCanZoom( cg.predictedPlayerState.weapon ) )
    {
      if ( cg.zoomed )
      {
        f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME;

        if ( f > 1.0 )
          fov_x = zoomFov;
        else
          fov_x = fov_x + f * ( zoomFov - fov_x );

        // BUTTON_ATTACK2 isn't held so unzoom next time
        if( !( cmd.buttons & BUTTON_ATTACK2 ) )
        {
          cg.zoomed   = qfalse;
          cg.zoomTime = cg.time;
        }
      }
      else
      {
        f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME;

        if ( f > 1.0 )
          fov_x = fov_x;
        else
          fov_x = zoomFov + f * ( fov_x - zoomFov );

        // BUTTON_ATTACK2 is held so zoom next time
        if( cmd.buttons & BUTTON_ATTACK2 )
        {
          cg.zoomed   = qtrue;
          cg.zoomTime = cg.time;
        }
      }
    }
  }

  x = cg.refdef.width / tan( fov_x / 360 * M_PI );
  fov_y = atan2( cg.refdef.height, x );
  fov_y = fov_y * 360 / M_PI;

  // warp if underwater
  contents = CG_PointContents( cg.refdef.vieworg, -1 );

  if( contents & ( CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA ) )
  {
    phase = cg.time / 1000.0 * WAVE_FREQUENCY * M_PI * 2;
    v = WAVE_AMPLITUDE * sin( phase );
    fov_x += v;
    fov_y -= v;
    inwater = qtrue;
  }
  else
    inwater = qfalse;

  if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_POISONCLOUDED &&
      cg.predictedPlayerState.stats[ STAT_HEALTH ] > 0 &&
      !( cg.snap->ps.pm_flags & PMF_FOLLOW ) )
  {
    phase = cg.time / 1000.0 * PCLOUD_ZOOM_FREQUENCY * M_PI * 2;
    v = PCLOUD_ZOOM_AMPLITUDE * sin( phase );
    v *= 1.0f - ( ( cg.time - cg.poisonedTime ) / (float)LEVEL1_PCLOUD_TIME );
    fov_x += v;
    fov_y += v;
  }


  // set it
  cg.refdef.fov_x = fov_x;
  cg.refdef.fov_y = fov_y;

  if( !cg.zoomed )
    cg.zoomSensitivity = (7 + (90/cg.refdef.fov_y))/8;//1;
  else
    cg.zoomSensitivity = cg.refdef.fov_y / 75.0;

  return inwater;
}
Example #5
0
static int
msProjectShapeLine(projectionObj *in, projectionObj *out,
                   shapeObj *shape, int line_index)

{
  int i;
  pointObj  lastPoint, thisPoint, wrkPoint, firstPoint;
  lineObj *line = shape->line + line_index;
  lineObj *line_out = line;
  int valid_flag = 0; /* 1=true, -1=false, 0=unknown */
  int numpoints_in = line->numpoints;
  int line_alloc = numpoints_in;
  int wrap_test;

#ifdef USE_PROJ_FASTPATHS
#define MAXEXTENT 20037508.34
#define M_PIby360 .0087266462599716479
#define MAXEXTENTby180 111319.4907777777777777777
  if(in->wellknownprojection == wkp_lonlat && out->wellknownprojection == wkp_gmerc) {
    for( i = line->numpoints-1; i >= 0; i-- ) {
#define p_x line->point[i].x
#define p_y line->point[i].y
      p_x *= MAXEXTENTby180;
      p_y = log(tan((90 + p_y) * M_PIby360)) * MS_RAD_TO_DEG;
      p_y *= MAXEXTENTby180;
      if (p_x > MAXEXTENT) p_x = MAXEXTENT;
      if (p_x < -MAXEXTENT) p_x = -MAXEXTENT;
      if (p_y > MAXEXTENT) p_y = MAXEXTENT;
      if (p_y < -MAXEXTENT) p_y = -MAXEXTENT;
#undef p_x
#undef p_y
    }
    return MS_SUCCESS;
  }
#endif



  wrap_test = out != NULL && out->proj != NULL && pj_is_latlong(out->proj)
              && !pj_is_latlong(in->proj);

  line->numpoints = 0;

  if( numpoints_in > 0 )
    firstPoint = line->point[0];

  memset( &lastPoint, 0, sizeof(lastPoint) );

  /* -------------------------------------------------------------------- */
  /*      Loop over all input points in linestring.                       */
  /* -------------------------------------------------------------------- */
  for( i=0; i < numpoints_in; i++ ) {
    int ms_err;
    wrkPoint = thisPoint = line->point[i];

    ms_err = msProjectPoint(in, out, &wrkPoint );

    /* -------------------------------------------------------------------- */
    /*      Apply wrap logic.                                               */
    /* -------------------------------------------------------------------- */
    if( wrap_test && i > 0 && ms_err != MS_FAILURE ) {
      double dist;
      pointObj pt1Geo;

      if( line_out->numpoints > 0 )
        pt1Geo = line_out->point[0];
      else
        pt1Geo = wrkPoint; /* this is a cop out */

      dist = wrkPoint.x - pt1Geo.x;
      if( fabs(dist) > 180.0
          && msTestNeedWrap( thisPoint, firstPoint,
                             pt1Geo, in, out ) ) {
        if( dist > 0.0 )
          wrkPoint.x -= 360.0;
        else if( dist < 0.0 )
          wrkPoint.x += 360.0;
      }
    }

    /* -------------------------------------------------------------------- */
    /*      Put result into output line with appropriate logic for          */
    /*      failure breaking lines, etc.                                    */
    /* -------------------------------------------------------------------- */
    if( ms_err == MS_FAILURE ) {
      /* We have started out invalid */
      if( i == 0 ) {
        valid_flag = -1;
      }

      /* valid data has ended, we need to work out the horizon */
      else if( valid_flag == 1 ) {
        pointObj startPoint, endPoint;

        startPoint = lastPoint;
        endPoint = thisPoint;
        if( msProjectSegment( in, out, &startPoint, &endPoint )
            == MS_SUCCESS ) {
          line_out->point[line_out->numpoints++] = endPoint;
        }
        valid_flag = -1;
      }

      /* Still invalid ... */
      else if( valid_flag == -1 ) {
        /* do nothing */
      }
    }

    else {
      /* starting out valid. */
      if( i == 0 ) {
        line_out->point[line_out->numpoints++] = wrkPoint;
        valid_flag = 1;
      }

      /* Still valid, nothing special */
      else if( valid_flag == 1 ) {
        line_out->point[line_out->numpoints++] = wrkPoint;
      }

      /* we have come over the horizon, figure out where, start newline*/
      else {
        pointObj startPoint, endPoint;

        startPoint = lastPoint;
        endPoint = thisPoint;
        if( msProjectSegment( in, out, &endPoint, &startPoint )
            == MS_SUCCESS ) {
          lineObj newLine;

          /* force pre-allocation of lots of points room */
          if( line_out->numpoints > 0
              && shape->type == MS_SHAPE_LINE ) {
            newLine.numpoints = numpoints_in - i + 1;
            newLine.point = line->point;
            msAddLine( shape, &newLine );

            /* new line is now lineout, but start without any points */
            line_out = shape->line + shape->numlines-1;

            line_out->numpoints = 0;

            /* the shape->line array is realloc, refetch "line" */
            line = shape->line + line_index;
          } else if( line_out == line
                     && line->numpoints >= i-2 ) {
            newLine.numpoints = numpoints_in;
            newLine.point = line->point;
            msAddLine( shape, &newLine );

            line = shape->line + line_index;

            line_out = shape->line + shape->numlines-1;
            line_out->numpoints = line->numpoints;
            line->numpoints = 0;

            /*
             * Now realloc this array large enough to hold all
             * the points we could possibly need to add.
             */
            line_alloc = line_alloc * 2;

            line_out->point = (pointObj *)
                              realloc(line_out->point,
                                      sizeof(pointObj) * line_alloc);
          }

          line_out->point[line_out->numpoints++] = startPoint;
        }
        line_out->point[line_out->numpoints++] = wrkPoint;
        valid_flag = 1;
      }
    }

    lastPoint = thisPoint;
  }

  /* -------------------------------------------------------------------- */
  /*      Make sure that polygons are closed, even if the trip over       */
  /*      the horizon left them unclosed.                                 */
  /* -------------------------------------------------------------------- */
  if( shape->type == MS_SHAPE_POLYGON
      && line_out->numpoints > 2
      && (line_out->point[0].x != line_out->point[line_out->numpoints-1].x
          || line_out->point[0].y != line_out->point[line_out->numpoints-1].y) ) {
    /* make a copy because msAddPointToLine can realloc the array */
    pointObj sFirstPoint = line_out->point[0];
    msAddPointToLine( line_out, &sFirstPoint );
  }

  return(MS_SUCCESS);
}
Example #6
0
double QgsDistanceArea::computeDistanceBearing(
  const QgsPoint& p1, const QgsPoint& p2,
  double* course1, double* course2 )
{
  if ( p1.x() == p2.x() && p1.y() == p2.y() )
    return 0;

  // ellipsoid
  double a = mSemiMajor;
  double b = mSemiMinor;
  double f = 1 / mInvFlattening;

  double p1_lat = DEG2RAD( p1.y() ), p1_lon = DEG2RAD( p1.x() );
  double p2_lat = DEG2RAD( p2.y() ), p2_lon = DEG2RAD( p2.x() );

  double L = p2_lon - p1_lon;
  double U1 = atan(( 1 - f ) * tan( p1_lat ) );
  double U2 = atan(( 1 - f ) * tan( p2_lat ) );
  double sinU1 = sin( U1 ), cosU1 = cos( U1 );
  double sinU2 = sin( U2 ), cosU2 = cos( U2 );
  double lambda = L;
  double lambdaP = 2 * M_PI;

  double sinLambda = 0;
  double cosLambda = 0;
  double sinSigma = 0;
  double cosSigma = 0;
  double sigma = 0;
  double alpha = 0;
  double cosSqAlpha = 0;
  double cos2SigmaM = 0;
  double C = 0;
  double tu1 = 0;
  double tu2 = 0;

  int iterLimit = 20;
  while ( qAbs( lambda - lambdaP ) > 1e-12 && --iterLimit > 0 )
  {
    sinLambda = sin( lambda );
    cosLambda = cos( lambda );
    tu1 = ( cosU2 * sinLambda );
    tu2 = ( cosU1 * sinU2 - sinU1 * cosU2 * cosLambda );
    sinSigma = sqrt( tu1 * tu1 + tu2 * tu2 );
    cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;
    sigma = atan2( sinSigma, cosSigma );
    alpha = asin( cosU1 * cosU2 * sinLambda / sinSigma );
    cosSqAlpha = cos( alpha ) * cos( alpha );
    cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha;
    C = f / 16 * cosSqAlpha * ( 4 + f * ( 4 - 3 * cosSqAlpha ) );
    lambdaP = lambda;
    lambda = L + ( 1 - C ) * f * sin( alpha ) *
             ( sigma + C * sinSigma * ( cos2SigmaM + C * cosSigma * ( -1 + 2 * cos2SigmaM * cos2SigmaM ) ) );
  }

  if ( iterLimit == 0 )
    return -1;  // formula failed to converge

  double uSq = cosSqAlpha * ( a * a - b * b ) / ( b * b );
  double A = 1 + uSq / 16384 * ( 4096 + uSq * ( -768 + uSq * ( 320 - 175 * uSq ) ) );
  double B = uSq / 1024 * ( 256 + uSq * ( -128 + uSq * ( 74 - 47 * uSq ) ) );
  double deltaSigma = B * sinSigma * ( cos2SigmaM + B / 4 * ( cosSigma * ( -1 + 2 * cos2SigmaM * cos2SigmaM ) -
                                       B / 6 * cos2SigmaM * ( -3 + 4 * sinSigma * sinSigma ) * ( -3 + 4 * cos2SigmaM * cos2SigmaM ) ) );
  double s = b * A * ( sigma - deltaSigma );

  if ( course1 )
  {
    *course1 = atan2( tu1, tu2 );
  }
  if ( course2 )
  {
    // PI is added to return azimuth from P2 to P1
    *course2 = atan2( cosU1 * sinLambda, -sinU1 * cosU2 + cosU1 * sinU2 * cosLambda ) + M_PI;
  }

  return s;
}
Example #7
0
	//function to find the body state vector at epoch
	int body::locate_body(const double& epoch, double* state, const bool& need_deriv, missionoptions* options)
	{
		double DT, n, M, E, V[6];

		switch (body_ephemeris_source)
		{
			case 1: //SPICE
				double LT_dump;
				spkez_c(spice_ID, epoch - (51544.5 * 86400.0), "J2000", "NONE", this->central_body_spice_ID, state, &LT_dump);

				if (need_deriv)
				{
					double statepert[6];
					spkez_c(spice_ID, epoch - (51544.5 * 86400.0) + 10.0, "J2000", "NONE", this->central_body_spice_ID, statepert, &LT_dump);
					state[6] = (statepert[3] - state[3]) / (10.0);
					state[7] = (statepert[4] - state[4]) / (10.0);
					state[8] = (statepert[5] - state[5]) / (10.0);
				}

				break;
			case 0: //static ephemeris
					//TODO static ephemeris is not ready!
					//note, always should give in Earth equatorial J2000 coordinates for internal processing

					DT = ( epoch - this->reference_epoch );
					

					if (this->SMA > 0.0)
						n = sqrt(this->universe_mu / (this->SMA*this->SMA*this->SMA));
					else
						n = sqrt(this->universe_mu / (-this->SMA*this->SMA*this->SMA));
					
					M = this->MA + n*DT;
					M = fmod(M, 2 * EMTG::math::PI);

					E = Kepler::KeplerLaguerreConway(this->ECC, M);
					V[0] = this->SMA; 
					V[1] = this->ECC;
					V[2] = this->INC;
					V[3] = this->RAAN;
					V[4] = this->AOP;

					true_anomaly = 2.0*atan(sqrt((1.0 + this->ECC) / (1.0 - this->ECC))*tan(E / 2.0));
					V[5] = true_anomaly;


					COE2inertial(V, this->universe_mu, state);

					if (need_deriv)
					{
						double r = sqrt(state[0]*state[0] + state[1]*state[1] + state[2]*state[2]);
						double r3 = r*r*r;
						state[6] = -universe_mu/r3 * state[0];
						state[7] = -universe_mu/r3 * state[1];
						state[8] = -universe_mu/r3 * state[2];
					}
				break;
			default:
				cout << "Invalid ephemeris source " << body_ephemeris_source << " for object " << name << endl;
				cout << "Program halted. Press enter to quit." << endl;
#ifndef BACKGROUND_MODE
				cin.ignore();
#endif
		}

		return 0;
	}
Example #8
0
// Draws the FBO texture for 3DTV.
void ApplicationOverlay::displayOverlayTexture3DTV(Camera& whichCamera, float aspectRatio, float fov) {
    if (_alpha == 0.0f) {
        return;
    }
    
    Application* application = Application::getInstance();
    
    MyAvatar* myAvatar = application->getAvatar();
    const glm::vec3& viewMatrixTranslation = application->getViewMatrixTranslation();
    
    glActiveTexture(GL_TEXTURE0);
    
    glEnable(GL_BLEND);
    glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
    _overlays.bindTexture();
    glEnable(GL_DEPTH_TEST);
    glDisable(GL_LIGHTING);
    glEnable(GL_TEXTURE_2D);
    
    glMatrixMode(GL_MODELVIEW);
    
    glPushMatrix();
    glLoadIdentity();
    // Transform to world space
    glm::quat rotation = whichCamera.getRotation();
    glm::vec3 axis2 = glm::axis(rotation);
    glRotatef(-glm::degrees(glm::angle(rotation)), axis2.x, axis2.y, axis2.z);
    glTranslatef(viewMatrixTranslation.x, viewMatrixTranslation.y, viewMatrixTranslation.z);
    
    // Translate to the front of the camera
    glm::vec3 pos = whichCamera.getPosition();
    glm::quat rot = myAvatar->getOrientation();
    glm::vec3 axis = glm::axis(rot);
    
    glTranslatef(pos.x, pos.y, pos.z);
    glRotatef(glm::degrees(glm::angle(rot)), axis.x, axis.y, axis.z);
    
    glColor4f(1.0f, 1.0f, 1.0f, _alpha);
    
    //Render
    const GLfloat distance = 1.0f;
    
    const GLfloat halfQuadHeight = distance * tan(fov);
    const GLfloat halfQuadWidth = halfQuadHeight * aspectRatio;
    const GLfloat quadWidth = halfQuadWidth * 2.0f;
    const GLfloat quadHeight = halfQuadHeight * 2.0f;
    
    GLfloat x = -halfQuadWidth;
    GLfloat y = -halfQuadHeight;
    glDisable(GL_DEPTH_TEST);
    
    glBegin(GL_QUADS);
    
    glTexCoord2f(0.0f, 1.0f); glVertex3f(x, y + quadHeight, -distance);
    glTexCoord2f(1.0f, 1.0f); glVertex3f(x + quadWidth, y + quadHeight, -distance);
    glTexCoord2f(1.0f, 0.0f); glVertex3f(x + quadWidth, y, -distance);
    glTexCoord2f(0.0f, 0.0f); glVertex3f(x, y, -distance);
    
    glEnd();
    
    if (_crosshairTexture == 0) {
        _crosshairTexture = Application::getInstance()->getGLWidget()->bindTexture(QImage(Application::resourcesPath() + "images/sixense-reticle.png"));
    }
    
    //draw the mouse pointer
    glBindTexture(GL_TEXTURE_2D, _crosshairTexture);
    
    const float reticleSize = 40.0f / application->getGLWidget()->width() * quadWidth;
    x -= reticleSize / 2.0f;
    y += reticleSize / 2.0f;
    const float mouseX = (application->getMouseX() / (float)application->getGLWidget()->width()) * quadWidth;
    const float mouseY = (1.0 - (application->getMouseY() / (float)application->getGLWidget()->height())) * quadHeight;
    
    glBegin(GL_QUADS);
    
    glColor3f(RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2]);
    
    glTexCoord2d(0.0f, 0.0f); glVertex3f(x + mouseX, y + mouseY, -distance);
    glTexCoord2d(1.0f, 0.0f); glVertex3f(x + mouseX + reticleSize, y + mouseY, -distance);
    glTexCoord2d(1.0f, 1.0f); glVertex3f(x + mouseX + reticleSize, y + mouseY - reticleSize, -distance);
    glTexCoord2d(0.0f, 1.0f); glVertex3f(x + mouseX, y + mouseY - reticleSize, -distance);
    
    glEnd();
    
    glEnable(GL_DEPTH_TEST);
    
    glPopMatrix();
    
    glDepthMask(GL_TRUE);
    glBindTexture(GL_TEXTURE_2D, 0);
    glDisable(GL_TEXTURE_2D);
    
    glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
    glEnable(GL_LIGHTING);
    
    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
}
Example #9
0
static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out) 
{
	switch (node->custom1) {
	
	case 0: /* Add */
		out[0]->vec[0] = in[0]->vec[0] + in[1]->vec[0];
		break; 
	case 1: /* Subtract */
		out[0]->vec[0] = in[0]->vec[0] - in[1]->vec[0];
		break; 
	case 2: /* Multiply */
		out[0]->vec[0] = in[0]->vec[0] * in[1]->vec[0];
		break; 
	case 3: /* Divide */
		{
			if (in[1]->vec[0]==0)	/* We don't want to divide by zero. */
				out[0]->vec[0] = 0.0;
			else
				out[0]->vec[0] = in[0]->vec[0] / in[1]->vec[0];
			}
		break;
	case 4: /* Sine */
		{
			if (in[0]->hasinput || !in[1]->hasinput)  /* This one only takes one input, so we've got to choose. */
				out[0]->vec[0] = sin(in[0]->vec[0]);
			else
				out[0]->vec[0] = sin(in[1]->vec[0]);
		}
		break;
	case 5: /* Cosine */
		{
			if (in[0]->hasinput || !in[1]->hasinput)  /* This one only takes one input, so we've got to choose. */
				out[0]->vec[0] = cos(in[0]->vec[0]);
			else
				out[0]->vec[0] = cos(in[1]->vec[0]);
		}
		break;
	case 6: /* Tangent */
		{
			if (in[0]->hasinput || !in[1]->hasinput)  /* This one only takes one input, so we've got to choose. */
				out[0]->vec[0] = tan(in[0]->vec[0]);
			else
				out[0]->vec[0] = tan(in[1]->vec[0]);
		}
		break;
	case 7: /* Arc-Sine */
		{
			if (in[0]->hasinput || !in[1]->hasinput) { /* This one only takes one input, so we've got to choose. */
				/* Can't do the impossible... */
				if (in[0]->vec[0] <= 1 && in[0]->vec[0] >= -1)
					out[0]->vec[0] = asin(in[0]->vec[0]);
				else
					out[0]->vec[0] = 0.0;
			}
			else {
				/* Can't do the impossible... */
				if (in[1]->vec[0] <= 1 && in[1]->vec[0] >= -1)
					out[0]->vec[0] = asin(in[1]->vec[0]);
				else
					out[0]->vec[0] = 0.0;
			}
		}
		break;
	case 8: /* Arc-Cosine */
		{
			if (in[0]->hasinput || !in[1]->hasinput) { /* This one only takes one input, so we've got to choose. */
				/* Can't do the impossible... */
				if (in[0]->vec[0] <= 1 && in[0]->vec[0] >= -1)
					out[0]->vec[0] = acos(in[0]->vec[0]);
				else
					out[0]->vec[0] = 0.0;
			}
			else {
				/* Can't do the impossible... */
				if (in[1]->vec[0] <= 1 && in[1]->vec[0] >= -1)
					out[0]->vec[0] = acos(in[1]->vec[0]);
				else
					out[0]->vec[0] = 0.0;
			}
		}
		break;
	case 9: /* Arc-Tangent */
		{
			if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
				out[0]->vec[0] = atan(in[0]->vec[0]);
			else
				out[0]->vec[0] = atan(in[1]->vec[0]);
		}
		break;
	case 10: /* Power */
		{
			/* Only raise negative numbers by full integers */
			if (in[0]->vec[0] >= 0) {
				out[0]->vec[0] = pow(in[0]->vec[0], in[1]->vec[0]);
			}
			else {
				float y_mod_1 = fabsf(fmodf(in[1]->vec[0], 1.0f));
				
				/* if input value is not nearly an integer, fall back to zero, nicer than straight rounding */
				if (y_mod_1 > 0.999f || y_mod_1 < 0.001f) {
					out[0]->vec[0] = powf(in[0]->vec[0], floorf(in[1]->vec[0] + 0.5f));
				}
				else {
					out[0]->vec[0] = 0.0f;
				}
			}

		}
		break;
	case 11: /* Logarithm */
		{
			/* Don't want any imaginary numbers... */
			if (in[0]->vec[0] > 0  && in[1]->vec[0] > 0)
				out[0]->vec[0] = log(in[0]->vec[0]) / log(in[1]->vec[0]);
			else
				out[0]->vec[0] = 0.0;
		}
		break;
	case 12: /* Minimum */
		{
			if (in[0]->vec[0] < in[1]->vec[0])
				out[0]->vec[0] = in[0]->vec[0];
			else
				out[0]->vec[0] = in[1]->vec[0];
		}
		break;
	case 13: /* Maximum */
		{
			if (in[0]->vec[0] > in[1]->vec[0])
				out[0]->vec[0] = in[0]->vec[0];
			else
				out[0]->vec[0] = in[1]->vec[0];
		}
		break;
	case 14: /* Round */
		{
			if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
				out[0]->vec[0] = (in[0]->vec[0] < 0) ? (int)(in[0]->vec[0] - 0.5f) : (int)(in[0]->vec[0] + 0.5f);
			else
				out[0]->vec[0] = (in[1]->vec[0] < 0) ? (int)(in[1]->vec[0] - 0.5f) : (int)(in[1]->vec[0] + 0.5f);
		}
		break;
	case 15: /* Less Than */
		{
			if (in[0]->vec[0] < in[1]->vec[0])
				out[0]->vec[0] = 1.0f;
			else
				out[0]->vec[0] = 0.0f;
		}
		break;
	case 16: /* Greater Than */
		{
			if (in[0]->vec[0] > in[1]->vec[0])
				out[0]->vec[0] = 1.0f;
			else
				out[0]->vec[0] = 0.0f;
		}
		break;
	case 17: /* Modulo */
		{
			if (in[1]->vec[0] == 0.0f)
				out[0]->vec[0] = 0.0f;
			else
				out[0]->vec[0] = fmod(in[0]->vec[0], in[1]->vec[0]);
		}
		break;
	}
}
Example #10
0
tree
tan (tree t) {
  if (is_double (t)) return as_tree (tan (as_double (t)));
  return tree (TAN, t);
}
Example #11
0
float CalcFrustumScale(float fFovDeg) {
	const float degToRad = 3.14159f * 2.0f / 360.0f;
	float fFovRad = fFovDeg * degToRad;
	return 1.0f / tan(fFovRad / 2.0f);
}
Example #12
0
void Raytracer::render(const char *filename, const char *depth_filename,
                       Scene const &scene)
{
    // Allocate the two images that will ultimately be saved.
    Image colorImage(scene.resolution[0], scene.resolution[1]);
    Image depthImage(scene.resolution[0], scene.resolution[1]);
    
    // Create the zBuffer.
    double *zBuffer = new double[scene.resolution[0] * scene.resolution[1]];
    for(int i = 0; i < scene.resolution[0] * scene.resolution[1]; i++) {
        zBuffer[i] = DBL_MAX;
    }

	// @@@@@@ YOUR CODE HERE
	// calculate camera parameters for rays, refer to the slides for details
	//!!! USEFUL NOTES: tan() takes rad rather than degree, use deg2rad() to transform
	//!!! USEFUL NOTES: view plane can be anywhere, but it will be implemented differently,
	//you can find references from the course slides 22_GlobalIllum.pdf
    
    
	Vector cameraPos = scene.camera.position;
	Vector cameraCenter = scene.camera.center;
	
	Vector cameraPosR = scene.camera.position;
	Vector cameraCenterR = scene.camera.center;
	
	// viewing direction vector get by taking center and subtracting camera position
	Vector wVecOriginal = scene.camera.center; - cameraPos;
    wVecOriginal.normalize();
	// up vector is defined (u)
    Vector uVec = scene.camera.up;
    uVec.normalize();
	// right vector is gotten by taking the cross product of w and v
	Vector rVecOriginal = wVecOriginal.cross(uVec);
	rVecOriginal.normalize();
	
	double stereoDisplacement = scene.camera.stereoDist / 2.0;
	int widthResolution = scene.resolution[0];
	if (scene.camera.stereoDist > 0.0) {		
		printf("Start left picture.\n");
		cameraPos = scene.camera.position + (rVecOriginal * stereoDisplacement);
		cameraPosR = scene.camera.position - (rVecOriginal * stereoDisplacement);
		
		widthResolution = floor(scene.resolution[0] / 2);
	} else if (scene.camera.stereoDist < 0.0) {		
		printf("Start left picture.\n");
		stereoDisplacement = - scene.camera.stereoDist / 2.0;
		cameraPos = scene.camera.position - (rVecOriginal * stereoDisplacement);
		cameraPosR = scene.camera.position + (rVecOriginal * stereoDisplacement);
		
		widthResolution = floor(scene.resolution[0] / 2);
	}

	
    Vector wVec = cameraCenter - cameraPos;
    wVec.normalize();
    Vector rVec = wVec.cross(uVec);
    rVec.normalize();
    
    // get top from tan(fovy)
    double tangent = tan(deg2rad(scene.camera.fovy/2));
	//double atangent = atan(deg2rad(scene.camera.fovy)/2);
    // get length of top from centre of image plane
    double top = scene.camera.zNear * tangent;
    double right = top * scene.camera.aspect;
	if (scene.camera.stereoDist != 0.0) {		
		right = right / 2;
	}
    double left = -right;
    double bottom = -top;
	
    // calculate vector from camera to left top of image plane
    Vector centerVec = cameraPos + (scene.camera.zNear * wVec);
    Vector oVec = centerVec + (left * rVec) + (bottom * uVec);
    double deltaU = (right - left) / scene.resolution[0];
	if (scene.camera.stereoDist != 0.0) {		
		deltaU = deltaU * 2;
	}
    double deltaV = (top - bottom) / scene.resolution[1];    
	    
    // Iterate over all the pixels in the image.
    for(int y = 0; y < scene.resolution[1]; y++) {
        for(int x = 0; x < widthResolution; x++) {

            // Generate the appropriate ray for this pixel
			Ray ray;
			if (scene.objects.empty())
			{
				//no objects in the scene, then we render the default scene:
				//in the default scene, we assume the view plane is at z = 640 with width and height both 640
				ray = Ray(cameraPos, (Vector(-320, -320, 640) + Vector(x + 0.5, y + 0.5, 0) - cameraPos).normalized());
			}
			else
			{
				// set primary ray using the camera parameters
				//!!! USEFUL NOTES: all world coordinate rays need to have a normalized direction
				
				Vector changeU = (x + 0.5) * deltaU * rVec;
                Vector changeY = (y + 0.5) * deltaV * uVec;
                Vector pixelPos = oVec + changeU + changeY;
                
                Vector rayOfHope = pixelPos - cameraPos;
                rayOfHope.normalize();
                
                ray = Ray(cameraPos, rayOfHope);
                //!!! rays do not have w coordinate constructed properly.
			}

            // Initialize recursive ray depth.
            int rayDepth = 0;
           
            // Our recursive raytrace will compute the color and the z-depth
            Vector color;

            // This should be the maximum depth, corresponding to the far plane.
            // NOTE: This assumes the ray direction is unit-length and the
            // ray origin is at the camera position.
            double depth = scene.camera.zFar;

            // Calculate the pixel value by shooting the ray into the scene
            trace(ray, rayDepth, scene, color, depth);

            // Depth test
            if(depth >= scene.camera.zNear && depth <= scene.camera.zFar && 
                depth < zBuffer[x + y*scene.resolution[0]]) {
                zBuffer[x + y*scene.resolution[0]] = depth;

                // Set the image color (and depth)
                colorImage.setPixel(x, y, color);
                depthImage.setPixel(x, y, (depth-scene.camera.zNear) / 
                                        (scene.camera.zFar-scene.camera.zNear));
            }
        }

		//output step information
		if (y % 100 == 0)
		{
			printf("Row %d pixels finished.\n", y);
		}
    }
	
	if (scene.camera.stereoDist != 0.0) {		
		printf("Start right picture.\n");
		Vector wVecR = cameraCenterR - cameraPosR;
		wVecR.normalize();
		// up vector is defined (u)
		// right vector is gotten by taking the cross product of w and v
		Vector rVecR = wVecR.cross(uVec);
		rVecR.normalize();
		
		// calculate vector from camera to left top of image plane
		Vector centerVecR = cameraPosR + (scene.camera.zNear * wVecR);
		Vector oVecR = centerVecR + (left * rVecR) + (bottom * uVec);
		
		// Iterate over all the pixels in the image.
		for(int y = 0; y < scene.resolution[1]; y++) {
			for(int x = 0; x < (scene.resolution[0] / 2); x++) {

				// Generate the appropriate ray for this pixel
				Ray ray;
				if (scene.objects.empty())
				{
					//no objects in the scene, then we render the default scene:
					//in the default scene, we assume the view plane is at z = 640 with width and height both 640
					ray = Ray(cameraPosR, (Vector(-320, -320, 640) + Vector(x + 0.5, y + 0.5, 0) - cameraPosR).normalized());
				}
				else
				{
					// set primary ray using the camera parameters
					//!!! USEFUL NOTES: all world coordinate rays need to have a normalized direction
					
					Vector changeU = (x + 0.5) * deltaU * rVecR;
					Vector changeY = (y + 0.5) * deltaV * uVec;
					Vector pixelPos = oVecR + changeU + changeY;
					
					Vector rayOfHope = pixelPos - cameraPosR;
					rayOfHope.normalize();
					ray = Ray(cameraPosR, rayOfHope);
					//!!! rays do not have w coordinate constructed properly.
				}

				// Initialize recursive ray depth.
				int rayDepth = 0;
			   
				// Our recursive raytrace will compute the color and the z-depth
				Vector color;

				// This should be the maximum depth, corresponding to the far plane.
				// NOTE: This assumes the ray direction is unit-length and the
				// ray origin is at the camera position.
				double depth = scene.camera.zFar;

				// Calculate the pixel value by shooting the ray into the scene
				trace(ray, rayDepth, scene, color, depth);

				// Depth test
				int testDepth = x + floor(scene.resolution[0] / 2) + y*scene.resolution[0];
				if(depth >= scene.camera.zNear && depth <= scene.camera.zFar && 
					depth < zBuffer[testDepth]) {
					zBuffer[testDepth] = depth;

					// Set the image color (and depth)
					colorImage.setPixel(x+floor(scene.resolution[0] / 2), y, color);
					depthImage.setPixel(x+floor(scene.resolution[0] / 2), y, (depth-scene.camera.zNear) / 
											(scene.camera.zFar-scene.camera.zNear));
				}
			}

			//output step information
			if (y % 100 == 0)
			{
				printf("Row %d pixels finished.\n", y);
			}
		}
	}

	//save image
    colorImage.writeBMP(filename);
    depthImage.writeBMP(depth_filename);

	printf("Ray tracing finished with images saved.\n");

    delete[] zBuffer;
}
/*
=================
UI_PlayerSetup_CalcFov

assume refdef is valid
=================
*/
static void UI_PlayerSetup_CalcFov( ref_params_t *fd )
{
	float x = fd->viewport[2] / tan( DEG2RAD( fd->fov_x ) * 0.5f );
	float half_fov_y = atan( fd->viewport[3] / x );
	fd->fov_y = RAD2DEG( half_fov_y ) * 2;
}
/*
=================
UI_PlayerSetup_Init
=================
*/
static void UI_PlayerSetup_Init( void )
{
	bool game_hlRally = FALSE;
	int addFlags = 0;

	memset( &uiPlayerSetup, 0, sizeof( uiPlayerSetup_t ));

	// disable playermodel preview for HLRally to prevent crash
	if( !stricmp( gMenu.m_gameinfo.gamefolder, "hlrally" ))
		game_hlRally = TRUE;

	//if( gMenu.m_gameinfo.flags & GFL_NOMODELS )
	//	addFlags |= QMF_INACTIVE;

	uiPlayerSetup.menu.vidInitFunc = UI_PlayerSetup_Init;

	uiPlayerSetup.background.generic.id = ID_BACKGROUND;
	uiPlayerSetup.background.generic.type = QMTYPE_BITMAP;
	uiPlayerSetup.background.generic.flags = QMF_INACTIVE;
	uiPlayerSetup.background.generic.x = 0;
	uiPlayerSetup.background.generic.y = 0;
	uiPlayerSetup.background.generic.width = uiStatic.width;
	uiPlayerSetup.background.generic.height = 768;
	uiPlayerSetup.background.pic = ART_BACKGROUND;

	uiPlayerSetup.banner.generic.id = ID_BANNER;
	uiPlayerSetup.banner.generic.type = QMTYPE_BITMAP;
	uiPlayerSetup.banner.generic.flags = QMF_INACTIVE|QMF_DRAW_ADDITIVE;
	uiPlayerSetup.banner.generic.x = UI_BANNER_POSX;
	uiPlayerSetup.banner.generic.y = UI_BANNER_POSY;
	uiPlayerSetup.banner.generic.width = UI_BANNER_WIDTH;
	uiPlayerSetup.banner.generic.height = UI_BANNER_HEIGHT;
	uiPlayerSetup.banner.pic = ART_BANNER;

	uiPlayerSetup.done.generic.id = ID_DONE;
	uiPlayerSetup.done.generic.type = QMTYPE_BM_BUTTON;
	uiPlayerSetup.done.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW;
	uiPlayerSetup.done.generic.x = 72;
	uiPlayerSetup.done.generic.y = 230;
	uiPlayerSetup.done.generic.name = "Done";
	uiPlayerSetup.done.generic.statusText = "Go back to the Multiplayer Menu";
	uiPlayerSetup.done.generic.callback = UI_PlayerSetup_Callback;

	UI_UtilSetupPicButton( &uiPlayerSetup.done, PC_DONE );

	uiPlayerSetup.AdvOptions.generic.id = ID_ADVOPTIONS;
	uiPlayerSetup.AdvOptions.generic.type = QMTYPE_BM_BUTTON;
	uiPlayerSetup.AdvOptions.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW;
	uiPlayerSetup.AdvOptions.generic.x = 72;
	uiPlayerSetup.AdvOptions.generic.y = 280;
	uiPlayerSetup.AdvOptions.generic.name = "Adv. Options";
	uiPlayerSetup.AdvOptions.generic.statusText = "Configure handness, fov and other advanced options";
	uiPlayerSetup.AdvOptions.generic.callback = UI_PlayerSetup_Callback;

	UI_UtilSetupPicButton( &uiPlayerSetup.AdvOptions, PC_ADV_OPT );

	uiPlayerSetup.view.generic.id = ID_VIEW;
	uiPlayerSetup.view.generic.type = QMTYPE_BITMAP;
	uiPlayerSetup.view.generic.flags = QMF_INACTIVE;
	uiPlayerSetup.view.generic.x = 660;
	uiPlayerSetup.view.generic.y = 260;
	uiPlayerSetup.view.generic.width = 260;
	uiPlayerSetup.view.generic.height = 320;
	uiPlayerSetup.view.generic.ownerdraw = UI_PlayerSetup_Ownerdraw;

	uiPlayerSetup.name.generic.id = ID_NAME;
	uiPlayerSetup.name.generic.type = QMTYPE_FIELD;
	uiPlayerSetup.name.generic.flags = QMF_CENTER_JUSTIFY|QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW;
	uiPlayerSetup.name.generic.x = 320;
	uiPlayerSetup.name.generic.y = 260;
	uiPlayerSetup.name.generic.width = 256;
	uiPlayerSetup.name.generic.height = 36;
	uiPlayerSetup.name.generic.callback = UI_PlayerSetup_Callback;
	uiPlayerSetup.name.generic.statusText = "Enter your multiplayer display name";
	uiPlayerSetup.name.maxLength = 32;

	uiPlayerSetup.model.generic.id = ID_MODEL;
	uiPlayerSetup.model.generic.type = QMTYPE_SPINCONTROL;
	uiPlayerSetup.model.generic.flags = QMF_CENTER_JUSTIFY|QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW|addFlags;
	uiPlayerSetup.model.generic.x = game_hlRally ? 320 : 702;
	uiPlayerSetup.model.generic.y = game_hlRally ? 320 : 590;
	uiPlayerSetup.model.generic.width = game_hlRally ? 256 : 176;
	uiPlayerSetup.model.generic.height = game_hlRally ? 36 : 32;
	uiPlayerSetup.model.generic.callback = UI_PlayerSetup_Callback;
	uiPlayerSetup.model.generic.statusText = "Select a model for representation in multiplayer";
	uiPlayerSetup.model.minValue = 0;
	uiPlayerSetup.model.maxValue = 1;
	uiPlayerSetup.model.range  = 1;

	uiPlayerSetup.topColor.generic.id = ID_TOPCOLOR;
	uiPlayerSetup.topColor.generic.type = QMTYPE_SLIDER;
	uiPlayerSetup.topColor.generic.flags = QMF_PULSEIFFOCUS|QMF_DROPSHADOW|addFlags;
	uiPlayerSetup.topColor.generic.name = "Top color";
	uiPlayerSetup.topColor.generic.x = 250;
	uiPlayerSetup.topColor.generic.y = 550;
	uiPlayerSetup.topColor.generic.width = 300;
	uiPlayerSetup.topColor.generic.callback = UI_PlayerSetup_Callback;
	uiPlayerSetup.topColor.generic.statusText = "Set a player model top color";
	uiPlayerSetup.topColor.minValue = 0.0;
	uiPlayerSetup.topColor.maxValue = 1.0;
	uiPlayerSetup.topColor.range = 0.05f;

	uiPlayerSetup.bottomColor.generic.id = ID_BOTTOMCOLOR;
	uiPlayerSetup.bottomColor.generic.type = QMTYPE_SLIDER;
	uiPlayerSetup.bottomColor.generic.flags = QMF_PULSEIFFOCUS|QMF_DROPSHADOW|addFlags;
	uiPlayerSetup.bottomColor.generic.name = "Bottom color";
	uiPlayerSetup.bottomColor.generic.x = 250;
	uiPlayerSetup.bottomColor.generic.y = 620;
	uiPlayerSetup.bottomColor.generic.width = 300;
	uiPlayerSetup.bottomColor.generic.callback = UI_PlayerSetup_Callback;
	uiPlayerSetup.bottomColor.generic.statusText = "Set a player model bottom color";
	uiPlayerSetup.bottomColor.minValue = 0.0;
	uiPlayerSetup.bottomColor.maxValue = 1.0;
	uiPlayerSetup.bottomColor.range = 0.05f;

	uiPlayerSetup.showModels.generic.id = ID_SHOWMODELS;
	uiPlayerSetup.showModels.generic.type = QMTYPE_CHECKBOX;
	uiPlayerSetup.showModels.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_ACT_ONRELEASE|QMF_MOUSEONLY|QMF_DROPSHADOW|addFlags;
	uiPlayerSetup.showModels.generic.name = "Show 3D Preview";
	uiPlayerSetup.showModels.generic.x = 72;
	uiPlayerSetup.showModels.generic.y = 380;
	uiPlayerSetup.showModels.generic.callback = UI_PlayerSetup_Callback;
	uiPlayerSetup.showModels.generic.statusText = "show 3D player models instead of preview thumbnails";

	uiPlayerSetup.hiModels.generic.id = ID_HIMODELS;
	uiPlayerSetup.hiModels.generic.type = QMTYPE_CHECKBOX;
	uiPlayerSetup.hiModels.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_ACT_ONRELEASE|QMF_MOUSEONLY|QMF_DROPSHADOW|addFlags;
	uiPlayerSetup.hiModels.generic.name = "High quality models";
	uiPlayerSetup.hiModels.generic.x = 72;
	uiPlayerSetup.hiModels.generic.y = 430;
	uiPlayerSetup.hiModels.generic.callback = UI_PlayerSetup_Callback;
	uiPlayerSetup.hiModels.generic.statusText = "show hi-res models in multiplayer";

	UI_PlayerSetup_GetConfig();

	UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.background );
	UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.banner );
	UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.done );
	UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.AdvOptions );
	// disable playermodel preview for HLRally to prevent crash
	if( game_hlRally == FALSE )
		UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.view );
	UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.name );

	//if( !gMenu.m_gameinfo.flags & GFL_NOMODELS )
	//{
		UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.model );
		UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.topColor );
		UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.bottomColor );
		UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.showModels );
		UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.hiModels );
	//}
	// setup render and actor
	uiPlayerSetup.refdef.fov_x = 40;

	// NOTE: must be called after UI_AddItem whan we sure what UI_ScaleCoords is done
	uiPlayerSetup.refdef.viewport[0] = uiPlayerSetup.view.generic.x;
	uiPlayerSetup.refdef.viewport[1] = uiPlayerSetup.view.generic.y;
	uiPlayerSetup.refdef.viewport[2] = uiPlayerSetup.view.generic.width;
	uiPlayerSetup.refdef.viewport[3] = uiPlayerSetup.view.generic.height;

	UI_PlayerSetup_CalcFov( &uiPlayerSetup.refdef );
	uiPlayerSetup.ent = GET_MENU_EDICT ();

	if( !uiPlayerSetup.ent )
		return;

	// adjust entity params
	uiPlayerSetup.ent->curstate.number = 1;	// IMPORTANT: always set playerindex to 1
	uiPlayerSetup.ent->curstate.animtime = gpGlobals->time;	// start animation
	uiPlayerSetup.ent->curstate.sequence = 1;
	uiPlayerSetup.ent->curstate.scale = 1.0f;
	uiPlayerSetup.ent->curstate.frame = 0.0f;
	uiPlayerSetup.ent->curstate.framerate = 1.0f;
	uiPlayerSetup.ent->curstate.effects |= EF_LIGHT;
	uiPlayerSetup.ent->curstate.controller[0] = 127;
	uiPlayerSetup.ent->curstate.controller[1] = 127;
	uiPlayerSetup.ent->curstate.controller[2] = 127;
	uiPlayerSetup.ent->curstate.controller[3] = 127;
	uiPlayerSetup.ent->latched.prevcontroller[0] = 127;
	uiPlayerSetup.ent->latched.prevcontroller[1] = 127;
	uiPlayerSetup.ent->latched.prevcontroller[2] = 127;
	uiPlayerSetup.ent->latched.prevcontroller[3] = 127;
	uiPlayerSetup.ent->origin[0] = uiPlayerSetup.ent->curstate.origin[0] = 45.0f / tan( DEG2RAD( uiPlayerSetup.refdef.fov_y / 2.0f ));
	uiPlayerSetup.ent->origin[2] = uiPlayerSetup.ent->curstate.origin[2] = 2.0f;
	uiPlayerSetup.ent->angles[1] = uiPlayerSetup.ent->curstate.angles[1] = 180.0f;
	uiPlayerSetup.ent->player = true; // yes, draw me as playermodel
}
bool TScriptInternalFunctions::runFunction(QString function, QStringList param, QString &result)
{
    QString fn = function.toUpper();
    if (fn == "ACOS") {
        if (param.length() < 1)
            return false;

        bool ok = false;
        double v = param[0].toDouble(&ok);

        if (!ok)
            v = 0;

        result = QString::number(acos(v));
        return true;
    }

    if (fn == "ASIN") {
        if (param.length() < 1)
            return false;

        bool ok = false;
        double v = param[0].toDouble(&ok);

        if (!ok)
            v = 0;

        result = QString::number(asin(v));
        return true;
    }

    if (fn == "ATAN") {
        if (param.length() < 1)
            return false;

        bool ok = false;
        double v = param[0].toDouble(&ok);

        if (!ok)
            v = 0;

        result = QString::number(atan(v));
        return true;
    }

    if (fn == "BUILDTYPE") {
#ifdef STANDALONE
        result = "STANDALONE";
#endif
#ifdef PACKAGED
        result = "PACKAGED";
#endif
        return true;
    }

    if (fn == "CALC") {
        // Calculate an expression (e.g. 5+5)
        if (param.length() == 0)
            return false;
        QString expr = param[0];
        result = calc(expr);
        return true;
    }

    if (fn == "COS") {
        if (param.length() < 1)
            return false;

        bool ok = false;
        double v = param[0].toDouble(&ok);

        if (!ok)
            v = 0;

        result = QString::number(cos(v));
        return true;
    }

    if (fn == "COLORAT") { // $ColorAt(@window, layer, x, y)
        if (param.length() < 3)
            return false;
        QString layer = "main";
        if (param.length() > 3) {
            layer = param[1];
            param.removeAt(1);
        }

        subwindow_t sw = getCustomWindow(param[0]);
        if (sw.type == WT_NOTHING)
            return false;
        int x = floor( param[1].toFloat() );
        int y = floor( param[2].toFloat() );

        result = sw.widget->picwinPtr()->colorAt(layer, x, y);
        return true;
    }

    if (fn == "CURWINTYPE") {
        // Returns the current target type (msg or channel)
        subwindow_t sw = winList->value(*activeWid);
        if (sw.type == WT_CHANNEL)
            result = "CHANNEL";
        else if (sw.type == WT_GRAPHIC)
            result = "GRAPHIC";
        else if (sw.type == WT_GWINPUT)
            result = "GRAPHICINPUT";
        else if (sw.type == WT_NOTHING)
            result = "NOTHIG";
        else if (sw.type == WT_PRIVMSG)
            result = "PRIVMSG";
        else if (sw.type == WT_STATUS)
            result = "STATUS";
        else if (sw.type == WT_TXTONLY)
            result = "TXTONLY";
        else
            result = "UNKNOWN";

        return true;
    }

    if (fn == "DLG") {
        // Returns information of a dialog or its objects
        // $dlg(dialog,object)
        if (param.count() == 2) {
            QString dlg = param[0];
            QString object = param[1];

            QHashIterator<QString,TCustomScriptDialog*> i(*dialogs);
            while (i.hasNext()) {
                i.next();
                if (i.key().toUpper() == dlg.toUpper()) {
                    result = i.value()->getLabel(object);
                    return true;
                }
            }
        }

        // $dlg(dialog,object,index)
        if (param.count() == 3) {
            QString dlg = param[0];
            QString object = param[1];
            QString index = param[2];

            QHashIterator<QString,TCustomScriptDialog*> i(*dialogs);
            while (i.hasNext()) {
                i.next();
                if (i.key().toUpper() == dlg.toUpper()) {
                    result = i.value()->getItem(object, index.toInt());
                    return true;
                }
            }
        }

        // Default
        return false;
    }

    if (fn == "FILE") {
        // Returns a file descriptor by opening a file for read and|or write
        // $file(file.name, rwb)
        // result: 0 cannot open, -1 not existing
        if (param.count() < 2) {
            result = "0";
            return true;
        }
        QString mode = param[1];

        bool read = false;
        bool write = false;
        bool binary = false;
        bool append = false;
        bool switchfail = false;
        for (int i = 0; i <= mode.length()-1; i++) {
            char c = mode[i].toLatin1();
                switch (c) {
                    case 'a':
                        append = true;
                        continue;
                    case 'r':
                        read = true;
                        continue;
                    case 'w':
                        write = true;
                        continue;
                    case 'b':
                        binary = true;
                        continue;
                    default:
                        switchfail = true;
                        break;
            }
        }

        if (switchfail == true) {
            result = "0";
            return true;
        }

        if ((read || write) == false)
            read = true;

        QIODevice::OpenMode om = 0;

        if (read)
            om |= QIODevice::ReadOnly;
        if (write)
            om |= QIODevice::WriteOnly;
        if (! binary)
            om |= QIODevice::Text;

        if (append)
            om |= QIODevice::Append;

        if (om == 0) {
            result = "0";
            return true;
        }

        QFile *f = new QFile(param[0]);

        if (! f->open(om)) {
            result = "0";
            return true;
        }

        t_sfile ts;
        ts.binary = binary;
        ts.read = read;
        ts.write = write;
        ts.fd = fdc;
        ts.file = f;

        files->insert(fdc, ts);
        result = QString::number(fdc++);
        return true;
    }

    if (fn == "FNEXIST") {
        // Checks if an actual function exists; This will NOT work on "internal" functions (these in here)
        if (param.count() != 1)
            return false;

        int idx = fnindex->value(param[0].toUpper(), -1);

        if (idx > -1)
            result = "1";
        else
            result = "0";
        return true;
    }

    if (fn == "GLUE") {
        // "glue" texts together.
        // $glue(hello,big,world) will return hellobigworld
        QString r;
        for (int i = 0; i <= param.length()-1; i++)
            r += param[i];

        result = r;
        return true;
    }

    if (fn == "HOSTMASK") {
        // Returns hostmask *!*@host.name of nickname if IAL got it.
        // Otherwise, if IAL doesn't, it returns nickname!*@* as hostmask.
        if (param.count() != 1) {
            result.clear();
            return false;
        }
        QString nickname = param[0];

        IConnection *con = conList->value(*activeConn);
        QString host = con->ial.getHost(nickname);
        if (host.isEmpty()) {
            host = nickname;
            host.append("!*@*");
        }
        else
            host.prepend("*!*@");

        result = host;

        return true;
    }

    if (fn == "IALHOSTMASK") {
        // Returns hostname of nickname if IAL got it, otherwise empty text.
        // Better off using $hostmask() instead.
        if (param.count() != 1) {
            result.clear();
            return false;
        }
        QString nickname = param[0];

        IConnection *con = conList->value(*activeConn);
        QString host = con->ial.getHost(nickname);

        if (! host.isEmpty())
            host.prepend("*!*@");

        result = host;

        return true;
    }

    if (fn == "LEN") {
        // Counts amount of letters in a given text
        if (param.count() == 0) {
            result = "0";
            return true;
        }
        result = QString::number( param.at(0).length() );
        return true;
    }

    if (fn == "NULL") {
        // Returns empty
        result.clear();
        return true;
    }

    if (fn == "PATH") {
        // $path(type)
        // Returns a file path to the given type.
        if (param.count() != 1)
            return false;

        QString type = param[0].toUpper();
        if (type == "CONFIG")
            result = CONF_PATH;
        if (type == "COMMON")
            result = COMMON_PATH;
        if (type == "EXEC")
            result = QApplication::applicationDirPath();
        if (type == "SKEL")
            result = SKEL_PATH;

        return true;
    }

    if (fn == "RAND") {
        // Pseudo-random number generator
        if (param.length() < 2)
            return false;
        int lo = param[0].toInt();
        int hi = param[1].toInt();
        result = rand(lo, hi);
        return true;
    }

    if (fn == "SIN") {
        if (param.length() < 1)
            return false;

        bool ok = false;
        double v = param[0].toDouble(&ok);

        if (!ok)
            v = 0;

        result = QString::number(sin(v));
        return true;
    }

    if (fn == "SOCKBUFLEN") {
        // Returns amount of bytes left in sockread buffer
        if (param.length() < 1)
            return false;

        result = sockfactory->sockBufLen(param[0]);
        return true;
    }

    if (fn == "SOCKLIST") {
        // Find socket names.
        // $socklist(patt_*, pos)
        // If pos is zero, that will return amount of socket names the pattern matches.
        // If pos > 0, this will return an actual socket name it matches.
        if (param.length() < 2)
            return false;

        result = sockfactory->socklist(param[0], param[1].toInt());
        return true;
    }

    if (fn == "SSTR") {
        // Substring, returns text by given positions inside the text.
        // $SSTR(The text, start, end) end is optional.
        if (param.length() < 2)
            return false;

        int start = param[1].toInt();
        int stop = -1;
        if (param.length() >= 3)
            stop = param[2].toInt();

        QString text = param[0];
        result = sstr(text, start, stop);
        return true;
    }

    if (fn == "TAN") {
        if (param.length() < 1)
            return false;

        bool ok = false;
        double v = param[0].toDouble(&ok);

        if (!ok)
            v = 0;

        result = QString::number(tan(v));
        return true;
    }

    if (fn == "TARGET") {
        // Returns the current target to send messages to (msg or channel)
        subwindow_t sw = winList->value(*activeWid);
        result.clear();
        if ((sw.type == WT_CHANNEL) || (sw.type == WT_PRIVMSG))
            result = sw.widget->getTarget();
        return true;
    }

    if (fn == "TEXTWIDTH") {
        // Return text width in pixles by given font name and size
        // $textwidth(font, size, text)
        if (param.count() != 3)
            return false;

        QFont font(param[0]);
        font.setPixelSize(param[1].toInt());

        QFontMetrics fm(font);
        result = QString::number( fm.width(param[2]) );

        return true;
    }

    if (fn == "TOKEN") {
        // Get a text by tokens
        // $token(text here, position, token)  the token is in ascii number.
        // If the position is zero, this will count amount of text items separated by the given token
        if (param.length() < 3)
        return false;

        bool ok = false;

        QString tcnum = param[2]; // token character (ascii num)
        QChar tc = tcnum.toInt(&ok); // converted from string-number to actual number, into a character.

        if (ok == false)
            return false;

        int p = param[1].toInt(&ok); // Which position to use

        if (ok == false)
            return false;

        result = token(param[0], p, tc);

        return true;
    }

    if (fn == "VERSION") {
        // IIRC version.
        result = VERSION_STRING;
        return true;
    }

    // No functions were matching, return false as error.
    return false;
}
Example #16
0
double dTan(double x){
  double v1 = tan(x);
  return 1+v1*v1;
}
Example #17
0
/*
===============
UI_DrawPlayer
===============
*/
void UI_DrawPlayer( float x, float y, float w, float h, uiPlayerInfo_t *pi, int time ) {
	refdef_t		refdef;
	refEntity_t		legs = {0};
	refEntity_t		torso = {0};
	refEntity_t		head = {0};
	refEntity_t		gun = {0};
	refEntity_t		barrel = {0};
	refEntity_t		flash = {0};
	vec3_t			origin;
	int				renderfx;
	vec3_t			mins = {-16, -16, -24};
	vec3_t			maxs = {16, 16, 32};
	float			len;
	float			xx;
	float			xscale;
	float			yscale;

	if ( !pi->legsModel || !pi->torsoModel || !pi->headModel || !pi->animations[0].numFrames ) {
		return;
	}

	dp_realtime = time;

	if ( pi->pendingWeapon != WP_NUM_WEAPONS && dp_realtime > pi->weaponTimer ) {
		pi->weapon = pi->pendingWeapon;
		pi->lastWeapon = pi->pendingWeapon;
		pi->pendingWeapon = WP_NUM_WEAPONS;
		pi->weaponTimer = 0;
		if( pi->currentWeapon != pi->weapon ) {
			trap_S_StartLocalSound( weaponChangeSound, CHAN_LOCAL );
		}
	}

	CG_AdjustFrom640( &x, &y, &w, &h );

	y -= jumpHeight;

	memset( &refdef, 0, sizeof( refdef ) );
	memset( &legs, 0, sizeof(legs) );
	memset( &torso, 0, sizeof(torso) );
	memset( &head, 0, sizeof(head) );

	refdef.rdflags = RDF_NOWORLDMODEL;

	AxisClear( refdef.viewaxis );

	refdef.x = x;
	refdef.y = y;
	refdef.width = w;
	refdef.height = h;

	if ( ui_stretch.integer ) {
		xscale = cgs.screenXScaleStretch;
		yscale = cgs.screenYScaleStretch;
	} else {
		xscale = cgs.screenXScale;
		yscale = cgs.screenYScale;
	}

	refdef.fov_x = (int)((float)refdef.width / xscale / 640.0f * 90.0f);
	xx = refdef.width / xscale / tan( refdef.fov_x / 360 * M_PI );
	refdef.fov_y = atan2( refdef.height / yscale, xx );
	refdef.fov_y *= ( 360 / M_PI );

	// calculate distance so the player nearly fills the box
	len = 0.7 * ( maxs[2] - mins[2] );		
	origin[0] = len / tan( DEG2RAD(refdef.fov_x) * 0.5 );
	origin[1] = 0.5 * ( mins[1] + maxs[1] );
	origin[2] = -0.5 * ( mins[2] + maxs[2] );

	refdef.time = dp_realtime;

	trap_R_ClearScene();

	// get the rotation information
	UI_PlayerAngles( pi, legs.axis, torso.axis, head.axis );
	
	// get the animation state (after rotation, to allow feet shuffle)
	UI_PlayerAnimation( pi, &legs.oldframe, &legs.frame, &legs.backlerp,
		 &torso.oldframe, &torso.frame, &torso.backlerp );

	renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW;

	//
	// add the legs
	//
	legs.hModel = pi->legsModel;
	legs.customSkin = CG_AddSkinToFrame( &pi->modelSkin );

	VectorCopy( origin, legs.origin );

	VectorCopy( origin, legs.lightingOrigin );
	legs.renderfx = renderfx;
	VectorCopy (legs.origin, legs.oldorigin);

	Byte4Copy( pi->c1RGBA, legs.shaderRGBA );

	CG_AddRefEntityWithMinLight( &legs );

	if (!legs.hModel) {
		return;
	}

	//
	// add the torso
	//
	torso.hModel = pi->torsoModel;
	if (!torso.hModel) {
		return;
	}

	torso.customSkin = legs.customSkin;

	VectorCopy( origin, torso.lightingOrigin );

	UI_PositionRotatedEntityOnTag( &torso, &legs, pi->legsModel, "tag_torso");

	torso.renderfx = renderfx;

	Byte4Copy( pi->c1RGBA, torso.shaderRGBA );

	CG_AddRefEntityWithMinLight( &torso );

	//
	// add the head
	//
	head.hModel = pi->headModel;
	if (!head.hModel) {
		return;
	}
	head.customSkin = legs.customSkin;

	VectorCopy( origin, head.lightingOrigin );

	UI_PositionRotatedEntityOnTag( &head, &torso, pi->torsoModel, "tag_head");

	head.renderfx = renderfx;

	Byte4Copy( pi->c1RGBA, head.shaderRGBA );

	CG_AddRefEntityWithMinLight( &head );

	//
	// add the gun
	//
	if ( pi->currentWeapon != WP_NONE ) {
		memset( &gun, 0, sizeof(gun) );
		gun.hModel = pi->weaponModel;
		Byte4Copy( pi->c1RGBA, gun.shaderRGBA );
		VectorCopy( origin, gun.lightingOrigin );
		UI_PositionEntityOnTag( &gun, &torso, pi->torsoModel, "tag_weapon");
		gun.renderfx = renderfx;
		CG_AddRefEntityWithMinLight( &gun );
	}

	//
	// add the spinning barrel
	//
	if ( pi->barrelModel ) {
		vec3_t	angles;

		memset( &barrel, 0, sizeof(barrel) );
		VectorCopy( origin, barrel.lightingOrigin );
		barrel.renderfx = renderfx;

		barrel.hModel = pi->barrelModel;
		angles[YAW] = 0;
		angles[PITCH] = 0;
		angles[ROLL] = UI_MachinegunSpinAngle( pi );
		AnglesToAxis( angles, barrel.axis );

		UI_PositionRotatedEntityOnTag( &barrel, &gun, pi->weaponModel, "tag_barrel");

		CG_AddRefEntityWithMinLight( &barrel );
	}

	//
	// add muzzle flash
	//
	if ( dp_realtime <= pi->muzzleFlashTime ) {
		if ( pi->flashModel ) {
			memset( &flash, 0, sizeof(flash) );
			flash.hModel = pi->flashModel;
			Byte4Copy( pi->c1RGBA, flash.shaderRGBA );
			VectorCopy( origin, flash.lightingOrigin );
			UI_PositionEntityOnTag( &flash, &gun, pi->weaponModel, "tag_flash");
			flash.renderfx = renderfx;
			CG_AddRefEntityWithMinLight( &flash );
		}

		// make a dlight for the flash
		if ( pi->flashDlightColor[0] || pi->flashDlightColor[1] || pi->flashDlightColor[2] ) {
			trap_R_AddJuniorLightToScene( flash.origin, 200 + (rand()&31), 1.0f, pi->flashDlightColor[0],
				pi->flashDlightColor[1], pi->flashDlightColor[2] );
		}
	}

	//
	// add the chat icon
	//
	if ( pi->chat ) {
		UI_PlayerFloatSprite( pi, torso.origin, trap_R_RegisterShaderNoMip( "sprites/balloon3" ) );
	}

	//
	// add an accent light
	//
	origin[0] -= 100;	// + = behind, - = in front
	origin[1] += 100;	// + = left, - = right
	origin[2] += 100;	// + = above, - = below
	trap_R_AddJuniorLightToScene( origin, 500, 1.0, 1.0, 1.0, 1.0 );

	origin[0] -= 100;
	origin[1] -= 100;
	origin[2] -= 100;
	trap_R_AddJuniorLightToScene( origin, 500, 1.0, 1.0, 0.0, 0.0 );

	trap_R_RenderScene( &refdef );
}
Example #18
0
double ddTan(double x){
  double v1 = tan(x);
  return 2*v1*(1+v1*v1);
}
CAAPhysicalJupiterDetails CAAPhysicalJupiter::Calculate(double JD)
{
  //What will be the return value
  CAAPhysicalJupiterDetails details;

  //Step 1
  double d = JD - 2433282.5;
  double T1 = d/36525;
  double alpha0 = 268.00 + 0.1061*T1;
  double alpha0rad = CAACoordinateTransformation::DegreesToRadians(alpha0);
  double delta0 = 64.50 - 0.0164*T1;
  double delta0rad = CAACoordinateTransformation::DegreesToRadians(delta0);

  //Step 2
  double W1 = CAACoordinateTransformation::MapTo0To360Range(17.710 + 877.90003539*d);
  double W2 = CAACoordinateTransformation::MapTo0To360Range(16.838 + 870.27003539*d);
  
  //Step 3
  double l0 = CAAEarth::EclipticLongitude(JD);
  double l0rad = CAACoordinateTransformation::DegreesToRadians(l0);
  double b0 = CAAEarth::EclipticLatitude(JD);
  double b0rad = CAACoordinateTransformation::DegreesToRadians(b0);
  double R = CAAEarth::RadiusVector(JD);

  //Step 4
  double l = CAAJupiter::EclipticLongitude(JD);
  double lrad = CAACoordinateTransformation::DegreesToRadians(l);
  double b = CAAJupiter::EclipticLatitude(JD);
  double brad = CAACoordinateTransformation::DegreesToRadians(b);
  double r = CAAJupiter::RadiusVector(JD);

  //Step 5
  double x = r*cos(brad)*cos(lrad) - R*cos(l0rad);
  double y = r*cos(brad)*sin(lrad) - R*sin(l0rad);
  double z = r*sin(brad) - R*sin(b0rad);
  double DELTA = sqrt(x*x + y*y + z*z);

  //Step 6
  l -= 0.012990*DELTA/(r*r);
  lrad = CAACoordinateTransformation::DegreesToRadians(l);

  //Step 7
  x = r*cos(brad)*cos(lrad) - R*cos(l0rad);
  y = r*cos(brad)*sin(lrad) - R*sin(l0rad);
  z = r*sin(brad) - R*sin(b0rad);
  DELTA = sqrt(x*x + y*y + z*z);

  //Step 8
  double e0 = CAANutation::MeanObliquityOfEcliptic(JD);
  double e0rad = CAACoordinateTransformation::DegreesToRadians(e0);

  //Step 9
  double alphas = atan2(cos(e0rad)*sin(lrad) - sin(e0rad)*tan(brad), cos(lrad));
  double deltas = asin(cos(e0rad)*sin(brad) + sin(e0rad)*cos(brad)*sin(lrad));

  //Step 10
  details.DS = CAACoordinateTransformation::RadiansToDegrees(asin(-sin(delta0rad)*sin(deltas) - cos(delta0rad)*cos(deltas)*cos(alpha0rad - alphas)));

  //Step 11
  double u = y*cos(e0rad) - z*sin(e0rad);
  double v = y*sin(e0rad) + z*cos(e0rad);
  double alpharad = atan2(u, x);
  double alpha = CAACoordinateTransformation::RadiansToDegrees(alpharad);
  double deltarad = atan2(v, sqrt(x*x + u*u));
  double delta = CAACoordinateTransformation::RadiansToDegrees(deltarad);
  double xi = atan2(sin(delta0rad)*cos(deltarad)*cos(alpha0rad - alpharad) - sin(deltarad)*cos(delta0rad), cos(deltarad)*sin(alpha0rad - alpharad));

  //Step 12
  details.DE = CAACoordinateTransformation::RadiansToDegrees(asin(-sin(delta0rad)*sin(deltarad) - cos(delta0rad)*cos(deltarad)*cos(alpha0rad - alpharad)));

  //Step 13
  details.Geometricw1 = CAACoordinateTransformation::MapTo0To360Range(W1 - CAACoordinateTransformation::RadiansToDegrees(xi) - 5.07033*DELTA);
  details.Geometricw2 = CAACoordinateTransformation::MapTo0To360Range(W2 - CAACoordinateTransformation::RadiansToDegrees(xi) - 5.02626*DELTA);

  //Step 14
  double C = 57.2958 * (2*r*DELTA + R*R - r*r - DELTA*DELTA)/(4*r*DELTA);
  if (sin(lrad - l0rad) > 0)
  {
    details.Apparentw1 = CAACoordinateTransformation::MapTo0To360Range(details.Geometricw1 + C);
    details.Apparentw2 = CAACoordinateTransformation::MapTo0To360Range(details.Geometricw2 + C);
  }
  else
  {
    details.Apparentw1 = CAACoordinateTransformation::MapTo0To360Range(details.Geometricw1 - C);
    details.Apparentw2 = CAACoordinateTransformation::MapTo0To360Range(details.Geometricw2 - C);
  }

  //Step 15
  double NutationInLongitude = CAANutation::NutationInLongitude(JD);
  double NutationInObliquity = CAANutation::NutationInObliquity(JD);
  e0 += NutationInObliquity/3600;
  e0rad = CAACoordinateTransformation::DegreesToRadians(e0);

  //Step 16
  alpha += 0.005693*(cos(alpharad)*cos(l0rad)*cos(e0rad) + sin(alpharad)*sin(l0rad))/cos(deltarad);
  alpha = CAACoordinateTransformation::MapTo0To360Range(alpha);
  alpharad = CAACoordinateTransformation::DegreesToRadians(alpha);
  delta += 0.005693*(cos(l0rad)*cos(e0rad)*(tan(e0rad)*cos(deltarad) - sin(alpharad)*sin(deltarad)) + cos(alpharad)*sin(deltarad)*sin(l0rad));
  deltarad = CAACoordinateTransformation::DegreesToRadians(delta);

  //Step 17
  double NutationRA = CAANutation::NutationInRightAscension(alpha/15, delta, e0, NutationInLongitude, NutationInObliquity);
  double alphadash = alpha + NutationRA/3600;
  double alphadashrad = CAACoordinateTransformation::DegreesToRadians(alphadash);
  double NutationDec = CAANutation::NutationInDeclination(alpha/15, delta, e0, NutationInLongitude, NutationInObliquity);
  double deltadash = delta + NutationDec/3600;
  double deltadashrad = CAACoordinateTransformation::DegreesToRadians(deltadash);
  NutationRA = CAANutation::NutationInRightAscension(alpha0/15, delta0, e0, NutationInLongitude, NutationInObliquity);
  double alpha0dash = alpha0 + NutationRA/3600;
  double alpha0dashrad = CAACoordinateTransformation::DegreesToRadians(alpha0dash);
  NutationDec = CAANutation::NutationInDeclination(alpha0/15, delta0, e0, NutationInLongitude, NutationInObliquity);
  double delta0dash = delta0 + NutationDec/3600;
  double delta0dashrad = CAACoordinateTransformation::DegreesToRadians(delta0dash);

  //Step 18
  details.P = CAACoordinateTransformation::MapTo0To360Range(CAACoordinateTransformation::RadiansToDegrees(atan2(cos(delta0dashrad)*sin(alpha0dashrad - alphadashrad), sin(delta0dashrad)*cos(deltadashrad) - cos(delta0dashrad)*sin(deltadashrad)*cos(alpha0dashrad - alphadashrad))));

  return details;
}
void FollowCamera::update(Step * _step){
	
	lastOrientation = childTransform->getOrientationQuat();
	glm::quat newOrientation = glm::quat(1.f, 0.f, 0.f, 0.f);
	newOrientation = glm::rotate(newOrientation, yaw, upVectorLocal);
	newOrientation = glm::rotate(newOrientation, pitch, rightVectorLocal);

	newOrientation = glm::slerp(lastOrientation, newOrientation, 0.15f * static_cast<float>(sweet::deltaTimeCorrection));
	childTransform->setOrientation(newOrientation);

	forwardVectorRotated   = newOrientation * forwardVectorLocal;
	rightVectorRotated	   = newOrientation * rightVectorLocal;
	upVectorRotated		   = newOrientation * upVectorLocal;
	
	lookAtSpot = glm::vec3(0.f, 0.f, 0.f);
	float targetMinX = 9999999999.f;
	float targetMinY = 9999999999.f;
	float targetMaxX = -9999999999.f;
	float targetMaxY = -9999999999.f;
	
	for(signed long int i = targets.size()-1; i >= 0; --i){
		if(!targets.at(i).active){
			if(targets.at(i).weight <= 0.001f){
				targets.erase(targets.begin() + i);
			}
		}else{
			targets.at(i).pos = targets.at(i).target->getWorldPos();
		}
	}

	for(Target & t : targets){
		targetMinX = std::min((t.pos.x-buffer)*t.weight, targetMinX);
		targetMaxX = std::max((t.pos.x+buffer)*t.weight, targetMaxX);
		targetMinY = std::min((t.pos.y-buffer)*t.weight, targetMinY);
		targetMaxY = std::max((t.pos.y+buffer)*t.weight, targetMaxY);

		if(t.active){
			t.weight = std::min(1.f, t.weight + 0.05f);
		}else{
			t.weight = std::max(0.f, t.weight - 0.01f);
		}
	}

	float screenWidth = targetMaxX - targetMinX;
	float screenHeight = targetMaxY - targetMinY;
	
	// move camera
	lookAtSpot.x = targetMinX;
	lookAtSpot.y = targetMinY;
	
	lookAtSpot += offset;
	
	if(useBounds){
		if(minBounds.height != 0){
			if(lookAtSpot.y < minBounds.y){
				lookAtSpot.y = minBounds.y;
			}
			if(lookAtSpot.y + screenHeight > minBounds.x + minBounds.height){
				lookAtSpot.y -= (lookAtSpot.y + screenHeight - (minBounds.y + minBounds.height));
			}
			if(lookAtSpot.y < minBounds.y){
				screenHeight -= minBounds.y - lookAtSpot.y;
				lookAtSpot.y = minBounds.y;
			}
		}

		if(minBounds.width != 0){
			if(lookAtSpot.x < minBounds.x){
				lookAtSpot.x = minBounds.x;
			}
			if(lookAtSpot.x + screenWidth > minBounds.x + minBounds.width){
				lookAtSpot.x -= (lookAtSpot.x + screenWidth - (minBounds.x + minBounds.width));
			}
			if(lookAtSpot.x < minBounds.x){
				screenWidth -= minBounds.x - lookAtSpot.x;
				lookAtSpot.x = minBounds.x;
			}
		}
	}

	// calculate zoom and account for FoV (the camera FoV seems to be vertical, so if the screen w > screen h, we need to take the h / the intended aspect ratio)
	float ar1 = screenWidth/screenHeight;
	glm::vec2 screenDimensions = sweet::getWindowDimensions();
	float ar2 = static_cast<float>(screenDimensions.x)/static_cast<float>(screenDimensions.y);
	float zoom;
	if(ar1 > ar2){
		zoom = std::max(minimumZoom, screenWidth / ar2);
	}else if(ar1 < ar2){
		zoom = std::max(minimumZoom, screenHeight);
	}else{
		zoom = std::max(minimumZoom, screenHeight);
	}

	lookAtSpot.x += screenWidth * 0.5f;
	lookAtSpot.y += screenHeight * 0.5f;

	lookAtSpot += offset;

	float dist = zoom / (tan(glm::radians(fieldOfView) * 0.5f) * 2.f);


	firstParent()->translate(lookAtSpot.x, lookAtSpot.y, dist, false);
}
Example #21
0
float Light::MicroFacet(Vector l, Vector v, Vector n, float m) {
    Vector h = (l + v) / Norm(l + v);
    float J = acos(DotProduct(h, n));
    auto Beckmann = static_cast<float>((1 / (4.0f * (m * m) * pow((cos(J)), 4))) * exp((-1.0f * (tan(J) * tan(J))) / (m * m)));
    return Beckmann;
}
Example #22
0
void latlon2_(double *alat1, double *alon1, double *delta, double *azi, double *alat2, double *alon2) {
	double alat, alatr, alon, b, c, coslat, dlon;
	double r13, sinlat, x1, x2, x3;

	/* changed for ellipticity of earth
	 * changed use of *alat1 and *alat2
	 */

	double esq, alat3;
	esq=(1.0-1.0/298.25)*(1.0-1.0/298.25);
	alat3=atan(tan(*alat1*DEG_TO_RAD)*esq)*RAD_TO_DEG;

	/* Convert a geographical location to geocentric cartesian 
	 * coordinates, assuming a spherical earth
	 */

	alat = 90.0 - *delta;
	alon = 180.0 - *azi;
	r13  = cos(DEG_TO_RAD*alat);

	/* x1:	Axis 1 intersects equator at  0 deg longitude  
	 * x2:	Axis 2 intersects equator at 90 deg longitude  
	 * x3:	Axis 3 intersects north pole
	 */

	x1 = r13*sin(DEG_TO_RAD*alon);
	x2 = sin(DEG_TO_RAD*alat);
	x3 = r13*cos(DEG_TO_RAD*alon);

	/* Rotate in cartesian coordinates.  The cartesian coordinate system 
	 * is most easily described in geographic terms.  The origin is at 
	 * the Earth's center.  Rotation by alat1 degrees southward, about 
	 * the 1-axis.
	 */

	alatr  = (90.0-alat3)/RAD_TO_DEG;
	sinlat = sin(alatr);
	coslat = cos(alatr);
	b      = x2;
	c      = x3;
	x2     = b*coslat - c*sinlat;
	x3     = b*sinlat + c*coslat;

	/* Convert geocentric cartesian coordinates to a geographical 
	 * location, assuming a spherical earth
	 */

	r13    = sqrt(x3*x3 + x1*x1);
	dlon   = RAD_TO_DEG*atan2(x1, x3);

	/*  changed for ellipticity of earth
	 *   *alat2 = RAD_TO_DEG*atan2(x2, r13);
	 */

	alat3= atan2(x2, r13);
	*alat2=RAD_TO_DEG * atan(tan(alat3)/esq);

	*alon2 = *alon1 + dlon;
	if (fabs(*alon2) > 180.0)
		*alon2 = SIGN((360.0-fabs(*alon2)), *alon2);
}
Example #23
0
Catoms2DSimulator::Catoms2DSimulator(int argc, char *argv[], Catoms2DBlockCode *(*catoms2DBlockCodeBuildingFunction)(Catoms2DBlock*)) : BaseSimulator::Simulator(argc, argv) {
	OUTPUT << "\033[1;34m" << "Catoms2DSimulator constructor" << "\033[0m" << endl;

	int currentID = 1;
	Catoms2DWorld *world = NULL;
	buildNewBlockCode = catoms2DBlockCodeBuildingFunction;
	float blockSize[3];

	testMode = false;

	/* reading the xml file */
	TiXmlNode *node = xmlDoc->FirstChild("world");
	if (node) {
		TiXmlElement* worldElement = node->ToElement();
		const char *attr= worldElement->Attribute("gridSize");
		int lx,ly,lz;
		if (attr) {
			string str=attr;
			int pos = str.find_first_of(',');
			lx = atoi(str.substr(0,pos).c_str());
			ly = 1;
			lz = atoi(str.substr(pos+1,str.length()-pos-1).c_str());
			OUTPUT << "grid size : " << lx << " x " << ly << " x " << lz << endl;
		} else {
			OUTPUT << "WARNING No grid size in XML file" << endl;
		}
		attr=worldElement->Attribute("windowSize");
		if (attr) {
			string str=attr;
	 		int pos = str.find_first_of(',');
			GlutContext::initialScreenWidth = atoi(str.substr(0,pos).c_str());
			GlutContext::initialScreenHeight = atoi(str.substr(pos+1,str.length()-pos-1).c_str());
			GlutContext::screenWidth = GlutContext::initialScreenWidth;
			GlutContext::screenHeight = GlutContext::initialScreenHeight;
		}

		createWorld(lx, ly, lz, argc, argv);
		world = getWorld();
		world->loadTextures("../../simulatorCore/catoms2DTextures");

	} else {
		ERRPUT << "ERROR : NO world in XML file" << endl;
		exit(1);
	}

	createScheduler();

	// loading the camera parameters
	TiXmlNode *nodeConfig = node->FirstChild("camera");
	if (nodeConfig) {
		TiXmlElement* cameraElement = nodeConfig->ToElement();
		const char *attr=cameraElement->Attribute("target");
		double def_near=1,def_far=1500;
		float angle=45.0;
		if (attr) {
			string str(attr);
			int pos = str.find_first_of(',');
			Vecteur target;
			target.pt[0] = atof(str.substr(0,pos).c_str());
			target.pt[1] = 1;
			target.pt[2] = atoi(str.substr(pos+1,str.length()-pos-1).c_str());
			world->getCamera()->setTarget(target);
		}
		attr=cameraElement->Attribute("angle");
		if (attr) {
			angle = atof(attr);
			world->getCamera()->setAngle(angle);
		}
		attr=cameraElement->Attribute("directionSpherical");
		if (attr) {
			string str(attr);
			int pos1 = str.find_first_of(','),
			pos2 = str.find_last_of(',');
			float az,ele,dist;
			az = -90.0+atof(str.substr(0,pos1).c_str());
			ele = atof(str.substr(pos1+1,pos2-pos1-1).c_str());
			dist = atof(str.substr(pos2+1,str.length()-pos1-1).c_str());
			world->getCamera()->setDirection(az,ele);
			world->getCamera()->setDistance(dist);
			az = dist*sin(angle*M_PI/180.0);
			def_near = dist-az;
			def_far = dist+az;
		}
		attr=cameraElement->Attribute("near");
		if (attr) {
			def_near = atof(attr);
		}
		attr=cameraElement->Attribute("far");
		if (attr) {
			def_far = atof(attr);
		}
		world->getCamera()->setNearFar(def_near,def_far);
	}

	// loading the spotlight parameters
	nodeConfig = node->FirstChild("spotlight");
	if (nodeConfig) {
		Vecteur target;
		float az=0,ele=60,dist=1000,angle=50;
		TiXmlElement* lightElement = nodeConfig->ToElement();
		const char *attr=lightElement->Attribute("target");
		if (attr) {
			string str(attr);
			int pos1 = str.find_first_of(','),
			pos2 = str.find_last_of(',');
			target.pt[0] = atof(str.substr(0,pos1).c_str());
			target.pt[1] = atof(str.substr(pos1+1,pos2-pos1-1).c_str());
			target.pt[2] = atof(str.substr(pos2+1,str.length()-pos1-1).c_str());
		}
		attr=lightElement->Attribute("directionSpherical");
		if (attr) {
			string str(attr);
			int pos1 = str.find_first_of(','),
			pos2 = str.find_last_of(',');
			az = -90.0+atof(str.substr(0,pos1).c_str());
			ele = atof(str.substr(pos1+1,pos2-pos1-1).c_str());
			dist = atof(str.substr(pos2+1,str.length()-pos1-1).c_str());
		}
		attr=lightElement->Attribute("angle");
		if (attr) {
			angle = atof(attr);
		}
		float farplane=2.0*dist*tan(angle*M_PI/180.0);
		world->getCamera()->setLightParameters(target,az,ele,dist,angle,10.0,farplane);

	}

	TiXmlNode *nodeBlock = node->FirstChild("blockList");
	if (nodeBlock) {
		Color defaultColor=DARKGREY;
		TiXmlElement* element = nodeBlock->ToElement();
		const char *attr= element->Attribute("color");
		if (attr) {
			string str(attr);
			int pos1 = str.find_first_of(','),
			pos2 = str.find_last_of(',');
			defaultColor.rgba[0] = atof(str.substr(0,pos1).c_str())/255.0;
			defaultColor.rgba[1] = atof(str.substr(pos1+1,pos2-pos1-1).c_str())/255.0;
			defaultColor.rgba[2] = atof(str.substr(pos2+1,str.length()-pos1-1).c_str())/255.0;
			OUTPUT << "new default color :" << defaultColor << endl;
		}
		attr= element->Attribute("blocksize");
        if (attr) {
             string str(attr);
             int pos1 = str.find_first_of(','),
              pos2 = str.find_last_of(',');
             blockSize[0] = atof(str.substr(0,pos1).c_str());
             blockSize[1] = atof(str.substr(pos1+1,pos2-pos1-1).c_str());
             blockSize[2] = atof(str.substr(pos2+1,str.length()-pos1-1).c_str());
             OUTPUT << "blocksize =" << blockSize[0] << "," << blockSize[1] << "," << blockSize[2] << endl;
             world->setBlocksSize(blockSize);
		}

	/* Reading a robotblock */
		TiXmlNode *block = nodeBlock->FirstChild("block");
		Vecteur position;
		Color color;
		bool master;
		while (block) {
		   element = block->ToElement();
		   color=defaultColor;
		   master=false;
		   attr = element->Attribute("color");
		   if (attr) {
			   string str(attr);
			   int pos1 = str.find_first_of(','),
		   		   pos2 = str.find_last_of(',');
			   color.set(atof(str.substr(0,pos1).c_str())/255.0,
                         atof(str.substr(pos1+1,pos2-pos1-1).c_str())/255.0,
                         atof(str.substr(pos2+1,str.length()-pos1-1).c_str())/255.0);
			   OUTPUT << "new color :" << defaultColor << endl;
			}
			attr = element->Attribute("position");
			if (attr) {
                string str(attr);
                int pos = str.find_first_of(',');
                int ix = atof(str.substr(0,pos).c_str()),
                    iy = atoi(str.substr(pos+1,str.length()-pos-1).c_str());
				//position.pt[0] = (ix+(iy%2)*0.5)*blockSize[0];
				//position.pt[1] = 0.5;
				//position.pt[2] = M_SQRT3_2*iy*blockSize[2];
				  position.pt[0] = ix;
				  position.pt[1] = 0;
				  position.pt[2] = iy;
			}
			attr = element->Attribute("master");
			if (attr) {
                string str(attr);
                if (str.compare("true")==0 || str.compare("1")==0) {
                            master=true;
                }
                OUTPUT << "master : " << master << endl;
			}
			world->addBlock(currentID++,Catoms2DSimulator::buildNewBlockCode,position,color,master);
			block = block->NextSibling("block");
		} // end while (block)
/*
		block = nodeBlock->FirstChild("blocksLine");
		int line,plane;
		while (block) {
			element = block->ToElement();
			color=defaultColor;
			attr = element->Attribute("color");
			if (attr) {
				string str(attr);
				int pos1 = str.find_first_of(','),
					pos2 = str.find_last_of(',');
				color.rgba[0] = atof(str.substr(0,pos1).c_str())/255.0;
				color.rgba[1] = atof(str.substr(pos1+1,pos2-pos1-1).c_str())/255.0;
				color.rgba[2] = atof(str.substr(pos2+1,str.length()-pos1-1).c_str())/255.0;
				OUTPUT << "line color :" << color << endl;

			}
			attr = element->Attribute("line");
			if (attr) {
				line = atoi(attr);
			}
			attr = element->Attribute("plane");
			if (attr) {
				plane = atoi(attr);
			}
			attr = element->Attribute("values");
			if (attr) {
				string str(attr);
				position.pt[2] = plane;
				position.pt[1] = line;
				int n = str.length();
				for(int i=0; i<n; i++) {
			    	if  (str[i]=='1') {
			    		position.pt[0]=i;
			    		world->addBlock(currentID++,Catoms2DSimulator::buildNewBlockCode,position,color);
			    	}
			    }
			}
			block = block->NextSibling("blocksLine");
		} // end while (nodeBlock)*/
	} else // end if(nodeBlock)
	{ cerr << "no Block List" << endl;
	}

	TiXmlNode *nodeGrid = node->FirstChild("targetGrid");
	if (nodeGrid) {
		world->initTargetGrid();
		TiXmlNode *block = nodeGrid->FirstChild("block");
		Vecteur position;
		const char *attr;
		TiXmlElement* element;
		while (block) {
		   	element = block->ToElement();
			attr = element->Attribute("position");
			if (attr) {
                string str(attr);
                int pos = str.find_first_of(',');
                int ix = atof(str.substr(0,pos).c_str()),
                    iy = atoi(str.substr(pos+1,str.length()-pos-1).c_str());
				position.pt[0] = ix;
				position.pt[1] = 0;
				position.pt[2] = iy;
			}
			world->setTargetGrid(fullCell,position[0],position[1],position[2]);
			block = block->NextSibling("block");
		}
		/*
		TiXmlNode *block = nodeGrid->FirstChild("targetLine");
		int line,plane;
		while (block) {
			TiXmlElement* element = block->ToElement();
			const char *attr = element->Attribute("line");
	 		if (attr) {
	 			line = atoi(attr);
	 		}
	 		attr = element->Attribute("plane");
	 		if (attr) {
	 			plane = atoi(attr);
	 		}
	 		attr = element->Attribute("values");
	 		if (attr) {
	 			string str(attr);
	 			int n = str.length();
	 			for(int i=0; i<n; i++) {
	 		    	world->setTargetGrid((str[i]=='1')?fullCell:emptyCell,i,line,plane);
	 		    }
	 		}
	 		block = block->NextSibling("targetLine");
	 	}*/
	 } else {
	 	ERRPUT << "No target grid" << endl;
	 }

    TiXmlNode *nodeCapa = node->FirstChild("capabilities");
	if (nodeCapa) {
        world->setCapabilities(new Catoms2DCapabilities(nodeCapa));
    }

    world->linkBlocks();

//	getScheduler()->sem_schedulerStart->post();
//	getScheduler()->setState(Scheduler::NOTSTARTED);

	if (!testMode) {
      GlutContext::mainLoop();
   }
}
double f( double x ){
      return ( p * exp( -x ) + q*sin( x ) + r*cos( x ) + s*tan( x ) + t*x*x + u );
}
Example #25
0
bool GeoAlgorithms::initVincenty(double aLat1, double aLon1, double aLat2, double aLon2)
{

   // Verify that input latitudes are between -90 and 90 and longitudes are
   // between -180 and 180
   if ((abs(aLat1) > 90) || (abs(aLat2) > 90) || (abs(aLon1) > 180)
        || (abs(aLon2) > 180))
   {
       return false;
   }

   // convert inputs in degrees to radians:
   aLat1 = aLat1 * 0.0174532925199433;
   aLon1 = aLon1 * 0.0174532925199433;
   aLat2 = aLat2 * 0.0174532925199433;
   aLon2 = aLon2 * 0.0174532925199433;

   // correct for errors at exact poles by adjusting 0.6 millimeters:
   if (abs(GeoConversions::PI_OVER_2-abs(aLat1)) < (1e-10))
   {
       aLat1 = getSign(aLat1) * (GeoConversions::PI_OVER_2 - (1e-10));
   }
   if (abs(GeoConversions::PI_OVER_2-abs(aLat2)) < (1e-10))
   {
       aLat2 = getSign(aLat2) * (GeoConversions::PI_OVER_2 - (1e-10));
   }

   // Ellipse CalcuaAltitudeions?
   mVincentyU1 = atan(m1MinF*tan(aLat1));
   mVincentyU2 = atan(m1MinF*tan(aLat2));
   aLon1 = getMod(aLon1, (GeoConversions::TWO_PI));
   aLon2 = getMod(aLon2, (GeoConversions::TWO_PI));
   mVincentyL = aLon2-aLon1;
   if (abs(mVincentyL) > PI)
   {
     mVincentyL = getSign(mVincentyL) * (GeoConversions::TWO_PI - abs(mVincentyL));
   }

   // Initialize Variables for Loop
   double sin_mVincentyU1 = sin(mVincentyU1);
   double cos_mVincentyU1 = cos(mVincentyU1);
   double sin_mVincentyU2 = sin(mVincentyU2);
   double cos_mVincentyU2 = cos(mVincentyU2);
   double sinU1_sinU2 = sin_mVincentyU1 * sin_mVincentyU2;
   double cosU1_sinU2 = cos_mVincentyU1 * sin_mVincentyU2;
   double sinU1_cosU2 = sin_mVincentyU1 * cos_mVincentyU2;
   double cosU1_cosU2 = cos_mVincentyU1 * cos_mVincentyU2;
   double sin_mVincentyLambda = 0;
   double cos_mVincentyLambda = 0;
   double cos_mVincentyAlpha = 0;
   double sin_mVincentySigma = 0;
   double cos_mVincentySigma = 0;
   double lLambdaOld = 0;
   long   lIterCount = 0;
   double lSinSigma = 0;
   double lCosSigma = 0;
   double c = 0;
   mVincentySigma = 0;
   mVincentyAlpha = 0;
   mVincentyCosToSigmaM = 0;
   mVincentyLambda = mVincentyL;

   // ?
   while ((!lIterCount) || abs((mVincentyLambda-lLambdaOld) > (1e-12)))
   {
      lIterCount += 1;
      if (lIterCount > 50)
      {
          mVincentyLambda = PI;
          break;
      }

      sin_mVincentyLambda = sin(mVincentyLambda);
      cos_mVincentyLambda = cos(mVincentyLambda);
      lLambdaOld = mVincentyLambda;
      lSinSigma = sqrt(pow(cos_mVincentyU2 * sin_mVincentyLambda, 2) +
         pow(cosU1_sinU2 - sinU1_cosU2 * cos_mVincentyLambda, 2));
      lCosSigma = sinU1_sinU2 + cosU1_cosU2 * cos_mVincentyLambda;
      mVincentySigma = atan2(lSinSigma, lCosSigma);
      sin_mVincentySigma = sin(mVincentySigma);
      cos_mVincentySigma = cos(mVincentySigma);
      mVincentyAlpha = asin(cosU1_cosU2 * sin_mVincentyLambda / sin_mVincentySigma);
      cos_mVincentyAlpha = cos(mVincentyAlpha);
      mVincentyCosToSigmaM = cos_mVincentySigma -  2 * sinU1_sinU2 / pow(cos_mVincentyAlpha, 2);
      c = mF/ 16 * pow(cos_mVincentyAlpha, 2) * (4 + mF * (4 - 3 * pow(cos_mVincentyAlpha, 2)));
      mVincentyLambda = mVincentyL + (1 - c) * mF * sin(mVincentyAlpha) * (mVincentySigma + c * sin_mVincentySigma *
         (mVincentyCosToSigmaM + c * cos_mVincentySigma * (-1 + 2 * pow(mVincentyCosToSigmaM, 2))));

      // Correct for convergence failure in the case of essentially
      // antipodal points
      if (mVincentyLambda > PI)
      {
          mVincentyLambda = PI;
          break;
      }
   }

   return true;
}
//---------------------
int fdct_wrapping_invsepangle(double XL1, double XL2, int nbangle, vector<CpxNumMat>& csc, CpxOffMat& Xhgh)
{
  typedef pair<int,int> intpair;
  map<intpair, fftwnd_plan> planmap;
  
  int XS1, XS2;  int XF1, XF2;  double XR1, XR2;	 fdct_wrapping_rangecompute(XL1, XL2, XS1, XS2, XF1, XF2, XR1, XR2);
  Xhgh.resize(XS1, XS2);
  
  int nbquadrants = 4;
  int nd = nbangle / 4;
  int wcnt = 0;
  
  //backup
  CpxOffMat Xhghb(Xhgh);
  double XL1b = XL1;  double XL2b = XL2;

  int qvec[] = {2,1,0,3};
  for(int qi=0; qi<nbquadrants; qi++) {
	 int q = qvec[qi];
	 //ROTATE data to its right position
	 fdct_wrapping_rotate_forward(q, XL1b, XL2b, XL1, XL2);	 XL1 = abs(XL1);	 XL2 = abs(XL2);
	 fdct_wrapping_rotate_forward(q, Xhghb, Xhgh);
	 //figure out XS, XF, XR
	 double XW1 = XL1/nd;	 double XW2 = XL2/nd;
	 int XS1, XS2;  int XF1, XF2;  double XR1, XR2;  fdct_wrapping_rangecompute(XL1, XL2, XS1, XS2, XF1, XF2, XR1, XR2);
	 for(int w=nd-1; w>=0; w--) {
		double xs = XR1/4 - (XW1/2)/4;
		double xe = XR1;
		double ys = -XR2 + (w-0.5)*XW2;
		double ye = -XR2 + (w+1.5)*XW2; //x range
		int xn = int(ceil(xe-xs));			 int yn = int(ceil(ye-ys));
		//MAKE THEM ODD
		if(xn%2==0) xn++;		if(yn%2==0) yn++;
		int xf = int(ceil(xs));			 //int yf = int(ceil(ys));
		//theta
		double thts, thtm, thte; //y direction
		if(w==0) {
		  thts = atan2(-1.0, 1.0-1.0/nd);
		  thtm = atan2(-1.0+1.0/nd, 1.0);
		  thte = atan2(-1.0+3.0/nd, 1.0);
		} else if(w==nd-1) {
		  thts = atan2(-1.0+(2.0*w-1.0)/nd, 1.0);
		  thtm = atan2(-1.0+(2.0*w+1.0)/nd, 1.0);
		  thte = atan2(1.0, 1.0-1.0/nd);
		} else {
		  thts = atan2(-1.0+(2.0*w-1.0)/nd, 1.0);
		  thtm = atan2(-1.0+(2.0*w+1.0)/nd, 1.0);
		  thte = atan2(-1.0+(2.0*w+3.0)/nd, 1.0);
		}
		int xh = xn/2;		int yh = yn/2; //half length
		CpxOffMat wpdata(xn,yn);

		{
		  //load
		  int xn = csc[wcnt].m();		  int yn = csc[wcnt].n();
		  CpxNumMat tpdata(csc[wcnt]);
		  //fft
		  fftwnd_plan p = NULL;
		  map<intpair, fftwnd_plan>::iterator mit=planmap.find( intpair(xn,yn) );
		  if(mit!=planmap.end()) {
			 p = (*mit).second;
		  } else {
			 p = fftw2d_create_plan(yn, xn, FFTW_FORWARD, FFTW_ESTIMATE | FFTW_IN_PLACE);
			 planmap[ intpair(xn, yn) ] = p;
		  }
		  fftwnd_one(p, (fftw_complex*)tpdata.data(), NULL);
		  double sqrtprod = sqrt(double(xn*yn));
		  for(int i=0; i<xn; i++)		  for(int j=0; j<yn; j++)			 tpdata(i,j) /= sqrtprod;
		  //fftshift
		  CpxOffMat rpdata;
		  fdct_wrapping_fftshift(tpdata,rpdata);
		  //rotate forward
		  fdct_wrapping_rotate_forward(q, rpdata, wpdata);
		}
		
		double R21 = XR2/XR1; //ratio
		for(int xcur=xf; xcur<xe; xcur++) { //for each layer
		  int yfm = (int)ceil( max(-XR2, R21*xcur*tan(thts)) );
		  int yto = (int)floor( min(XR2, R21*xcur*tan(thte)) );
		  for(int ycur=yfm; ycur<=yto; ycur++) {
			 int tmpx = xcur%xn;				  if(tmpx<-xh) tmpx+=xn;				  if(tmpx>=-xh+xn) tmpx-=xn;
			 int tmpy = ycur%yn;				  if(tmpy<-yh) tmpy+=yn;				  if(tmpy>=-yh+yn) tmpy-=yn;
			 //partition of unity
			 double thtcur = atan2(ycur/XR2, xcur/XR1);
			 double wtht;
			 if(thtcur<thtm) {
				double l,r; fdct_wrapping_window((thtcur-thts)/(thtm-thts), l, r);
				wtht = l;
			 } else {
				double l,r; fdct_wrapping_window((thtcur-thtm)/(thte-thtm), l, r);
				wtht = r;
			 }
			 double pou = wtht;
			 wpdata(tmpx,tmpy) *= pou;
			 Xhgh(xcur,ycur) += wpdata(tmpx,tmpy);
		  }
		}
		
		wcnt++;
	 }//w loop
	 fdct_wrapping_rotate_backward(q, Xhgh, Xhghb);
  } //q loop
  Xhgh = Xhghb;
  XL1 = XL1b;  XL2 = XL2b;

  assert(wcnt==nbangle);
  
  for(map<intpair, fftwnd_plan>::iterator mit=planmap.begin(); mit!=planmap.end(); mit++) {
	 fftwnd_plan p = (*mit).second;
	 fftwnd_destroy_plan(p);
  }
  return 0;
}
Example #27
0
/*
==============
CG_DrawSkyBoxPortal
==============
*/
void CG_DrawSkyBoxPortal( void ) {
	static float lastfov = 90;      // for transitions back from zoomed in modes
	refdef_t backuprefdef;
	float fov_x;
	float fov_y;
	float x;
	char *cstr;
	char *token;
	float zoomFov;
	float f;
	static qboolean foginited = qfalse; // only set the portal fog values once

	if ( !( cstr = (char *)CG_ConfigString( CS_SKYBOXORG ) ) || !strlen( cstr ) ) {
		// no skybox in this map
		return;
	}

	// if they are waiting at the mission stats screen, show the stats
	if ( cg_gameType.integer == GT_SINGLE_PLAYER ) {
		if ( strlen( cg_missionStats.string ) > 1 ) {
			return;
		}
	}

	backuprefdef = cg.refdef;

	if ( cg_skybox.integer ) {
		token = COM_ParseExt( &cstr, qfalse );
		if ( !token || !token[0] ) {
			CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring\n" );
		}
		cg.refdef.vieworg[0] = atof( token );

		token = COM_ParseExt( &cstr, qfalse );
		if ( !token || !token[0] ) {
			CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring\n" );
		}
		cg.refdef.vieworg[1] = atof( token );

		token = COM_ParseExt( &cstr, qfalse );
		if ( !token || !token[0] ) {
			CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring\n" );
		}
		cg.refdef.vieworg[2] = atof( token );

		token = COM_ParseExt( &cstr, qfalse );
		if ( !token || !token[0] ) {
			CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring\n" );
		}
		fov_x = atoi( token );

		if ( !fov_x ) {
			fov_x = 90;
		}


		// setup fog the first time, ignore this part of the configstring after that
		token = COM_ParseExt( &cstr, qfalse );
		if ( !token || !token[0] ) {
			CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring.  No fog state\n" );
		} else {
			vec4_t fogColor;
			int fogStart, fogEnd;

			if ( atoi( token ) ) {   // this camera has fog
				//			if(!foginited) {
				if ( 1 ) {
					token = COM_ParseExt( &cstr, qfalse );
					if ( !token || !token[0] ) {
						CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring.  No fog[0]\n" );
					}
					fogColor[0] = atof( token );

					token = COM_ParseExt( &cstr, qfalse );
					if ( !token || !token[0] ) {
						CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring.  No fog[1]\n" );
					}
					fogColor[1] = atof( token );

					token = COM_ParseExt( &cstr, qfalse );
					if ( !token || !token[0] ) {
						CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring.  No fog[2]\n" );
					}
					fogColor[2] = atof( token );

					token = COM_ParseExt( &cstr, qfalse );
					if ( !token || !token[0] ) {
						fogStart = 0;
					} else {
						fogStart = atoi( token );
					}

					token = COM_ParseExt( &cstr, qfalse );
					if ( !token || !token[0] ) {
						fogEnd = 0;
					} else {
						fogEnd = atoi( token );
					}

					trap_R_SetFog( FOG_PORTALVIEW, fogStart, fogEnd, fogColor[0], fogColor[1], fogColor[2], 1.1 );
					foginited = qtrue;
				}
			} else {
				if ( !foginited ) {
					trap_R_SetFog( FOG_PORTALVIEW, 0,0,0,0,0,0 ); // init to null
					foginited = qtrue;
				}
			}
		}

		//----(SA)	end


		if ( cg.predictedPlayerState.pm_type == PM_INTERMISSION ) {
			// if in intermission, use a fixed value
			fov_x = 90;
		} else {
			// user selectable
			if ( cgs.dmflags & DF_FIXED_FOV ) {
				// dmflag to prevent wide fov for all clients
				fov_x = 90;
			} else {
				fov_x = cg_fov.value;
				if ( fov_x < 1 ) {
					fov_x = 1;
				} else if ( fov_x > 160 ) {
					fov_x = 160;
				}
			}

			// account for zooms
			if ( cg.zoomval ) {
				zoomFov = cg.zoomval;   // (SA) use user scrolled amount

				if ( zoomFov < 1 ) {
					zoomFov = 1;
				} else if ( zoomFov > 160 ) {
					zoomFov = 160;
				}
			} else {
				zoomFov = lastfov;
			}

			// do smooth transitions for the binocs
			if ( cg.zoomedBinoc ) {        // binoc zooming in
				f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME;
				if ( f > 1.0 ) {
					fov_x = zoomFov;
				} else {
					fov_x = fov_x + f * ( zoomFov - fov_x );
				}
				lastfov = fov_x;
			} else if ( cg.zoomval ) {    // zoomed by sniper/snooper
				fov_x = cg.zoomval;
				lastfov = fov_x;
			} else {                    // binoc zooming out
				f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME;
				if ( f > 1.0 ) {
					fov_x = fov_x;
				} else {
					fov_x = zoomFov + f * ( fov_x - zoomFov );
				}
			}
		}

		if ( cg.weaponSelect == WP_SNOOPERSCOPE ) {
			cg.refdef.rdflags |= RDF_SNOOPERVIEW;
		} else {
			cg.refdef.rdflags &= ~RDF_SNOOPERVIEW;
		}

		if ( cg.snap->ps.persistant[PERS_HWEAPON_USE] ) {
			fov_x = 55;
		}

		x = cg.refdef.width / tan( fov_x / 360 * M_PI );
		fov_y = atan2( cg.refdef.height, x );
		fov_y = fov_y * 360 / M_PI;

		cg.refdef.fov_x = fov_x;
		cg.refdef.fov_y = fov_y;

		cg.refdef.rdflags |= RDF_SKYBOXPORTAL;
		cg.refdef.rdflags |= RDF_DRAWSKYBOX;

	} else {    // end if(cg_skybox.integer)

		cg.refdef.rdflags |= RDF_SKYBOXPORTAL;
		cg.refdef.rdflags &= ~RDF_DRAWSKYBOX;
	}


	cg.refdef.time = cg.time;

	// draw the skybox
	trap_R_RenderScene( &cg.refdef );

	cg.refdef = backuprefdef;
}
Example #28
0
void Game::setupViewpoint(SIDE side)
{
	//22.5 correspond à l'angle de vision du viewport divisé par 2, en degrés
	setupViewpoint(
		0.0,
		0.0,
		static_cast<float>(side * (world->getDepth() / 2 + Tools<float>::maximum(world->getHeight(), world->getWidth()) / (2 * tan(22.5 * Tools<int>::pi() / 180)))),
		0.0,
		0.0,
		1.0f
		);
}
Example #29
0
void turret_breach_think(edict_t * self)
{
    edict_t *ent;
    vec3_t current_angles;
    vec3_t delta;

    VectorCopy(self->s.angles, current_angles);
    AnglesNormalize(current_angles);

    AnglesNormalize(self->move_angles);
    if (self->move_angles[PITCH] > 180)
        self->move_angles[PITCH] -= 360;

    // clamp angles to mins & maxs
    if (self->move_angles[PITCH] > self->pos1[PITCH])
        self->move_angles[PITCH] = self->pos1[PITCH];
    else if (self->move_angles[PITCH] < self->pos2[PITCH])
        self->move_angles[PITCH] = self->pos2[PITCH];

    if ((self->move_angles[YAW] < self->pos1[YAW])
            || (self->move_angles[YAW] > self->pos2[YAW])) {
        float dmin, dmax;

        dmin = fabs(self->pos1[YAW] - self->move_angles[YAW]);
        if (dmin < -180)
            dmin += 360;
        else if (dmin > 180)
            dmin -= 360;
        dmax = fabs(self->pos2[YAW] - self->move_angles[YAW]);
        if (dmax < -180)
            dmax += 360;
        else if (dmax > 180)
            dmax -= 360;
        if (fabs(dmin) < fabs(dmax))
            self->move_angles[YAW] = self->pos1[YAW];
        else
            self->move_angles[YAW] = self->pos2[YAW];
    }

    VectorSubtract(self->move_angles, current_angles, delta);
    if (delta[0] < -180)
        delta[0] += 360;
    else if (delta[0] > 180)
        delta[0] -= 360;
    if (delta[1] < -180)
        delta[1] += 360;
    else if (delta[1] > 180)
        delta[1] -= 360;
    delta[2] = 0;

    if (delta[0] > self->speed * FRAMETIME)
        delta[0] = self->speed * FRAMETIME;
    if (delta[0] < -1 * self->speed * FRAMETIME)
        delta[0] = -1 * self->speed * FRAMETIME;
    if (delta[1] > self->speed * FRAMETIME)
        delta[1] = self->speed * FRAMETIME;
    if (delta[1] < -1 * self->speed * FRAMETIME)
        delta[1] = -1 * self->speed * FRAMETIME;

    VectorScale(delta, 1.0 / FRAMETIME, self->avelocity);

    self->nextthink = level.time + FRAMETIME;

    for (ent = self->teammaster; ent; ent = ent->teamchain)
        ent->avelocity[1] = self->avelocity[1];

    // if we have adriver, adjust his velocities
    if (self->owner) {
        float angle;
        float target_z;
        float diff;
        vec3_t target;
        vec3_t dir;

        // angular is easy, just copy ours
        self->owner->avelocity[0] = self->avelocity[0];
        self->owner->avelocity[1] = self->avelocity[1];

        // x & y
        angle = self->s.angles[1] + self->owner->move_origin[1];
        angle *= (M_PI * 2 / 360);
        target[0] =
            SnapToEights(self->s.origin[0] +
                         cos(angle) * self->owner->move_origin[0]);
        target[1] =
            SnapToEights(self->s.origin[1] +
                         sin(angle) * self->owner->move_origin[0]);
        target[2] = self->owner->s.origin[2];

        VectorSubtract(target, self->owner->s.origin, dir);
        self->owner->velocity[0] = dir[0] * 1.0 / FRAMETIME;
        self->owner->velocity[1] = dir[1] * 1.0 / FRAMETIME;

        // z
        angle = self->s.angles[PITCH] * (M_PI * 2 / 360);
        target_z =
            SnapToEights(self->s.origin[2] +
                         self->owner->move_origin[0] * tan(angle) +
                         self->owner->move_origin[2]);

        diff = target_z - self->owner->s.origin[2];
        self->owner->velocity[2] = diff * 1.0 / FRAMETIME;

        if (self->spawnflags & 65536) {
            turret_breach_fire(self);
            self->spawnflags &= ~65536;
        }
    }
}
Example #30
0
/**
 * \brief Calculate distance between two points
 * This function uses an algorithm for an oblate spheroid earth model.
 * The algorithm is described here: 
 * http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf
 * \return Distance in meters
 */
double nmea_distance_ellipsoid(
        const nmeaPOS *from_pos,    /**< From position in radians */
        const nmeaPOS *to_pos,      /**< To position in radians */
        double *from_azimuth,       /**< (O) azimuth at "from" position in radians */
        double *to_azimuth          /**< (O) azimuth at "to" position in radians */
        )
{
    /* All variables */
    double f, a, b, sqr_a, sqr_b;
    double L, phi1, phi2, U1, U2, sin_U1, sin_U2, cos_U1, cos_U2;
    double sigma, sin_sigma, cos_sigma, cos_2_sigmam, sqr_cos_2_sigmam, sqr_cos_alpha, lambda, sin_lambda, cos_lambda, delta_lambda;
    int remaining_steps; 
    double sqr_u, A, B, delta_sigma;

    /* Check input */
    NMEA_ASSERT(from_pos != 0);
    NMEA_ASSERT(to_pos != 0);

    if ((from_pos->lat == to_pos->lat) && (from_pos->lon == to_pos->lon))
    { /* Identical points */
        if ( from_azimuth != 0 )
            *from_azimuth = 0;
        if ( to_azimuth != 0 )
            *to_azimuth = 0;
        return 0;    
    } /* Identical points */

    /* Earth geometry */
    f = NMEA_EARTH_FLATTENING;
    a = NMEA_EARTH_SEMIMAJORAXIS_M;
    b = (1 - f) * a;
    sqr_a = a * a;
    sqr_b = b * b;

    /* Calculation */
    L = to_pos->lon - from_pos->lon;
    phi1 = from_pos->lat;
    phi2 = to_pos->lat;
    U1 = atan((1 - f) * tan(phi1));
    U2 = atan((1 - f) * tan(phi2));
    sin_U1 = sin(U1);
    sin_U2 = sin(U2);
    cos_U1 = cos(U1);
    cos_U2 = cos(U2);

    /* Initialize iteration */
    sigma = 0;
    sin_sigma = sin(sigma);
    cos_sigma = cos(sigma);
    cos_2_sigmam = 0;
    sqr_cos_2_sigmam = cos_2_sigmam * cos_2_sigmam;
    sqr_cos_alpha = 0;
    lambda = L;
    sin_lambda = sin(lambda);                            
    cos_lambda = cos(lambda);                       
    delta_lambda = lambda;
    remaining_steps = 20; 

    while ((delta_lambda > 1e-12) && (remaining_steps > 0)) 
    { /* Iterate */
        /* Variables */
        double tmp1, tmp2, sin_alpha, cos_alpha, C, lambda_prev;

        /* Calculation */
        tmp1 = cos_U2 * sin_lambda;
        tmp2 = cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda;  
        sin_sigma = sqrt(tmp1 * tmp1 + tmp2 * tmp2);                
        cos_sigma = sin_U1 * sin_U2 + cos_U1 * cos_U2 * cos_lambda;   
        sin_alpha = cos_U1 * cos_U2 * sin_lambda / sin_sigma;  
        cos_alpha = cos(asin(sin_alpha));                 
        sqr_cos_alpha = cos_alpha * cos_alpha;                     
        cos_2_sigmam = cos_sigma - 2 * sin_U1 * sin_U2 / sqr_cos_alpha;
        sqr_cos_2_sigmam = cos_2_sigmam * cos_2_sigmam; 
        C = f / 16 * sqr_cos_alpha * (4 + f * (4 - 3 * sqr_cos_alpha));
        lambda_prev = lambda; 
        sigma = asin(sin_sigma); 
        lambda = L + 
            (1 - C) * f * sin_alpha
            * (sigma + C * sin_sigma * (cos_2_sigmam + C * cos_sigma * (-1 + 2 * sqr_cos_2_sigmam)));                                                
        delta_lambda = lambda_prev - lambda; 
        if ( delta_lambda < 0 ) delta_lambda = -delta_lambda; 
        sin_lambda = sin(lambda);
        cos_lambda = cos(lambda);
        remaining_steps--; 
    }  /* Iterate */

    /* More calculation  */
    sqr_u = sqr_cos_alpha * (sqr_a - sqr_b) / sqr_b; 
    A = 1 + sqr_u / 16384 * (4096 + sqr_u * (-768 + sqr_u * (320 - 175 * sqr_u)));
    B = sqr_u / 1024 * (256 + sqr_u * (-128 + sqr_u * (74 - 47 * sqr_u)));
    delta_sigma = B * sin_sigma * ( 
        cos_2_sigmam + B / 4 * ( 
        cos_sigma * (-1 + 2 * sqr_cos_2_sigmam) -
        B / 6 * cos_2_sigmam * (-3 + 4 * sin_sigma * sin_sigma) * (-3 + 4 * sqr_cos_2_sigmam)
        ));

    /* Calculate result */
    if ( from_azimuth != 0 )
    {
        double tan_alpha_1 = cos_U2 * sin_lambda / (cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda);
        *from_azimuth = atan(tan_alpha_1);
    }
    if ( to_azimuth != 0 )
    {
        double tan_alpha_2 = cos_U1 * sin_lambda / (-sin_U1 * cos_U2 + cos_U1 * sin_U2 * cos_lambda);
        *to_azimuth = atan(tan_alpha_2);
    }

    return b * A * (sigma - delta_sigma);
}