gKit2 light
Loading...
Searching...
No Matches
tuto_englobant.cpp File Reference
#include <algorithm>
#include <vector>
#include <cfloat>
#include <chrono>
#include "vec.h"
#include "mat.h"
#include "color.h"
#include "image.h"
#include "image_io.h"
#include "image_hdr.h"
#include "orbiter.h"
#include "mesh.h"
#include "wavefront.h"

Go to the source code of this file.

Classes

struct  RayHit
struct  BBox
 boite englobante. More...
struct  Triangle
 triangle pour le bvh, cf fonction bounds() et intersect(). More...
struct  triangle_less1
struct  ray_less1

Functions

void direct (const std::vector< Triangle > &triangles, const int tbegin, const int tend, std::vector< RayHit > &rays, const int rbegin, const int rend)
void divide (const BBox &bounds, std::vector< Triangle > &triangles, const int tbegin, const int tend, std::vector< RayHit > &rays, const int rbegin, const int rend)
int main (const int argc, const char **argv)

Function Documentation

◆ direct()

void direct ( const std::vector< Triangle > & triangles,
const int tbegin,
const int tend,
std::vector< RayHit > & rays,
const int rbegin,
const int rend )

Definition at line 121 of file tuto_englobant.cpp.

124{
125 for(int i= rbegin; i < rend; i++)
126 for(int k= tbegin; k < tend; k++)
127 triangles[k].intersect(rays[i]);
128}

◆ divide()

void divide ( const BBox & bounds,
std::vector< Triangle > & triangles,
const int tbegin,
const int tend,
std::vector< RayHit > & rays,
const int rbegin,
const int rend )

Definition at line 158 of file tuto_englobant.cpp.

161{
162 if(tbegin == tend || rbegin == rend)
163 // plus de triangles ou de rayons, rien a faire...
164 return;
165
166 // il ne reste plus que quelques triangles, finir les calculs d'intersection...
167 if(tend - tbegin <= 4)
168 {
169 direct(triangles, tbegin, tend, rays, rbegin, rend);
170 return;
171 }
172
173 // axe le plus etire de l'englobant
174 Vector d= Vector(bounds.pmin, bounds.pmax);
175 int axis;
176 if(d.x > d.y && d.x > d.z) // x plus grand que y et z ?
177 axis= 0;
178 else if(d.y > d.z) // y plus grand que z ? (et que x implicitement)
179 axis= 1;
180 else // x et y ne sont pas les plus grands...
181 axis= 2;
182
183 // coupe l'englobant au milieu
184 float cut= bounds.centroid(axis);
185
186 // repartit les triangles
187 Triangle *pm= std::partition(triangles.data() + tbegin, triangles.data() + tend, triangle_less1(axis, cut));
188 int m= std::distance(triangles.data(), pm);
189
190 // la repartition des triangles peut echouer, et tous les triangles sont dans la meme partie...
191 // forcer quand meme un decoupage en 2 ensembles
192 if(m == tbegin || m == tend)
193 m= (tbegin + tend) / 2;
194 assert(m != tbegin);
195 assert(m != tend);
196
197 // construit les englobants
198 BBox left= triangles[tbegin].bounds();
199 for(int i= tbegin+1; i < m; i++)
200 left.insert(triangles[i].bounds());
201
202 // repartit les rayons
203 RayHit *prleft= std::partition(rays.data() + rbegin, rays.data() + rend, ray_less1(left));
204 int rleft= std::distance(rays.data(), prleft);
205
206 divide(left, triangles, tbegin, m, rays, rbegin, rleft);
207
208 // on recommence pour la droite
209 BBox right= triangles[m].bounds();
210 for(int i= m+1; i < tend; i++)
211 right.insert(triangles[i].bounds());
212
213 RayHit *prright= std::partition(rays.data() + rbegin, rays.data() + rend, ray_less1(right));
214 int rright= std::distance(rays.data(), prright);
215
216 divide(right, triangles, m, tend, rays, rbegin, rright);
217}
void bounds(const MeshData &data, Point &pmin, Point &pmax)
renvoie l'englobant.
boite englobante.
Definition tuto_bvh.cpp:47
triangle pour le bvh, cf fonction bounds() et intersect().
Definition tuto_bvh.cpp:84
representation d'un vecteur 3d.
Definition vec.h:67

