00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "Canvas.h"
00011 #include "color.h"
00012 #include "xmath.h"
00013 #include "TriangleMesh.h"
00014
00015 #include <iostream>
00016 #include <sstream>
00017 #include <iomanip>
00018
00019
00020 using namespace columbia;
00021
00022
00023
00024
00025
00026 inline RGB compute_lighting(RGB const& material_col, RGB const& light_col, Vector const& light_dir, Vector* normal=0)
00027 {
00028 if(normal)
00029 {
00030 float pro = normal->x * light_dir.x + normal->y * light_dir.y + normal->z * light_dir.z;
00031 if(pro < 0)
00032 return Black;
00033
00034 return
00035 (material_col * light_col) *
00036 ( (pro / (sqrt(normal->x * normal->x + normal->y * normal->y + normal->z * normal->z) *
00037 sqrt(light_dir.x * light_dir.x + light_dir.y * light_dir.y + light_dir.z * light_dir.z) )) );
00038 }
00039 return material_col;
00040 }
00041
00042
00043 int main(int argc, char** argv)
00044 {
00045 bool draw_wireframe = false;
00046 if(argc > 2)
00047 draw_wireframe = (argv[2][0]=='w');
00048 float scale_factor = 0.15;
00049 if(argc > 3)
00050 scale_factor *= argv[3][0] - '0';
00051
00052 try
00053 {
00054 Canvas canvas;
00055 canvas.filename = "t.ppm";
00056
00057 TriangleMesh msh(argv[1]);
00058
00059 bool has_normal = msh.has_normal;
00060
00061 Vector translate = - msh.bbox.center;
00062
00063 float scale_x = canvas.hReso / (msh.bbox.max.x - msh.bbox.min.x) ;
00064 float scale_y = canvas.vReso / (msh.bbox.max.y - msh.bbox.min.y) ;
00065 float scale = std :: min (scale_x, scale_y) * scale_factor;
00066 float z_range = msh.bbox.max.z - msh.bbox.min.z;
00067
00068 RGB material_col = Firebrick;
00069 RGB light_col1 = White;
00070 RGB light_col2 = White * .0;
00071
00072 Vector light_dir1(.2, 0, 1);
00073
00074
00075 for(int f = 0; f < msh.total_triangles; ++f)
00076 {
00077 int i = msh.F[f].i, j = msh.F[f].j, k = msh.F[f].k;
00078 int ni = msh.F[f].ni, nj = msh.F[f].nj, nk = msh.F[f].nk;
00079
00080 RGB col1, col2, col3;
00081
00082 if(has_normal)
00083 {
00084 col1 = compute_lighting(material_col, light_col1, light_dir1, &msh.N[ni]);
00085 col2 = compute_lighting(material_col, light_col1, light_dir1, &msh.N[nj]);
00086 col3 = compute_lighting(material_col, light_col1, light_dir1, &msh.N[nk]);
00087 }
00088 else
00089 {
00090 col1 = material_col * ( (msh.V[i].z - msh.bbox.min.z) / z_range );
00091 col2 = material_col * ( (msh.V[j].z - msh.bbox.min.z) / z_range );
00092 col3 = material_col * ( (msh.V[k].z - msh.bbox.min.z) / z_range );
00093 }
00094 if(draw_wireframe)
00095 canvas.WireTriangle( (msh.V[i] + translate) * scale, col1,
00096 (msh.V[j] + translate) * scale, col2,
00097 (msh.V[k] + translate) * scale, col3);
00098 else
00099 {
00100 canvas.SolidTriangle( (msh.V[i] + translate) * scale, col1,
00101 (msh.V[j] + translate) * scale, col2,
00102 (msh.V[k] + translate) * scale, col3);
00103 }
00104 }
00105
00106 canvas.WritePPM();
00107 }
00108 catch(char const* msg)
00109 {
00110 std :: cerr << msg << std :: endl;
00111 }
00112
00113
00114 return 0;
00115 }
00116