Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

MaterialList.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 1995-2019 The Board of Trustees of the
00004  *cr                        University of Illinois
00005  *cr                         All Rights Reserved
00006  *cr
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: MaterialList.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.36 $      $Date: 2019/01/17 21:21:00 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *   Material properties list structure, master list of all materials
00019  ***************************************************************************/
00020 
00021 #include "MaterialList.h"
00022 #include "Displayable.h"
00023 #include <stdio.h>
00024 #include <string.h>
00025 #include <math.h>
00026 
00027 static const Material defOpaque = {
00028   0.00f, // ambient
00029   0.50f, // specular
00030   0.65f, // diffuse
00031  40.00f, // shininess 
00032   0.00f, // mirror    
00033   1.00f, // opacity
00034   0.00f, // outline
00035   0.00f, // outlinewidth
00036   0.00f, // transmode
00037   0      // index
00038 };
00039 
00040 static const Material defTransp = {
00041   0.00f, // ambient
00042   0.50f, // specular
00043   0.65f, // diffuse
00044  40.00f, // shininess 
00045   0.00f, // mirror    
00046   0.30f, // opacity
00047   0.00f, // outline
00048   0.00f, // outlinewidth
00049   0.00f, // transmode
00050   1      // index
00051 };
00052 
00053 
00054 // raw shininess values will run from 1 to 1000, but be scaled from 0 to 1
00055 // in the user interface.  If y is the internal value and x is the 
00056 // external (user interface value), then y = A exp(k * (x-0.5)), where...
00057 static const double SHINY_A = sqrt(1000.0);  // ...and...
00058 static const double SHINY_k = log(1000.0);
00059 
00060 MaterialList::MaterialList(Displayable *rootd) : root(rootd) {
00061   mlist = new NameList<Material *>;
00062   Material *opaque, *transp;
00063   opaque = new Material;
00064   transp = new Material;
00065   memcpy(opaque, &defOpaque, sizeof(Material));
00066   memcpy(transp, &defTransp, sizeof(Material));
00067   
00068   // add to list 
00069   mlist->add_name("Opaque",opaque);
00070   mlist->add_name("Transparent",transp);
00071 
00072   // the update_material makes all child displayables update as well; this
00073   // is needed in the case of Scene::root to make sure that Scene::background
00074   // is properly initialized.
00075   root->update_material(material(0));
00076   matcounter = 2;
00077 }
00078 
00079 void MaterialList::notify(int ind) {
00080   const Material *mat = mlist->data(ind);
00081   root->update_material(mat);
00082 }
00083 
00084 MaterialList::~MaterialList() {
00085   for (int i=0; i<mlist->num(); i++) delete mlist->data(i);
00086   delete mlist;
00087 }
00088 
00089 void MaterialList::set_name(int i, const char *nm) {
00090   mlist->set_name(i, nm);
00091 }
00092 
00093 void MaterialList::set_ambient(int i, float f) {
00094   if (i<0 || i >= num()) return;
00095   mlist->data(i)->ambient = f;
00096   notify(i);
00097 }
00098  
00099 void MaterialList::set_specular(int i, float f) {
00100   if (i<0 || i >= num()) return;
00101   mlist->data(i)->specular = f;
00102   notify(i);
00103 }
00104  
00105 void MaterialList::set_diffuse(int i, float f) {
00106   if (i<0 || i >= num()) return;
00107   mlist->data(i)->diffuse = f;
00108   notify(i);
00109 }
00110  
00111 void MaterialList::set_shininess(int i, float f) {
00112   if (i<0 || i >= num()) return;
00113   double val = SHINY_A * exp(SHINY_k * (f-0.5));
00114   mlist->data(i)->shininess = (float) val;
00115   notify(i);
00116 }
00117 
00118 void MaterialList::set_mirror(int i, float f) {
00119   if (i<0 || i >= num()) return;
00120   mlist->data(i)->mirror = f;
00121   notify(i);
00122 }
00123  
00124 void MaterialList::set_opacity(int i, float f) {
00125   if (i<0 || i >= num()) return;
00126   mlist->data(i)->opacity = f;
00127   notify(i);
00128 }
00129 
00130 void MaterialList::set_outline(int i, float f) {
00131   if (i<0 || i >= num()) return;
00132   mlist->data(i)->outline = f;
00133   notify(i);
00134 }
00135 
00136 void MaterialList::set_outlinewidth(int i, float f) {
00137   if (i<0 || i >= num()) return;
00138   mlist->data(i)->outlinewidth = f;
00139   notify(i);
00140 }
00141 
00142 void MaterialList::set_transmode(int i, float f) {
00143   if (i<0 || i >= num()) return;
00144   mlist->data(i)->transmode = f;
00145   notify(i);
00146 }
00147  
00148 const char *MaterialList::add_material(const char *newname, 
00149                                        const char *copyfrom) {
00150   int copyind = 0;
00151   if (copyfrom) {
00152     copyind = material_index(copyfrom);
00153     if (copyind < 0) return NULL;  // material to copy from does not exist
00154   }
00155   char buf[20];
00156   const char *name = newname;
00157   if (!name) {
00158     // find a new unique name.
00159     int id = mlist->num();
00160     do {
00161       sprintf(buf, "Material%d", id++);
00162       name = buf;
00163     } while (mlist->typecode(name) >= 0);
00164   } else {
00165     if (mlist->typecode(name) >= 0)
00166       return NULL; // name already present
00167   }
00168   Material *newmat = new Material;
00169   memcpy(newmat, mlist->data(copyind), sizeof(Material));
00170   newmat->ind = matcounter++;
00171   int ind = mlist->add_name(name, newmat);
00172   return mlist->name(ind);
00173 } 
00174 
00175 float MaterialList::get_ambient(int i) {
00176   return mlist->data(i)->ambient;
00177 }
00178 
00179 float MaterialList::get_specular(int i) {
00180   return mlist->data(i)->specular;
00181 }
00182 
00183 float MaterialList::get_diffuse(int i) {
00184   return mlist->data(i)->diffuse;
00185 }
00186 
00187 float MaterialList::get_shininess(int i) {
00188   double val = mlist->data(i)->shininess;
00189   return ((float) (log(val/SHINY_A)/SHINY_k + 0.5f)); 
00190 }
00191 
00192 float MaterialList::get_mirror(int i) {
00193   return mlist->data(i)->mirror;
00194 }
00195 
00196 float MaterialList::get_opacity(int i) {
00197   return mlist->data(i)->opacity;
00198 }
00199 
00200 float MaterialList::get_outline(int i) {
00201   return mlist->data(i)->outline;
00202 }
00203 
00204 float MaterialList::get_outlinewidth(int i) {
00205   return mlist->data(i)->outlinewidth;
00206 }
00207 
00208 float MaterialList::get_transmode(int i) {
00209   return mlist->data(i)->transmode;
00210 }
00211 
00212 int MaterialList::delete_material(int n) {
00213   int i, num = mlist->num();
00214   if (n < 2 || n >= num) 
00215     return FALSE;
00216 
00217   NameList<Material *> *newlist = new NameList<Material *>;
00218   for (i=0; i<num; i++) {
00219     Material *mat = mlist->data(i);
00220     if (i == n) {
00221       delete mat;
00222     } else {
00223       mat->ind = newlist->num();   
00224       newlist->add_name(mlist->name(i), mat); 
00225     }
00226   }
00227   delete mlist;
00228   mlist = newlist;
00229 
00230   // notify displayables that material n has been deleted.  Pass reference
00231   // to self so that the displayable can get a new material if it's old
00232   // one was deleted.
00233   root->delete_material(n, this);
00234   return TRUE;
00235 }
00236 
00237 int MaterialList::restore_default(int ind) {
00238   if (ind == 0 || ind == 1) {
00239     Material *mat = mlist->data(ind);
00240     const Material *from = (ind == 0) ? &defOpaque : &defTransp;
00241     memcpy(mat, from, sizeof(Material));
00242     notify(ind);
00243     return TRUE;
00244   }
00245   return FALSE;
00246 }
00247 

Generated on Fri Apr 19 02:44:33 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002