Exemple #1
0
bool cGrCelestialBody::reposition( sgVec3 p, double angle, double rightAscension, double declination, double sol_dist )
{
    sgMat4 T1, T2, GST, RA, DEC;
    sgVec3 axis;
    sgVec3 v;

    sgMakeTransMat4( T1, p );

    sgSetVec3( axis, 0.0, 0.0, -1.0 );
    sgMakeRotMat4( GST, (float)angle, axis );

    sgSetVec3( axis, 0.0, 0.0, 1.0 );
    sgMakeRotMat4( RA, (float)((rightAscension * SGD_RADIANS_TO_DEGREES) - 90.0), axis );

    sgSetVec3( axis, 1.0, 0.0, 0.0 );
    sgMakeRotMat4( DEC, (float)(declination * SGD_RADIANS_TO_DEGREES), axis );

    sgSetVec3( v, 0.0, (float)sol_dist, 0.0 );
    sgMakeTransMat4( T2, v );

    sgMat4 TRANSFORM;
    sgCopyMat4( TRANSFORM, T1 );
    sgPreMultMat4( TRANSFORM, GST );
    sgPreMultMat4( TRANSFORM, RA );
    sgPreMultMat4( TRANSFORM, DEC );
    sgPreMultMat4( TRANSFORM, T2 );

    sgCoord skypos;
    sgSetCoord( &skypos, TRANSFORM );

    transform->setTransform( &skypos );

    return true;
}
Exemple #2
0
bool cGrSkyDome::reposition( sgVec3 p, double lon, double lat, double spin )
{
  sgMat4 T, LON, LAT, SPIN;
  sgVec3 axis;

  // Translate to view position
  sgMakeTransMat4( T, p );

  // Rotate to proper orientation
  sgSetVec3( axis, 0.0, 0.0, 1.0 );
  sgMakeRotMat4( LON, (float)(lon * SGD_RADIANS_TO_DEGREES), axis );

  sgSetVec3( axis, 0.0, 1.0, 0.0 );
  sgMakeRotMat4( LAT, (float)(90.0 - lat * SGD_RADIANS_TO_DEGREES), axis );

  sgSetVec3( axis, 0.0, 0.0, 1.0 );
  sgMakeRotMat4( SPIN, (float)(spin * SGD_RADIANS_TO_DEGREES), axis );

  sgMat4 TRANSFORM;

  sgCopyMat4( TRANSFORM, T );
  sgPreMultMat4( TRANSFORM, LON );
  sgPreMultMat4( TRANSFORM, LAT );
  sgPreMultMat4( TRANSFORM, SPIN );

  sgCoord skypos;
  sgSetCoord( &skypos, TRANSFORM );

  dome_transform->setTransform( &skypos );
  asl = - skypos.xyz[2];

  return true;
}
void IceFloe::build( int nsrcpnt, sgVec2 *srcpnt ) {
	sgVec2 c;	
	sgSetVec2( c, 0.0, 0.0 );
	int n=0,i;

	// find the centeroid
	for ( i = 0; i < nsrcpnt; i++) {

		c[0] += srcpnt[i][0];
		c[1] += srcpnt[i][1];
		n++;
	}

	if (n>0.00001) {
		c[0] /= n;
		c[1] /= n;
	}

	// make the points local
	pnts = new sgVec3[ nsrcpnt ];
	npnts = nsrcpnt;
	for ( i=0; i < nsrcpnt; i++) {				
		sgSetVec3( pnts[i], srcpnt[i][0] - c[0], 0.0, 
					        srcpnt[i][1] - c[1] );		
	}

	// set location
	sgSetVec3( pos, c[0], 0.0, c[1] );
}
bool cGrMoon::reposition(sgVec3 p, double angle, double moonrightAscension, double moondeclination, double moon_dist)
{
    sgMat4 T1, T2, GST, RA, DEC;
    sgVec3 axis;
    sgVec3 v;

    sgMakeTransMat4( T1, p );

    sgSetVec3( axis, 0.0, 0.0, -1.0 );
    sgMakeRotMat4( GST, angle, axis );
    sgSetVec3( axis, 0.0, 0.0, 1.0 );
    sgMakeRotMat4( RA, (moonrightAscension * SGD_RADIANS_TO_DEGREES) - 90.0, axis );
    sgSetVec3( axis, 1.0, 0.0, 0.0 );
    sgMakeRotMat4( DEC, moondeclination * SGD_RADIANS_TO_DEGREES, axis );
    sgSetVec3( v, 0.0, moon_dist, 0.0 );
    sgMakeTransMat4( T2, v );

    sgMat4 TRANSFORM;
    sgCopyMat4( TRANSFORM, T1 );
    sgPreMultMat4( TRANSFORM, GST );
    sgPreMultMat4( TRANSFORM, RA );
    sgPreMultMat4( TRANSFORM, DEC );
    sgPreMultMat4( TRANSFORM, T2 );

    sgCoord skypos;
    sgSetCoord( &skypos, TRANSFORM );

    moon_transform->setTransform( &skypos );

    return true;
}
TransIcelandicExpress::TransIcelandicExpress() {
	// constructor
	music = NULL;
	angle = 0.0;
	dot_init = false;

	sgSetVec3( cameraPos, 0.0f, 0.013f, -0.2f );

	sgSetVec4( light_pos, -1.0f, -1.0f, -1.0f, 0.0f );

	sgSetVec4( light_amb,  0.2f, 0.2f, 0.3f, 1.0f );
	sgSetVec4( light_diff, 1.0f, 1.0f, 0.8f, 1.0f );
	sgSetVec4( light_spec, 1.0f, 1.0f, 1.0f, 1.0f );

	sgSetVec4( ocean_diff, 0.4f, 0.5f, 0.7f, 1.0f );

	player = new Player();

	showHelp = true;

	roadX = 0;
	roadY = 0;

	loadLevel( "./gamedata/levels/tess2.txt" );
	//loadLevel( "./gamedata/levels/SimpleRoad.txt" );
	//loadLevel( "./gamedata/levels/Challenge2.txt" );
}
Exemple #6
0
//
// Update the position of the moon image in the sky
//
void CMoonImage::Reposition (sgVec3 p, double theta, double lst, double lat,
               double ra, double dec, double spin)
{
  sgMat4 LST, LAT, RA, DEC, D, SCALE, ECLIPTIC, SPIN;
  sgVec3 axis;
  sgVec3 v;

  // Create scaling matrix for moon illusion (appears larger near horizon)
  float scale = 1.0f;
  sgMakeIdentMat4 (SCALE);
  float maxMagnification = 0.5f;
  float minThreshold = DegToRad (80.0f);
  float maxThreshold = DegToRad (95.0f);
  float span = maxThreshold - minThreshold;
  if ((theta >= minThreshold) && (theta <= maxThreshold)) {
    sgMat4 I;
    sgMakeIdentMat4 (I);
    scale = 1.0f + (maxMagnification * (theta - minThreshold) / span);
    sgScaleMat4 (SCALE, I, scale);
  }

  // Rotation matrix for latitude
  sgSetVec3 (axis, -1.0f, 0, 0);
  sgMakeRotMat4 (LAT, 90.0f-(float)lat, axis);

  // Rotation matrix for local sidereal time, converted from h to deg
  sgSetVec3 (axis, 0, 0, -1.0f);
  sgMakeRotMat4 (LST, ((float)lst * 15), axis);

  // Rotation matrix for right ascension
  sgSetVec3 (axis, 0, 0, 1);
  sgMakeRotMat4 (RA, RadToDeg ((float)ra), axis);

  // Rotation matrix for declination
  sgSetVec3 (axis, 1, 0, 0);
  sgMakeRotMat4 (DEC, 90.0f - RadToDeg ((float)dec), axis);

  // Translate moon distance
  sgSetVec3 (v, 0, 0, distance);
  sgMakeTransMat4 (D, v);

  // Rotate to align moon equator with ecliptic
  sgSetVec3 (axis, 1.0f, 0, 0);
  sgMakeRotMat4 (ECLIPTIC, 90.0f, axis);

  /// Rotate the moon image accurately towards the sun position
  sgSetVec3 (axis, 0, 0, 1);
  sgMakeRotMat4 (SPIN, spin, axis);

  // Combine all transforms
  sgMakeIdentMat4 (T);
  sgPreMultMat4 (T, LAT);
  sgPreMultMat4 (T, LST);
  sgPreMultMat4 (T, RA);
  sgPreMultMat4 (T, DEC);
  sgPreMultMat4 (T, D);
  sgPreMultMat4 (T, ECLIPTIC);
  sgPreMultMat4 (T, SPIN);

}
void CRRCControlSurfaceAnimation::transformPoint(CRRCMath::Vector3& point)
{
  sgVec3 pnt_sg;

  sgSetVec3(pnt_sg, (float)point.r[0], (float)point.r[1], (float)point.r[2]);
  sgXformVec3(pnt_sg, current_transformation);

  point.r[0] = pnt_sg[SG_X];
  point.r[1] = pnt_sg[SG_Y];
  point.r[2] = pnt_sg[SG_Z];
}
/** \brief Create a rotation matrix
 *
 *  This function creates a rotation matrix from the original
 *  OpenGL glRotatef commands in CRRCAirplaneLaRCSim::draw().
 *
 *  \param m The matrix to be rotated
 *  \param phi Euler angle phi
 *  \param theta Euler angle theta
 *  \param psi Euler angle psi
 */
