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; }
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; }
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"); }
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; }