示例#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;
}
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;
}
示例#3
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;
}
示例#4
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;
}
示例#5
0
static ssgTransform *initWheel(tCarElt *car, int wheel_index)
{
	int		i, j, k;
	float	alpha;
	sgVec3	vtx;
	sgVec4	clr;
	sgVec3	nrm;
	sgVec2	tex;
	tdble	b_offset = 0.0f;
	tdble	curAngle = 0.0f;

#define BRK_BRANCH	16
#define BRK_ANGLE	(2.0 * M_PI / (tdble)BRK_BRANCH)
#define BRK_OFFSET	0.2

	switch(wheel_index) {
		case FRNT_RGT:
			curAngle = -(M_PI / 2.0 + BRK_ANGLE);
			b_offset = BRK_OFFSET - car->_tireWidth(wheel_index) / 2.0;
			break;
		case FRNT_LFT:
			curAngle = -(M_PI / 2.0 + BRK_ANGLE);
			b_offset = car->_tireWidth(wheel_index) / 2.0 - BRK_OFFSET;
			break;
		case REAR_RGT:
			curAngle = (M_PI / 2.0 - BRK_ANGLE);
			b_offset = BRK_OFFSET - car->_tireWidth(wheel_index) / 2.0;
			break;
		case REAR_LFT:
			curAngle = (M_PI / 2.0 - BRK_ANGLE);
			b_offset = car->_tireWidth(wheel_index) / 2.0 - BRK_OFFSET;
			break;
	}

	/* hub */
	ssgVertexArray	*brk_vtx = new ssgVertexArray(BRK_BRANCH + 1);
	ssgColourArray	*brk_clr = new ssgColourArray(1);
	ssgNormalArray	*brk_nrm = new ssgNormalArray(1);
	tdble hubRadius;
	
	/* center */
	vtx[0] = vtx[2] = 0.0;
	vtx[1] = b_offset;
	brk_vtx->add(vtx);
	
	hubRadius = car->_brakeDiskRadius(wheel_index) * 0.6;
	for (i = 0; i < BRK_BRANCH; i++) {
		alpha = (float)i * 2.0 * M_PI / (float)(BRK_BRANCH - 1);
		vtx[0] = hubRadius * cos(alpha);
		vtx[1] = b_offset;
		vtx[2] = hubRadius * sin(alpha);
		brk_vtx->add(vtx);
	}
	

	clr[0] = clr[1] = clr[2] = 0.0;
	clr[3] = 1.0;
	brk_clr->add(clr);
	nrm[0] = nrm[2] = 0.0;

	// Make normal point outside to have proper lighting.
	switch(wheel_index) {
		case FRNT_RGT:
		case REAR_RGT:
			nrm[1] = -1.0;
			break;
		case FRNT_LFT:
		case REAR_LFT:
			nrm[1] = 1.0;
			break;
	}

	brk_nrm->add(nrm);

	ssgVtxTable *brk = new ssgVtxTable(GL_TRIANGLE_FAN, brk_vtx, brk_nrm, NULL, brk_clr);
	brk->setCullFace(0);
	brk->setState(commonState);

	ssgTransform *wheel = new ssgTransform;
	wheel->addKid(brk);

	/* Brake disk */
	brk_vtx = new ssgVertexArray(BRK_BRANCH + 4);
	brk_clr = new ssgColourArray(1);
	brk_nrm = new ssgNormalArray(1);

	for (i = 0; i < (BRK_BRANCH / 2 + 2); i++) {
		alpha = curAngle + (float)i * 2.0 * M_PI / (float)(BRK_BRANCH - 1);
		vtx[0] = car->_brakeDiskRadius(wheel_index) * cos(alpha);
		vtx[1] = b_offset;
		vtx[2] = car->_brakeDiskRadius(wheel_index) * sin(alpha);
		brk_vtx->add(vtx);
		vtx[0] = car->_brakeDiskRadius(wheel_index) * cos(alpha) * 0.6;
		vtx[1] = b_offset;
		vtx[2] = car->_brakeDiskRadius(wheel_index) * sin(alpha) * 0.6;
		brk_vtx->add(vtx);
	}
	

	clr[0] = clr[1] = clr[2] = 0.1;
	clr[3] = 1.0;
	brk_clr->add(clr);
	//nrm[0] = nrm[2] = 0.0;
	//nrm[1] = 1.0;
	brk_nrm->add(nrm);
	
	brk = new ssgVtxTable(GL_TRIANGLE_STRIP, brk_vtx, brk_nrm, NULL, brk_clr);
	brk->setCullFace(0);
	brk->setState(brakeState);
	grCarInfo[grCarIndex].brkColor[wheel_index] = brk_clr;

	wheel->addKid(brk);

	/* Brake caliper */
	brk_vtx = new ssgVertexArray(BRK_BRANCH - 4);
	brk_clr = new ssgColourArray(1);
	brk_nrm = new ssgNormalArray(1);

	for (i = 0; i < (BRK_BRANCH / 2 - 2); i++) {
		alpha = - curAngle + (float)i * 2.0 * M_PI / (float)(BRK_BRANCH - 1);
		vtx[0] = (car->_brakeDiskRadius(wheel_index) + 0.02) * cos(alpha);
		vtx[1] = b_offset;
		vtx[2] = (car->_brakeDiskRadius(wheel_index) + 0.02) * sin(alpha);
		brk_vtx->add(vtx);
		vtx[0] = car->_brakeDiskRadius(wheel_index) * cos(alpha) * 0.6;
		vtx[1] = b_offset;
		vtx[2] = car->_brakeDiskRadius(wheel_index) * sin(alpha) * 0.6;
		brk_vtx->add(vtx);
	}
	

	clr[0] = 0.2;
	clr[1] = 0.2;
	clr[2] = 0.2;
	clr[3] = 1.0;
	brk_clr->add(clr);
	//nrm[0] = nrm[2] = 0.0;
	//nrm[1] = 1.0;
	brk_nrm->add(nrm);

	brk = new ssgVtxTable(GL_TRIANGLE_STRIP, brk_vtx, brk_nrm, NULL, brk_clr);
	brk->setCullFace(0);
	brk->setState(commonState);

	wheel->addKid(brk);

	DBG_SET_NAME(wheel, "Wheel", grCarIndex, wheel_index);

	grCarInfo[grCarIndex].wheelPos[wheel_index] = wheel;

	/* wheels */
	ssgTransform *whrotation = new ssgTransform;
	grCarInfo[grCarIndex].wheelRot[wheel_index] = whrotation;
	wheel->addKid(whrotation);
	ssgSelector *whselector = new ssgSelector;
	whrotation->addKid(whselector);
	grCarInfo[grCarIndex].wheelselector[wheel_index] = whselector;

	float	wheelRadius = car->_rimRadius(wheel_index) + car->_tireHeight(wheel_index);

	// Create wheels for 4 speeds (stillstanding - fast --> motion blur, look at the texture).
	for (j = 0; j < 4; j++) {
		ssgBranch *whl_branch = new ssgBranch;
		ssgEntity *whl3d = 0;

		// load speed-dependant 3D wheels if available and if detailed wheels are desired.
		// wheel data files are located in the wheels directory. first set directory.
		if (grUseDetailedWheels == DETAILED) {
			const int bufsize = 1024;
			char buf[bufsize];
			const char* wheel_dir = GfParmGetStr(car->_carHandle, SECT_GROBJECTS, PRM_WHEEL_3D_DIR, 0);
			if (wheel_dir != 0) {
				snprintf(buf, bufsize, "wheels/%s", wheel_dir);
				ssgModelPath(buf);
				ssgTexturePath(buf);
			}
			
			// set basename for wheel file 0..3 gets appended
			const char* wheel_obj = GfParmGetStr(car->_carHandle, SECT_GROBJECTS, PRM_WHEEL_3D, 0);
			if (wheel_obj != 0 && wheel_dir != 0) {
				snprintf(buf, bufsize, "%s%d.acc", wheel_obj, j);
				whl3d = grssgCarLoadAC3D(buf, NULL, car->index);
			}
		}
		
		// if we have a 3D wheel, use it.  otherwise use normal generated wheel...
		if (whl3d) {
			// Adapt size of the wheel
			ssgTransform *whl_size = new ssgTransform;
			sgMat4 wheelsz;

			sgSetVec4(wheelsz[0], wheelRadius * 2, SG_ZERO, SG_ZERO, SG_ZERO) ;
			sgSetVec4(wheelsz[1], SG_ZERO, car->_tireWidth(wheel_index), SG_ZERO, SG_ZERO) ;
			sgSetVec4(wheelsz[2], SG_ZERO, SG_ZERO, wheelRadius * 2, SG_ZERO) ;
			sgSetVec4(wheelsz[3], SG_ZERO, SG_ZERO, SG_ZERO, SG_ONE) ;

			whl_size->setTransform(wheelsz);

			whl_size->addKid(whl3d);
			whl3d = whl_size;

			if (wheel_index == FRNT_RGT || wheel_index == REAR_RGT) {
				// flip wheel around so it faces the right way
				ssgTransform *whl_mesh_transform = new ssgTransform;
				sgCoord wheelpos;
				sgSetCoord(&wheelpos, 0, 0, 0, 180, 0, 0);
				whl_mesh_transform->setTransform( &wheelpos);
				whl_mesh_transform->addKid(whl3d);
				whl_branch->addKid(whl_mesh_transform);
			} else {
				whl_branch->addKid(whl3d);
			}
		} else {
			static sgVec2	toffset[4] = { {0.0, 0.5}, {0.5, 0.5}, {0.0, 0.0}, {0.5, 0.0} };
            // TORCS's standard generated wheel
			const int WHL_BRANCH = 16;

			/* Tread */
			{
				ssgVertexArray	*whl_vtx = new ssgVertexArray(2 * WHL_BRANCH);
				ssgColourArray	*whl_clr = new ssgColourArray(2 * WHL_BRANCH);
				ssgNormalArray	*whl_nrm = new ssgNormalArray(1);

				whl_nrm->add(nrm);
				clr[3] = 1.0;
				for (i = 0; i < WHL_BRANCH; i++) {
					alpha = (float)i * 2.0 * M_PI / (float)(WHL_BRANCH - 1);
					vtx[0] = wheelRadius * cos(alpha);
					vtx[2] = wheelRadius * sin(alpha);
					vtx[1] = - car->_tireWidth(wheel_index) / 2.0;
					whl_vtx->add(vtx);
					vtx[1] = car->_tireWidth(wheel_index) / 2.0;
					whl_vtx->add(vtx);
					if (i % 2) {
						clr[0] = clr[1] = clr[2] = 0.15;
					} else {
						clr[0] = clr[1] = clr[2] = 0.0;
					}
					whl_clr->add(clr);
					whl_clr->add(clr);
				}
				ssgVtxTable *whl = new ssgVtxTable(GL_TRIANGLE_STRIP, whl_vtx, whl_nrm, NULL, whl_clr);
				whl->setState(commonState);
				whl->setCullFace(0);

					// stripify wheel, should improve performance
					ssgStripify(whl);

				whl_branch->addKid(whl);
			}

			/* Rim */
			switch(wheel_index) {
				case FRNT_RGT:
				case REAR_RGT:
					b_offset = -0.05;
					break;
				case FRNT_LFT:
				case REAR_LFT:
					b_offset = 0.05;
					break;
			}

			// Make inside rim very dark and take care of normals.
			float colorfactor[2];
			float norm_orig = nrm[1];

			if (nrm[1] > 0.0f) {
				colorfactor[0] = 0.3f;
				colorfactor[1] = 1.0f;
				nrm[1] *= -1.0f;
			} else {
				colorfactor[0] = 1.0f;
				colorfactor[1] = 0.3f;
			}

			for (k = 0; k < 2; k++) {
				ssgVertexArray	*whl_vtx = new ssgVertexArray(WHL_BRANCH + 1);
				ssgTexCoordArray	*whl_tex = new ssgTexCoordArray(WHL_BRANCH + 1);
				ssgColourArray	*whl_clr = new ssgColourArray(1);
				ssgNormalArray	*whl_nrm = new ssgNormalArray(1);

				clr[0] = 0.8f*colorfactor[k];
				clr[1] = 0.8f*colorfactor[k];
				clr[2] = 0.8f*colorfactor[k];
				clr[3] = 1.0f;

				whl_clr->add(clr);
				whl_nrm->add(nrm);
				vtx[0] = vtx[2] = 0.0;
				vtx[1] = (float)(2 * k - 1) * car->_tireWidth(wheel_index) / 2.0 - b_offset;
				whl_vtx->add(vtx);
				tex[0] = 0.25 + toffset[j][0];
				tex[1] = 0.25 + toffset[j][1];
				whl_tex->add(tex);
				vtx[1] = (float)(2 * k - 1) * car->_tireWidth(wheel_index) / 2.0;
				for (i = 0; i < WHL_BRANCH; i++) {
					alpha = (float)i * 2.0 * M_PI / (float)(WHL_BRANCH - 1);
					vtx[0] = wheelRadius * cos(alpha);
					vtx[2] = wheelRadius * sin(alpha);
					whl_vtx->add(vtx);
					tex[0] = 0.25 + 0.25 * cos(alpha) + toffset[j][0];
					tex[1] = 0.25 + 0.25 * sin(alpha) + toffset[j][1];
					whl_tex->add(tex);
				}
				ssgVtxTable *whl = new ssgVtxTable(GL_TRIANGLE_FAN, whl_vtx, whl_nrm, whl_tex, whl_clr);
				whl->setState(grCarInfo[grCarIndex].wheelTexture);
				whl->setCullFace(0);

					// stripify rim, should improve performance
					ssgStripify(whl);

				whl_branch->addKid(whl);

				// Swap normal for "inside" rim face.
				nrm[1] *= -1.0;
			}

			nrm[1] = norm_orig;
		}

		whselector->addKid(whl_branch);
	}
	
	return wheel;
}
示例#6
0
void grDrawCar(tCarElt *car, tCarElt *curCar, int dispCarFlag, int dispDrvFlag, double curTime, class cGrPerspCamera *curCam)
{
	sgCoord wheelpos;
	int index, i, j;
	static float maxVel[3] = { 20.0, 40.0, 70.0 };
	float lod;

	TRACE_GL("cggrDrawCar: start");

	index = car->index;
	if (car->priv.collision_state.collision_count > 0) {
		tCollisionState* collision_state = &car->priv.collision_state;
		grPropagateDamage (grCarInfo[index].carEntity, collision_state->pos, collision_state->force, 0);
		collision_state->collision_count = 0;
	}
	
	grCarInfo[index].distFromStart=grGetDistToStart(car);
	grCarInfo[index].envAngle=RAD2DEG(car->_yaw);

	if ((car == curCar) && (dispCarFlag != 1)) {
		grCarInfo[index].LODSelector->select(0);
	} else {
		lod = curCam->getLODFactor(car->_pos_X, car->_pos_Y, car->_pos_Z);
		i = 0;
		while (lod < grCarInfo[index].LODThreshold[i] * grLodFactorValue) {
			i++;
		}
		if ((car->_state & RM_CAR_STATE_DNF) && (grCarInfo[index].LODThreshold[i] > 0.0)) {
			i++;
		}
		grCarInfo[index].LODSelector->select(grCarInfo[index].LODSelectMask[i]);
		if (dispDrvFlag) {
			grCarInfo[index].driverSelector->select(1);
		} else {
			grCarInfo[index].driverSelector->select(0);
		}
	}

	sgCopyMat4(grCarInfo[index].carPos, car->_posMat);
	grCarInfo[index].px=car->_pos_X;
	grCarInfo[index].py=car->_pos_Y;

	grCarInfo[index].carTransform->setTransform(grCarInfo[index].carPos);

	if ((car == curCar) && (dispCarFlag != 1)) {
		grDrawShadow(car, 0);
	} else {
		grDrawShadow(car, 1);
	}
	
	grUpdateSkidmarks(car, curTime); 
	grDrawSkidmarks(car);
	grAddSmoke(car, curTime);
	
	if ((car == curCar) && (dispCarFlag != 1)) {
		grUpdateCarlight(car, curCam, 0);
	} else {
		grUpdateCarlight(car, curCam, 1);
	}

	/* Env mapping selection by the position on the track */
	grCarInfo[index].envSelector->selectStep(car->_trkPos.seg->envIndex);

	/* wheels */
	for (i = 0; i < 4; i++) {
		float	*clr;

		sgSetCoord(&wheelpos, car->priv.wheel[i].relPos.x, car->priv.wheel[i].relPos.y, car->priv.wheel[i].relPos.z,
					RAD2DEG(car->priv.wheel[i].relPos.az), RAD2DEG(car->priv.wheel[i].relPos.ax), 0);
		grCarInfo[index].wheelPos[i]->setTransform(&wheelpos);
		sgSetCoord(&wheelpos, 0, 0, 0, 0, 0, RAD2DEG(car->priv.wheel[i].relPos.ay));
		grCarInfo[index].wheelRot[i]->setTransform(&wheelpos);
		for (j = 0; j < 3; j++) {
			if (fabs(car->_wheelSpinVel(i)) < maxVel[j]) 
				break;
		}
		grCarInfo[index].wheelselector[i]->select(1<<j);
		clr = grCarInfo[index].brkColor[i]->get(0);
		clr[0] = 0.1 + car->_brakeTemp(i) * 1.5;
		clr[1] = 0.1 + car->_brakeTemp(i) * 0.3;
		clr[2] = 0.1 - car->_brakeTemp(i) * 0.3;
	}

	/* push the car at the end of the display order */
	CarsAnchorTmp->addKid(grCarInfo[index].carTransform);
	CarsAnchor->removeKid(grCarInfo[index].carTransform);
	CarsAnchor->addKid(grCarInfo[index].carTransform);
	CarsAnchorTmp->removeKid(grCarInfo[index].carTransform);

	TRACE_GL("cggrDrawCar: end");
}
示例#7
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;
}
示例#8
0
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;
}