1 /*
  2   Copyright (c) 2008 Seneca College
  3   Licenced under the MIT License (http://www.c3dl.org/index.php/mit-license/)
  4 */
  5 
  6 /**
  7   @class c3dl.Material contains values which describe the behaviour of an object when light
  8   illuminates it.  A material can be applied to an object which will make the object appear
  9   to be compose of something rough, shiny, metalic, etc. An object may also emit light, in 
 10   which case a light is not required to be in the scene for the object to be colored/lit.
 11 */
 12 c3dl.Material = function()
 13 {
 14   this.emission = [0,0,0];
 15   this.ambient = [0,0,0];
 16   this.diffuse = [0,0,0];
 17   this.specular = [0,0,0];
 18   this.shininess = 0;
 19   this.name = "unnamed";
 20   
 21   /**
 22     Get a deep copy of this object.
 23 
 24     @returns {c3dl.Material} a deep copy of this object.
 25   */
 26   this.getCopy = function()
 27   {
 28     return c3dl.copyObj(this);
 29   }
 30   
 31   /**
 32     Get the color this material emits.
 33 
 34     @returns {Array} Three float values in the range 0 - 1 in the order RGB.
 35   */
 36   this.getEmission = function()
 37   {
 38     return c3dl.copyObj(this.emission);
 39   }
 40   
 41   /**
 42     Get how much ambient light this material reflects.
 43     
 44     @returns {Array} Three float values in the range 0 - 1 in the order RGB.
 45   */
 46   this.getAmbient = function()
 47   {
 48     return c3dl.copyObj(this.ambient);
 49   }
 50   
 51   /**
 52     Get how much diffuse light this material reflects.
 53   
 54     @returns {Array} Three float values in the range 0 - 1 in the order RGB.
 55   */
 56   this.getDiffuse = function()
 57   {
 58     return c3dl.copyObj(this.diffuse);
 59   }
 60 
 61   /**
 62     Get the name of this material.
 63 
 64     @returns {String} name of this material.
 65   */
 66   this.getName = function()
 67   {
 68     return this.name;
 69   }
 70 
 71   /**
 72     Get how much specular light this material reflects.
 73   
 74     @returns {Array} Three float values in the range 0 - 1 in the order RGB.
 75   */
 76   this.getSpecular = function()
 77   {
 78     return c3dl.copyObj(this.specular);
 79   }
 80 
 81   /**
 82     Get how shiny this material is.
 83 
 84     @returns {float}
 85   */
 86   this.getShininess = function()
 87   {
 88     return this.shininess;
 89   }
 90   
 91   /**
 92     Set how much light this material should emit.
 93     
 94     Examples of objects emitting their own light include 
 95     real world lights,
 96     glow-in-the-dark objects,
 97     any objects which should not appear black in absence of lights
 98 
 99     @param {Array} color Three float values in the range 0 - 1 in the order RGB.
100   */
101   this.setEmission = function(color)
102   {
103     if(this.assertColor(color))
104     {
105       this.emission = c3dl.copyObj(color);
106     }
107   }
108   
109   /**
110     Set how much ambient light this material reflects.
111   
112     @param {Array} color Three float values in the range 0 - 1 in the order RGB.
113   */
114   this.setAmbient = function(color)
115   {
116     if(this.assertColor(color))
117     {
118       this.ambient = c3dl.copyObj(color);
119     }
120   }
121   
122   /**
123     Set how much diffuse light this material reflects.
124     
125     @param {Array} color Three float values in the range 0 - 1 in the order RGB.
126   */
127   this.setDiffuse = function(color)
128   {
129     if(this.assertColor(color))
130     {
131       this.diffuse = c3dl.copyObj(color);
132     }
133   }
134 
135   /**
136     Set how much specular light this material reflects.
137       
138     @param {Array} color Three float values in the range 0 - 1 in the order RGB.
139   */
140   this.setSpecular = function(color)
141   {
142     if(this.assertColor(color))
143     {
144       this.specular = c3dl.copyObj(color);
145     }
146   }
147 
148   /**
149     Set how shiny this material is.
150       
151     @param {float} shine
152   */
153   this.setShininess = function(shine)
154   {
155     // allow negatives? what is the maximum?
156     this.shininess = shine;
157   }
158   
159   /**
160     Set a new name for this material. 
161     
162     The default name for materials is "unnamed".
163     
164     @param {String} name New name of the material.
165   */
166   this.setName = function(name)
167   {
168     this.name = name;
169   }
170   
171   /**
172     Get a string representation of this object.
173     
174     @returns {String} A string of all the variables and their values 
175     seperated by <br />.
176   */
177   this.toString = function()
178   {
179     var breakStr = "<br />";
180     
181     return  "Name: "      + this.getName()     + breakStr +
182             "Emission: "  + this.getEmission() + breakStr +
183             "Ambient: "   + this.getAmbient()  + breakStr + 
184             "Diffuse: "   + this.getDiffuse()  + breakStr +
185             "Specular: "  + this.getSpecular() + breakStr +
186             "Shininess: " + this.getShininess();
187   }
188   
189   /**
190     @private
191     
192     @param color
193   */
194   this.assertColor = function(color)
195   {
196     if(color instanceof Array && color.length == 3)
197     {
198       return true;
199     }
200     else
201     {
202       c3dl.debug.logWarning("Invalid argument passed to material set* method." +
203                             "Color values must be arrays with exactly 3 elements.");
204       return false;
205     }
206   }
207 }
208