◆ main()

int main ( const int argc,
const char ** argv )

Definition at line 220 of file tuto_englobant.cpp.

221{
222 const char *mesh_filename= "data/cornell.obj";
223 if(argc > 1)
224 mesh_filename= argv[1];
225
226 const char *orbiter_filename= "data/cornell_orbiter.txt";
227 if(argc > 2)
228 orbiter_filename= argv[2];
229
230 Orbiter camera;
231 if(camera.read_orbiter(orbiter_filename) < 0)
232 return 1;
233
234 Mesh mesh= read_mesh(mesh_filename);
235 BBox bounds;
236 mesh.bounds(bounds.pmin, bounds.pmax);
237
238 // recupere les triangles
239 std::vector<Triangle> triangles;
240 {
241 int n= mesh.triangle_count();
242 for(int i= 0; i < n; i++)
243 triangles.emplace_back(mesh.triangle(i), i);
244 }
245
246 Image image(1024, 768);
247
248 // recupere les transformations
249 camera.projection(image.width(), image.height(), 45);
250 Transform model= Identity();
251 Transform view= camera.view();
252 Transform projection= camera.projection();
253 Transform viewport= camera.viewport();
254 Transform inv= Inverse(viewport * projection * view * model);
255
256 // genere un rayon par pixel de l'image
257 std::vector<RayHit> rays;
258 for(unsigned y= 0; y < image.height(); y++)
259 for(unsigned x= 0; x < image.width(); x++)
260 {
261 // generer le rayon
262 Point origine= inv(Point(x + .5f, y + .5f, 0));
263 Point extremite= inv(Point(x + .5f, y + .5f, 1));
264
265 rays.emplace_back(origine, extremite, x, y);
266 }
267
268// mesure les temps d'execution
269#if 0
270 {
271 auto start= std::chrono::high_resolution_clock::now();
272 direct(triangles, 0, int(triangles.size()), rays, 0, int(rays.size()));
273
274 auto stop= std::chrono::high_resolution_clock::now();
275 int cpu= std::chrono::duration_cast<std::chrono::milliseconds>(stop - start).count();
276 printf("direct %dms\n", cpu);
277 }
278#endif
279
280 {
281 auto start= std::chrono::high_resolution_clock::now();
282 divide(bounds, triangles, 0, int(triangles.size()), rays, 0, int(rays.size()));
283
284 auto stop= std::chrono::high_resolution_clock::now();
285 int cpu= std::chrono::duration_cast<std::chrono::milliseconds>(stop - start).count();
286 printf("divide %dms\n", cpu);
287 }
288
289 // reconstruit l'image
290 for(unsigned i= 0; i < rays.size(); i++)
291 {
292 if(rays[i])
293 {
294 int x= rays[i].x;
295 int y= rays[i].y;
296 float u= rays[i].u;
297 float v= rays[i].v;
298 float w= 1 - u - v;
299 image(x, y)= Color(w, u, v);
300 }
301 }
302 write_image(image, "divide.png");
303
304
305 return 0;
306}
representation d'une image.
Definition image.h:21
representation d'un objet / maillage.
Definition mesh.h:121
representation de la camera, type orbiter, placee sur une sphere autour du centre de l'objet.
Definition orbiter.h:17
void printf(Text &text, const int px, const int py, const char *format,...)
affiche un texte a la position x, y. meme utilisation que printf().
Definition text.cpp:140
bool write_image(const Image &image, const char *filename, const bool flipY)
enregistre une image au format .png
Definition image_io.cpp:245
Transform Inverse(const Transform &m)
renvoie l'inverse de la matrice.
Definition mat.cpp:197
Transform Identity()
construit la transformation identite.
Definition mat.cpp:187
Mesh read_mesh(const char *filename)
charge un fichier wavefront .obj et renvoie un mesh compose de triangles non indexes....
Definition wavefront.cpp:14
representation d'une couleur (rgba) transparente ou opaque.
Definition color.h:14
representation d'un point 3d.
Definition vec.h:21
representation d'une transformation, une matrice 4x4, organisee par ligne / row major.
Definition mat.h:21