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; }
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 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; }
// // 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); }
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(); }
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; }
void calc_coord(void) { sgMat4 m, m2; int i, j; tFace *curFace; float width, height; float scale, offX, offY; int largerRow; float maxWidth; int col; ssgBranch *branch; ColWidth = (float*)calloc(NbMaxCols, sizeof(float)); fprintf(stderr, "After Rotation:\n"); largerRow = 0; maxWidth = 0; for (i = 0; i < NbRows; i++) { curFace = GF_TAILQ_FIRST(&(Row[i].faces)); while (curFace) { if (curFace->isPresent) { branch = curFace->branch->getParent(0); if (branch->isAKindOf(_SSG_TYPE_BASETRANSFORM)) { ((ssgBaseTransform*)branch)->getTransform(m2); curFace->align[0] *= m2[3][0]; curFace->align[1] *= m2[3][1]; curFace->align[2] *= m2[3][2]; fprintf(stderr, "Align face %s : %f %f %f\n", curFace->faceName, curFace->align[0], curFace->align[1], curFace->align[2]); } sgMakeTransMat4(m, curFace->align); sgMakeIdentMat4(m2); for (j = 0; j < 3; j++) { m2[j][j] = curFace->lscale[j]; } sgPostMultMat4(m, m2); sgMakeRotMat4(m2, curFace->xform.hpr); sgPostMultMat4(m, m2); sgCopyMat4(curFace->mat, m); sgXformPnt3(curFace->sbbmin, curFace->lbbmin, m); sgXformPnt3(curFace->sbbmax, curFace->lbbmax, m); fprintf(stderr, " Face %s : %f %f %f --- %f %f %f\n", curFace->faceName, curFace->sbbmin[0], curFace->sbbmin[1], curFace->sbbmin[2], curFace->sbbmax[0], curFace->sbbmax[1], curFace->sbbmax[2]); curFace->lwidth = 2.0 * MAX(fabs(curFace->sbbmin[0]), fabs(curFace->sbbmax[0])); curFace->lheight = 2.0 * MAX(fabs(curFace->sbbmin[2]), fabs(curFace->sbbmax[2])); //curFace->lwidth = fabs(curFace->sbbmin[0] - curFace->sbbmax[0]); //curFace->lheight = fabs(curFace->sbbmin[2] - curFace->sbbmax[2]); Row[i].lwidth += curFace->lwidth; Row[i].lheight = MAX(Row[i].lheight, curFace->lheight); } curFace = GF_TAILQ_NEXT(curFace, link); } if (Row[i].lwidth > maxWidth) { maxWidth = Row[i].lwidth; largerRow = i; } } height = 0; fprintf(stderr, "After Scaling:\n"); for (i = 0; i < NbRows; i++) { height += Row[i].lheight; } width = maxWidth; scale = (float)ImgSize / MAX(width, height); curFace = GF_TAILQ_FIRST(&(Row[largerRow].faces)); i = 0; fprintf(stderr, "Columns : "); while (curFace) { ColWidth[i] = curFace->lwidth * scale; fprintf(stderr, "%.2f ", ColWidth[i]); curFace = GF_TAILQ_NEXT(curFace, link); i++; } fprintf(stderr, "\n"); fprintf(stderr, "Total Width = %.2f Height = %.2f\n", width, height); fprintf(stderr, "Image Width = %.2f Height = %.2f\n", width*scale, height*scale); offY = - (float)ImgSize / 2.0; for (i = 0; i < NbRows; i++) { curFace = GF_TAILQ_FIRST(&(Row[i].faces)); offY += Row[i].lheight*scale / 2.0; col = 0; offX = - (float)ImgSize / 2.0; while (curFace) { if (curFace->isPresent) { sgCopyMat4(m, curFace->mat); curFace->texScale = scale; sgMakeIdentMat4(m2); for (j = 0; j < 3; j++) { m2[j][j] = scale; } sgPostMultMat4(m, m2); sgXformPnt3(curFace->sbbmin, curFace->lbbmin, m); sgXformPnt3(curFace->sbbmax, curFace->lbbmax, m); offX += ColWidth[col] / 2.0; curFace->offset[0] = offX; curFace->offset[2] = offY; offX += ColWidth[col] / 2.0; sgMakeTransMat4(m2, curFace->offset); sgPostMultMat4(m, m2); sgCopyMat4(curFace->mat, m); curFace->branch->setTransform(m); } else { offX += ColWidth[col]; } col++; curFace = GF_TAILQ_NEXT(curFace, link); } offY += Row[i].lheight*scale / 2.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 ssgVtxTableCarlight::draw_geometry () { if (on == 0) { return; } int num_normals = getNumNormals(); float alpha; GLfloat modelView[16]; sgVec3 A, B, C, D; sgVec3 right, up; sgVec3 axis; sgMat4 mat; sgMat4 mat3; sgVec3 *vx = (sgVec3 *) vertices->get(0); sgVec3 *nm = (sgVec3 *) normals->get(0); alpha = 0.75f; glDepthMask(GL_FALSE); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glPolygonOffset(-15.0f, -20.0f); glEnable(GL_POLYGON_OFFSET_FILL); // get the matrix. glGetFloatv(GL_MODELVIEW_MATRIX, modelView); // get the up and right vector from the matrice view. up[0] = modelView[1]; up[1] = modelView[5]; up[2] = modelView[9]; right[0] = modelView[0]; right[1] = modelView[4]; right[2] = modelView[8]; // compute the coordinates of the four points of the quadri. // up and right points C[0] = right[0] + up[0]; C[1] = right[1] + up[1]; C[2] = right[2] + up[2]; // left and up D[0] = -right[0] + up[0]; D[1] = -right[1] + up[1]; D[2] = -right[2] + up[2]; // down and left A[0] = -right[0] - up[0]; A[1] = -right[1] - up[1]; A[2] = -right[2] - up[2]; // right and down B[0] = right[0] - up[0]; B[1] = right[1] - up[1]; B[2] = right[2] - up[2]; axis[0] = 0; axis[1] = 0; axis[2] = 1; if (grMaxTextureUnits > 1) { glActiveTextureARB (GL_TEXTURE0_ARB); } sgMakeRotMat4(mat, ((float)rand()/(float)RAND_MAX)*45, axis); glMatrixMode(GL_TEXTURE); glLoadIdentity (); sgMakeTransMat4(mat3, 0.5, 0.5, 0); glMultMatrixf((float *)mat3); glMultMatrixf((float *)mat); sgMakeTransMat4(mat3, -0.5, -0.5, 0); glMultMatrixf((float *)mat3); glMatrixMode(GL_MODELVIEW); for (int I = 0; I < on; I++) { glBegin(gltype) ; glColor4f(0.8, 0.8, 0.8, alpha); if (num_normals == 1) { glNormal3fv(nm[0]); } // the computed coordinates are translated from the smoke position with the x,y,z speed. glTexCoord2f(0, 0); glVertex3f(vx[0][0] + factor*size*A[0], vx[0][1] + factor*size*A[1], vx[0][2] + factor*size*A[2]); glTexCoord2f(0, 1); glVertex3f(vx[0][0] + factor*size*B[0], vx[0][1] + factor*size*B[1], vx[0][2] + factor*size*B[2]); glTexCoord2f(1, 0); glVertex3f(vx[0][0] + factor*size*D[0], vx[0][1] + factor*size*D[1], vx[0][2] + factor*size*D[2]); glTexCoord2f(1, 1); glVertex3f(vx[0][0]+factor*size*C[0],vx[0][1]+factor*size*C[1], vx[0][2]+factor*size*C[2]); glEnd(); } glDisable(GL_POLYGON_OFFSET_FILL); if (grMaxTextureUnits > 1) { glActiveTextureARB (GL_TEXTURE0_ARB); } glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glDepthMask(GL_TRUE); }