1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
/*
* Class PlanarPolygon
* TCSS 491 Computational Worlds
* Steve Bradshaw
*/
package tesseract.objects;
import javax.media.j3d.Appearance;
import javax.media.j3d.Geometry;
import javax.media.j3d.Group;
import javax.media.j3d.ImageComponent2D;
import javax.media.j3d.Material;
import javax.media.j3d.Node;
import javax.media.j3d.PolygonAttributes;
import javax.media.j3d.Shape3D;
import javax.media.j3d.Texture;
import javax.media.j3d.Texture2D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TriangleFanArray;
import javax.vecmath.Matrix3f;
import javax.vecmath.Matrix4f;
import javax.vecmath.Point3f;
import javax.vecmath.TexCoord2f;
import javax.vecmath.Vector3f;
import com.sun.j3d.utils.geometry.GeometryInfo;
import com.sun.j3d.utils.geometry.NormalGenerator;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.image.TextureLoader;
/**
* This class creates an ellipsoid using the formula
* (x/a)^2 + (y/b)^2 + (z/c)^2 = 1 using a matrix3f transformation
* on a basic Sphere. This class sets 'a' to a constant 1.0 and allows
* 'b' and 'c' to alter the ellipsoid's shape along with the radius field
* Sphere. Since this is a sphere, the normals are already calculated.
*
* @author Steve Bradshaw
* @version 8 Feb 2011
*/
public class PlanarPolygon extends PhysicalObject {
/**
* Default mass.
*/
private static final float DEFAULT_MASS = Float.POSITIVE_INFINITY;
//private static final float DEFAULT_MASS = 6;
public Vector3f normal;
// Right-hand side of the plane equation: Ax + By + Cz = D
public float intercept;
/**
* Number of divisions in the sphere.
*/
public static final int DEFAULT_DIVISIONS = 6;
/**
* A Default radius.
*/
public static final float DEFAULT_RADIUS = 0.1f;
/**
* Create a new Ellipsoid.
*
* @param position Initial position.
* @param mass Initial mass.
* @param radius the radius of the base sphere.
* @param divisions an in for the shape divisions.
*/
public PlanarPolygon(final Vector3f position, final float mass,
final float radius, final int divisions) {
super(position, mass);
setShape(createShape(radius, divisions));
if (inverseMass != 0) {
inverseInertiaTensor.m00 = 1f / 4 / inverseMass * radius * radius;
inverseInertiaTensor.m11 = 2 * inverseInertiaTensor.m00;
inverseInertiaTensor.m22 = inverseInertiaTensor.m00;
inverseInertiaTensor.invert();
}
updateTransformGroup();
}
/**
* Create a new Ellipsoid.
*
* @param position Initial position.
* @param radius a float for the size of the base sphere.
*/
public PlanarPolygon(final Vector3f position, final float radius) {
super(position, DEFAULT_MASS);
setShape(createShape(radius, DEFAULT_DIVISIONS));
if (inverseMass != 0) {
inverseInertiaTensor.m00 = 1f / 4 / inverseMass * radius * radius;
inverseInertiaTensor.m11 = 2 * inverseInertiaTensor.m00;
inverseInertiaTensor.m22 = inverseInertiaTensor.m00;
inverseInertiaTensor.invert();
}
updateTransformGroup();
}
/**
* This method creates a planar polygon shape with lava texture.
*
* @param radius a float for the size of the base polygon
* @param divisions an int for the number of divisons
* @param appearance an Appearance object
*/
private Node createShape(final float radius, final int divisions) {
TriangleFanArray geometry = new TriangleFanArray(divisions,
TriangleFanArray.COORDINATES | TriangleFanArray.TEXTURE_COORDINATE_2, new int[] {divisions});
for (int i = 0; i < divisions; i++) {
float baseX = (float)Math.cos(2 * Math.PI * i / divisions);
float baseZ = -(float)Math.sin(2 * Math.PI * i / divisions);
geometry.setCoordinate(i, new Point3f(radius * baseX, 0, radius * baseZ));
geometry.setTextureCoordinate(0, i, new TexCoord2f((baseX + 1) / 2, (-baseZ + 1) / 2));
}
GeometryInfo gInfo = new GeometryInfo(geometry);
new NormalGenerator().generateNormals(gInfo);
gInfo.convertToIndexedTriangles();
Shape3D polygon = new Shape3D(gInfo.getGeometryArray());
TextureLoader tl = new TextureLoader("lava.jpg", null);
ImageComponent2D image = tl.getImage();
int width = image.getWidth();
int height = image.getHeight();
Texture2D texture = new Texture2D(Texture.MULTI_LEVEL_MIPMAP, Texture.RGB, width, height);
int imageLevel = 0;
texture.setImage(imageLevel, image);
while (width > 1 || height > 1) {
imageLevel++;
if (width > 1) width /= 2;
if (height > 1) height /= 2;
texture.setImage(imageLevel, tl.getScaledImage(width, height));
}
texture.setMagFilter(Texture2D.NICEST);
texture.setMinFilter(Texture2D.NICEST);
Material mat = new Material();
mat.setDiffuseColor(1, 0, 0);
Appearance appearance = new Appearance();
appearance.setTexture(texture);
appearance.setMaterial(mat);
PolygonAttributes polyAttr = new PolygonAttributes(PolygonAttributes.POLYGON_FILL, PolygonAttributes.CULL_NONE, 0);
appearance.setPolygonAttributes(polyAttr);
geometry.setCapability(Geometry.ALLOW_INTERSECT);
polygon = new Shape3D(geometry, appearance);
return polygon;
}
}
|