001: /*
002: * $RCSfile: SensorGnomonEcho.java,v $
003: *
004: * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * - Redistribution of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * - Redistribution in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * Neither the name of Sun Microsystems, Inc. or the names of
019: * contributors may be used to endorse or promote products derived
020: * from this software without specific prior written permission.
021: *
022: * This software is provided "AS IS," without a warranty of any
023: * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
024: * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
025: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
026: * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
027: * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
028: * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
029: * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
030: * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
031: * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
032: * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
033: * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
034: * POSSIBILITY OF SUCH DAMAGES.
035: *
036: * You acknowledge that this software is not designed, licensed or
037: * intended for use in the design, construction, operation or
038: * maintenance of any nuclear facility.
039: *
040: * $Revision: 1.4 $
041: * $Date: 2007/02/09 17:20:15 $
042: * $State: Exp $
043: */
044:
045: package com.sun.j3d.utils.behaviors.sensor;
046:
047: import javax.media.j3d.Shape3D;
048: import javax.media.j3d.Material;
049: import javax.media.j3d.Appearance;
050: import javax.media.j3d.Transform3D;
051: import javax.media.j3d.GeometryArray;
052: import javax.media.j3d.TriangleArray;
053: import javax.media.j3d.TransparencyAttributes;
054: import javax.vecmath.Point3f;
055: import javax.vecmath.Vector3f;
056:
057: /**
058: * A Shape3D representing a gnomon pointing along each coordinate
059: * axis. The base of the gnomon is a cube, and the coordinate axes are
060: * represented by pyramids attached to each face of the cube.
061: *
062: * @since Java 3D 1.3
063: */
064: public class SensorGnomonEcho extends Shape3D {
065: /**
066: * Constructs a SensorGnomonEcho. Read and write capabilities are
067: * granted for the Appearance, Material, TransparencyAttributes,
068: * and TransparencyAttributes mode and value.
069: *
070: * @param transform translation and/or rotation to apply to the gnomon
071: * geometry; this should be the position and orientation of the sensor
072: * hotspot in the sensor's local coordinate system
073: * @param baseWidth width of each edge of the base cube in meters
074: * @param axisLength distance in meters from the gnomon center to
075: * the apex of the pyramid attached to each face of the base cube
076: * @param enableLighting boolean indicating whether normals should be
077: * generated and lighting enabled
078: */
079: public SensorGnomonEcho(Transform3D transform, double baseWidth,
080: double axisLength, boolean enableLighting) {
081: super ();
082:
083: int FRONT = 0;
084: int BACK = 1;
085: int LEFT = 2;
086: int RIGHT = 3;
087: int TOP = 4;
088: int BOTTOM = 5;
089: Point3f[] axes = new Point3f[6];
090: float length = (float) axisLength;
091:
092: axes[FRONT] = new Point3f(0f, 0f, length);
093: axes[BACK] = new Point3f(0f, 0f, -length);
094: axes[LEFT] = new Point3f(-length, 0f, 0f);
095: axes[RIGHT] = new Point3f(length, 0f, 0f);
096: axes[TOP] = new Point3f(0f, length, 0f);
097: axes[BOTTOM] = new Point3f(0f, -length, 0f);
098:
099: if (transform != null)
100: for (int i = FRONT; i <= BOTTOM; i++)
101: transform.transform(axes[i]);
102:
103: float offset = (float) baseWidth / 2.0f;
104: Point3f[][] cube = new Point3f[6][4];
105:
106: cube[FRONT][0] = new Point3f(-offset, -offset, offset);
107: cube[FRONT][1] = new Point3f(offset, -offset, offset);
108: cube[FRONT][2] = new Point3f(offset, offset, offset);
109: cube[FRONT][3] = new Point3f(-offset, offset, offset);
110:
111: cube[BACK][0] = new Point3f(offset, -offset, -offset);
112: cube[BACK][1] = new Point3f(-offset, -offset, -offset);
113: cube[BACK][2] = new Point3f(-offset, offset, -offset);
114: cube[BACK][3] = new Point3f(offset, offset, -offset);
115:
116: if (transform != null)
117: for (int i = FRONT; i <= BACK; i++)
118: for (int j = 0; j < 4; j++)
119: transform.transform(cube[i][j]);
120:
121: cube[LEFT][0] = cube[BACK][1];
122: cube[LEFT][1] = cube[FRONT][0];
123: cube[LEFT][2] = cube[FRONT][3];
124: cube[LEFT][3] = cube[BACK][2];
125:
126: cube[RIGHT][0] = cube[FRONT][1];
127: cube[RIGHT][1] = cube[BACK][0];
128: cube[RIGHT][2] = cube[BACK][3];
129: cube[RIGHT][3] = cube[FRONT][2];
130:
131: cube[TOP][0] = cube[FRONT][3];
132: cube[TOP][1] = cube[FRONT][2];
133: cube[TOP][2] = cube[BACK][3];
134: cube[TOP][3] = cube[BACK][2];
135:
136: cube[BOTTOM][0] = cube[BACK][1];
137: cube[BOTTOM][1] = cube[BACK][0];
138: cube[BOTTOM][2] = cube[FRONT][1];
139: cube[BOTTOM][3] = cube[FRONT][0];
140:
141: int v = 0;
142: Point3f[] vertices = new Point3f[72];
143:
144: for (int i = 0; i < 6; i++) {
145: vertices[v++] = cube[i][0];
146: vertices[v++] = cube[i][1];
147: vertices[v++] = axes[i];
148: vertices[v++] = cube[i][1];
149: vertices[v++] = cube[i][2];
150: vertices[v++] = axes[i];
151: vertices[v++] = cube[i][2];
152: vertices[v++] = cube[i][3];
153: vertices[v++] = axes[i];
154: vertices[v++] = cube[i][3];
155: vertices[v++] = cube[i][0];
156: vertices[v++] = axes[i];
157: }
158:
159: int vertexFormat;
160: Material m = new Material();
161: m.setCapability(Material.ALLOW_COMPONENT_READ);
162: m.setCapability(Material.ALLOW_COMPONENT_WRITE);
163:
164: if (enableLighting) {
165: vertexFormat = GeometryArray.COORDINATES
166: | GeometryArray.NORMALS;
167: m.setLightingEnable(true);
168: } else {
169: vertexFormat = GeometryArray.COORDINATES;
170: m.setLightingEnable(false);
171: }
172:
173: TriangleArray ta = new TriangleArray(72, vertexFormat);
174: ta.setCoordinates(0, vertices);
175:
176: if (enableLighting) {
177: Vector3f v0 = new Vector3f();
178: Vector3f v1 = new Vector3f();
179: Vector3f[] normals = new Vector3f[72];
180:
181: for (int i = 0; i < 72; i += 3) {
182: v0.sub(vertices[i + 1], vertices[i]);
183: v1.sub(vertices[i + 2], vertices[i]);
184:
185: Vector3f n = new Vector3f();
186: n.cross(v0, v1);
187: n.normalize();
188:
189: normals[i] = n;
190: normals[i + 1] = n;
191: normals[i + 2] = n;
192: }
193: ta.setNormals(0, normals);
194: }
195:
196: Appearance a = new Appearance();
197: a.setMaterial(m);
198: a.setCapability(Appearance.ALLOW_MATERIAL_READ);
199: a.setCapability(Appearance.ALLOW_MATERIAL_WRITE);
200:
201: TransparencyAttributes tra = new TransparencyAttributes();
202: tra.setCapability(TransparencyAttributes.ALLOW_MODE_READ);
203: tra.setCapability(TransparencyAttributes.ALLOW_MODE_WRITE);
204: tra.setCapability(TransparencyAttributes.ALLOW_VALUE_READ);
205: tra.setCapability(TransparencyAttributes.ALLOW_VALUE_WRITE);
206: ta
207: .setCapability(TransparencyAttributes.ALLOW_BLEND_FUNCTION_READ);
208: ta
209: .setCapability(TransparencyAttributes.ALLOW_BLEND_FUNCTION_WRITE);
210:
211: a.setTransparencyAttributes(tra);
212: a.setCapability(Appearance.ALLOW_TRANSPARENCY_ATTRIBUTES_READ);
213: a.setCapability(Appearance.ALLOW_TRANSPARENCY_ATTRIBUTES_WRITE);
214:
215: setGeometry(ta);
216: setAppearance(a);
217:
218: setCapability(ALLOW_APPEARANCE_READ);
219: setCapability(ALLOW_APPEARANCE_WRITE);
220: }
221: }
|