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; }
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; }
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; }
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"); }
/** * \brief Tile the terrain * * This function recursively walks the scene graph and sorts all * triangles into a grid of smaller graphs. This reduces the * calculation effort: If the position of the plane and therefore * the grid below it is known, only a small fraction of all * triangles has to be tested. * * During the recursive walk down the tree, the function tracks * all transformations. If a leaf node is encountered, the contained * triangles are transformed by the tracked transformations to * get the absolute position of each triangle. Then all triangles * are sorted into the grid by their absolute position. * * \param e Pointer to the currently processed entity * \param xform Reference to the current transformation */ void HD_TilingTerrain::tiling_terrain(ssgEntity * e, sgMat4 xform) { // only continue if HOT traversal is enabled for this entity if ( e->getTraversalMask() & SSGTRAV_HOT ) { if ( e->isAKindOf(ssgTypeBranch()) ) { ssgBranch *br = (ssgBranch *) e ; if ( e -> isA ( ssgTypeTransform() ) ) { sgMat4 xform1; ((ssgTransform *)e)->getTransform ( xform1 ) ; sgPreMultMat4 ( xform, xform1 ) ;//Pre or Post ??? /* std::cout << "------tranform " << br<< std::endl; std::cout << "-------------- " << xform[0][0]<<" "<< xform[0][1]<<" "<< xform[0][2]<<" "<< xform[0][3]<< std::endl; std::cout << "-------------- " << xform[1][0]<<" "<< xform[1][1]<<" "<< xform[1][2]<<" "<< xform[1][3]<< std::endl; std::cout << "-------------- " << xform[2][0]<<" "<< xform[2][1]<<" "<< xform[2][2]<<" "<< xform[2][3]<< std::endl; std::cout << "-------------- " << xform[3][0]<<" "<< xform[3][1]<<" "<< xform[3][2]<<" "<< xform[3][3]<< std::endl; */ } //else std::cout << "------branch " << br<< std::endl; // Bug #16552: "xform" is actually passed by reference and // not by value. Therefore we have to store it locally and // restore it before recursing to the next child. Else all // children receive an xform matrix that was modified by // the previous child. sgMat4 local_xform; sgCopyMat4(local_xform, xform); for ( int i = 0 ; i < br -> getNumKids () ; i++ ) { tiling_terrain ( br -> getKid ( i ), xform); // restore transformation matrix sgCopyMat4(xform, local_xform); } } else if ( e -> isAKindOf ( ssgTypeLeaf() ) ) { //std::cout << "------leaf " << e<< std::endl; ssgLeaf *leaf = (ssgLeaf *) e ; int nt = leaf->getNumTriangles(); //std::cout << "------n triangles " << nt<< std::endl; for ( int i = 0 ; i < nt ; i++ )//pour chaque triangle { short iv1,iv2,iv3;/*float *v1, *v2, *v3;*/ sgVec3 v1,v2,v3; leaf->getTriangle ( i, &iv1, &iv2, &iv3 ); sgCopyVec3 (v1 , leaf->getVertex(iv1)); sgXformPnt3( v1, xform); sgCopyVec3 (v2 , leaf->getVertex(iv2)); sgXformPnt3( v2, xform); sgCopyVec3 (v3 , leaf->getVertex(iv3)); sgXformPnt3( v3, xform); /* std::cout << "------triangle " << std::endl; std::cout << "-------------- " << v1[0]<<" "<< v1[1]<<" "<< v1[2]<<" "<< std::endl; std::cout << "-------------- " << v2[0]<<" "<< v2[1]<<" "<< v2[2]<<" "<< std::endl; std::cout << "-------------- " << v3[0]<<" "<< v3[1]<<" "<< v3[2]<<" "<< std::endl; */ //calcule cube englobant sgBox box; box.empty(); box.extend(v1); box.extend(v2); box.extend(v3); //std::cout << "Min " << box.min[0]<<", "<<box.min[1]<<", "<<box.min[2]<<" Max"<<box.max[0]<<", "<<box.max[1]<<", "<<box.max[2]<< std::endl; //ajoute dans cellules recouvertes int save = 1; int i1 = (int)(-0.1+box.min[0]/SIZE_CELL_GRID_PLANES) + SIZE_GRID_PLANES/2; int i2 = (int)(0.1+box.max[0]/SIZE_CELL_GRID_PLANES) + SIZE_GRID_PLANES/2; int j1 = (int)(-0.1+box.min[2]/SIZE_CELL_GRID_PLANES) + SIZE_GRID_PLANES/2; int j2 = (int)(0.1+box.max[2]/SIZE_CELL_GRID_PLANES) + SIZE_GRID_PLANES/2; if (((i1<0) && (i2<0)) ||((i1>SIZE_GRID_PLANES) && (i2>SIZE_GRID_PLANES)) ) { save = 0; } if (((j1<0) && (j2<0)) ||((j1>SIZE_GRID_PLANES) && (j2>SIZE_GRID_PLANES)) ) { save = 0; } if (i1<0) i1=0; if (i1>SIZE_GRID_PLANES) i1 = SIZE_GRID_PLANES; if (i2<0) i2=0; if (i2>SIZE_GRID_PLANES) i2 = SIZE_GRID_PLANES; if (j1<0) j1=0; if (j1>SIZE_GRID_PLANES) j1 = SIZE_GRID_PLANES; if (j2<0) j2=0; if (j2>SIZE_GRID_PLANES) j2 = SIZE_GRID_PLANES; //std::cout << "cellules i, j " << i1 <<", "<<i2<<", "<<j1<<","<<j2<< std::endl; if (save) { for ( int i = i1 ; i <= i2; i++ ) { for ( int j = j1 ; j <= j2; j++ ) { //std::cout << "met dans cellule " << i <<", "<<j<< std::endl; tile_table[i][j]->add(v1); tile_table[i][j]->add(v2); tile_table[i][j]->add(v3); } } } } } } }
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; } }