Esempio n. 1
0
void
PlanetographicGrid::render(Renderer* renderer,
                           const Point3f& pos,
                           float discSizeInPixels,
                           double tdb) const
{
    Quatd q = Quatd::yrotation(PI) * body.getEclipticToBodyFixed(tdb);
    Quatf qf((float) q.w, (float) q.x, (float) q.y, (float) q.z);

    // The grid can't be rendered exactly on the planet sphere, or
    // there will be z-fighting problems. Render it at a height above the
    // planet that will place it about one pixel away from the planet.
    float scale = (discSizeInPixels + 1) / discSizeInPixels;
    scale = max(scale, 1.001f);
    float offset = scale - 1.0f;

    Vec3f semiAxes = body.getSemiAxes();

    Vec3d posd(pos.x, pos.y, pos.z);
    Vec3d viewRayOrigin = Vec3d(-pos.x, -pos.y, -pos.z)  * (~q).toMatrix3();
    
    // Calculate the view normal; this is used for placement of the long/lat
    // label text.
    Vec3f vn  = Vec3f(0.0f, 0.0f, -1.0f) * renderer->getCameraOrientation().toMatrix3();
    Vec3d viewNormal(vn.x, vn.y, vn.z);

    // Enable depth buffering
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
    glDisable(GL_BLEND);

    glDisable(GL_TEXTURE_2D);

    glPushMatrix();
    glRotate(~qf);
    glScale(scale * semiAxes);

    glEnableClientState(GL_VERTEX_ARRAY);

    glVertexPointer(3, GL_FLOAT, 0, xzCircle);

    // Only show the coordinate labels if the body is sufficiently large on screen
    bool showCoordinateLabels = false;
    if (discSizeInPixels > 50)
        showCoordinateLabels = true;

    float latitudeStep = minLatitudeStep;
    float longitudeStep = minLongitudeStep;
    if (discSizeInPixels < 200)
    {
        latitudeStep = 30.0f;
        longitudeStep = 30.0f;
    }
    
    for (float latitude = -90.0f + latitudeStep; latitude < 90.0f; latitude += latitudeStep)
    {
        float phi = degToRad(latitude);
        float r = (float) cos(phi);

        if (latitude == 0.0f)
        {
            glColor(Renderer::PlanetEquatorColor);
            glLineWidth(2.0f);
        }
        else
        {
            glColor(Renderer::PlanetographicGridColor);
        }
        glPushMatrix();
        glTranslatef(0.0f, (float) sin(phi), 0.0f);
        glScalef(r, r, r);
        glDrawArrays(GL_LINE_LOOP, 0, circleSubdivisions);
        glPopMatrix();
        glLineWidth(1.0f);
        
        if (showCoordinateLabels)
        {
            if (latitude != 0.0f && abs(latitude) < 90.0f)
            {
                char buf[64];

                char ns;
                if (latitude < 0.0f)
                    ns = northDirection == NorthNormal ? 'S' : 'N';
                else
                    ns = northDirection == NorthNormal ? 'N' : 'S';
                sprintf(buf, "%d%c", (int) fabs((double) latitude), ns);
                longLatLabel(buf, 0.0, latitude, viewRayOrigin, viewNormal, posd, q, semiAxes, offset, renderer);
                longLatLabel(buf, 180.0, latitude, viewRayOrigin, viewNormal, posd, q, semiAxes, offset, renderer);
            }
        }
    }

    glVertexPointer(3, GL_FLOAT, 0, xyCircle);

    for (float longitude = 0.0f; longitude <= 180.0f; longitude += longitudeStep)
    {
        glColor(Renderer::PlanetographicGridColor);
        glPushMatrix();
        glRotatef(longitude, 0.0f, 1.0f, 0.0f);
        glDrawArrays(GL_LINE_LOOP, 0, circleSubdivisions);
        glPopMatrix();

        if (showCoordinateLabels)
        {
            int showLongitude = 0;
            char ew = 'E';

            switch (longitudeConvention)
            {
            case EastWest:
                ew = 'E';
                showLongitude = (int) longitude;
                break;
            case Eastward:
                if (longitude > 0.0f)
                    showLongitude = 360 - (int) longitude;
                ew = 'E';
                break;
            case Westward:
                if (longitude > 0.0f)
                    showLongitude = 360 - (int) longitude;
                ew = 'W';
                break;
            }

            char buf[64];
            sprintf(buf, "%d%c", (int) showLongitude, ew);
            longLatLabel(buf, longitude, 0.0, viewRayOrigin, viewNormal, posd, q, semiAxes, offset, renderer);
            if (longitude > 0.0f && longitude < 180.0f)
            {
                showLongitude = (int) longitude;
                switch (longitudeConvention)
                {
                case EastWest:
                    ew = 'W';
                    showLongitude = (int) longitude;
                    break;
                case Eastward:
                    showLongitude = (int) longitude;
                    ew = 'E';
                    break;
                case Westward:
                    showLongitude = (int) longitude;
                    ew = 'W';
                    break;
                }

                sprintf(buf, "%d%c", showLongitude, ew);       
                longLatLabel(buf, -longitude, 0.0, viewRayOrigin, viewNormal, posd, q, semiAxes, offset, renderer);
            }
        }
    }

    glDisableClientState(GL_VERTEX_ARRAY);

    glPopMatrix();

    glDisable(GL_LIGHTING);

    glDisable(GL_DEPTH_TEST);
    glDepthMask(GL_FALSE);
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE);
}
Esempio n. 2
0
CornellBox::CornellBox() {
  Ray c(Vec3<double>(50,52,295.6),Vec3<double>(0,-0.042612,-1).norm());
  setCamera(c);
  std::mt19937 gen(RANDOM());
  std::normal_distribution<> sized(sizecenter,5);
  std::normal_distribution<> posd(40,10);

  auto hsv2vec3 = [](float h, float s, float v) {
    float r,g,b;
    HSVtoRGB(&r,&g,&b,h,s,v);
    return Vec3<double>(r,g,b);
  };
  auto clamp = [](float v) {
    if(v < 0) return 0.0f;
    if(v > 1) return 1.0f;
    return v;
  };
  auto randColor = [&](){
    const float rate = 2;
    std::exponential_distribution<> d(rate+1);
    std::uniform_real_distribution<float> h(0,360);
    return hsv2vec3(
      h(gen),
      clamp((rate-d(gen))/rate),
      clamp((rate-d(gen))/rate)
    );
  };

  // Set objects
  auto makeWall = [&](Vec3<double> p, Vec3<double> c)
  {
    auto s = new Sphere(1e5);
    s->position = p;
    s->color = c;
    s->material_type = M_DIFFUSE;
    addShape(s);
  };

  auto makeLight = [&](Vec3<double> p, Vec3<double> c)
  {
    auto s = new Sphere(600);
    s->position = p;
    s->emission = c;
    s->material_type = M_DIFFUSE;
    addShape(s);
  };
  auto makeGlass = [&](double size, Vec3<double> p)
  {
    if(size == -1) {
      size = sized(gen);
      if(size < 1) size = 1;
      p.y += size;
      if(p.x - size < 0) p.x = size;
      if(p.z - size < 0) p.z = size;
      if(p.x + size > 81.6) p.x = 81.6 - size;
      if(p.z + size > 81.6) p.z = 81.6 - size;
    }
    auto s = new Sphere(size);
    s->position = p;
    s->color = Vec3<double>(1,1,1)*.999;
    s->material_type = M_REFRACTION;
    addShape(s);
  };
  auto makeMirror = [&](double size, Vec3<double> p)
  {
    if(size == -1) {
      size = sized(gen);
      if(size < 1) size = 1;
      p.y += size;
      if(p.x - size < 0) p.x = size;
      if(p.z - size < 0) p.z = size;
      if(p.x + size > 81.6) p.x = 81.6 - size;
      if(p.z + size > 81.6) p.z = 81.6 - size;
    }
    auto s = new Sphere(size);
    s->position = p;
    s->color = Vec3<double>(1,1,1)*.999;
    s->material_type = M_SPECULAR;
    addShape(s);
  };

  makeWall(Vec3<double>(1e5+1,40.8,81.6), randColor()); // right
  makeWall(Vec3<double>(-1e5+99,40.8,81.6), randColor());// left

  makeWall(Vec3<double>(50,40.8, 1e5), Vec3<double>(.75,.75,.75)); // back
  makeWall(Vec3<double>(50, 1e5, 81.6),Vec3<double>(.75,.75,.75)); // top
  makeWall(Vec3<double>(50,-1e5+81.6,81.6),Vec3<double>(.75,.75,.75)); // bottom

  
  
  makeGlass(-1, Vec3<double>(posd(gen)+5,posd(gen),posd(gen)/2+40));

  makeMirror(-1, Vec3<double>(posd(gen)-5,0,posd(gen)));
  
  makeLight(Vec3<double>(50,681.6-0.27,81.6),Vec3<double>(12,12,12));

  enumerateLights();
}