KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > ext > awt > image > renderable > SpecularLightingRable8Bit


1 /*
2
3    Copyright 2001,2003 The Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16
17  */

18 package org.apache.batik.ext.awt.image.renderable;
19
20 import java.awt.Rectangle JavaDoc;
21 import java.awt.RenderingHints JavaDoc;
22 import java.awt.Shape JavaDoc;
23 import java.awt.geom.AffineTransform JavaDoc;
24 import java.awt.geom.Rectangle2D JavaDoc;
25 import java.awt.image.RenderedImage JavaDoc;
26 import java.awt.image.renderable.RenderContext JavaDoc;
27
28 import org.apache.batik.ext.awt.image.GraphicsUtil;
29 import org.apache.batik.ext.awt.image.Light;
30 import org.apache.batik.ext.awt.image.PadMode;
31 import org.apache.batik.ext.awt.image.rendered.AffineRed;
32 import org.apache.batik.ext.awt.image.rendered.BumpMap;
33 import org.apache.batik.ext.awt.image.rendered.CachableRed;
34 import org.apache.batik.ext.awt.image.rendered.PadRed;
35 import org.apache.batik.ext.awt.image.rendered.SpecularLightingRed;
36
37 /**
38  * Implementation of the SpecularLightRable interface.
39  *
40  * @author <a HREF="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
41  * @version $Id: SpecularLightingRable8Bit.java,v 1.14 2005/03/27 08:58:33 cam Exp $
42  */

