001/** 002 * Copyright (c) 2008-2014 Ardor Labs, Inc. 003 * 004 * This file is part of Ardor3D. 005 * 006 * Ardor3D is free software: you can redistribute it and/or modify it 007 * under the terms of its license which may be found in the accompanying 008 * LICENSE file or at <http://www.ardor3d.com/LICENSE>. 009 */ 010 011package com.ardor3d.light; 012 013import java.io.IOException; 014import java.io.Serializable; 015 016import com.ardor3d.math.ColorRGBA; 017import com.ardor3d.math.type.ReadOnlyColorRGBA; 018import com.ardor3d.util.export.InputCapsule; 019import com.ardor3d.util.export.OutputCapsule; 020import com.ardor3d.util.export.Savable; 021 022/** 023 * <code>Light</code> defines the attributes of a light element. This class is abstract and intended to be sub-classed 024 * by specific lighting types. A light will illuminate portions of the scene by assigning its properties to the objects 025 * in the scene. This will affect the objects color values, depending on the color of the ambient, diffuse and specular 026 * light components. 027 * 028 * Ambient light defines the general light of the scene, that is the intensity and color of lighting if no particular 029 * lights are affecting it. 030 * 031 * Diffuse lighting defines the reflection of light on matte surfaces. 032 * 033 * Specular lighting defines the reflection of light on shiny surfaces. 034 */ 035public abstract class Light implements Serializable, Savable { 036 037 private static final long serialVersionUID = 1L; 038 039 /** 040 * dark grey (.4, .4, .4, 1) 041 */ 042 public static final ReadOnlyColorRGBA DEFAULT_AMBIENT = new ColorRGBA(0.4f, 0.4f, 0.4f, 1.0f); 043 044 /** 045 * white (1, 1, 1, 1) 046 */ 047 public static final ReadOnlyColorRGBA DEFAULT_DIFFUSE = new ColorRGBA(1, 1, 1, 1); 048 049 /** 050 * white (1, 1, 1, 1) 051 */ 052 public static final ReadOnlyColorRGBA DEFAULT_SPECULAR = new ColorRGBA(1, 1, 1, 1); 053 054 public enum Type { 055 Directional, Point, Spot 056 } 057 058 // light attributes. 059 private final ColorRGBA _ambient = new ColorRGBA(DEFAULT_AMBIENT); 060 private final ColorRGBA _diffuse = new ColorRGBA(DEFAULT_DIFFUSE); 061 private final ColorRGBA _specular = new ColorRGBA(DEFAULT_SPECULAR); 062 063 private boolean _attenuate; 064 private float _constant = 1; 065 private float _linear; 066 private float _quadratic; 067 068 private int _lightMask = 0; 069 private int _backLightMask = 0; 070 071 private boolean _enabled; 072 073 private String _name; 074 075 /** when true, indicates the lights in this lightState will cast shadows. */ 076 protected boolean _shadowCaster; 077 078 /** 079 * Constructor instantiates a new <code>Light</code> object. All light color values are set to white. 080 * 081 */ 082 public Light() {} 083 084 /** 085 * 086 * <code>getType</code> returns the type of the light that has been created. 087 * 088 * @return the type of light that has been created. 089 */ 090 public abstract Type getType(); 091 092 /** 093 * <code>getConstant</code> returns the value for the constant attenuation. 094 * 095 * @return the value for the constant attenuation. 096 */ 097 public float getConstant() { 098 return _constant; 099 } 100 101 /** 102 * <code>setConstant</code> sets the value for the constant attentuation. 103 * 104 * @param constant 105 * the value for the constant attenuation. 106 */ 107 public void setConstant(final float constant) { 108 _constant = constant; 109 } 110 111 /** 112 * <code>getLinear</code> returns the value for the linear attenuation. 113 * 114 * @return the value for the linear attenuation. 115 */ 116 public float getLinear() { 117 return _linear; 118 } 119 120 /** 121 * <code>setLinear</code> sets the value for the linear attentuation. 122 * 123 * @param linear 124 * the value for the linear attenuation. 125 */ 126 public void setLinear(final float linear) { 127 _linear = linear; 128 } 129 130 /** 131 * <code>getQuadratic</code> returns the value for the quadratic attentuation. 132 * 133 * @return the value for the quadratic attenuation. 134 */ 135 public float getQuadratic() { 136 return _quadratic; 137 } 138 139 /** 140 * <code>setQuadratic</code> sets the value for the quadratic attenuation. 141 * 142 * @param quadratic 143 * the value for the quadratic attenuation. 144 */ 145 public void setQuadratic(final float quadratic) { 146 _quadratic = quadratic; 147 } 148 149 /** 150 * <code>isAttenuate</code> returns true if attenuation is to be used for this light. 151 * 152 * @return true if attenuation is to be used, false otherwise. 153 */ 154 public boolean isAttenuate() { 155 return _attenuate; 156 } 157 158 /** 159 * <code>setAttenuate</code> sets if attenuation is to be used. True sets it on, false otherwise. 160 * 161 * @param attenuate 162 * true to use attenuation, false not to. 163 */ 164 public void setAttenuate(final boolean attenuate) { 165 _attenuate = attenuate; 166 } 167 168 /** 169 * 170 * <code>isEnabled</code> returns true if the light is enabled, false otherwise. 171 * 172 * @return true if the light is enabled, false if it is not. 173 */ 174 public boolean isEnabled() { 175 return _enabled; 176 } 177 178 /** 179 * 180 * <code>setEnabled</code> sets the light on or off. True turns it on, false turns it off. 181 * 182 * @param value 183 * true to turn the light on, false to turn it off. 184 */ 185 public void setEnabled(final boolean value) { 186 _enabled = value; 187 } 188 189 /** 190 * <code>getSpecular</code> returns the specular color value for this light. 191 * 192 * @return the specular color value of the light. 193 */ 194 public ReadOnlyColorRGBA getSpecular() { 195 return _specular; 196 } 197 198 /** 199 * <code>setSpecular</code> sets the specular color value for this light. 200 * 201 * @param specular 202 * the specular color value of the light. 203 */ 204 public void setSpecular(final ReadOnlyColorRGBA specular) { 205 _specular.set(specular); 206 } 207 208 /** 209 * <code>getDiffuse</code> returns the diffuse color value for this light. 210 * 211 * @return the diffuse color value for this light. 212 */ 213 public ReadOnlyColorRGBA getDiffuse() { 214 return _diffuse; 215 } 216 217 /** 218 * <code>setDiffuse</code> sets the diffuse color value for this light. 219 * 220 * @param diffuse 221 * the diffuse color value for this light. 222 */ 223 public void setDiffuse(final ReadOnlyColorRGBA diffuse) { 224 _diffuse.set(diffuse); 225 } 226 227 /** 228 * <code>getAmbient</code> returns the ambient color value for this light. 229 * 230 * @return the ambient color value for this light. 231 */ 232 public ReadOnlyColorRGBA getAmbient() { 233 return _ambient; 234 } 235 236 /** 237 * <code>setAmbient</code> sets the ambient color value for this light. 238 * 239 * @param ambient 240 * the ambient color value for this light. 241 */ 242 public void setAmbient(final ReadOnlyColorRGBA ambient) { 243 _ambient.set(ambient); 244 } 245 246 /** 247 * @return Returns the lightMask - default is 0 or not masked. 248 */ 249 public int getLightMask() { 250 return _lightMask; 251 } 252 253 /** 254 * <code>setLightMask</code> sets what attributes of this light to apply as an int comprised of bitwise |'ed values 255 * from LightState.Mask_XXXX. LightMask.MASK_GLOBALAMBIENT is ignored. 256 * 257 * @param lightMask 258 * The lightMask to set. 259 */ 260 public void setLightMask(final int lightMask) { 261 _lightMask = lightMask; 262 } 263 264 /** 265 * Saves the light mask to a back store. That backstore is recalled with popLightMask. Despite the name, this is not 266 * a stack and additional pushes will simply overwrite the backstored value. 267 */ 268 public void pushLightMask() { 269 _backLightMask = _lightMask; 270 } 271 272 /** 273 * Recalls the light mask from a back store or 0 if none was pushed. 274 * 275 * @see com.ardor3d.light.Light#pushLightMask() 276 */ 277 public void popLightMask() { 278 _lightMask = _backLightMask; 279 } 280 281 /** 282 * @return Returns whether this light is able to cast shadows. 283 */ 284 public boolean isShadowCaster() { 285 return _shadowCaster; 286 } 287 288 /** 289 * @param mayCastShadows 290 * true if this light can be used to derive shadows (when used in conjunction with a shadow pass.) 291 */ 292 public void setShadowCaster(final boolean mayCastShadows) { 293 _shadowCaster = mayCastShadows; 294 } 295 296 /** 297 * Copies the light values from the given light into this Light. 298 * 299 * @param light 300 * the Light to copy from. 301 */ 302 public void copyFrom(final Light light) { 303 _ambient.set(light._ambient); 304 _attenuate = light._attenuate; 305 _constant = light._constant; 306 _diffuse.set(light._diffuse); 307 _enabled = light._enabled; 308 _linear = light._linear; 309 _quadratic = light._quadratic; 310 _shadowCaster = light._shadowCaster; 311 _specular.set(light._specular); 312 } 313 314 public String getName() { 315 return _name; 316 } 317 318 public void setName(final String name) { 319 _name = name; 320 } 321 322 @Override 323 public void write(final OutputCapsule capsule) throws IOException { 324 capsule.write(_ambient, "ambient", new ColorRGBA(DEFAULT_AMBIENT)); 325 capsule.write(_diffuse, "diffuse", new ColorRGBA(DEFAULT_DIFFUSE)); 326 capsule.write(_specular, "specular", new ColorRGBA(DEFAULT_SPECULAR)); 327 capsule.write(_attenuate, "attenuate", false); 328 capsule.write(_constant, "constant", 1); 329 capsule.write(_linear, "linear", 0); 330 capsule.write(_quadratic, "quadratic", 0); 331 capsule.write(_lightMask, "lightMask", 0); 332 capsule.write(_backLightMask, "backLightMask", 0); 333 capsule.write(_enabled, "enabled", false); 334 capsule.write(_shadowCaster, "shadowCaster", false); 335 capsule.write(_name, "name", null); 336 } 337 338 @Override 339 public void read(final InputCapsule capsule) throws IOException { 340 _ambient.set((ColorRGBA) capsule.readSavable("ambient", new ColorRGBA(DEFAULT_AMBIENT))); 341 _diffuse.set((ColorRGBA) capsule.readSavable("diffuse", new ColorRGBA(DEFAULT_DIFFUSE))); 342 _specular.set((ColorRGBA) capsule.readSavable("specular", new ColorRGBA(DEFAULT_SPECULAR))); 343 _attenuate = capsule.readBoolean("attenuate", false); 344 _constant = capsule.readFloat("constant", 1); 345 _linear = capsule.readFloat("linear", 0); 346 _quadratic = capsule.readFloat("quadratic", 0); 347 _lightMask = capsule.readInt("lightMask", 0); 348 _backLightMask = capsule.readInt("backLightMask", 0); 349 _enabled = capsule.readBoolean("enabled", false); 350 _shadowCaster = capsule.readBoolean("shadowCaster", false); 351 _name = capsule.readString("name", null); 352 } 353 354 @Override 355 public Class<? extends Light> getClassTag() { 356 return this.getClass(); 357 } 358}