• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2009-2010 jMonkeyEngine All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *  *
7  * * Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  *
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  *
14  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
15  * may be used to endorse or promote products derived from this software
16  * without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 package com.jme3.math;
31 
32 import com.jme3.export.*;
33 import java.io.IOException;
34 
35 /**
36  * <code>ColorRGBA</code> defines a color made from a collection of red, green
37  * and blue values. An alpha value determines is transparency. All values must
38  * be between 0 and 1. If any value is set higher or lower than these
39  * constraints they are clamped to the min or max. That is, if a value smaller
40  * than zero is set the value clamps to zero. If a value higher than 1 is
41  * passed, that value is clamped to 1. However, because the attributes r, g, b,
42  * a are public for efficiency reasons, they can be directly modified with
43  * invalid values. The client should take care when directly addressing the
44  * values. A call to clamp will assure that the values are within the
45  * constraints.
46  *
47  * @author Mark Powell
48  * @version $Id: ColorRGBA.java,v 1.29 2007/09/09 18:25:14 irrisor Exp $
49  */
50 public final class ColorRGBA implements Savable, Cloneable, java.io.Serializable {
51 
52     static final long serialVersionUID = 1;
53     /**
54      * the color black (0,0,0).
55      */
56     public static final ColorRGBA Black = new ColorRGBA(0f, 0f, 0f, 1f);
57     /**
58      * the color white (1,1,1).
59      */
60     public static final ColorRGBA White = new ColorRGBA(1f, 1f, 1f, 1f);
61     /**
62      * the color gray (.2,.2,.2).
63      */
64     public static final ColorRGBA DarkGray = new ColorRGBA(0.2f, 0.2f, 0.2f, 1.0f);
65     /**
66      * the color gray (.5,.5,.5).
67      */
68     public static final ColorRGBA Gray = new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f);
69     /**
70      * the color gray (.8,.8,.8).
71      */
72     public static final ColorRGBA LightGray = new ColorRGBA(0.8f, 0.8f, 0.8f, 1.0f);
73     /**
74      * the color red (1,0,0).
75      */
76     public static final ColorRGBA Red = new ColorRGBA(1f, 0f, 0f, 1f);
77     /**
78      * the color green (0,1,0).
79      */
80     public static final ColorRGBA Green = new ColorRGBA(0f, 1f, 0f, 1f);
81     /**
82      * the color blue (0,0,1).
83      */
84     public static final ColorRGBA Blue = new ColorRGBA(0f, 0f, 1f, 1f);
85     /**
86      * the color yellow (1,1,0).
87      */
88     public static final ColorRGBA Yellow = new ColorRGBA(1f, 1f, 0f, 1f);
89     /**
90      * the color magenta (1,0,1).
91      */
92     public static final ColorRGBA Magenta = new ColorRGBA(1f, 0f, 1f, 1f);
93     /**
94      * the color cyan (0,1,1).
95      */
96     public static final ColorRGBA Cyan = new ColorRGBA(0f, 1f, 1f, 1f);
97     /**
98      * the color orange (251/255, 130/255,0).
99      */
100     public static final ColorRGBA Orange = new ColorRGBA(251f / 255f, 130f / 255f, 0f, 1f);
101     /**
102      * the color brown (65/255, 40/255, 25/255).
103      */
104     public static final ColorRGBA Brown = new ColorRGBA(65f / 255f, 40f / 255f, 25f / 255f, 1f);
105     /**
106      * the color pink (1, 0.68, 0.68).
107      */
108     public static final ColorRGBA Pink = new ColorRGBA(1f, 0.68f, 0.68f, 1f);
109     /**
110      * the black color with no alpha (0, 0, 0, 0);
111      */
112     public static final ColorRGBA BlackNoAlpha = new ColorRGBA(0f, 0f, 0f, 0f);
113     /**
114      * The red component of the color.
115      */
116     public float r;
117     /**
118      * The green component of the color.
119      */
120     public float g;
121     /**
122      * the blue component of the color.
123      */
124     public float b;
125     /**
126      * the alpha component of the color. 0 is transparent and 1 is opaque
127      */
128     public float a;
129 
130     /**
131      * Constructor instantiates a new <code>ColorRGBA</code> object. This
132      * color is the default "white" with all values 1.
133      *
134      */
ColorRGBA()135     public ColorRGBA() {
136         r = g = b = a = 1.0f;
137     }
138 
139     /**
140      * Constructor instantiates a new <code>ColorRGBA</code> object. The
141      * values are defined as passed parameters. These values are then clamped
142      * to insure that they are between 0 and 1.
143      * @param r the red component of this color.
144      * @param g the green component of this color.
145      * @param b the blue component of this color.
146      * @param a the alpha component of this color.
147      */
ColorRGBA(float r, float g, float b, float a)148     public ColorRGBA(float r, float g, float b, float a) {
149         this.r = r;
150         this.g = g;
151         this.b = b;
152         this.a = a;
153     }
154 
155     /**
156      * Copy constructor creates a new <code>ColorRGBA</code> object, based on
157      * a provided color.
158      * @param rgba the <code>ColorRGBA</code> object to copy.
159      */
ColorRGBA(ColorRGBA rgba)160     public ColorRGBA(ColorRGBA rgba) {
161         this.a = rgba.a;
162         this.r = rgba.r;
163         this.g = rgba.g;
164         this.b = rgba.b;
165     }
166 
167     /**
168      *
169      * <code>set</code> sets the RGBA values of this color. The values are then
170      * clamped to insure that they are between 0 and 1.
171      *
172      * @param r the red component of this color.
173      * @param g the green component of this color.
174      * @param b the blue component of this color.
175      * @param a the alpha component of this color.
176      * @return this
177      */
set(float r, float g, float b, float a)178     public ColorRGBA set(float r, float g, float b, float a) {
179         this.r = r;
180         this.g = g;
181         this.b = b;
182         this.a = a;
183         return this;
184     }
185 
186     /**
187      * <code>set</code> sets the values of this color to those set by a parameter
188      * color.
189      *
190      * @param rgba ColorRGBA the color to set this color to.
191      * @return this
192      */
set(ColorRGBA rgba)193     public ColorRGBA set(ColorRGBA rgba) {
194         if (rgba == null) {
195             r = 0;
196             g = 0;
197             b = 0;
198             a = 0;
199         } else {
200             r = rgba.r;
201             g = rgba.g;
202             b = rgba.b;
203             a = rgba.a;
204         }
205         return this;
206     }
207 
208     /**
209      * <code>clamp</code> insures that all values are between 0 and 1. If any
210      * are less than 0 they are set to zero. If any are more than 1 they are
211      * set to one.
212      *
213      */
clamp()214     public void clamp() {
215         if (r < 0) {
216             r = 0;
217         } else if (r > 1) {
218             r = 1;
219         }
220 
221         if (g < 0) {
222             g = 0;
223         } else if (g > 1) {
224             g = 1;
225         }
226 
227         if (b < 0) {
228             b = 0;
229         } else if (b > 1) {
230             b = 1;
231         }
232 
233         if (a < 0) {
234             a = 0;
235         } else if (a > 1) {
236             a = 1;
237         }
238     }
239 
240     /**
241      *
242      * <code>getColorArray</code> retrieves the color values of this object as
243      * a four element float array.
244      * @return the float array that contains the color elements.
245      */
getColorArray()246     public float[] getColorArray() {
247         return new float[]{r, g, b, a};
248     }
249 
250     /**
251      * Stores the current r/g/b/a values into the tempf array.  The tempf array must have a
252      * length of 4 or greater, or an array index out of bounds exception will be thrown.
253      * @param store The array of floats to store the values into.
254      * @return The float[] after storage.
255      */
getColorArray(float[] store)256     public float[] getColorArray(float[] store) {
257         store[0] = r;
258         store[1] = g;
259         store[2] = b;
260         store[3] = a;
261         return store;
262     }
263 
getAlpha()264     public float getAlpha() {
265         return a;
266     }
267 
getRed()268     public float getRed() {
269         return r;
270     }
271 
getBlue()272     public float getBlue() {
273         return b;
274     }
275 
getGreen()276     public float getGreen() {
277         return g;
278     }
279 
280     /**
281      * Sets this color to the interpolation by changeAmnt from this to the finalColor
282      * this=(1-changeAmnt)*this + changeAmnt * finalColor
283      * @param finalColor The final color to interpolate towards
284      * @param changeAmnt An amount between 0.0 - 1.0 representing a precentage
285      *  change from this towards finalColor
286      */
interpolate(ColorRGBA finalColor, float changeAmnt)287     public void interpolate(ColorRGBA finalColor, float changeAmnt) {
288         this.r = (1 - changeAmnt) * this.r + changeAmnt * finalColor.r;
289         this.g = (1 - changeAmnt) * this.g + changeAmnt * finalColor.g;
290         this.b = (1 - changeAmnt) * this.b + changeAmnt * finalColor.b;
291         this.a = (1 - changeAmnt) * this.a + changeAmnt * finalColor.a;
292     }
293 
294     /**
295      * Sets this color to the interpolation by changeAmnt from beginColor to finalColor
296      * this=(1-changeAmnt)*beginColor + changeAmnt * finalColor
297      * @param beginColor The begining color (changeAmnt=0)
298      * @param finalColor The final color to interpolate towards (changeAmnt=1)
299      * @param changeAmnt An amount between 0.0 - 1.0 representing a precentage
300      *  change from beginColor towards finalColor
301      */
interpolate(ColorRGBA beginColor, ColorRGBA finalColor, float changeAmnt)302     public void interpolate(ColorRGBA beginColor, ColorRGBA finalColor, float changeAmnt) {
303         this.r = (1 - changeAmnt) * beginColor.r + changeAmnt * finalColor.r;
304         this.g = (1 - changeAmnt) * beginColor.g + changeAmnt * finalColor.g;
305         this.b = (1 - changeAmnt) * beginColor.b + changeAmnt * finalColor.b;
306         this.a = (1 - changeAmnt) * beginColor.a + changeAmnt * finalColor.a;
307     }
308 
309     /**
310      *
311      * <code>randomColor</code> is a utility method that generates a random
312      * color.
313      *
314      * @return a random color.
315      */
randomColor()316     public static ColorRGBA randomColor() {
317         ColorRGBA rVal = new ColorRGBA(0, 0, 0, 1);
318         rVal.r = FastMath.nextRandomFloat();
319         rVal.g = FastMath.nextRandomFloat();
320         rVal.b = FastMath.nextRandomFloat();
321         return rVal;
322     }
323 
324     /**
325      * Multiplies each r/g/b/a of this color by the r/g/b/a of the given color and
326      * returns the result as a new ColorRGBA.  Used as a way of combining colors and lights.
327      * @param c The color to multiply.
328      * @return The new ColorRGBA.  this*c
329      */
mult(ColorRGBA c)330     public ColorRGBA mult(ColorRGBA c) {
331         return new ColorRGBA(c.r * r, c.g * g, c.b * b, c.a * a);
332     }
333 
334     /**
335      * Multiplies each r/g/b/a of this color by the given scalar and
336      * returns the result as a new ColorRGBA.  Used as a way of making colors dimmer
337      * or brighter..
338      * @param scalar The scalar to multiply.
339      * @return The new ColorRGBA.  this*scalar
340      */
mult(float scalar)341     public ColorRGBA mult(float scalar) {
342         return new ColorRGBA(scalar * r, scalar * g, scalar * b, scalar * a);
343     }
344 
345     /**
346      * Multiplies each r/g/b/a of this color by the r/g/b/a of the given color and
347      * returns the result as a new ColorRGBA.  Used as a way of combining colors and lights.
348      * @param scalar scalar to multiply with
349      * @return The new ColorRGBA.  this*c
350      */
multLocal(float scalar)351     public ColorRGBA multLocal(float scalar) {
352         this.r *= scalar;
353         this.g *= scalar;
354         this.b *= scalar;
355         this.a *= scalar;
356         return this;
357     }
358 
359     /**
360      * Adds each r/g/b/a of this color by the r/g/b/a of the given color and
361      * returns the result as a new ColorRGBA.
362      * @param c The color to add.
363      * @return The new ColorRGBA.  this+c
364      */
add(ColorRGBA c)365     public ColorRGBA add(ColorRGBA c) {
366         return new ColorRGBA(c.r + r, c.g + g, c.b + b, c.a + a);
367     }
368 
369     /**
370      * Multiplies each r/g/b/a of this color by the r/g/b/a of the given color and
371      * returns the result as a new ColorRGBA.  Used as a way of combining colors and lights.
372      * @param c The color to multiply.
373      * @return The new ColorRGBA.  this*c
374      */
addLocal(ColorRGBA c)375     public ColorRGBA addLocal(ColorRGBA c) {
376         set(c.r + r, c.g + g, c.b + b, c.a + a);
377         return this;
378     }
379 
380     /**
381      * <code>toString</code> returns the string representation of this color.
382      * The format of the string is:<br>
383      * <Class Name>: [R=RR.RRRR, G=GG.GGGG, B=BB.BBBB, A=AA.AAAA]
384      * @return the string representation of this color.
385      */
toString()386     public String toString() {
387         return "Color[" + r + ", " + g + ", " + b + ", " + a + "]";
388     }
389 
390     @Override
clone()391     public ColorRGBA clone() {
392         try {
393             return (ColorRGBA) super.clone();
394         } catch (CloneNotSupportedException e) {
395             throw new AssertionError(); // can not happen
396         }
397     }
398 
399     /**
400      * Saves this ColorRGBA into the given float[] object.
401      *
402      * @param floats
403      *            The float[] to take this ColorRGBA. If null, a new float[4] is
404      *            created.
405      * @return The array, with R, G, B, A float values in that order
406      */
toArray(float[] floats)407     public float[] toArray(float[] floats) {
408         if (floats == null) {
409             floats = new float[4];
410         }
411         floats[0] = r;
412         floats[1] = g;
413         floats[2] = b;
414         floats[3] = a;
415         return floats;
416     }
417 
418     /**
419      * <code>equals</code> returns true if this color is logically equivalent
420      * to a given color. That is, if the values of the two colors are the same.
421      * False is returned otherwise.
422      * @param o the object to compare againts.
423      * @return true if the colors are equal, false otherwise.
424      */
equals(Object o)425     public boolean equals(Object o) {
426         if (!(o instanceof ColorRGBA)) {
427             return false;
428         }
429 
430         if (this == o) {
431             return true;
432         }
433 
434         ColorRGBA comp = (ColorRGBA) o;
435         if (Float.compare(r, comp.r) != 0) {
436             return false;
437         }
438         if (Float.compare(g, comp.g) != 0) {
439             return false;
440         }
441         if (Float.compare(b, comp.b) != 0) {
442             return false;
443         }
444         if (Float.compare(a, comp.a) != 0) {
445             return false;
446         }
447         return true;
448     }
449 
450     /**
451      * <code>hashCode</code> returns a unique code for this color object based
452      * on it's values. If two colors are logically equivalent, they will return
453      * the same hash code value.
454      * @return the hash code value of this color.
455      */
hashCode()456     public int hashCode() {
457         int hash = 37;
458         hash += 37 * hash + Float.floatToIntBits(r);
459         hash += 37 * hash + Float.floatToIntBits(g);
460         hash += 37 * hash + Float.floatToIntBits(b);
461         hash += 37 * hash + Float.floatToIntBits(a);
462         return hash;
463     }
464 
write(JmeExporter e)465     public void write(JmeExporter e) throws IOException {
466         OutputCapsule capsule = e.getCapsule(this);
467         capsule.write(r, "r", 0);
468         capsule.write(g, "g", 0);
469         capsule.write(b, "b", 0);
470         capsule.write(a, "a", 0);
471     }
472 
read(JmeImporter e)473     public void read(JmeImporter e) throws IOException {
474         InputCapsule capsule = e.getCapsule(this);
475         r = capsule.readFloat("r", 0);
476         g = capsule.readFloat("g", 0);
477         b = capsule.readFloat("b", 0);
478         a = capsule.readFloat("a", 0);
479     }
480 
asBytesRGBA()481     public byte[] asBytesRGBA() {
482         byte[] store = new byte[4];
483         store[0] = (byte) ((int) (r * 255) & 0xFF);
484         store[1] = (byte) ((int) (g * 255) & 0xFF);
485         store[2] = (byte) ((int) (b * 255) & 0xFF);
486         store[3] = (byte) ((int) (a * 255) & 0xFF);
487         return store;
488     }
489 
asIntARGB()490     public int asIntARGB() {
491         int argb = (((int) (a * 255) & 0xFF) << 24)
492                 | (((int) (r * 255) & 0xFF) << 16)
493                 | (((int) (g * 255) & 0xFF) << 8)
494                 | (((int) (b * 255) & 0xFF));
495         return argb;
496     }
497 
asIntRGBA()498     public int asIntRGBA() {
499         int rgba = (((int) (r * 255) & 0xFF) << 24)
500                 | (((int) (g * 255) & 0xFF) << 16)
501                 | (((int) (b * 255) & 0xFF) << 8)
502                 | (((int) (a * 255) & 0xFF));
503         return rgba;
504     }
505 
asIntABGR()506     public int asIntABGR() {
507         int abgr = (((int) (a * 255) & 0xFF) << 24)
508                 | (((int) (b * 255) & 0xFF) << 16)
509                 | (((int) (g * 255) & 0xFF) << 8)
510                 | (((int) (r * 255) & 0xFF));
511         return abgr;
512     }
513 
fromIntARGB(int color)514     public void fromIntARGB(int color) {
515         a = ((byte) (color >> 24) & 0xFF) / 255f;
516         r = ((byte) (color >> 16) & 0xFF) / 255f;
517         g = ((byte) (color >> 8) & 0xFF) / 255f;
518         b = ((byte) (color) & 0xFF) / 255f;
519     }
520 
fromIntRGBA(int color)521     public void fromIntRGBA(int color) {
522         r = ((byte) (color >> 24) & 0xFF) / 255f;
523         g = ((byte) (color >> 16) & 0xFF) / 255f;
524         b = ((byte) (color >> 8) & 0xFF) / 255f;
525         a = ((byte) (color) & 0xFF) / 255f;
526     }
527 
528     /**
529      * Transform the current ColorRGBA to a Vector3f using
530      * x = r, y = g, z = b. The Alpha value is not used.
531      *
532      * This method is useful to use for shaders assignment.
533      * @return A Vector3f containing the RGB value of current color definition.
534      */
toVector3f()535     public Vector3f toVector3f() {
536         return new Vector3f(r, g, b);
537     }
538 
539     /**
540      * Transform the current ColorRGBA to a Vector4f using
541      * x = r, y = g, z = b, w = a.
542      *
543      * This method is useful to use for shaders assignment.
544      * @return A Vector4f containing the RGBA value of current color definition.
545      */
toVector4f()546     public Vector4f toVector4f() {
547         return new Vector4f(r, g, b, a);
548     }
549 }
550