inline void makeOGLRotMat4(sgMat4 m, double phi, double theta, double psi)
{
  sgMat4 temp;
  sgVec3 rvec;
  
  //~ sgSetVec3(rvec, 0.0, 1.0, 0.0);
  //~ sgMakeRotMat4(temp, 90.0, rvec);
  //~ sgPreMultMat4(m, temp);
  
  sgSetVec3(rvec, 0.0, 1.0, 0.0);
  sgMakeRotMat4(temp, 180.0f - (float)psi * SG_RADIANS_TO_DEGREES, rvec);
  sgPreMultMat4(m, temp);
  
  sgSetVec3(rvec, -1.0, 0.0, 0.0);
  sgMakeRotMat4(temp, (float)theta * SG_RADIANS_TO_DEGREES, rvec);
  sgPreMultMat4(m, temp);
  
  sgSetVec3(rvec, 0.0, 0.0, 1.0);
  sgMakeRotMat4(temp, (float)phi * SG_RADIANS_TO_DEGREES, rvec);
  sgPreMultMat4(m, temp);
}
void TransIcelandicExpress::mouseMotion( int xrel, int yrel ) {
	// rotate the camera
	sgVec3 axis, oldCamPos;
	sgMat4 m;
	float rot_factor = 0.5;

	// change heading
	sgSetVec3( axis, 0.0, 1.0, 0.0 );
	sgMakeRotMat4( m, (float)xrel * rot_factor, axis ) ;

	sgXformVec3( cameraPos, m ) ;

	// change pitch
	sgSetVec3( axis, 1.0, 0.0, 0.0 );
	sgMakeRotMat4( m, (float)yrel * rot_factor, axis ) ;

	sgCopyVec3( oldCamPos, cameraPos );
	sgXformVec3( cameraPos, m ) ;

	// don't let the camera go below player
	if (cameraPos[1] < 0.0 ) {
		sgCopyVec3( cameraPos, oldCamPos );		
	}
}
Exemple #10
0
bool cGrStars::reposition( sgVec3 p, double angle )
{
  sgMat4 T1, GST;
  sgVec3 axis;

  sgMakeTransMat4( T1, p );

  sgSetVec3( axis, 0.0, 0.0, -1.0 );
  sgMakeRotMat4( GST, (float)angle, axis );

  sgMat4 TRANSFORM;
  sgCopyMat4( TRANSFORM, T1 );
  sgPreMultMat4( TRANSFORM, GST );

  sgCoord skypos;
  sgSetCoord( &skypos, TRANSFORM );

  stars_transform->setTransform( &skypos );

  return true;
}
/**
 *  Create a CRRCControlSurfaceAnimation object
 *
 *  Initialize the animation from an 
 *  <animation type="ControlSurface"> tag
 */
