1<?php
2
3/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5/**
6 * 3d Library
7 *
8 * PHP versions 5
9 *
10 * LICENSE:
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
24 *
25 * @category  Image
26 * @package   Image_3D
27 * @author    Kore Nordmann <3d@kore-nordmann.de>
28 * @copyright 1997-2005 Kore Nordmann
29 * @license   http://www.gnu.org/licenses/lgpl.txt lgpl 2.1
30 * @version   CVS: $Id$
31 * @link      http://pear.php.net/package/PackageName
32 * @since     File available since Release 0.1.0
33 */
34
35// {{{ Image_3D_Color
36
37/**
38 * Image_3D_Color
39 *
40 * Base class for colors and textures.
41 *
42 * @category  Image
43 * @package   Image_3D
44 * @author    Kore Nordmann <3d@kore-nordmann.de>
45 * @copyright 1997-2005 Kore Nordmann
46 * @license   http://www.gnu.org/licenses/lgpl.txt lgpl 2.1
47 * @version   Release: @package_version@
48 * @link      http://pear.php.net/package/PackageName
49 * @since     Class available since Release 0.1.0
50 */
51class Image_3D_Color
52{
53
54    // {{{ properties
55
56    /**
57     * Color values
58     *
59     * @var array
60     */
61    protected $_rgbaValue;
62
63    /**
64     * Array with lights which influence this color
65     *
66     * @var array
67     */
68    protected $_lights;
69
70    /**
71     * Resulting light for this color
72     *
73     * @var array
74     */
75    protected $_light;
76
77    /**
78     * Optinal value for reflection
79     *
80     * @var float
81     */
82    protected $_reflection;
83
84    // }}}
85    // {{{ __construct()
86
87    /**
88     * Constructor for Image_3D_Color
89     *
90     * All colors accept values in integer (0 - 255) or float (0 - 1)
91     *
92     * @param mixed $red   red
93     * @param mixed $green green
94     * @param mixed $blue  blue
95     * @param mixed $alpha alpha
96     *
97     * @return  Image_3D_Color              Instance of Color
98     */
99    public function __construct($red = 0., $green = 0., $blue = 0., $alpha = 0., $reflection = null)
100    {
101        $this->_rgbaValue = array();
102
103        $this->_lights = array();
104        $this->_light  = array(0, 0, 0);
105
106        $arglist  = func_get_args();
107        $argcount = func_num_args();
108
109        for ($i = 0; $i < 4; $i++) {
110            if ($i >= $argcount) {
111                $this->_rgbaValue[$i] = 0;
112            } elseif (is_int($arglist[$i])) {
113                $this->_rgbaValue[$i] = (float) min(1, max(0, (float) $arglist[$i] / 255));
114            } elseif (is_float($arglist[$i])) {
115                $this->_rgbaValue[$i] = (float) min(1, max(0, $arglist[$i]));
116            } else {
117                $this->_rgbaValue[$i] = 0;
118            }
119        }
120
121        $this->setReflection($reflection);
122    }
123
124    // }}}
125    // {{{ mixAlpha()
126
127    /**
128     * Apply alphavalue to color
129     *
130     * Apply alpha value to color. It may be int or float. 255 / 1. means full
131     * oppacity
132     *
133     * @param mixed $alpha Alphavalue
134     *
135     * @return  void
136     */
137    public function mixAlpha($alpha = 1.)
138    {
139        if (is_int($alpha)) {
140            $this->_rgbaValue[3] *= (float) min(1, max(0, (float) $alpha / 255));
141        } else {
142            $this->_rgbaValue[3] *= (float) min(1, max(0, (float) $alpha));
143        }
144    }
145
146    // }}}
147    // {{{ setReflection()
148
149    /**
150     * sets reflection intensity
151     *
152     * @param float $reflection reflection
153     *
154     * @return void
155     */
156    public function setReflection($reflection)
157    {
158        $this->_reflection = min(1, max(0, (float) $reflection));
159    }
160
161    // }}}
162    // {{{ getReflection()
163
164    /**
165     * return reflection intensity
166     *
167     * @return  float           reflection
168     */
169    public function getReflection()
170    {
171        if (!isset($this->_reflection)) {
172            return 0;
173        } else {
174            return $this->_reflection;
175        }
176    }
177
178    // }}}
179    // {{{ getValues()
180
181    /**
182     * return RGBA values
183     *
184     * Return an array with rgba-values
185     *  0 =>    (float) red
186     *  1 =>    (float) green
187     *  2 =>    (float) blue
188     *  3 =>    (float) alpha
189     *
190     * @return  array           RGBA-Values
191     */
192    public function getValues()
193    {
194        return $this->_rgbaValue;
195    }
196
197    // }}}
198    // {{{ addLight()
199
200    /**
201     * Add light
202     *
203     * Add an light which influence the object this color is created for
204     *
205     * @param Image_3D_Color $color     Lightcolor
206     * @param mixed          $intensity Intensity
207     *
208     * @return  void
209     */
210    public function addLight(Image_3D_Color $color, $intensity = .5)
211    {
212        $this->_lights[] = array($intensity, $color);
213    }
214
215    // }}}
216    // {{{ _calcLights()
217
218    /**
219     * Calculate lights
220     *
221     * Calculate light depending an all lights which influence this object
222     *
223     * @return  void
224     */
225    protected function _calcLights()
226    {
227        foreach ($this->_lights as $light) {
228            list($intensity, $color) = $light;
229
230            $colorArray = $color->getValues();
231
232            $this->_light[0] += $colorArray[0] * $intensity * (1 - $colorArray[3]);
233            $this->_light[1] += $colorArray[1] * $intensity * (1 - $colorArray[3]);
234            $this->_light[2] += $colorArray[2] * $intensity * (1 - $colorArray[3]);
235        }
236    }
237
238    // }}}
239    // {{{ _mixColor()
240
241    /**
242     * Mix Color with light
243     *
244     * Recalculate color depending on the lights
245     *
246     * @return  void
247     */
248    protected function _mixColor()
249    {
250        $this->_rgbaValue[0] = min(1, $this->_rgbaValue[0] * $this->_light[0]);
251        $this->_rgbaValue[1] = min(1, $this->_rgbaValue[1] * $this->_light[1]);
252        $this->_rgbaValue[2] = min(1, $this->_rgbaValue[2] * $this->_light[2]);
253    }
254
255    // }}}
256    // {{{ calculateColor()
257
258    /**
259     * Calculate new color
260     *
261     * Calculate color depending on the lights
262     *
263     * @return  void
264     */
265    public function calculateColor()
266    {
267        if (!count($this->_lights)) {
268            $this->_rgbaValue = array(0, 0, 0, $this->_rgbaValue[3]);
269            return true;
270        }
271
272        $this->_calcLights();
273        $this->_mixColor();
274    }
275
276    // }}}
277    // {{{ merge()
278
279    /**
280     * Merge with other colors
281     *
282     * Merge color with other colors
283     *
284     * @return  void
285     */
286    public function merge($colors)
287    {
288        $count = 0;
289        foreach ($colors as $color) {
290            if (!($color instanceof Image_3D_Color)) {
291                continue;
292            }
293
294            $values = $color->getValues();
295
296            $this->_rgbaValue[0] += $values[0];
297            $this->_rgbaValue[1] += $values[1];
298            $this->_rgbaValue[2] += $values[2];
299            $this->_rgbaValue[3] += $values[3];
300
301            ++$count;
302        }
303
304        $this->_rgbaValue[0] /= $count;
305        $this->_rgbaValue[1] /= $count;
306        $this->_rgbaValue[2] /= $count;
307        $this->_rgbaValue[3] /= $count;
308
309        return $this;
310    }
311
312    // }}}
313    // {{{ __toString()
314
315    /**
316     * Return Color as string
317     *
318     * Return a string representation of the color
319     *
320     * @return  string          String representation of color
321     */
322    public function __toString()
323    {
324        return sprintf("Color: r %.2f g %.2f b %.2f a %.2f\n", $this->_rgbaValue[0], $this->_rgbaValue[1], $this->_rgbaValue[2], $this->_rgbaValue[3]);
325    }
326
327    // }}}
328}
329
330// }}}
331