Ejemplo n.º 1
0
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;
}
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 );
}