43 public class SpecularLightingRable8Bit
44     extends AbstractColorInterpolationRable
45     implements SpecularLightingRable {
46     /**
47      * Surface Scale
48      */

49     private double surfaceScale;
50
51     /**
52      * Specular constant
53      */

54     private double ks;
55
56     /**
57      * Specular exponent
58      */

59     private double specularExponent;
60
61     /**
62      * Light used for the specular lighting computations
63      */

64     private Light light;
65
66     /**
67      * Lit Area
68      */

69     private Rectangle2D JavaDoc litRegion;
70
71     /**
72      * The dx/dy to use in user space for the sobel gradient.
73      */

74     private float [] kernelUnitLength = null;
75
76     public SpecularLightingRable8Bit(Filter src,
77                                      Rectangle2D JavaDoc litRegion,
78                                      Light light,
79                                      double ks,
80                                      double specularExponent,
81                                      double surfaceScale,
82                                      double [] kernelUnitLength) {
83         super(src, null);
84         setLight(light);
85         setKs(ks);
86         setSpecularExponent(specularExponent);
87         setSurfaceScale(surfaceScale);
88         setLitRegion(litRegion);
89         setKernelUnitLength(kernelUnitLength);
90     }
91
92     /**
93      * Returns the source to be filtered
94      */

95     public Filter getSource(){
96         return (Filter)getSources().get(0);
97     }
98
99     /**
100      * Sets the source to be filtered
101      */

102     public void setSource(Filter src){
103         init(src, null);
104     }
105
106     /**
107      * Returns this filter's bounds
108      */

109     public Rectangle2D JavaDoc getBounds2D(){
110         return (Rectangle2D JavaDoc)(litRegion.clone());
111     }
112
113     /**
114      * Returns this filter's litRegion
115      */

116     public Rectangle2D JavaDoc getLitRegion(){
117         return getBounds2D();
118     }
119
120     /**
121      * Set this filter's litRegion
122      */

123     public void setLitRegion(Rectangle2D JavaDoc litRegion){
124         touch();
125         this.litRegion = litRegion;
126     }
127
128     /**
129      * @return Light object used for the specular lighting
130      */

131     public Light getLight(){
132         return light;
133     }
134
135     /**
136      * @param light New Light object
137      */

138     public void setLight(Light light){
139         touch();
140         this.light = light;
141     }
142
143     /**
144      * @return surfaceScale
145      */

146     public double getSurfaceScale(){
147         return surfaceScale;
148     }
149
150     /**
151      * Sets the surface scale
152      */

153     public void setSurfaceScale(double surfaceScale){
154         touch();
155         this.surfaceScale = surfaceScale;
156     }
157
158     /**
159      * @return specular constant, or ks.
160      */

161     public double getKs(){
162         return ks;
163     }
164
165     /**
166      * Sets the specular constant, or ks
167      */

168     public void setKs(double ks){
169         touch();
170         this.ks = ks;
171     }
172
173     /**
174      * @return specular exponent
175      */

176     public double getSpecularExponent(){
177         return specularExponent;
178     }
179
180     /**
181      * Sets the specular exponent
182      */

183     public void setSpecularExponent(double specularExponent){
184         touch();
185         this.specularExponent = specularExponent;
186     }
187
188     /**
189      * Returns the min [dx,dy] distance in user space for evalutation of
190      * the sobel gradient.
191      */

192     public double [] getKernelUnitLength() {
193         if (kernelUnitLength == null)
194             return null;
195
196         double [] ret = new double[2];
197         ret[0] = kernelUnitLength[0];
198         ret[1] = kernelUnitLength[1];
199         return ret;
200     }
201
202     /**
203      * Sets the min [dx,dy] distance in user space for evaluation of the
204      * sobel gradient. If set to zero or null then device space will be used.
205      */

206     public void setKernelUnitLength(double [] kernelUnitLength) {
207         touch();
208         if (kernelUnitLength == null) {
209             this.kernelUnitLength = null;
210             return;
211         }
212
213         if (this.kernelUnitLength == null)
214             this.kernelUnitLength = new float[2];
215
216         this.kernelUnitLength[0] = (float)kernelUnitLength[0];
217         this.kernelUnitLength[1] = (float)kernelUnitLength[1];
218     }
219
220     public RenderedImage JavaDoc createRendering(RenderContext JavaDoc rc){
221         Shape JavaDoc aoi = rc.getAreaOfInterest();
222         if (aoi == null)
223             aoi = getBounds2D();
224
225         Rectangle2D JavaDoc aoiR = aoi.getBounds2D();
226         Rectangle2D.intersect(aoiR, getBounds2D(), aoiR);
227
228         AffineTransform JavaDoc at = rc.getTransform();
229         Rectangle JavaDoc devRect = at.createTransformedShape(aoiR).getBounds();
230
231         if(devRect.width == 0 || devRect.height == 0){
232             return null;
233         }
234
235         //
236
// SpecularLightingRed only operates on a scaled space.
237
// The following extracts the scale portion of the
238
// user to device transform
239
//
240
// The source is rendered with the scale-only transform
241
// and the rendered result is used as a bumpMap for the
242
// SpecularLightingRed filter.
243
//
244
double sx = at.getScaleX();
245         double sy = at.getScaleY();
246
247         double shx = at.getShearX();
248         double shy = at.getShearY();
249
250         double tx = at.getTranslateX();
251         double ty = at.getTranslateY();
252
253          // The Scale is the "hypotonose" of the matrix vectors.
254
double scaleX = Math.sqrt(sx*sx + shy*shy);
255         double scaleY = Math.sqrt(sy*sy + shx*shx);
256
257         if(scaleX == 0 || scaleY == 0){
258             // Non invertible transform
259
return null;
260         }
261
262         // These values represent the scale factor to the intermediate
263
// coordinate system where we will apply our convolution.
264
if (kernelUnitLength != null) {
265             if (scaleX >= 1/kernelUnitLength[0])
266                 scaleX = 1/kernelUnitLength[0];
267
268             if (scaleY >= 1/kernelUnitLength[1])
269                 scaleY = 1/kernelUnitLength[1];
270         }
271
272         AffineTransform JavaDoc scale =
273             AffineTransform.getScaleInstance(scaleX, scaleY);
274
275         devRect = scale.createTransformedShape(aoiR).getBounds();
276
277         // Grow for surround needs.
278
aoiR.setRect(aoiR.getX() -(2/scaleX),
279                      aoiR.getY() -(2/scaleY),
280                      aoiR.getWidth() +(4/scaleX),
281                      aoiR.getHeight()+(4/scaleY));
282
283
284         // Build texture from the source
285
rc = (RenderContext JavaDoc)rc.clone();
286         rc.setAreaOfInterest(aoiR);
287         rc.setTransform(scale);
288
289         // System.out.println("scaleX / scaleY : " + scaleX + "/" + scaleY);
290

291         CachableRed cr;
292         cr = GraphicsUtil.wrap(getSource().createRendering(rc));
293
294         BumpMap bumpMap = new BumpMap(cr, surfaceScale, scaleX, scaleY);
295
296         cr = new SpecularLightingRed(ks, specularExponent, light, bumpMap,
297                                      devRect, 1/scaleX, 1/scaleY,
298                                      isColorSpaceLinear());
299
300         // Return sheared/rotated tiled image
301
AffineTransform JavaDoc shearAt =
302             new AffineTransform JavaDoc(sx/scaleX, shy/scaleX,
303                                 shx/scaleY, sy/scaleY,
304                                 tx, ty);
305
306         if(!shearAt.isIdentity()) {
307             RenderingHints JavaDoc rh = rc.getRenderingHints();
308             Rectangle JavaDoc padRect = new Rectangle JavaDoc(devRect.x-1, devRect.y-1,
309                                               devRect.width+2,
310                                               devRect.height+2);
311             cr = new PadRed(cr, padRect, PadMode.REPLICATE, rh);
312
313             cr = new AffineRed(cr, shearAt, rh);
314         }
315
316         return cr;
317     }
318 }
319
320
Popular Tags