Size: 4687 bytes.


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// cs/apps/trycopilot.ai/scene_animator.hh
// cs/apps/trycopilot.ai/scene_animator.hh
// cs/apps/trycopilot.ai/scene_animator.hh
#ifndef CS_APPS_TRYCOPILOT_AI_SCENE_ANIMATOR_HH
#define CS_APPS_TRYCOPILOT_AI_SCENE_ANIMATOR_HH

#include <stdio.h>

#include <functional>
#include <tuple>
#include <vector>

#include "cs/apps/trycopilot.ai/text/fonts/mono.hh"
#include "cs/renderer/film.hh"
#include "cs/renderer/linalg/transform.hh"
#include "cs/renderer/numbers/map_value.hh"
#include "cs/renderer/scene.hh"
#include "cs/renderer/scene_renderer.hh"
#include "cs/renderer/shapes/plane.hh"
#include "cs/renderer/shapes/shape.hh"
#include "cs/renderer/shapes/sphere.hh"
#include "cs/util/timeit.hh"

using ::cs::renderer::Camera;
using ::cs::renderer::Film;
using ::cs::renderer::Scene;
using ::cs::renderer::SceneRenderer;
using ::cs::renderer::shapes::Plane;
using ::cs::renderer::shapes::Shape;
using ::cs::renderer::shapes::Sphere;
using ::cs::util::timeit;
using p3 = ::cs::renderer::geo::Point3;
using v3 = ::cs::renderer::geo::Vector3;
using r3 = ::cs::renderer::geo::Ray3;
using ::cs::apps::trycopilotai::text::fonts::Mono;
using ::cs::numbers::map_value;
using ::cs::renderer::linalg::Transform;
using ::cs::renderer::linalg::transforms::LookAt;
using ::cs::renderer::linalg::transforms::Translate;

namespace cs::apps::trycopilotai {

struct SceneAnimator {
  size_t num_frames_;
  std::tuple<unsigned int, unsigned int> film_dimensions_;
  SceneAnimator(size_t num_frames,
                std::tuple<unsigned int, unsigned int>
                    film_dimensions)
      : num_frames_(num_frames),
        film_dimensions_(film_dimensions) {}

  std::vector<Film> render_all_frames(
      std::function<void(unsigned int, unsigned int,
                         unsigned int)>
          on_frame_rendered_cb = nullptr) {
    std::vector<Film> frames(num_frames_);

    // Setup scene
    std::vector<Shape*> shapes{
        // Unit sphere at the origin
        new Sphere(p3(0, 0, 0), 0.5),
        // One smaller sphere at x=-1
        new Sphere(p3(-1, 0, 0), 0.25),
        // One even smaller sphere at y=1
        new Sphere(p3(0, 1, 0), 0.125),
        // One even smaller sphere at z=-1
        new Sphere(p3(0, 0, -1), 0.0625),
        // new Sphere(p3(2, 0, 0), 0.5),
        // new Sphere(p3(0, 2, 0), 0.25),
        // new Sphere(p3(0, -1, 0), 0.25),
        // new Plane(p3(1, 1, 1).unit(), -5),
    };

    Scene scene(shapes);

    for (size_t i = 0; i < num_frames_; i++) {
      // Setup camera
      unsigned int pixels_per_unit =
          std::min(std::get<0>(film_dimensions_),
                   std::get<1>(film_dimensions_)) /
          2;
      p3 pos(map_value<float>(i, 0, num_frames_, -25, 5), 0,
             map_value<float>(i, 0, num_frames_, -10, -5));
      p3 look(0, 0, 0);
      p3 up(0, 1, 0);
      Transform w2c = LookAt(pos, look, up);
      float focal_length = 5;
      Camera camera(w2c, pixels_per_unit, focal_length,
                    Film(film_dimensions_));

      // Setup renderer
      SceneRenderer renderer(camera, scene);

      Film film;
      // Measure the render time
      [[maybe_unused]]
      unsigned int render_time_ms =
          timeit([&film, &renderer]() {
            film = renderer.render();
          });

      // Draw some text on the film
      [[maybe_unused]] auto [width, height] =
          film_dimensions_;
      int xStart = 16;
      int yStart = 16;
      DrawString(&film, &xStart, yStart,
                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 2);

      frames[i] = film;

      if (on_frame_rendered_cb) {
        on_frame_rendered_cb(render_time_ms, i + 1,
                             num_frames_);
      }
    }

    // De-allocate shapes
    for (Shape* shape : shapes) {
      delete shape;
    }

    return frames;
  }

  void DrawString(Film* film, int* xStart, int yStart,
                  std::string str, int scale = 1) {
    for (char ch : str) {
      for (unsigned int x = 0; x < 8; x++) {
        for (unsigned int y = 0; y < 8; y++) {
          bool value = cs::apps::trycopilotai::text::fonts::
              SampleCharacterPixel(ch, x, y);
          char rgba = value ? 255 : 0;
          unsigned int film_x = *xStart + x;
          unsigned int film_y = yStart + y;
          if (film_x < 0 || film_x >= film->width ||
              film_y < 0 || film_y >= film->height) {
            continue;
          }
          film->pixels[film_x][film_y] =
              renderer::Pixel(rgba, rgba, rgba, rgba);
        }
      }
      // Move the x start position
      *xStart += 8;
    }
  }
};

}  // namespace cs::apps::trycopilotai

#endif  // CS_APPS_TRYCOPILOT_AI_SCENE_ANIMATOR_HH
v0 (commit) © 2025 @p13i.io | Load balancer proxied to: cs-code-viewer-3:8080 in 4ms.