CRRCControlSurfaceAnimation::CRRCControlSurfaceAnimation(SimpleXMLTransfer *xml)
 : CRRCAnimation(new ssgTransform()), fallback_data(0.0f),
   eventAdapter(this, &CRRCControlSurfaceAnimation::axisValueCallback, Event::Input),
    aileron(0.0f), elevator(0.0f), rudder(0.0f), throttle(0.0f),
    spoiler(0.0f), flap(0.0f), retract(0.0f), pitch(0.0f)
{
  bool failed = false;
  
  // evaluate <object> tag
  SimpleXMLTransfer *map = xml->getChild("object", true);
  symbolic_name = map->getString("name", "no_name_set");
  max_angle = (float)(map->getDouble("max_angle", 0.0) * SG_RADIANS_TO_DEGREES);
  abs_max_angle = (float)fabs((double)max_angle);

  // find hinges and evaluate all <control> tags
  int num_controls = 0;
  int num_hinges = 0;
  for (int i = 0; i < xml->getChildCount(); i++)
  {
    SimpleXMLTransfer *child = xml->getChildAt(i);
    if (child->getName() == "hinge")
    {
      // found a <hinge> child
      sgVec3 pos;
      pos[SG_X] = (float)(-1 * child->getDouble("y", 0.0));
      pos[SG_Y] = (float)(-1 * child->getDouble("x", 0.0));
      pos[SG_Z] = (float)(-1 * child->getDouble("z", 0.0));
      if (num_hinges == 0)
      {
        sgCopyVec3(hinge_1, pos);
      }
      else if (num_hinges == 1)
      {
        sgCopyVec3(hinge_2, pos);
      }
      num_hinges++;
    }
    else if (child->getName() == "control")
    {
      // found a <control> child
      // The "*2" factor for each gain value scales the control input
      // values from -0.5...+0.5 to -1.0...+1.0. This saves one
      // float multiplication per mapping in the runtime update() routine.
      std::string mapping = child->getString("mapping", "NOTHING");
      float gain = (float)child->getDouble("gain", 1.0);
      if (mapping == "ELEVATOR")
      {
        datasource.push_back(&elevator);
        source_gain.push_back(gain * 2);
        num_controls++;
      }
      else if (mapping == "AILERON")
      {
        datasource.push_back(&aileron);
        source_gain.push_back(gain * 2);
        num_controls++;
      }
      else if (mapping == "THROTTLE")
      {
        datasource.push_back(&throttle);
        source_gain.push_back(gain * 2);
        num_controls++;
      }
      else if (mapping == "RUDDER")
      {
        datasource.push_back(&rudder);
        source_gain.push_back(gain * 2);
        num_controls++;
      }
      else if (mapping == "FLAP")
      {
        datasource.push_back(&flap);
        source_gain.push_back(gain * 2);
        num_controls++;
      }
      else if (mapping == "SPOILER")
      {
        datasource.push_back(&spoiler);
        source_gain.push_back(gain * 2);
        num_controls++;
      }
      else if (mapping == "RETRACT")
      {
        datasource.push_back(&retract);
        source_gain.push_back(gain * 2);
        num_controls++;
      }
      else if (mapping == "PITCH")
      {
        datasource.push_back(&pitch);
        source_gain.push_back(gain * 2);
        num_controls++;
      }
      else
      {
        std::cerr << "ControlSurfaceAnimation: ignoring <control> tag without mapping." << std::endl;
      }
      
    }
  }

  if (num_controls < 1)
  {
    std::cerr << "ControlSurfaceAnimation: found animation without proper <control> tag. Animation disabled." << std::endl;
    failed = true;
  }

  if (num_hinges < 2)
  {
    std::cerr << "ControlSurfaceAnimation: Must specify exactly two hinges!" << std::endl;
    failed = true;
  }
  else
  {
    if (num_hinges > 2)
    {
      std::cerr << "ControlSurfaceAnimation: Must specify exactly two hinges!" << std::endl;
      std::cerr << "ControlSurfaceAnimation: Ignoring excessive hinge tag(s)." << std::endl;
    }
    sgSubVec3(axis, hinge_2, hinge_1);
    if (sgLengthVec3(axis) < 0.001)
    {
      std::cerr << "ControlSurfaceAnimation: Insufficient spacing between hinges!" << std::endl;
      failed = true;
    }
  }

  if (failed)
  {
    std::cerr << "ControlSurfaceAnimation: Animation setup failed." << std::endl;
    // set to some non-critical defaults
    datasource.resize(1);
    datasource[0] = &fallback_data;
    source_gain.resize(1);
    source_gain[0] = 1.0;
    sgSetVec3(hinge_1, 0.0f, 0.0f, 0.0f);
    sgSetVec3(hinge_2, 1.0f, 0.0f, 0.0f);
    sgSubVec3(axis, hinge_2, hinge_1);
  }
  
  sgMakeIdentMat4(move_to_origin);
  move_to_origin[3][0] = -hinge_1[0];
  move_to_origin[3][1] = -hinge_1[1];
  move_to_origin[3][2] = -hinge_1[2];

  sgMakeTransMat4(move_back, hinge_1);

  realInit();
}
void
cGrCloudLayer::build( ssgSimpleState *cloud_state, float span, float elevation, float thickness, float transition )
{
  layer_span = span;
  layer_asl = elevation;
  layer_thickness = thickness;
  layer_transition = transition;

  scale = 4000.0;
  last_lon = last_lat = -999.0f;
  last_x = last_y = 0.0f;

  sgVec2 base;
  sgSetVec2( base, (float)grRandom(), (float)grRandom() );

  // build the cloud layer
  sgVec4 color;
  sgVec3 vertex;
  sgVec2 tc;

  const float layer_scale = layer_span / scale;
  const float mpi = SG_PI/4;
  const float alt_diff = layer_asl * 1.5f;

  for (int i = 0; i < 4; i++) 
  {
    if ( layer[i] != NULL ) 
    {
      layer_transform->removeKid(layer[i]); // automatic delete
    }

    vl[i] = new ssgVertexArray( 10 );
    cl[i] = new ssgColourArray( 10 );
    tl[i] = new ssgTexCoordArray( 10 );

    sgSetVec3( vertex, layer_span*(i-2)/2, -layer_span,
      (float)(alt_diff * (sin(i*mpi) - 2)) );

    sgSetVec2( tc, base[0] + layer_scale * i/4, base[1] );

    sgSetVec4( color, 1.0f, 1.0f, 1.0f, (i == 0) ? 0.0f : 0.15f );

    cl[i]->add( color );
    vl[i]->add( vertex );
    tl[i]->add( tc );

    for (int j = 0; j < 4; j++) 
    {
      sgSetVec3( vertex, layer_span*(i-1)/2, layer_span*(j-2)/2,
        (float)(alt_diff * (sin((i+1)*mpi) + sin(j*mpi) - 2)) );

      sgSetVec2( tc, base[0] + layer_scale * (i+1)/4,
        base[1] + layer_scale * j/4 );

      sgSetVec4( color, 1.0f, 1.0f, 1.0f,
        ( (j == 0) || (i == 3)) ?  
        ( (j == 0) && (i == 3)) ? 0.0f : 0.15f : 1.0f );

      cl[i]->add( color );
      vl[i]->add( vertex );
      tl[i]->add( tc );

      sgSetVec3( vertex, layer_span*(i-2)/2, layer_span*(j-1)/2,
        (float)(alt_diff * (sin(i*mpi) + sin((j+1)*mpi) - 2)) );

      sgSetVec2( tc, base[0] + layer_scale * i/4,
        base[1] + layer_scale * (j+1)/4 );

      sgSetVec4( color, 1.0f, 1.0f, 1.0f,
        ((j == 3) || (i == 0)) ?
        ((j == 3) && (i == 0)) ? 0.0f : 0.15f : 1.0f );
      cl[i]->add( color );
      vl[i]->add( vertex );
      tl[i]->add( tc );
    }

    sgSetVec3( vertex, layer_span*(i-1)/2, layer_span, 
      (float)(alt_diff * (sin((i+1)*mpi) - 2)) );

    sgSetVec2( tc, base[0] + layer_scale * (i+1)/4,
    base[1] + layer_scale );

    sgSetVec4( color, 1.0f, 1.0f, 1.0f, (i == 3) ? 0.0f : 0.15f );

    cl[i]->add( color );
    vl[i]->add( vertex );
    tl[i]->add( tc );

    layer[i] = new ssgVtxTable(GL_TRIANGLE_STRIP, vl[i], NULL, tl[i], cl[i]);
    layer_transform->addKid( layer[i] );

    layer[i]->setState( cloud_state );
  }

  // force a repaint of the sky colors with arbitrary defaults
  repaint( color );
}
bool cGrCloudLayer::reposition( sgVec3 p, sgVec3 up, double lon, double lat, double alt, double dt )
{
  sgMat4 T1, LON, LAT;
  sgVec3 axis;

  // combine p and asl (meters) to get translation offset
  sgVec3 asl_offset;
  sgCopyVec3( asl_offset, up );
  sgNormalizeVec3( asl_offset );
  if ( alt <= layer_asl ) 
  {
    sgScaleVec3( asl_offset, layer_asl );
  }
  else 
  {
    sgScaleVec3( asl_offset, layer_asl + layer_thickness );
  }
  sgAddVec3( asl_offset, p );

  // Translate to zero elevation
  sgMakeTransMat4( T1, asl_offset );

  // Rotate to proper orientation
  sgSetVec3( axis, 0.0, 0.0, 1.0 );
  sgMakeRotMat4( LON, (float)(lon * SGD_RADIANS_TO_DEGREES), axis );

  sgSetVec3( axis, 0.0, 1.0, 0.0 );
  sgMakeRotMat4( LAT, (float)(90.0 - lat * SGD_RADIANS_TO_DEGREES), axis );

  sgMat4 TRANSFORM;

  sgCopyMat4( TRANSFORM, T1 );
  sgPreMultMat4( TRANSFORM, LON );
  sgPreMultMat4( TRANSFORM, LAT );

  sgCoord layerpos;
  sgSetCoord( &layerpos, TRANSFORM );

  layer_transform->setTransform( &layerpos );

  // now calculate update texture coordinates
  if ( last_lon < -900 ) 
  {
    last_lon = lon;
    last_lat = lat;
  }

  double sp_dist = speed*dt;

  if ( lon != last_lon || lat != last_lat || sp_dist != 0 ) 
  {
    double course = 0.0, dist = 0.0;
    if ( lon != last_lon || lat != last_lat ) 
    {
	sgVec2 start, dest;
	sgSetVec2(start, (float)last_lon, (float)last_lat);
	sgSetVec2(dest, (float)lon, (float)lat);
	calc_gc_course_dist( dest, start, &course, &dist );
    }

    // calculate cloud movement
    double ax = 0.0, ay = 0.0, bx = 0.0, by = 0.0;

    if (dist > 0.0) 
    {
      ax = cos(course) * dist;
      ay = sin(course) * dist;
    }

    if (sp_dist > 0) 
    {
      bx = cos(-direction * SGD_DEGREES_TO_RADIANS) * sp_dist;
      by = sin(-direction * SGD_DEGREES_TO_RADIANS) * sp_dist;
    }

    float xoff = (float)((ax + bx) / (2 * scale));
    float yoff = (float)((ay + by) / (2 * scale));

    const float layer_scale = layer_span / scale;

    float *base, *tc;

    base = tl[0]->get( 0 );
    base[0] += xoff;

    if ( base[0] > -10.0 && base[0] < 10.0 ) 
    {
      base[0] -= (int)base[0];
    }
    else 
    {
      base[0] = 0.0;
	  ulSetError(UL_WARNING, "Warning: base1\n");
    }

    base[1] += yoff;

    if ( base[1] > -10.0 && base[1] < 10.0 ) 
    {
      base[1] -= (int)base[1];
    }
    else 
    {
      base[1] = 0.0;
	  ulSetError(UL_WARNING, "Warning: base2\n");
    }

    for (int i = 0; i < 4; i++) 
    {
      tc = tl[i]->get( 0 );
      sgSetVec2( tc, base[0] + layer_scale * i/4, base[1] );

      for (int j = 0; j < 4; j++) 
      {
        tc = tl[i]->get( j*2+1 );
        sgSetVec2( tc, base[0] + layer_scale * (i+1)/4,
        base[1] + layer_scale * j/4 );

        tc = tl[i]->get( (j+1)*2 );
        sgSetVec2( tc, base[0] + layer_scale * i/4,
        base[1] + layer_scale * (j+1)/4 );
      }

      tc = tl[i]->get( 9 );
      sgSetVec2( tc, base[0] + layer_scale * (i+1)/4,
      base[1] + layer_scale );
    }

    last_lon = lon;
    last_lat = lat;
  }

  return true;
}
bool cGrCloudLayer::repositionFlat( sgVec3 p, double dt )
{
  sgMat4 T1;

  // combine p and asl (meters) to get translation offset
  sgVec3 asl_offset;
  if ( p[SG_Z] <= layer_asl ) 
  {
    sgSetVec3( asl_offset, p[SG_X], p[SG_Y], layer_asl );
  }
  else 
  {
    sgSetVec3( asl_offset, p[SG_X], p[SG_Y], layer_asl + layer_thickness );
  }

  // Translate to elevation
  sgMakeTransMat4( T1, asl_offset );

  sgMat4 TRANSFORM;
  sgCopyMat4( TRANSFORM, T1 );

  sgCoord layerpos;
  sgSetCoord( &layerpos, TRANSFORM );

  layer_transform->setTransform( &layerpos );

  // now calculate update texture coordinates
  double sp_dist = speed*dt;

  if ( p[SG_X] != last_x || p[SG_Y] != last_y || sp_dist != 0 ) 
  {
    // calculate cloud movement
    double ax = 0.0, ay = 0.0, bx = 0.0, by = 0.0;

    ax = p[SG_X] - last_x;
    ay = p[SG_Y] - last_y;

    if (sp_dist > 0) 
    {
      bx = cos(-direction * SGD_DEGREES_TO_RADIANS) * sp_dist;
      by = sin(-direction * SGD_DEGREES_TO_RADIANS) * sp_dist;
    }

    float xoff = (float)((ax + bx) / (2 * scale));
    float yoff = (float)((ay + by) / (2 * scale));

    const float layer_scale = layer_span / scale;

    float *base, *tc;

    base = tl[0]->get( 0 );
    base[0] += xoff;

    // the while loops can lead to *long* pauses if base[0] comes
    // with a bogus value.
    // while ( base[0] > 1.0 ) { base[0] -= 1.0; }
    // while ( base[0] < 0.0 ) { base[0] += 1.0; }
    if ( base[0] > -10.0 && base[0] < 10.0 ) 
    {
      base[0] -= (int)base[0];
    }
    else 
    {
      base[0] = 0.0;
	  ulSetError(UL_WARNING, "Warning: base1\n");
    }

    base[1] += yoff;
    // the while loops can lead to *long* pauses if base[0] comes
    // with a bogus value.
    // while ( base[1] > 1.0 ) { base[1] -= 1.0; }
    // while ( base[1] < 0.0 ) { base[1] += 1.0; }
    if ( base[1] > -10.0 && base[1] < 10.0 ) 
    {
      base[1] -= (int)base[1];
    }
    else 
    {
      base[1] = 0.0;
	  ulSetError(UL_WARNING, "Warning: base2\n");
    }

    for (int i = 0; i < 4; i++) 
    {
      tc = tl[i]->get( 0 );
      sgSetVec2( tc, base[0] + layer_scale * i/4, base[1] );

      for (int j = 0; j < 4; j++) 
      {
        tc = tl[i]->get( j*2+1 );
        sgSetVec2( tc, base[0] + layer_scale * (i+1)/4,
        base[1] + layer_scale * j/4 );

        tc = tl[i]->get( (j+1)*2 );
        sgSetVec2( tc, base[0] + layer_scale * i/4,
        base[1] + layer_scale * (j+1)/4 );
      }

      tc = tl[i]->get( 9 );
      sgSetVec2( tc, base[0] + layer_scale * (i+1)/4,
      base[1] + layer_scale );
    }

    last_x = p[SG_X];
    last_y = p[SG_Y];
  }

  return true;
}
/** \brief The per-frame OpenGL display routine
 *
 *  This function does the complete OpenGL drawing. First
 *  the 3D scene is drawn, then some 2D overlays
 *  (wind and battery indicator, GUI).
 */
