//------------------------------------------------------------------------------ // gso_Renderer class -- // (C) Piero Giubilato 2008-1010, Berkeley Lab -- //------------------------------------------------------------------------------ //______________________________________________________________________________ // {Trace} // [File name] "gso_Renderer.cpp" // [Author] "Piero Giubilato" // [Version] "0.5" // [Modified by] "Piero Giubilato" // [Last revision] "22 Jan 2008" // [Language] "C++" // [Compiler] "Visual C++ 9.x" // [Member of] "Cool SEAL" // [Project] "SEAL" // [Description] "Source for the gso_Renderer class" // [Key documentation] // "Visual C++ Reference Help" // "Root reference guide" // {Trace} //______________________________________________________________________________ // Standard component #include // Application component #include "global.h" #include "gso_Renderer.h" // Static member instantiation // Deafult consts const Float_t gso_Renderer::kl_Default = 0.7; //const Double_t gso_Renderer::km_Amb = 0.2; // Ambient reflection //const Double_t gso_Renderer::km_Diff = 1.6; // Diffuse reflection //const Double_t gso_Renderer::km_Spec = 1.2; // Specular reflection //const Double_t gso_Renderer::km_Shine = 50; // Shininess const gso_Material gso_Renderer::k_Material(0,0.2,1.6,1.2,50); // Material // Global light properties UInt_t gso_Renderer::light_Mode = 0; Double_t gso_Renderer::light_Strenght = 1; TVector3 gso_Renderer::light_Vect(2,4,-6); Double_t gso_Renderer::light_Color[3] = {1,1,1}; // Global default material pproperties Double_t gso_Renderer::mk_Amb = 0.2; // Ambient reflection Double_t gso_Renderer::mk_Diff = 1.6; // Diffuse reflection Double_t gso_Renderer::mk_Spec = 1.2; // Specular reflection Double_t gso_Renderer::mk_Shine = 50; // Shininess //______________________________________________________________________________ gso_Renderer::gso_Renderer() { // Default constructor dbg_Print("gso_Renderer::gso_Renderer:()", DBG_LVL_FLOW); } //______________________________________________________________________________ gso_Renderer::~gso_Renderer() { // Default constructor dbg_Print("gso_Renderer::~gso_Renderer:()", DBG_LVL_FLOW); } //______________________________________________________________________________ UInt_t gso_Renderer::l_Mode() { // Returns the light mode return light_Mode; } //______________________________________________________________________________ UInt_t gso_Renderer::l_Mode(UInt_t mode) { // Sets the light mode light_Mode = mode; return light_Mode; } //______________________________________________________________________________ Double_t gso_Renderer::l_Strenght() { // Returns the light mode return light_Strenght; } //______________________________________________________________________________ Double_t gso_Renderer::l_Strenght(Double_t strenght) { // Setsthe light mode light_Strenght = strenght; return light_Strenght; } //______________________________________________________________________________ void gso_Renderer::l_Vect(Float_t* x, Float_t* y, Float_t* z) { // Returns the light vector *x = (Float_t)light_Vect.X(); *y = (Float_t)light_Vect.Y(); *z = (Float_t)light_Vect.Z(); } //______________________________________________________________________________ void gso_Renderer::l_Vect(Float_t x, Float_t y, Float_t z) { // Sets the light vector light_Vect.SetXYZ(x, y, z); } //______________________________________________________________________________ void gso_Renderer::l_Color(Float_t* r, Float_t* g, Float_t* b) { // Returns the light color *r = (Float_t)light_Color[0]; *g = (Float_t)light_Color[1]; *b = (Float_t)light_Color[2]; } //______________________________________________________________________________ void gso_Renderer::l_Color(Float_t r, Float_t g, Float_t b) { // Sets the light color light_Color[0] = r; light_Color[1] = g; light_Color[2] = b; } //______________________________________________________________________________ void gso_Renderer::m_Set(Double_t k_Amb, Double_t k_Diff, Double_t k_Spec, Double_t k_Shine) { // Sets the parameter for the rendered material (it would be nice to implement // a material library... no time at the moment!!) dbg_Print("gso_Renderer::m_Set:(scalars)", DBG_LVL_FLOW); // k_Amb -> Material ambient reflection, std = 0.2 // k_Diff -> Material diffuse reflection, std = 1.6 // k_Spec -> Material specular reflection, std = 1.2 // k_Diff -> Material shineness spread, std = 50 (plastic) ... 200(metal) // See a Phong algorithm description for more info on these parameters // Simply set mk_Amb = k_Amb; mk_Diff = k_Diff; mk_Spec = k_Spec; mk_Shine = k_Shine; } //______________________________________________________________________________ void gso_Renderer::m_Set(const gso_Material* mat) { // Sets the parameter for the rendered material (it would be nice to implement // a material library... no time at the moment!!) dbg_Print("gso_Renderer::m_Set:(gso_Material)", DBG_LVL_FLOW); // Simply set mk_Amb = mat->k_Amb; mk_Diff = mat->k_Diff; mk_Spec = mat->k_Spec; mk_Shine = mat->k_Shine; } //______________________________________________________________________________ void gso_Renderer::light_Map(Float_t* light_Map, const Float_t* surf_Map, UInt_t map_Width, UInt_t map_Height) { // This function built a light map starting from a surface point elevation map. // // **************************************************************** // *** IMPORTANT: the function assumes a surf_Map of 1 unit per *** // *** dimension bigger than the generated lightMap! *** // **************************************************************** // dbg_Print("gso_Renderer::light_Map:(default)", DBG_LVL_FLOW); // (x,y)-------(x+1,y) // | // | // | // (x,y+1) // default light (to be replaced by renderer light...) TVector3 l_Amb(1, 1, 1); // Ambient light color strenght TVector3 l_Diff(1, 1, 1); // Diffuse light color strenght TVector3 l_Spec(1, 1, 1); // Specular light color strenght // Creates a shifted (dim + 1) map to interpolate the original height values. // -------------------------------------------------------------------------- UInt_t surf_Width = map_Width + 1; UInt_t surf_Height = map_Height + 1; UInt_t surf_Front = 0, map_Front = 0; /* UInt_t poly_Width = surf_Width + 1; UInt_t poly_Height = surf_Height + 1; Float_t* poly_Map = new Float_t[poly_Width * poly_Height]; // Pivot position UInt_t poly_TL = 0; UInt_t poly_TR = poly_Width - 1; UInt_t poly_BL = (poly_Height - 1) * poly_Width; UInt_t poly_BR = poly_Height * poly_Width - 1; // Core interpolation for (UInt_t y = 1; y < poly_Height - 1; y++) { surf_Front = y * surf_Width; poly_Front = y * poly_Width; for (UInt_t x = 1; x < poly_Width - 1; x++) { poly_Map[poly_Front + x] = (surf_Map[surf_Front + x] + surf_Map[surf_Front + x - 1] + surf_Map[surf_Front - surf_Width + x] + surf_Map[surf_Front - surf_Width + x - 1]) / 4; } } // Vertical Borders interpolation for (UInt_t y = 1; y < poly_Height - 1; y++) { poly_Map[y * poly_Width] = (surf_Map[surf_Width * (y - 1)] + surf_Map[surf_Width * y]) / 2; // Left border poly_Map[y * poly_Width + poly_TR] = (surf_Map[surf_Width * (y - 1) + surf_Width - 1] + surf_Map[surf_Width * y + surf_Width - 1]) / 2; // Right border } // Horizontal Borders interpolation for (UInt_t x = 1; x < poly_Width - 1; x++) { poly_Map[x] = (surf_Map[x - 1] + surf_Map[x]) / 2; // Top border poly_Map[poly_BL + x] = (surf_Map[surf_Width * (surf_Height - 1) + x - 1] + surf_Map[surf_Width * (surf_Height - 1) + x]) / 2; // Bottom border } // Corners interpolation poly_Map[poly_TL] = (surf_Map[0] + poly_Map[1] + poly_Map[poly_Width]) / 3; // Top Left poly_Map[poly_TR] = (surf_Map[surf_Width - 1] + poly_Map[surf_Width - 1] + poly_Map[2 * (surf_Width + 1)]) / 3; // Top Right poly_Map[poly_BL] = (surf_Map[surf_Width * (surf_Height - 1)] + poly_Map[poly_BL - poly_Width] + poly_Map[poly_BL + 1]) / 3; // Bottom Left poly_Map[poly_BR] = (surf_Map[surf_Width * surf_Height - 1] + poly_Map[poly_BR - poly_Width] + poly_Map[poly_BR - 1]) / 3; // Top Left */ // RENDERING (Phong) // ----------------- // Phong model additional vectors TVector3 nV[5]; // Normal to the interpolate surface TVector3 rV(0,0,0); // Reflection vector TVector3 oV(0,0,1); // Observer vector TVector3 lV = light_Vect.Unit(); // Light vector (the same for both diffuse and specular) // Calculates and interpolates the illumination coefficienties TVector3 seg[2]; Float_t z_Point[6] = {0, 0, 0, 0, 0, 0}; Float_t x_Step[6] = {0, -0.5, -0.5, +0.5, +0.5, -0.5}; Float_t y_Step[6] = {0, -0.5, +0.5, +0.5, -0.5, -0.5}; // Rendering scan for (UInt_t y = 0; y < map_Height; y++) { // Get current row front surf_Front = y * surf_Width; map_Front = y * map_Width; // Scans all the columns for (UInt_t x = 0; x < map_Width; x++) { // Computes the relative light slope in case of pointlike source if (light_Mode == 1) { lV.SetXYZ(x - light_Vect.X(), y - light_Vect.Y(), surf_Map[surf_Front + x] - light_Vect.Z()); lV = lV.Unit(); } // Gets the point z_Point[1] = surf_Map[surf_Front + x]; // 1 ----- 4 z_Point[2] = surf_Map[surf_Front + surf_Width + x]; // | \ / | z_Point[3] = surf_Map[surf_Front + surf_Width + x + 1]; // | 0 | z_Point[4] = surf_Map[surf_Front + x + 1]; // | / \ | z_Point[0] = (z_Point[1] + z_Point[2] + // 2 ----- 3 z_Point[3] +z_Point[4]) / 4; z_Point[5] = z_Point[1]; // Computes the normal by averaging the four different // triangles associated to each point nV[0].SetXYZ(0, 0, 0); for (UInt_t i = 1; i < 5; i++) { seg[0].SetXYZ(x_Step[i], y_Step[i], z_Point[i] - z_Point[0]); seg[1].SetXYZ(x_Step[i + 1], y_Step[i + 1], z_Point[i + 1] - z_Point[0]); nV[i] = seg[0].Cross(seg[1]); nV[0] += nV[i]; } nV[0] = nV[0].Unit(); // Computes the reflection vector rV = lV - 2 * nV[0]*lV.Dot(nV[0]); rV = rV.Unit(); // Diffuse light Double_t f_Diff = light_Strenght * mk_Diff * nV[0].Dot(lV); if (f_Diff < 0) f_Diff = 0; // Specular light Double_t f_Spec = light_Strenght * (mk_Spec * pow(rV.Dot(oV), mk_Shine)); if (f_Spec < 0) f_Spec = 0; // Sum up! light_Map[map_Front + x] = (Float_t)(mk_Amb + f_Diff + f_Spec); // General } } // Removed the maps //delete poly_Map; }