001: /*
002: * $Header: /cvs/j3dfly/J3dFly/src/org/jdesktop/j3dfly/utils/environment/J3dSky.java,v 1.1 2005/04/20 21:04:52 paulby Exp $
003: *
004: * Sun Public License Notice
005: *
006: * The contents of this file are subject to the Sun Public License Version
007: * 1.0 (the "License"). You may not use this file except in compliance with
008: * the License. A copy of the License is available at http://www.sun.com/
009: *
010: * The Original Code is Java 3D(tm) Fly Through.
011: * The Initial Developer of the Original Code is Paul Byrne.
012: * Portions created by Paul Byrne are Copyright (C) 2002.
013: * All Rights Reserved.
014: *
015: * Contributor(s): Paul Byrne.
016: *
017: **/
018: package org.jdesktop.j3dfly.utils.environment;
019:
020: import javax.media.j3d.Background;
021: import javax.media.j3d.BranchGroup;
022: import javax.media.j3d.Group;
023: import javax.media.j3d.OrderedGroup;
024: import javax.media.j3d.Appearance;
025: import javax.media.j3d.PolygonAttributes;
026: import javax.media.j3d.ColoringAttributes;
027: import javax.media.j3d.BoundingSphere;
028: import javax.media.j3d.TriangleFanArray;
029: import javax.media.j3d.TriangleStripArray;
030: import javax.media.j3d.Shape3D;
031: import javax.media.j3d.TransformGroup;
032: import javax.media.j3d.Alpha;
033: import javax.media.j3d.Transform3D;
034: import javax.media.j3d.Switch;
035:
036: import javax.vecmath.Point3d;
037: import javax.vecmath.Point3f;
038: import javax.vecmath.Color3f;
039: import javax.vecmath.TexCoord2f;
040:
041: import com.sun.j3d.utils.image.TextureLoader;
042:
043: import org.jdesktop.j3dfly.utils.environment.geometry.SkyDome;
044:
045: /**
046: *
047: * @author Paul Byrne
048: * @version 1.6, 01/18/02
049: */
050: public class J3dSky extends javax.media.j3d.BranchGroup {
051:
052: private Background background;
053:
054: private SkyDome sky;
055: private SkyBehavior skyBehavior;
056: private Switch skySwitch;
057:
058: /** Creates new J3dSky */
059: public J3dSky() {
060: BranchGroup bg = new BranchGroup();
061:
062: TransformGroup skyTG = new TransformGroup();
063: skyTG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
064:
065: OrderedGroup og = new OrderedGroup();
066: og.addChild(createSky());
067: og.addChild(createSun());
068: og.addChild(createMoon());
069:
070: skyTG.addChild(og);
071:
072: OrderedGroup og2 = new OrderedGroup();
073:
074: og2.addChild(skyTG);
075: //og2.addChild( createHorizon() );
076:
077: bg.addChild(og2);
078:
079: background = new Background(bg);
080: background.setApplicationBounds(new BoundingSphere(
081: new Point3d(), Double.POSITIVE_INFINITY));
082:
083: skySwitch = new Switch();
084: skySwitch.setCapability(Switch.ALLOW_SWITCH_WRITE);
085: skySwitch.setCapability(Switch.ALLOW_SWITCH_READ);
086: skySwitch.setWhichChild(Switch.CHILD_NONE);
087:
088: skySwitch.addChild(background);
089:
090: //skySwitch.addChild( createFloor() );
091:
092: BranchGroup lightBG = new BranchGroup();
093: skyBehavior = new SkyBehavior(sky, skyTG, lightBG);
094: skySwitch.addChild(lightBG);
095: skySwitch.addChild(skyBehavior);
096:
097: this .addChild(skySwitch);
098: }
099:
100: /*
101: * Set time of day.
102: *
103: * Time must be in the range 0-24
104: */
105: public void setTimeOfDay(float time) {
106: skyBehavior.setTimeOfDay(time);
107: }
108:
109: /**
110: * Enable/Disable the sky
111: */
112: public void setEnable(boolean enable) {
113: if (enable)
114: skySwitch.setWhichChild(Switch.CHILD_ALL);
115: else
116: skySwitch.setWhichChild(Switch.CHILD_NONE);
117: }
118:
119: /**
120: * Return true if the sky is enabled, false otherwise
121: */
122: public boolean isEnabled() {
123: if (skySwitch.getWhichChild() == Switch.CHILD_NONE)
124: return false;
125: else
126: return true;
127: }
128:
129: private Group createSky() {
130: Appearance app = new Appearance();
131:
132: sky = new SkyDome(0, 15, app);
133:
134: return sky;
135: }
136:
137: private Group createSun() {
138: // X = 1 is east
139: // X = -1 is west
140: // Geometry is defined on horizon in the east
141:
142: int fanSize = 20;
143: TriangleFanArray geom = new TriangleFanArray(fanSize + 2,
144: TriangleFanArray.COORDINATES, new int[] { fanSize + 2 });
145:
146: float x = 0.999f;
147: float angleStep = (float) Math.PI / (fanSize / 2f);
148: float radius = 0.05f;
149:
150: geom.setCoordinate(0, new Point3f(0f, x, 0f));
151: geom.setCoordinate(1, new Point3f(radius, x, 0f));
152: float angle = -angleStep;
153: for (int i = fanSize + 1; i > 0; i--) {
154: geom.setCoordinate(i, new Point3f((float) Math.cos(angle)
155: * radius, x, (float) Math.sin(angle) * radius));
156: angle -= angleStep;
157: }
158:
159: Group g = new Group();
160:
161: Appearance app = new Appearance();
162: ColoringAttributes clrAttr = new ColoringAttributes();
163: clrAttr.setColor(new Color3f(1f, 1f, 168 / 255f));
164: app.setColoringAttributes(clrAttr);
165:
166: g.addChild(new Shape3D(geom, app));
167: return g;
168: }
169:
170: private Group createMoon() {
171: // X = 1 is east
172: // X = -1 is west
173: // Geometry is defined on horizon in the east
174:
175: int fanSize = 20;
176: TriangleFanArray geom = new TriangleFanArray(fanSize + 2,
177: TriangleFanArray.COORDINATES
178: | TriangleFanArray.TEXTURE_COORDINATE_2,
179: new int[] { fanSize + 2 });
180:
181: float x = -0.999f;
182: float angleStep = (float) Math.PI / (fanSize / 2f);
183: float radius = 0.03f;
184:
185: geom.setCoordinate(0, new Point3f(0f, x, 0f));
186: geom.setTextureCoordinate(0, 0, new TexCoord2f(0.5f, 0.5f));
187: geom.setCoordinate(1, new Point3f(radius, x, 0f));
188: geom.setTextureCoordinate(0, 1, new TexCoord2f(1f, 0.5f));
189: float angle = -angleStep;
190: for (int i = 2; i < (fanSize + 2); i++) {
191: geom.setCoordinate(i, new Point3f((float) Math.cos(angle)
192: * radius, x, (float) Math.sin(angle) * radius));
193: geom.setTextureCoordinate(0, i, new TexCoord2f(
194: 0.5f + (float) Math.cos(angle) / 2f,
195: 0.5f + (float) Math.sin(angle) / 2f));
196: angle -= angleStep;
197: }
198:
199: Group g = new Group();
200:
201: Appearance app = new Appearance();
202: TextureLoader l = new TextureLoader(
203: getClass()
204: .getResource(
205: "/com/sun/j3d/demos/utils/environment/geometry/MoonFlat_256x256.jpg"),
206: null);
207: app.setTexture(l.getTexture());
208:
209: g.addChild(new Shape3D(geom, app));
210: return g;
211: }
212:
213: private BranchGroup createFloor() {
214: BranchGroup ret = new BranchGroup();
215: float floorSize = 50f;
216:
217: javax.media.j3d.QuadArray quad = new javax.media.j3d.QuadArray(
218: 4, javax.media.j3d.QuadArray.COORDINATES);
219: quad.setCoordinates(0, new float[] { floorSize, -1f, floorSize,
220: floorSize, -1f, -floorSize, -floorSize, -1f,
221: -floorSize, -floorSize, -1f, floorSize });
222: Appearance app = new Appearance();
223: PolygonAttributes poly = new PolygonAttributes();
224: poly.setCullFace(PolygonAttributes.CULL_NONE);
225: app.setPolygonAttributes(poly);
226: ret.addChild(new Shape3D(quad, app));
227:
228: Transform3D t3d = new Transform3D();
229: t3d.set(new javax.vecmath.Vector3f(0f, 3f, 0f));
230: TransformGroup tg = new TransformGroup(t3d);
231:
232: tg.addChild(new com.sun.j3d.utils.geometry.Sphere(2f));
233:
234: ret.addChild(tg);
235:
236: return ret;
237: }
238:
239: private BranchGroup createHorizon() {
240: BranchGroup ret = new BranchGroup();
241:
242: float scale = 0.1f;
243: float[] horizon = new float[] { 1f, 0.8f, 0.3f, 0.7f, 0.6f,
244: 0.45f, 0.6f };
245: float base = 0f;
246:
247: float radius = 1f;
248:
249: float points[] = new float[(horizon.length + 1) * 2 * 3];
250: float normals[] = new float[(horizon.length + 1) * 2 * 3];
251:
252: float angle = 0f;
253: for (int i = 0; i < horizon.length; i++) {
254: points[i * 6] = radius * (float) Math.sin(angle);
255: points[i * 6 + 1] = base;
256: points[i * 6 + 2] = radius * (float) Math.cos(angle);
257:
258: normals[i * 6] = -points[i * 6];
259: normals[i * 6 + 1] = 0f;
260: normals[i * 6 + 2] = -points[i * 6 + 2];
261:
262: points[i * 6 + 3] = radius * (float) Math.sin(angle);
263: points[i * 6 + 4] = base + (horizon[i] * scale);
264: points[i * 6 + 5] = radius * (float) Math.cos(angle);
265:
266: normals[i * 6 + 3] = -points[i * 6 + 3];
267: normals[i * 6 + 4] = 0f;
268: normals[i * 6 + 5] = -points[i * 6 + 5];
269:
270: angle += 2 * Math.PI / horizon.length;
271: }
272:
273: points[horizon.length * 6] = points[0];
274: points[horizon.length * 6 + 1] = points[1];
275: points[horizon.length * 6 + 2] = points[2];
276: points[horizon.length * 6 + 3] = points[3];
277: points[horizon.length * 6 + 4] = points[4];
278: points[horizon.length * 6 + 5] = points[5];
279:
280: normals[horizon.length * 6] = -points[0];
281: normals[horizon.length * 6 + 1] = 0f;
282: normals[horizon.length * 6 + 2] = -points[2];
283: normals[horizon.length * 6 + 3] = -points[3];
284: normals[horizon.length * 6 + 4] = 0f;
285: normals[horizon.length * 6 + 5] = -points[5];
286:
287: TriangleStripArray triStrip = new TriangleStripArray(
288: points.length / 3, TriangleStripArray.COORDINATES
289: | TriangleStripArray.NORMALS,
290: new int[] { points.length / 3 });
291: triStrip.setCoordinates(0, points);
292: triStrip.setNormals(0, normals);
293:
294: Appearance app = new Appearance();
295: //PolygonAttributes polyAttr = new PolygonAttributes();
296: //polyAttr.setCullFace( PolygonAttributes.CULL_NONE );
297: //app.setPolygonAttributes( polyAttr );
298: ColoringAttributes clrAttr = new ColoringAttributes();
299: clrAttr
300: .setColor(new Color3f(201 / 255f, 167 / 255f, 98 / 255f));
301: app.setColoringAttributes(clrAttr);
302: Shape3D s = new Shape3D(triStrip, app);
303:
304: ret.addChild(s);
305:
306: return ret;
307: }
308:
309: /**
310: * Add a listener for time change events
311: */
312: void addTimeChangeListener(SkyTimeListener listener) {
313: skyBehavior.addTimeChangeListener(listener);
314: }
315: }
|