void display()
{
  CRRCMath::Vector3 plane_pos = FDM2Graphics(Global::aircraft->getPos());

  // Prepare the current frame buffer and reset
  // the modelview matrix (for non-SSG drawing)
  GLbitfield clearmask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
   if (vidbits.stencil)
    {
    clearmask |= GL_STENCIL_BUFFER_BIT;
    }
  glClear(clearmask);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glPushMatrix();
  //~ glBlendFunc(GL_ONE, GL_ZERO);
  //~ glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);

  // Set up the viewing transformation (for SSG drawing)
  sgVec3 viewpos, planepos, up;
  
  sgSetVec3(viewpos, player_pos.r[0], player_pos.r[1], player_pos.r[2]);                
  sgSetVec3(planepos, looking_pos.r[0], looking_pos.r[1], looking_pos.r[2]);
  sgSetVec3(up, 0.0, 1.0, 0.0);
  context->setCameraLookAt(viewpos, planepos, up);

  // 3D scene
  if( Global::scenery != NULL)
  {
    // 3D scene: sky sphere
    draw_sky(&viewpos, Global::Simulation->getTotalTime());
  
    // 3D scene: airplane
    if (Global::aircraft->getModel() != NULL)
    {
      // For SSG rendering, this call does not draw anything,
      // but calculates the airplane's transformation matrix
      glDisable(GL_TEXTURE_2D);
      glEnable(GL_LIGHTING);
      glEnable(GL_LIGHT0);
      Global::aircraft->getModel()->draw(Global::aircraft->getFDM());
    }
  
    // 3D scene: scenery
    Global::scenery->draw(Global::Simulation->getTotalTime());
  }
  // Lighting setup. Only needed as long as there are
  // non-SSG parts that modify the light sources.
  sgVec4 lightamb;
  sgSetVec4(lightamb , 0.2f, 0.2f, 0.2f, 1.0f);
  ssgGetLight(0)->setPosition(lightposn);
  ssgGetLight(0)->setColour(GL_AMBIENT, lightamb);

  // Draw the scenegraph (airplane model, shadow)
  ssgCullAndDraw(scene);
  context->forceBasicState();

  // ssgCullAndDraw() ends up with an identity modelview matrix,
  // so we have to set up our own viewing transformation for
  // the thermals
  glLoadIdentity();
  gluLookAt(player_pos.r[0], player_pos.r[1], player_pos.r[2],
            looking_pos.r[0], looking_pos.r[1], looking_pos.r[2],
            0.0, 1.0, 0.0);
  
  if (Global::training_mode==TRUE)
  {
    draw_thermals(Global::aircraft->getPos());
  }
  
  // 3D scene: game-mode-specific stuff (pylons etc.)
  Global::gameHandler->draw();

  glPopMatrix();


  // Overlay: game handler
  Global::gameHandler->display_infos(window_xsize, window_ysize);

  // Overlay: scope for audio interface
  if ( Global::testmode.test_mode
       &&
       (Global::TXInterface->inputMethod() == T_TX_Interface::eIM_audio) )
  {
    GlOverlay::setupRenderingState(window_xsize, window_ysize);
    oscillo();
    GlOverlay::restoreRenderingState();
  }

  // Overlay: wind direction indicator
  {
    double dx  = (plane_pos.r[2] - player_pos.r[2]);
    double dy  = (player_pos.r[0] - plane_pos.r[0]);
    double dir = atan2(dy, dx);

    GlOverlay::setupRenderingState(window_xsize, window_ysize);
    draw_wind(dir);
    GlOverlay::restoreRenderingState();
  }

  // Overlay: battery capacity/fuel left
  {
    int r   = window_ysize >> 5;
    int w   = r >> 1;
    int h   = window_ysize >> 3;
    int ht  = (int)(Global::aircraft->getFDM()->getBatCapLeft() * h);
                    
#if 0
    glDisable(GL_LIGHTING);
    glMatrixMode (GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity ();
    gluOrtho2D (0, window_xsize-1, 0, window_ysize);
#endif
    GlOverlay::setupRenderingState(window_xsize, window_ysize);
    
    // Background
    glColor3f (0, 0, 0);
    glRectf(window_xsize-w, r+ht,
            window_xsize-1, r+h);
    glTranslatef(0,0,0.1);
  
    // Indicator
    glColor3f (0, 1, 0.);
    glRectf(window_xsize-w, r,
            window_xsize-1, r+ht);
    
#if 0
    glPopMatrix();
    glEnable(GL_LIGHTING);    
    glMatrixMode(GL_MODELVIEW);
#endif
    GlOverlay::restoreRenderingState();

  }

  // Overlay: console
  console->render(window_xsize, window_ysize);
  
  // Overlay: gui
  Global::gui->draw();
  
  // check for any OpenGL errors
  evaluateOpenGLErrors();

  // Force pipeline flushing and flip front and back buffer
  glFlush();
  SDL_GL_SwapBuffers();
}
Exemple #16
0
// initialize the sky object and connect it into our scene graph
ssgBranch * cGrSkyDome::build( double hscale, double vscale )
{
  sgVec4 color;
  double theta;
  int i;

  // clean-up previous
  ssgDeRefDelete( dome_transform );

  // create new
  dome_transform = new ssgTransform;
  dome_transform->ref();

  // set up the state
  dome_state = new ssgSimpleState();
  dome_state->setShadeModel( GL_SMOOTH );
  dome_state->disable( GL_LIGHTING );
  dome_state->disable( GL_CULL_FACE );
  dome_state->disable( GL_TEXTURE_2D );
  dome_state->enable( GL_COLOR_MATERIAL );
  dome_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
  dome_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
  dome_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
  dome_state->disable( GL_BLEND );
  dome_state->disable( GL_ALPHA_TEST );

  // initialize arrays
  center_disk_vl = new ssgVertexArray( 14 );
  center_disk_cl = new ssgColourArray( 14 );

  upper_ring_vl = new ssgVertexArray( 26 );
  upper_ring_cl = new ssgColourArray( 26 );

  middle_ring_vl = new ssgVertexArray( 26 );
  middle_ring_cl = new ssgColourArray( 26 );

  lower_ring_vl = new ssgVertexArray( 26 );
  lower_ring_cl = new ssgColourArray( 26 );

  // initially seed to all blue
  sgSetVec4( color, 0.0, 0.0, 1.0, 1.0 );

  // generate the raw vertex data
  sgVec3 center_vertex;
  sgVec3 upper_vertex[12];
  sgVec3 middle_vertex[12];
  sgVec3 lower_vertex[12];
  sgVec3 bottom_vertex[12];

  sgSetVec3( center_vertex, 0.0, 0.0, (float)(center_elev * vscale));

  for ( i = 0; i < 12; i++ ) 
  {
    theta = (i * 30.0) * SGD_DEGREES_TO_RADIANS;

    sgSetVec3( upper_vertex[i],
      (float)(cos(theta) * upper_radius * hscale),
      (float)(sin(theta) * upper_radius * hscale),
      (float)(upper_elev * vscale));

    sgSetVec3( middle_vertex[i],
      (float)(cos(theta) * middle_radius * hscale),
      (float)(sin(theta) * middle_radius * hscale),
      (float)(middle_elev * vscale));

    sgSetVec3( lower_vertex[i],
      (float)(cos(theta) * lower_radius * hscale),
      (float)(sin(theta) * lower_radius * hscale),
      (float)(lower_elev * vscale));

    sgSetVec3( bottom_vertex[i],
      (float)(cos(theta) * bottom_radius * hscale),
      (float)(sin(theta) * bottom_radius * hscale),
      (float)(bottom_elev * vscale));
  }

  // generate the center disk vertex/color arrays
  center_disk_vl->add( center_vertex );
  center_disk_cl->add( color );
  for ( i = 11; i >= 0; i-- ) 
  {
    center_disk_vl->add( upper_vertex[i] );
    center_disk_cl->add( color );
  }
  center_disk_vl->add( upper_vertex[11] );
  center_disk_cl->add( color );

  // generate the upper ring
  for ( i = 0; i < 12; i++ ) 
  {
    upper_ring_vl->add( middle_vertex[i] );
    upper_ring_cl->add( color );

    upper_ring_vl->add( upper_vertex[i] );
    upper_ring_cl->add( color );
  }
  upper_ring_vl->add( middle_vertex[0] );
  upper_ring_cl->add( color );

  upper_ring_vl->add( upper_vertex[0] );
  upper_ring_cl->add( color );

  // generate middle ring
  for ( i = 0; i < 12; i++ ) 
  {
    middle_ring_vl->add( lower_vertex[i] );
    middle_ring_cl->add( color );

    middle_ring_vl->add( middle_vertex[i] );
    middle_ring_cl->add( color );
  }
  middle_ring_vl->add( lower_vertex[0] );
  middle_ring_cl->add( color );

  middle_ring_vl->add( middle_vertex[0] );
  middle_ring_cl->add( color );

  // generate lower ring
  for ( i = 0; i < 12; i++ ) 
  {
    lower_ring_vl->add( bottom_vertex[i] );
    lower_ring_cl->add( color );

    lower_ring_vl->add( lower_vertex[i] );
    lower_ring_cl->add( color );
  }
  lower_ring_vl->add( bottom_vertex[0] );
  lower_ring_cl->add( color );

  lower_ring_vl->add( lower_vertex[0] );
  lower_ring_cl->add( color );

  // force a repaint of the sky colors with ugly defaults
  sgVec3 fog_color;
  sgSetVec3( fog_color, 1.0, 1.0, 1.0 );
  repaint( color, fog_color, 0.0, 5000.0 );

  // build the ssg scene graph sub tree for the sky and connected
  // into the provide scene graph branch
  ssgVtxTable *center_disk, *upper_ring, *middle_ring, *lower_ring;

  center_disk = new ssgVtxTable( GL_TRIANGLE_FAN, 
  center_disk_vl, NULL, NULL, center_disk_cl );

  upper_ring = new ssgVtxTable( GL_TRIANGLE_STRIP, 
  upper_ring_vl, NULL, NULL, upper_ring_cl );

  middle_ring = new ssgVtxTable( GL_TRIANGLE_STRIP, 
  middle_ring_vl, NULL, NULL, middle_ring_cl );

  lower_ring = new ssgVtxTable( GL_TRIANGLE_STRIP, 
  lower_ring_vl, NULL, NULL, lower_ring_cl );

  center_disk->setState( dome_state );
  upper_ring->setState( dome_state );
  middle_ring->setState( dome_state );
  lower_ring->setState( dome_state );

  dome_transform->addKid( center_disk );
  dome_transform->addKid( upper_ring );
  dome_transform->addKid( middle_ring );
  dome_transform->addKid( lower_ring );

  // not entirely satisfying.  We are depending here that the first
  // thing we add to a parent is the first drawn
  center_disk->setCallback( SSG_CALLBACK_PREDRAW, grSkyDomePreDraw );
  center_disk->setCallback( SSG_CALLBACK_POSTDRAW, grSkyDomePostDraw );

  upper_ring->setCallback( SSG_CALLBACK_PREDRAW, grSkyDomePreDraw );
  upper_ring->setCallback( SSG_CALLBACK_POSTDRAW, grSkyDomePostDraw );

  middle_ring->setCallback( SSG_CALLBACK_PREDRAW, grSkyDomePreDraw );
  middle_ring->setCallback( SSG_CALLBACK_POSTDRAW, grSkyDomePostDraw );

  lower_ring->setCallback( SSG_CALLBACK_PREDRAW, grSkyDomePreDraw );
  lower_ring->setCallback( SSG_CALLBACK_POSTDRAW, grSkyDomePostDraw );

  return dome_transform;
}
//--------------------------------------------------------------------
Player::Player() : SceneObject() {
	sgSetVec3( vel, 0.0, 0.0, 0.0 );
}
Exemple #18
0
/*void CSkyManager::GetSkyDomeColour (float theta, float phi, float &r, float &g, float &b)
{
  // Set default fog colour
  // r = g = b = 0.0f;

  if (domeimage != NULL) domeimage->GetDomeColour (theta, phi, r, g, b);
}
*/
void CSkyManager::PreDraw (void)
{
  SPosition eyePos = globals->geop;
  double mjd = globals->tim->GetModifiedJulianDate ();
  double lst = globals->tim->GetLocalSiderealTime(eyePos.lon);

  // Convert camera eye position to cartesian coordinates
  SVector v;
  v = GeodToCartesian (eyePos);
  sgVec3 p;
  sgSetVec3 (p, (float)v.x, (float)v.y, (float)v.z);

  // Convert latitude and longitude to degrees for sky object repositioning
  double lat = eyePos.lat / 3600;
  double lon = eyePos.lon / 3600;

  /// \todo  Sun/moon positions only need to be recalculated infrequently, not
  ///   on every update cycle

  // Update ephemeris calculations for sun.  This needs to be done first since
  //   the sun elevation is needed to update the other celestial objects
  sol->UpdatePosition (mjd);

  // Update ephemeris calculations for other celestial objects
  moon->UpdatePosition (mjd, lst, lat, sol);

  /// \todo  Planet positions only need to be calculated once at situation start
  mercury->UpdatePosition (mjd, sol);
  venus->UpdatePosition (mjd, sol);
  mars->UpdatePosition (mjd, sol);
  jupiter->UpdatePosition (mjd, sol);
  saturn->UpdatePosition (mjd, sol);

  // Get solar zenith and azimuth angles
  
  calc_zenith_azimuth_angles (sol->GetRightAscension(), sol->GetDeclination(),
                              lat, lon,
                              &solTheta, &solPhi);

  double moonTheta, moonPhi;
  calc_zenith_azimuth_angles (moon->GetRightAscension(), moon->GetDeclination(),
                              lat, lon,
                              &moonTheta, &moonPhi);

  // Update sky lighting model
  skylight->Update (solTheta, solPhi, moonTheta, moonPhi);

  // DEBUG
//  char debug[80];
//  sprintf (debug, "solTheta=%7.3f deg, solPhi=%7.3f deg",
//    RadToDeg (solTheta), RadToDeg (solPhi));
//  DrawNoticeToUser (debug, 1);

  // Update appearance and position of sky dome
  domeimage->Repaint (solTheta, solPhi);

  // Update appearance and position of Sol
//  solimage->Repaint (solTheta);
//  solimage->Reposition (p, lst, lat,
//                      sol->GetRightAscension(), sol->GetDeclination(),
//                      skyDistance);

  // Update appearance and position of the Moon
  /// \todo  Orient moon towards sun using the 'spin' parameter
  moonimage->Repaint (moonTheta, moon->GetAge ());
  moonimage->Reposition (p, moonTheta, lst, lat,
                       moon->GetRightAscension(), moon->GetDeclination(), 0);

  // Determine limiting magnitude and ambient light factor for night sky objects
  float limit, factor;
  float limitLastUpdate = 10.0;
//  EDarkPhase phase = limitingMagnitude (solTheta, &limit, &factor);
  limitingMagnitude (solTheta, &limit, &factor);

  // If the limiting magnitude has changed by more than the preset value, repaint
  //   the stars and planets
  //  if (phase != old_phase) {
  if (fabs (limitLastUpdate - limit) > 0.1) {
    limitLastUpdate = limit;
    // Update appearance for all planets and stars
    mercuryimage->Repaint ((float)mercury->GetMagnitude (), limit, factor);
    venusimage->Repaint ((float)venus->GetMagnitude(), limit, factor);
    marsimage->Repaint ((float)mars->GetMagnitude(), limit, factor);
    jupiterimage->Repaint ((float)jupiter->GetMagnitude(), limit, factor);
    saturnimage->Repaint ((float)saturn->GetMagnitude(), limit, factor);
    starimage->Repaint (limit, factor);
  }

  // Update positions of all planets
  mercuryimage->Reposition (p, lst, lat,
                            mercury->GetRightAscension(), mercury->GetDeclination(),
                            skyDistance);
  venusimage->Reposition (p, lst, lat,
                          venus->GetRightAscension(), venus->GetDeclination(),
                          skyDistance);
  marsimage->Reposition (p, lst, lat,
                         mars->GetRightAscension(), mars->GetDeclination(),
                         skyDistance);
  jupiterimage->Reposition (p, lst, lat,
                            jupiter->GetRightAscension(), jupiter->GetDeclination(),
                            skyDistance);
  saturnimage->Reposition (p, lst, lat,
                           saturn->GetRightAscension(), saturn->GetDeclination(),
                           skyDistance);

  // Update positions of stars
  starimage->Reposition (p, lon, lat, lst);

  // Depth testing is disabled for all sky elements, therefore they must be drawn
  //   from "farthest" to "nearest"
  glPushAttrib (GL_DEPTH_BUFFER_BIT);
  glDisable (GL_DEPTH_TEST);

  // Draw sky sub-components
  domeimage->Draw ();
  starimage->Draw ();
  saturnimage->Draw ();
  jupiterimage->Draw ();
  marsimage->Draw ();
  venusimage->Draw ();
  mercuryimage->Draw ();

  // Sun and moon images temporarily left undrawn
  //solimage->Draw ();
  moonimage->Draw ();
  glPopAttrib ();
}
SceneObject::SceneObject() {
	sgSetVec3( pos, 0.0, 0.0, 0.0 );
	sgSetVec3( hpr, 0.0, 0.0, 0.0 );

	sgSetVec4( dbgDiffColor, 1.0, 0.5, 0.5, 1.0 );
}
void TransIcelandicExpress::simulate() {
	sgVec3 fwd, right, up, frict, v;
	sgVec3 playerForce;
	float cf_accel = 1.0,  // m/s^2 
		  maxVel = 0.5,    // m/2
		  cf_friction_land = 8.0,
		  cf_friction_ice = 5.0;
	float pv, 
		  ff; // friction fudge... more friction for slow objects

	float timestep = 0.01f;
	static float timeleft = 0.0f;	
	timeleft += deltaT;

	sgSetVec3( up, 0.0, 1.0, 0.0 );
	sgSetVec3( playerForce, 0.0, 0.0, 0.0 );	

	while (timeleft > timestep) {
		
		sgCopyVec3( fwd, cameraPos );
		sgNegateVec3( fwd );
		fwd[1] = 0.0;
		sgNormalizeVec3( fwd );
		sgVectorProductVec3( right, fwd, up );

		// todo: if on the ground
		sgScaleVec3( fwd, cf_moveForward );
		sgAddVec3( playerForce, fwd );

		sgScaleVec3( right, cf_moveSideways );
		sgAddVec3( playerForce, right );

		sgScaleVec3( playerForce, cf_accel * timestep );
		sgAddVec3( player->vel, playerForce );

		pv = sgLengthVec3( player->vel ) ;
		ff = (1.0 - ((pv / maxVel)* 0.8));
		ff = ff*ff;

		sgCopyVec3( frict, player->vel );
		sgNegateVec3( frict );
		sgScaleVec3( frict, ff * cf_friction_ice * timestep );	
		sgAddVec3( player->vel, frict );		
		
		dbgVel.push_back( pv );
		if (dbgVel.size() > 100 ) {
			dbgVel.pop_front();
		}
		
		if ( pv > maxVel ) {
			//printf("maxvel!\n" );
			sgNormalizeVec3( player->vel );
			sgScaleVec3( player->vel, maxVel );
		}

		sgCopyVec3( v, player->vel );
		sgScaleVec3( v, timestep );
		sgAddVec3( player->pos, v );
	
		// advance
		timeleft -= timestep;		
	}

	player->pos[1] = getHeight( player->pos );
}
void TransIcelandicExpress::loadLevel( const char *filename ) {
	FILE *fp = fopen( filename, "r" );
	char line[1000], cmd[100], type[100];
	IceFloe *floe;
	sgVec2 *pnt;
	float x, y;
	int num, npnt, i, j;

	// clear any floes
	for (std::vector<IceFloe*>::iterator floei=floes.begin();
		floei != floes.end(); floei++ ) {

		delete *floei;
	}
	floes.erase( floes.begin(), floes.end() );


	while (fgets( line, 1000, fp )) {
		if (line[0]=='#') continue;

		sscanf( line, "%s", cmd );
		if (!strcmp(cmd, "location")) {
			sscanf( line, "%*s %f %f %s\n", &x, &y, type );
			if (!strcmp( type, "StartPos" )) {
				sgSetVec3( player->pos, x, 0.05f, y );
				player->pos[1] = getHeight( player->pos );
			} else if (!strcmp( type, "Sheep" )) {
				SceneObject *shp;
				shp = new SceneObject();
				sgSetVec3( shp->pos, x, 0.05f, y );
				shp->pos[1] = getHeight( shp->pos );
				sgSetVec4( shp->dbgDiffColor, 0.8f, 0.8f, 0.8f, 1.0f );
				sheep.push_back( shp );
			} else if (!strcmp( type, "Crate" )) {
				SceneObject *crt;
				crt = new SceneObject();
				sgSetVec3( crt->pos, x, 0.05f, y );
				crt->pos[1] = getHeight( crt->pos );
				sgSetVec4( crt->dbgDiffColor, 1.0f, 0.9f, 0.4f, 1.0f );
				crates.push_back( crt );
			}

		} else if (!strcmp(cmd, "mapsize")) {

			// delete the old map if present
			for (j = 0; j < roadY; j++) {
				for (i = 0; i < roadX; i++) {
					delete road[i][j];
					road[i][j] = NULL;
				}
			}

			sscanf( line, "%*s %d %d", &roadX, &roadY );

			// make a new map
			for (j = 0; j < roadY; j++) {
				for (i = 0; i < roadX; i++) {				
					road[i][j] = new Road();
				}
			}
		} else if (!strcmp(cmd, "road_tiles")) {
			int pylon, roadway;

			sscanf( line, "%*s %d", &num );

			for (int n = 0; n < num; n++ ) {
				fgets( line, 1000, fp );
				sscanf( line, "%s %d %d %d %d", cmd, &i, &j, &roadway, &pylon ); 
				if (strcmp(cmd, "road")) {
					printf( "Error: Expecting 'road' got %s\n", line );
				} else {
					road[i][j]->pylon = pylon;
					road[i][j]->road = roadway;
					road[i][j]->base_height = c_RoadLevel * 0.5;

					sgSetVec3( road[i][j]->pos, float(i) + 0.5f, 0.0f, float(j) + 0.5f);
				}
			}

		} else if (!strcmp(cmd, "num_floes")) {
			sscanf( line, "%*s %d", &num );
			for (i = 0; i < num; i++) {
				fgets( line, 1000, fp );
				floe = new IceFloe();
				sscanf( line, "%s %f %f %d %d %s %d",
					cmd, &(floe->health), &(floe->height),
					&(floe->breakable), &(floe->anchored),
					type, &npnt );

				pnt = new sgVec2[ npnt ];
				for ( j = 0; j < npnt; j++ ) {
					fgets( line, 1000, fp );
					sscanf( line, "%f %f", &x, &y );
					pnt[j][0] = x;
					pnt[j][1] = y;
				}

				floe->build( npnt, pnt );
				delete [] pnt;

				floes.push_back( floe );
			}
		} else {
			printf ("Skipping command %s \n", cmd );
		}
	}
	
}
Exemple #22
0
bool cGrSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sol_angle, double vis )
{
  double diff, prev_sun_angle = 999.0;
  sgVec3 outer_param, outer_amt, outer_diff;
  sgVec3 middle_param, middle_amt, middle_diff;
  int i, j;

  if (prev_sun_angle == sol_angle)
        return true;

  prev_sun_angle = sol_angle;

  //sol_angle *= SGD_RADIANS_TO_DEGREES;

  // Check for sunrise/sunset condition
  if ((sol_angle > 80.0)) 
  { 
    sgSetVec3( outer_param,
      (float)((10.0 - fabs(90.0 - sol_angle)) / 20.0),
      (float)((10.0 - fabs(90.0 - sol_angle)) / 40.0),
      (float)(-(10.0 - fabs(90.0 - sol_angle)) / 30.0));

    sgSetVec3( middle_param,
      (float)((10.0 - fabs(90.0 - sol_angle)) / 40.0),
      (float)((10.0 - fabs(90.0 - sol_angle)) / 80.0),
      0.0 );

    sgScaleVec3( outer_diff, outer_param, 1.0f / 6.0f );

    sgScaleVec3( middle_diff, middle_param, 1.0f / 6.0f );
  }
  else 
  {
    sgSetVec3( outer_param, 0.0, 0.0, 0.0 );
    sgSetVec3( middle_param, 0.0, 0.0, 0.0 );

    sgSetVec3( outer_diff, 0.0, 0.0, 0.0 );
    sgSetVec3( middle_diff, 0.0, 0.0, 0.0 );
  }

  // calculate transition colors between sky and fog
  sgCopyVec3( outer_amt, outer_param );
  sgCopyVec3( middle_amt, middle_param );

  //
  // First, recalulate the basic colors
  //

  sgVec4 center_color;
  sgVec4 upper_color[12];
  sgVec4 middle_color[12];
  sgVec4 lower_color[12];
  sgVec4 bottom_color[12];

  double vis_factor, cvf = vis;

  if (cvf > 45000)
        cvf = 45000;

  vis_factor = (vis - 1000.0) / 2000.0;
  if ( vis_factor < 0.0 ) 
  {
        vis_factor = 0.0;
  } else if ( vis_factor > 1.0) 
  {
        vis_factor = 1.0;
  }

  for ( j = 0; j < 3; j++ ) 
  {
    diff = sky_color[j] - fog_color[j];
    center_color[j] = sky_color[j]; // - (float)(diff * ( 1.0 - vis_factor ));
  }

  for ( i = 0; i < 6; i++ ) 
  {
    for ( j = 0; j < 3; j++ ) 
    {
      double saif = sol_angle/SG_PI;
      diff = sky_color[j] - fog_color[j] * (0.8 + j * 0.2) * (0.8 + saif - ((6-i)/10));

      upper_color[i][j] = sky_color[j] - (float)(diff * ( 1.0 - vis_factor * (0.7 + 0.3 * cvf/45000)));
      middle_color[i][j] = sky_color[j] - (float)(diff * ( 1.0 - vis_factor * (0.1 + 0.85 * cvf/45000)))
			 + middle_amt[j];
      lower_color[i][j] = fog_color[j] + outer_amt[j];

      if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; }
      if ( upper_color[i][j] < 0.0 ) { upper_color[i][j] = 0.0; }
      if ( middle_color[i][j] > 1.0 ) { middle_color[i][j] = 1.0; }
      if ( middle_color[i][j] < 0.0 ) { middle_color[i][j] = 0.0; }
      if ( lower_color[i][j] > 1.0 ) { lower_color[i][j] = 1.0; }
      if ( lower_color[i][j] < 0.0 ) { lower_color[i][j] = 0.0; }
    }
    upper_color[i][3] = middle_color[i][3] = lower_color[i][3] = 1.0;

    for ( j = 0; j < 3; j++ ) 
    {
      outer_amt[j] -= outer_diff[j];
      middle_amt[j] -= middle_diff[j];
    }
  }

  sgSetVec3( outer_amt, 0.0, 0.0, 0.0 );
  sgSetVec3( middle_amt, 0.0, 0.0, 0.0 );

  for ( i = 6; i < 12; i++ ) 
  {
    for ( j = 0; j < 3; j++ ) 
    {
	  double saif = sol_angle/SG_PI;
      diff = (sky_color[j] - fog_color[j]) * (0.8 + j * 0.2) * (0.8 + saif - ((-i+12)/10));

      upper_color[i][j] = sky_color[j] - (float)(diff *
                                 ( 1.0 - vis_factor * (0.7 + 0.3 * cvf/45000)));
      middle_color[i][j] = sky_color[j] - (float)(diff *
                                 ( 1.0 - vis_factor * (0.1 + 0.85 * cvf/45000)))
								  + middle_amt[j];
      lower_color[i][j] = fog_color[j] + outer_amt[j];

      if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; }
      if ( upper_color[i][j] < 0.0 ) { upper_color[i][j] = 0.0; }
      if ( middle_color[i][j] > 1.0 ) { middle_color[i][j] = 1.0; }
      if ( middle_color[i][j] < 0.0 ) { middle_color[i][j] = 0.0; }
      if ( lower_color[i][j] > 1.0 ) { lower_color[i][j] = 1.0; }
      if ( lower_color[i][j] < 0.0 ) { lower_color[i][j] = 0.0; }
    }
    upper_color[i][3] = middle_color[i][3] = lower_color[i][3] = 1.0;

    for ( j = 0; j < 3; j++ ) 
    {
      outer_amt[j] += outer_diff[j];
      middle_amt[j] += middle_diff[j];
    }
  }

  fade_to_black( (sgVec4 *) center_color, asl * center_elev, 1);
  fade_to_black( upper_color, (asl+0.05f) * upper_elev, 12);
  fade_to_black( middle_color, (asl+0.05f) * middle_elev, 12);
  fade_to_black( lower_color, (asl+0.05f) * lower_elev, 12);

  for ( i = 0; i < 12; i++ ) 
  {
    sgCopyVec4( bottom_color[i], fog_color );
  }

  //
  // Second, assign the basic colors to the object color arrays
  //

  float *slot;
  int counter;

  // update the center disk color arrays
  counter = 0;
  slot = center_disk_cl->get( counter++ );
  // sgVec4 red;
  // sgSetVec4( red, 1.0, 0.0, 0.0, 1.0 );
  sgCopyVec4( slot, center_color );
  for ( i = 11; i >= 0; i-- ) 
  {
    slot = center_disk_cl->get( counter++ );
    sgCopyVec4( slot, upper_color[i] );
  }
  slot = center_disk_cl->get( counter++ );
  sgCopyVec4( slot, upper_color[11] );

  // generate the upper ring
  counter = 0;
  for ( i = 0; i < 12; i++ ) 
  {
    slot = upper_ring_cl->get( counter++ );
    sgCopyVec4( slot, middle_color[i] );

    slot = upper_ring_cl->get( counter++ );
    sgCopyVec4( slot, upper_color[i] );
  }
  slot = upper_ring_cl->get( counter++ );
  sgCopyVec4( slot, middle_color[0] );

  slot = upper_ring_cl->get( counter++ );
  sgCopyVec4( slot, upper_color[0] );

  // generate middle ring
  counter = 0;
  for ( i = 0; i < 12; i++ ) 
  {
    slot = middle_ring_cl->get( counter++ );
    sgCopyVec4( slot, lower_color[i] );

    slot = middle_ring_cl->get( counter++ );
    sgCopyVec4( slot, middle_color[i] );
  }
  slot = middle_ring_cl->get( counter++ );
  sgCopyVec4( slot, lower_color[0] );

  slot = middle_ring_cl->get( counter++ );
  sgCopyVec4( slot, middle_color[0] );

  // generate lower ring
  counter = 0;
  for ( i = 0; i < 12; i++ ) 
  {
    slot = lower_ring_cl->get( counter++ );
    sgCopyVec4( slot, bottom_color[i] );

    slot = lower_ring_cl->get( counter++ );
    sgCopyVec4( slot, lower_color[i] );
  }
  slot = lower_ring_cl->get( counter++ );
  sgCopyVec4( slot, bottom_color[0] );

  slot = lower_ring_cl->get( counter++ );
  sgCopyVec4( slot, lower_color[0] );

  return true;
}
Exemple #23
0
ssgBranch * cGrCelestialBody::build( ssgSimpleState *orb_state, ssgSimpleState *halo_state, double body_size )
{
    ssgVertexArray *halo_vl;
    ssgTexCoordArray *halo_tl;

    // clean-up previous
    ssgDeRefDelete( transform );

    // build the ssg scene graph sub tree for the sky and connected
    // into the provide scene graph branch
    transform = new ssgTransform;
    transform->ref();

    cl = new ssgColourArray( 1 );
    sgVec4 color;
    sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
    cl->add( color );

    ssgBranch *orb = grMakeSphere( orb_state, cl, (float)body_size, 15, 15,
                                   grCelestialBodyOrbPreDraw, grCelestialBodyOrbPostDraw );

    transform->addKid( orb );

    // force a repaint of the colors with arbitrary defaults
    repaint( 0.0 );

    if (halo_state)
    {
        // Build ssg structure
        float size = float(body_size * 10.0);
        sgVec3 v3;
        halo_vl = new ssgVertexArray;
        sgSetVec3( v3, -size, 0.0, -size );
        halo_vl->add( v3 );
        sgSetVec3( v3, size, 0.0, -size );
        halo_vl->add( v3 );
        sgSetVec3( v3, -size, 0.0,  size );
        halo_vl->add( v3 );
        sgSetVec3( v3, size, 0.0,  size );
        halo_vl->add( v3 );

        sgVec2 v2;
        halo_tl = new ssgTexCoordArray;
        sgSetVec2( v2, 0.0f, 0.0f );
        halo_tl->add( v2 );
        sgSetVec2( v2, 1.0, 0.0 );
        halo_tl->add( v2 );
        sgSetVec2( v2, 0.0, 1.0 );
        halo_tl->add( v2 );
        sgSetVec2( v2, 1.0, 1.0 );
        halo_tl->add( v2 );

        ssgLeaf *halo =
            new ssgVtxTable ( GL_TRIANGLE_STRIP, halo_vl, NULL, halo_tl, cl );
        halo->setState( halo_state );

        halo->setCallback( SSG_CALLBACK_PREDRAW, grCelestialBodyHaloPreDraw );
        halo->setCallback( SSG_CALLBACK_POSTDRAW, grCelestialBodyHaloPostDraw );

        transform->addKid( halo );
        //transform->addKid(new ssgaLensFlare);
    }

    return transform;
}
Exemple #24
0
//
// Update the position of the moon image in the sky
//
void CMoonImage::Reposition (sgVec3 p, double theta, double lst, double lat,
               double ra, double dec, double spin)
{
  sgMat4 LST, LAT, RA, DEC, D, SCALE, ECLIPTIC, SPIN;
  sgVec3 axis;
  sgVec3 v;

  // Create scaling matrix for moon illusion (appears larger near horizon)
  float scale = 1.0f;
  sgMakeIdentMat4 (SCALE);
  float maxMagnification = 0.5f;
  float minThreshold = DegToRad (80.0f);
  float maxThreshold = DegToRad (95.0f);
  float span = maxThreshold - minThreshold;
  if ((theta >= minThreshold) && (theta <= maxThreshold)) {
    sgMat4 I;
    sgMakeIdentMat4 (I);
    scale = 1.0f + (maxMagnification * (theta - minThreshold) / span);
    sgScaleMat4 (SCALE, I, scale);
  }

  // Rotation matrix for latitude
  sgSetVec3 (axis, -1.0f, 0, 0);
  sgMakeRotMat4 (LAT, 90.0f-(float)lat, axis);

  // Rotation matrix for local sidereal time, converted from h to deg
  sgSetVec3 (axis, 0, 0, -1.0f);
  sgMakeRotMat4 (LST, ((float)lst * 15), axis);

  // Rotation matrix for right ascension
  sgSetVec3 (axis, 0, 0, 1);
  sgMakeRotMat4 (RA, RadToDeg ((float)ra), axis);

  // Rotation matrix for declination
  sgSetVec3 (axis, 1, 0, 0);
  sgMakeRotMat4 (DEC, 90.0f - RadToDeg ((float)dec), axis);

  // Translate moon distance
  sgSetVec3 (v, 0, 0, distance);
  sgMakeTransMat4 (D, v);

  // Rotate to align moon equator with ecliptic
  sgSetVec3 (axis, 1.0f, 0, 0);
  sgMakeRotMat4 (ECLIPTIC, 90.0f, axis);

  /// Rotate the moon image accurately towards the sun position
  sgSetVec3 (axis, 0, 0, 1);
  sgMakeRotMat4 (SPIN, spin, axis);

  // Combine all transforms
  sgMakeIdentMat4 (T);
  sgPreMultMat4 (T, LAT);
  sgPreMultMat4 (T, LST);
  sgPreMultMat4 (T, RA);
  sgPreMultMat4 (T, DEC);
  sgPreMultMat4 (T, D);
  sgPreMultMat4 (T, ECLIPTIC);
  sgPreMultMat4 (T, SPIN);

/*
  char debug[256];
  double jd = CTimeManager::Instance().GetJulianDate();
  SDateTime dt = CTimeManager::Instance().GetLocalDateTime ();
  sprintf (debug, "JD=%f D=%d/%d/%d T=%d:%d RA=%f Dec=%f", jd,
    dt.date.year, dt.date.month, dt.date.day, dt.time.hour, dt.time.minute,
    RadToDeg(ra), RadToDeg(dec));
  DrawNoticeToUser (debug, 1);
*/
}
void IceFloe::drawGeom() {	
	int i, j;
	float h;

	h = height * TransIcelandicExpress::c_RoadLevel;	

	// draw the sides	
	sgVec3 edge, n, up;
	sgSetVec3( up, 0.0, 1.0, 0.0 );
	glBegin( GL_QUADS );
	for (j = npnts-1, i = 0; i < npnts; j=i++) {
		sgSetVec3( edge, pnts[j][0] - pnts[i][0], 0.0,
						 pnts[j][2] - pnts[i][2] );

		sgNormalizeVec3( edge );
		sgVectorProductVec3( n, edge, up );
	
		glNormal3f( n[0], n[1], n[2] );

		glVertex3f( pnts[i][0], h, pnts[i][2] );
		glVertex3f( pnts[j][0], h, pnts[j][2] );
		glVertex3f( pnts[j][0], 0.0, pnts[j][2] );
		glVertex3f( pnts[i][0], 0.0, pnts[i][2] );						
	}
	glEnd();

	// tesselate the top
	if (!tess.size()) {
		if (!gluTess) {

			gluTess = gluNewTess();
			gluTessCallback( gluTess, GLU_BEGIN,  (void(__stdcall *)(void))tessBegin );
			gluTessCallback( gluTess, GLU_END,    (void(__stdcall *)(void))tessEnd );
			gluTessCallback( gluTess, GLU_VERTEX, (void(__stdcall *)(void))tessVertex );
			gluTessCallback( gluTess, GLU_ERROR,  (void(__stdcall *)(void))tessError );
		}

		printf("Tesselating polygon....\n");
		floeToTess = this;

		gluBeginPolygon( gluTess );
		GLdouble *v;
		for (i = 0; i < npnts; i++) {
			pnts[i][1] = h;

			v = new GLdouble[4];
			v[0] = pnts[i][0]; 
			v[1] = pnts[i][1]; 
			v[2] = pnts[i][2];			

			printf("gluTessVertex %3.4f %3.4f %3.4f\n",
				v[0], v[1], v[2] );
			gluTessVertex( gluTess, v, pnts[i] );
		}
		printf("About to call end....\n");
		gluEndPolygon( gluTess );
		printf("Done.\n");

		floeToTess = NULL;
	} 

	// draw the top
	glNormal3f( 0.0, 1.0, 0.0 );
	glBegin( GL_TRIANGLES );	
	for (std::vector<TessTri*>::iterator ti = tess.begin();
		 ti != tess.end(); ti++ ) {

		glVertex3f( (*ti)->a[0], (*ti)->a[1], (*ti)->a[2] );
		glVertex3f( (*ti)->b[0], (*ti)->b[1], (*ti)->b[2] );
		glVertex3f( (*ti)->c[0], (*ti)->c[1], (*ti)->c[2] );

	}
	glEnd();

}
Exemple #26
0
ssgBranch * cGrStars::build( int num, sgdVec3 *star_data, double star_dist )
{
  sgVec4 color;

  // clean-up previous
  ssgDeRefDelete( stars_transform );

  // create new
  stars_transform = new ssgTransform;
  stars_transform->ref();

  if ( star_data == NULL )
  {
	  if (num > 0)
		  ulSetError(UL_WARNING, "null star data passed to cGrStars::build()");
	  else
		  return stars_transform;
  }

  // set up the orb state
  state = new ssgSimpleState();
  state->disable( GL_LIGHTING );
  state->disable( GL_CULL_FACE );
  state->disable( GL_TEXTURE_2D );
  state->enable( GL_COLOR_MATERIAL );
  state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
  state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
  state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
  state->enable( GL_BLEND );
  state->disable( GL_ALPHA_TEST );

  vl = new ssgVertexArray( num );
  cl = new ssgColourArray( num );
  // cl = new ssgColourArray( 1 );
  // sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
  // cl->add( color );

  // Build ssg structure
  sgVec3 p;
  for ( int i = 0; i < num; ++i ) 
  {
    // position seeded to arbitrary values
    sgSetVec3( p, 
      (float)( star_dist * cos( star_data[i][0] )
        * cos( star_data[i][1] )),
      (float)( star_dist * sin( star_data[i][0] )
        * cos( star_data[i][1] )),
      (float)( star_dist * sin( star_data[i][1] )));
    vl->add( p );

    // color (magnitude)
    sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
    cl->add( color );
  }

  ssgLeaf *stars_obj = 
    new ssgVtxTable ( GL_POINTS, vl, NULL, NULL, cl );
  stars_obj->setState( state );
  stars_obj->setCallback( SSG_CALLBACK_PREDRAW, grStarPreDraw );
  stars_obj->setCallback( SSG_CALLBACK_POSTDRAW, grStarPostDraw );

  stars_transform->addKid( stars_obj );

  return stars_transform;
}
Exemple #27
0
ssgBranch *grMakeSphere(
  ssgSimpleState *state, ssgColourArray *cl,
  float radius, int slices, int stacks,
  ssgCallback predraw, ssgCallback postdraw )
{
  double rho, drho, theta, dtheta;
  float x, y, z;
  float s, t, ds, dt;
  int i, j, imin, imax;
  float nsign = 1.0;
  ssgBranch *sphere = new ssgBranch;
  sgVec2 vec2;
  sgVec3 vec3;

  drho = SGD_PI / (float)stacks;
  dtheta = (2.0 * SGD_PI) / (float)slices;

  /* texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y
     axis t goes from -1.0/+1.0 at z = -radius/+radius (linear along
     longitudes) cannot use triangle fan on texturing (s coord. at
     top/bottom tip varies) */

  ds = 1.0f / slices;
  dt = 1.0f / stacks;
  t = 1.0;  /* because loop now runs from 0 */
  imin = 0;
  imax = stacks;

  /* build slices as quad strips */
  for ( i = imin; i < imax; i++ ) 
  {
    ssgVertexArray   *vl = new ssgVertexArray();
    ssgNormalArray   *nl = new ssgNormalArray();
    ssgTexCoordArray *tl = new ssgTexCoordArray();

    rho = i * drho;
    s = 0.0;
    for ( j = 0; j <= slices; j++ ) 
    {
      theta = (j == slices) ? 0.0 : j * dtheta;
      x = (float)(-sin(theta) * sin(rho));
      y = (float)(cos(theta) * sin(rho));
      z = (float)(nsign * cos(rho));

      sgSetVec3( vec3, x*nsign, y*nsign, z*nsign );
      sgNormalizeVec3( vec3 );
      nl->add( vec3 );

      sgSetVec2( vec2, s, t );
      tl->add( vec2 );

      sgSetVec3( vec3, x*radius, y*radius, z*radius );
      vl->add( vec3 );

      x = (float)(-sin(theta) * sin(rho+drho));
      y = (float)(cos(theta) * sin(rho+drho));
      z = (float)(nsign * cos(rho+drho));

      sgSetVec3( vec3, x*nsign, y*nsign, z*nsign );
      sgNormalizeVec3( vec3 );
      nl->add( vec3 );

      sgSetVec2( vec2, s, t-dt );
      tl->add( vec2 );
      s += ds;

      sgSetVec3( vec3, x*radius, y*radius, z*radius );
      vl->add( vec3 );
    }

    ssgLeaf *slice = 
      new ssgVtxTable ( GL_TRIANGLE_STRIP, vl, nl, tl, cl );

    if ( vl->getNum() != nl->getNum() ) 
    {
      ulSetError(UL_FATAL, "bad sphere1\n");
      exit(-1);
    }
    if ( vl->getNum() != tl->getNum() ) 
    {
      ulSetError(UL_FATAL, "bad sphere2\n");
      exit(-1);
    }
    slice->setState( state );
    slice->setCallback( SSG_CALLBACK_PREDRAW, predraw );
    slice->setCallback( SSG_CALLBACK_POSTDRAW, postdraw );

    sphere->addKid( slice );

    t -= dt;
  }

  return sphere;
}