aboutsummaryrefslogtreecommitdiffstats
path: root/src/classes/share
diff options
context:
space:
mode:
authorKevin Rushforth <[email protected]>2005-10-17 22:56:23 +0000
committerKevin Rushforth <[email protected]>2005-10-17 22:56:23 +0000
commit356bbf2bd325380e16fd77d34fffd084dc1c0928 (patch)
tree1d67b61e1a427baa49047341ee825bca9b423553 /src/classes/share
parent68449b2071392af151a75f90610026465c426401 (diff)
Merged changes from dev-1_4 branch into the main trunk.
NOTE: all 1.4 development will now proceed on the main trunk. The dev-1_4 branch is closed. git-svn-id: https://svn.java.net/svn/j3d-core~svn/trunk@445 ba19aa83-45c5-6ac9-afd3-db810772062c
Diffstat (limited to 'src/classes/share')
-rw-r--r--src/classes/share/javax/media/j3d/AlternateAppearance.java32
-rw-r--r--src/classes/share/javax/media/j3d/AlternateAppearanceRetained.java2
-rw-r--r--src/classes/share/javax/media/j3d/Appearance.java20
-rw-r--r--src/classes/share/javax/media/j3d/AppearanceRetained.java21
-rw-r--r--src/classes/share/javax/media/j3d/AttributeBin.java267
-rw-r--r--src/classes/share/javax/media/j3d/AuralAttributes.java29
-rw-r--r--src/classes/share/javax/media/j3d/AuralAttributesRetained.java2
-rw-r--r--src/classes/share/javax/media/j3d/Background.java32
-rw-r--r--src/classes/share/javax/media/j3d/BehaviorStructure.java2
-rw-r--r--src/classes/share/javax/media/j3d/BoundingBox.java2
-rw-r--r--src/classes/share/javax/media/j3d/BoundingLeaf.java13
-rw-r--r--src/classes/share/javax/media/j3d/BoundingPolytope.java30
-rw-r--r--src/classes/share/javax/media/j3d/BoundingSphere.java2
-rw-r--r--src/classes/share/javax/media/j3d/BranchGroup.java399
-rw-r--r--src/classes/share/javax/media/j3d/BranchGroupRetained.java152
-rw-r--r--src/classes/share/javax/media/j3d/Canvas3D.java468
-rw-r--r--src/classes/share/javax/media/j3d/CanvasViewCache.java81
-rw-r--r--src/classes/share/javax/media/j3d/CanvasViewEventCatcher.java14
-rw-r--r--src/classes/share/javax/media/j3d/CapabilityBits.java37
-rw-r--r--src/classes/share/javax/media/j3d/CgShaderProgram.java173
-rw-r--r--src/classes/share/javax/media/j3d/CgShaderProgramRetained.java283
-rw-r--r--src/classes/share/javax/media/j3d/Clip.java11
-rw-r--r--src/classes/share/javax/media/j3d/ColoringAttributes.java21
-rw-r--r--src/classes/share/javax/media/j3d/CompressedGeometry.java75
-rw-r--r--src/classes/share/javax/media/j3d/CompressedGeometryHeader.java2
-rw-r--r--src/classes/share/javax/media/j3d/CompressedGeometryRetained.java34
-rw-r--r--src/classes/share/javax/media/j3d/ConeSound.java40
-rw-r--r--src/classes/share/javax/media/j3d/DepthComponent.java8
-rw-r--r--src/classes/share/javax/media/j3d/DirectionalLight.java15
-rw-r--r--src/classes/share/javax/media/j3d/DisplayListRenderMethod.java6
-rw-r--r--src/classes/share/javax/media/j3d/ExceptionStrings.properties72
-rw-r--r--src/classes/share/javax/media/j3d/ExponentialFog.java21
-rw-r--r--src/classes/share/javax/media/j3d/ExponentialFogRetained.java25
-rw-r--r--src/classes/share/javax/media/j3d/Fog.java19
-rw-r--r--src/classes/share/javax/media/j3d/FogRetained.java21
-rw-r--r--src/classes/share/javax/media/j3d/Font3D.java45
-rw-r--r--src/classes/share/javax/media/j3d/FreeListManager.java8
-rw-r--r--src/classes/share/javax/media/j3d/GLSLShaderProgram.java158
-rw-r--r--src/classes/share/javax/media/j3d/GLSLShaderProgramRetained.java281
-rw-r--r--src/classes/share/javax/media/j3d/Geometry.java10
-rw-r--r--src/classes/share/javax/media/j3d/GeometryArray.java1977
-rw-r--r--src/classes/share/javax/media/j3d/GeometryArrayRetained.java1792
-rw-r--r--src/classes/share/javax/media/j3d/GeometryDecompressorRetained.java2
-rw-r--r--src/classes/share/javax/media/j3d/GeometryRetained.java73
-rw-r--r--src/classes/share/javax/media/j3d/GeometryStripArray.java146
-rw-r--r--src/classes/share/javax/media/j3d/GeometryStripArrayRetained.java158
-rw-r--r--src/classes/share/javax/media/j3d/GeometryStructure.java1
-rwxr-xr-xsrc/classes/share/javax/media/j3d/GraphStructureChangeListener.java54
-rw-r--r--src/classes/share/javax/media/j3d/GraphicsConfigInfo.java35
-rw-r--r--src/classes/share/javax/media/j3d/GraphicsConfigTemplate3D.java35
-rw-r--r--src/classes/share/javax/media/j3d/GraphicsContext3D.java265
-rw-r--r--src/classes/share/javax/media/j3d/Group.java9
-rw-r--r--src/classes/share/javax/media/j3d/GroupRetained.java30
-rw-r--r--src/classes/share/javax/media/j3d/ImageComponent.java14
-rw-r--r--src/classes/share/javax/media/j3d/ImageComponent2DRetained.java6
-rw-r--r--src/classes/share/javax/media/j3d/ImageComponent3D.java2
-rw-r--r--src/classes/share/javax/media/j3d/IndexedGeometryArray.java447
-rw-r--r--src/classes/share/javax/media/j3d/IndexedGeometryArrayRetained.java1106
-rw-r--r--src/classes/share/javax/media/j3d/IndexedGeometryStripArray.java170
-rw-r--r--src/classes/share/javax/media/j3d/IndexedGeometryStripArrayRetained.java42
-rw-r--r--src/classes/share/javax/media/j3d/IndexedLineArray.java219
-rw-r--r--src/classes/share/javax/media/j3d/IndexedLineArrayRetained.java54
-rw-r--r--src/classes/share/javax/media/j3d/IndexedLineStripArray.java254
-rw-r--r--src/classes/share/javax/media/j3d/IndexedLineStripArrayRetained.java77
-rw-r--r--src/classes/share/javax/media/j3d/IndexedPointArray.java206
-rw-r--r--src/classes/share/javax/media/j3d/IndexedPointArrayRetained.java38
-rw-r--r--src/classes/share/javax/media/j3d/IndexedQuadArray.java208
-rw-r--r--src/classes/share/javax/media/j3d/IndexedQuadArrayRetained.java73
-rw-r--r--src/classes/share/javax/media/j3d/IndexedTriangleArray.java215
-rw-r--r--src/classes/share/javax/media/j3d/IndexedTriangleArrayRetained.java95
-rw-r--r--src/classes/share/javax/media/j3d/IndexedTriangleFanArray.java248
-rw-r--r--src/classes/share/javax/media/j3d/IndexedTriangleFanArrayRetained.java116
-rw-r--r--src/classes/share/javax/media/j3d/IndexedTriangleStripArray.java244
-rw-r--r--src/classes/share/javax/media/j3d/IndexedTriangleStripArrayRetained.java97
-rw-r--r--src/classes/share/javax/media/j3d/IndexedUnorderSet.java2
-rw-r--r--src/classes/share/javax/media/j3d/J3DBuffer.java12
-rw-r--r--src/classes/share/javax/media/j3d/J3DGraphics2DImpl.java52
-rw-r--r--src/classes/share/javax/media/j3d/J3dMessage.java3
-rw-r--r--src/classes/share/javax/media/j3d/J3dNotification.java42
-rw-r--r--src/classes/share/javax/media/j3d/Light.java20
-rw-r--r--src/classes/share/javax/media/j3d/LineArray.java183
-rw-r--r--src/classes/share/javax/media/j3d/LineArrayRetained.java50
-rw-r--r--src/classes/share/javax/media/j3d/LineAttributes.java13
-rw-r--r--src/classes/share/javax/media/j3d/LineStripArray.java208
-rw-r--r--src/classes/share/javax/media/j3d/LineStripArrayRetained.java99
-rw-r--r--src/classes/share/javax/media/j3d/LinearFog.java39
-rw-r--r--src/classes/share/javax/media/j3d/LinearFogRetained.java26
-rw-r--r--src/classes/share/javax/media/j3d/Link.java12
-rw-r--r--src/classes/share/javax/media/j3d/LinkRetained.java2
-rw-r--r--src/classes/share/javax/media/j3d/Locale.java445
-rw-r--r--src/classes/share/javax/media/j3d/MasterControl.java330
-rw-r--r--src/classes/share/javax/media/j3d/Material.java16
-rw-r--r--src/classes/share/javax/media/j3d/MediaContainer.java17
-rw-r--r--src/classes/share/javax/media/j3d/MediaContainerRetained.java2
-rw-r--r--src/classes/share/javax/media/j3d/ModelClip.java20
-rw-r--r--src/classes/share/javax/media/j3d/Morph.java40
-rw-r--r--src/classes/share/javax/media/j3d/MorphRetained.java132
-rw-r--r--src/classes/share/javax/media/j3d/Node.java112
-rw-r--r--src/classes/share/javax/media/j3d/NodeData.java4
-rw-r--r--src/classes/share/javax/media/j3d/NodeRetained.java36
-rw-r--r--src/classes/share/javax/media/j3d/NotificationThread.java120
-rw-r--r--src/classes/share/javax/media/j3d/OrderedGroup.java6
-rw-r--r--src/classes/share/javax/media/j3d/OrientedShape3D.java24
-rw-r--r--src/classes/share/javax/media/j3d/PhysicalBody.java2
-rw-r--r--src/classes/share/javax/media/j3d/PickConeRay.java2
-rw-r--r--src/classes/share/javax/media/j3d/PickConeSegment.java2
-rw-r--r--src/classes/share/javax/media/j3d/PickCylinder.java2
-rw-r--r--src/classes/share/javax/media/j3d/PickCylinderRay.java2
-rw-r--r--src/classes/share/javax/media/j3d/PickCylinderSegment.java2
-rw-r--r--src/classes/share/javax/media/j3d/PickInfo.java1056
-rw-r--r--src/classes/share/javax/media/j3d/PickPoint.java4
-rw-r--r--src/classes/share/javax/media/j3d/Picking.java660
-rw-r--r--src/classes/share/javax/media/j3d/PointArray.java182
-rw-r--r--src/classes/share/javax/media/j3d/PointArrayRetained.java39
-rw-r--r--src/classes/share/javax/media/j3d/PointAttributes.java12
-rw-r--r--src/classes/share/javax/media/j3d/PointLight.java16
-rw-r--r--src/classes/share/javax/media/j3d/PointSound.java34
-rw-r--r--src/classes/share/javax/media/j3d/PolygonAttributes.java13
-rw-r--r--src/classes/share/javax/media/j3d/QuadArray.java183
-rw-r--r--src/classes/share/javax/media/j3d/QuadArrayRetained.java52
-rw-r--r--src/classes/share/javax/media/j3d/Raster.java22
-rw-r--r--src/classes/share/javax/media/j3d/RasterRetained.java3
-rw-r--r--src/classes/share/javax/media/j3d/RenderBin.java539
-rw-r--r--src/classes/share/javax/media/j3d/RenderMolecule.java93
-rw-r--r--src/classes/share/javax/media/j3d/Renderer.java192
-rw-r--r--src/classes/share/javax/media/j3d/RenderingAttributes.java851
-rw-r--r--src/classes/share/javax/media/j3d/RenderingAttributesRetained.java275
-rw-r--r--src/classes/share/javax/media/j3d/RenderingAttributesStructure.java24
-rw-r--r--src/classes/share/javax/media/j3d/SceneGraphObject.java99
-rw-r--r--src/classes/share/javax/media/j3d/ScreenViewCache.java32
-rw-r--r--src/classes/share/javax/media/j3d/Sensor.java278
-rw-r--r--src/classes/share/javax/media/j3d/SetLiveState.java2
-rw-r--r--src/classes/share/javax/media/j3d/Shader.java131
-rw-r--r--src/classes/share/javax/media/j3d/ShaderAppearance.java285
-rw-r--r--src/classes/share/javax/media/j3d/ShaderAppearanceRetained.java360
-rw-r--r--src/classes/share/javax/media/j3d/ShaderAttribute.java77
-rw-r--r--src/classes/share/javax/media/j3d/ShaderAttributeArray.java147
-rw-r--r--src/classes/share/javax/media/j3d/ShaderAttributeArrayRetained.java996
-rw-r--r--src/classes/share/javax/media/j3d/ShaderAttributeBinding.java128
-rw-r--r--src/classes/share/javax/media/j3d/ShaderAttributeBindingRetained.java57
-rw-r--r--src/classes/share/javax/media/j3d/ShaderAttributeObject.java130
-rw-r--r--src/classes/share/javax/media/j3d/ShaderAttributeObjectRetained.java311
-rw-r--r--src/classes/share/javax/media/j3d/ShaderAttributeRetained.java82
-rw-r--r--src/classes/share/javax/media/j3d/ShaderAttributeSet.java263
-rw-r--r--src/classes/share/javax/media/j3d/ShaderAttributeSetRetained.java390
-rw-r--r--src/classes/share/javax/media/j3d/ShaderAttributeValue.java100
-rw-r--r--src/classes/share/javax/media/j3d/ShaderAttributeValueRetained.java499
-rw-r--r--src/classes/share/javax/media/j3d/ShaderBin.java363
-rw-r--r--src/classes/share/javax/media/j3d/ShaderError.java410
-rw-r--r--src/classes/share/javax/media/j3d/ShaderErrorListener.java33
-rw-r--r--src/classes/share/javax/media/j3d/ShaderProgram.java194
-rw-r--r--src/classes/share/javax/media/j3d/ShaderProgramRetained.java1196
-rw-r--r--src/classes/share/javax/media/j3d/ShaderRetained.java78
-rw-r--r--src/classes/share/javax/media/j3d/Shape3D.java20
-rw-r--r--src/classes/share/javax/media/j3d/Shape3DCompileRetained.java162
-rw-r--r--src/classes/share/javax/media/j3d/Shape3DRetained.java237
-rw-r--r--src/classes/share/javax/media/j3d/SharedGroup.java14
-rw-r--r--src/classes/share/javax/media/j3d/SharedGroupRetained.java6
-rw-r--r--src/classes/share/javax/media/j3d/Sound.java32
-rw-r--r--src/classes/share/javax/media/j3d/SoundRetained.java18
-rw-r--r--src/classes/share/javax/media/j3d/SoundScheduler.java46
-rw-r--r--src/classes/share/javax/media/j3d/SoundSchedulerAtom.java10
-rw-r--r--src/classes/share/javax/media/j3d/SoundStructure.java14
-rw-r--r--src/classes/share/javax/media/j3d/Soundscape.java12
-rw-r--r--src/classes/share/javax/media/j3d/SourceCodeShader.java121
-rw-r--r--src/classes/share/javax/media/j3d/SourceCodeShaderRetained.java85
-rw-r--r--src/classes/share/javax/media/j3d/SpotLight.java17
-rw-r--r--src/classes/share/javax/media/j3d/Switch.java17
-rw-r--r--src/classes/share/javax/media/j3d/TexCoordGeneration.java35
-rw-r--r--src/classes/share/javax/media/j3d/Text3D.java25
-rw-r--r--src/classes/share/javax/media/j3d/Text3DRetained.java32
-rw-r--r--src/classes/share/javax/media/j3d/Texture.java27
-rw-r--r--src/classes/share/javax/media/j3d/Texture2D.java14
-rw-r--r--src/classes/share/javax/media/j3d/TextureAttributes.java16
-rw-r--r--src/classes/share/javax/media/j3d/TextureAttributesRetained.java28
-rw-r--r--src/classes/share/javax/media/j3d/TextureBin.java220
-rw-r--r--src/classes/share/javax/media/j3d/TextureRetained.java57
-rw-r--r--src/classes/share/javax/media/j3d/TextureUnitState.java10
-rw-r--r--src/classes/share/javax/media/j3d/TextureUnitStateRetained.java11
-rw-r--r--src/classes/share/javax/media/j3d/TimerThread.java4
-rw-r--r--src/classes/share/javax/media/j3d/Transform3D.java4
-rw-r--r--src/classes/share/javax/media/j3d/TransformGroup.java14
-rw-r--r--src/classes/share/javax/media/j3d/TransformGroupData.java4
-rw-r--r--src/classes/share/javax/media/j3d/TransformGroupRetained.java8
-rw-r--r--src/classes/share/javax/media/j3d/TransformStructure.java4
-rw-r--r--src/classes/share/javax/media/j3d/TransparencyAttributes.java223
-rw-r--r--src/classes/share/javax/media/j3d/TransparencyAttributesRetained.java10
-rw-r--r--src/classes/share/javax/media/j3d/TransparentRenderingInfo.java96
-rw-r--r--src/classes/share/javax/media/j3d/TriangleArray.java185
-rw-r--r--src/classes/share/javax/media/j3d/TriangleArrayRetained.java58
-rw-r--r--src/classes/share/javax/media/j3d/TriangleFanArray.java212
-rw-r--r--src/classes/share/javax/media/j3d/TriangleFanArrayRetained.java125
-rw-r--r--src/classes/share/javax/media/j3d/TriangleStripArray.java211
-rw-r--r--src/classes/share/javax/media/j3d/TriangleStripArrayRetained.java58
-rw-r--r--src/classes/share/javax/media/j3d/View.java2
-rw-r--r--src/classes/share/javax/media/j3d/ViewCache.java3
-rw-r--r--src/classes/share/javax/media/j3d/ViewPlatform.java7
-rw-r--r--src/classes/share/javax/media/j3d/ViewPlatformRetained.java1
-rw-r--r--src/classes/share/javax/media/j3d/ViewSpecificGroup.java8
-rw-r--r--src/classes/share/javax/media/j3d/ViewSpecificGroupRetained.java4
-rw-r--r--src/classes/share/javax/media/j3d/VirtualUniverse.java190
-rw-r--r--src/classes/share/javax/media/j3d/WakeupIndexedList.java2
202 files changed, 21444 insertions, 5686 deletions
diff --git a/src/classes/share/javax/media/j3d/AlternateAppearance.java b/src/classes/share/javax/media/j3d/AlternateAppearance.java
index e6d160c..fccc203 100644
--- a/src/classes/share/javax/media/j3d/AlternateAppearance.java
+++ b/src/classes/share/javax/media/j3d/AlternateAppearance.java
@@ -92,7 +92,13 @@ public class AlternateAppearance extends Leaf {
public static final int ALLOW_SCOPE_WRITE =
CapabilityBits.ALTERNATE_APPEARANCE_ALLOW_SCOPE_WRITE;
-
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_INFLUENCING_BOUNDS_READ,
+ ALLOW_APPEARANCE_READ,
+ ALLOW_SCOPE_READ
+ };
+
/**
* Constructs an AlternateAppearance node with default
* parameters. The default values are as follows:
@@ -106,28 +112,30 @@ public class AlternateAppearance extends Leaf {
*/
public AlternateAppearance() {
// Just use the defaults
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
}
-
- /**
- * Creates the retained mode AlternateAppearanceRetained object that this
- * Alternate Appearance component object will point to.
- */
- void createRetained() {
- this.retained = new AlternateAppearanceRetained();
- this.retained.setSource(this);
- }
-
-
/**
* Constructs an AlternateAppearance node with the specified appearance.
* @param appearance the appearance that is used for those nodes affected
* by this AlternateAppearance node.
*/
public AlternateAppearance(Appearance appearance) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
((AlternateAppearanceRetained)retained).initAppearance(appearance);
}
+ /**
+ * Creates the retained mode AlternateAppearanceRetained object that this
+ * Alternate Appearance component object will point to.
+ */
+ void createRetained() {
+ this.retained = new AlternateAppearanceRetained();
+ this.retained.setSource(this);
+ }
/**
* Sets the appearance of this AlternateAppearance node.
diff --git a/src/classes/share/javax/media/j3d/AlternateAppearanceRetained.java b/src/classes/share/javax/media/j3d/AlternateAppearanceRetained.java
index 0b88951..b7d17bf 100644
--- a/src/classes/share/javax/media/j3d/AlternateAppearanceRetained.java
+++ b/src/classes/share/javax/media/j3d/AlternateAppearanceRetained.java
@@ -803,7 +803,7 @@ class AlternateAppearanceRetained extends LeafRetained {
// AlternateAppearance alternate appearance = (AlternateAppearance) originalNode;
-// // TODO: clone appearance
+// // XXXX: clone appearance
// setInfluencingBounds(alternate appearance.getInfluencingBounds());
diff --git a/src/classes/share/javax/media/j3d/Appearance.java b/src/classes/share/javax/media/j3d/Appearance.java
index cb24eba..88aea7b 100644
--- a/src/classes/share/javax/media/j3d/Appearance.java
+++ b/src/classes/share/javax/media/j3d/Appearance.java
@@ -285,7 +285,21 @@ public class Appearance extends NodeComponent {
public static final int ALLOW_TEXTURE_UNIT_STATE_WRITE =
CapabilityBits.APPEARANCE_ALLOW_TEXTURE_UNIT_STATE_WRITE;
-
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_COLORING_ATTRIBUTES_READ,
+ ALLOW_LINE_ATTRIBUTES_READ,
+ ALLOW_MATERIAL_READ,
+ ALLOW_POINT_ATTRIBUTES_READ,
+ ALLOW_POLYGON_ATTRIBUTES_READ,
+ ALLOW_RENDERING_ATTRIBUTES_READ,
+ ALLOW_TEXGEN_READ,
+ ALLOW_TEXTURE_ATTRIBUTES_READ,
+ ALLOW_TEXTURE_READ,
+ ALLOW_TEXTURE_UNIT_STATE_READ,
+ ALLOW_TRANSPARENCY_ATTRIBUTES_READ
+ };
+
/**
* Constructs an Appearance component object using defaults for all
* state variables. All component object references are initialized
@@ -293,6 +307,8 @@ public class Appearance extends NodeComponent {
*/
public Appearance() {
// Just use default values
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -919,7 +935,7 @@ public class Appearance extends NodeComponent {
if ((nc != null) && nc.getDuplicateOnCloneTree())
return true;
- // TODO: TextureUnitState
+ // XXXX: TextureUnitState
return false;
}
diff --git a/src/classes/share/javax/media/j3d/AppearanceRetained.java b/src/classes/share/javax/media/j3d/AppearanceRetained.java
index cc0489e..215c8eb 100644
--- a/src/classes/share/javax/media/j3d/AppearanceRetained.java
+++ b/src/classes/share/javax/media/j3d/AppearanceRetained.java
@@ -83,9 +83,6 @@ class AppearanceRetained extends NodeComponentRetained {
static final int POINT = 0x0200;
static final int TEXTURE_UNIT_STATE = 0x0400;
- static final int ALL_COMPONENTS = (MATERIAL|TEXTURE|TEXCOORD_GEN|TEXTURE_ATTR|COLOR|TRANSPARENCY|
- RENDERING|POLYGON|LINE|POINT|TEXTURE_UNIT_STATE);
-
static final int ALL_SOLE_USERS = 0;
// A pointer to the scene graph appearance object
@@ -876,11 +873,18 @@ class AppearanceRetained extends NodeComponentRetained {
}
+ void setLive(boolean backgroundGroup, int refCount) {
+ // System.out.println("AppearceRetained.setLive()");
+ doSetLive(backgroundGroup, refCount);
+ markAsLive();
+ }
+
/**
- * This setLive routine first calls the superclass's method, then
- * it adds itself to the list of lights
+ * This method calls the setLive method of all appearance bundle
+ * objects.
*/
- void setLive(boolean backgroundGroup, int refCount) {
+ void doSetLive(boolean backgroundGroup, int refCount) {
+ // System.out.println("AppearceRetained.doSetLive()");
if (material != null) {
@@ -938,12 +942,11 @@ class AppearanceRetained extends NodeComponentRetained {
// Increment the reference count and initialize the appearance
// mirror object
super.doSetLive(backgroundGroup, refCount);
- super.markAsLive();
}
/**
- * This clearLive routine first calls the superclass's method, then
- * it removes itself to the list of lights
+ * This method calls the clearLive method of all appearance bundle
+ * objects.
*/
void clearLive(int refCount) {
super.clearLive(refCount);
diff --git a/src/classes/share/javax/media/j3d/AttributeBin.java b/src/classes/share/javax/media/j3d/AttributeBin.java
index 8e98708..cc1afd4 100644
--- a/src/classes/share/javax/media/j3d/AttributeBin.java
+++ b/src/classes/share/javax/media/j3d/AttributeBin.java
@@ -28,6 +28,11 @@ class AttributeBin extends Object implements ObjectUpdate {
RenderingAttributesRetained definingRenderingAttributes = null;
/**
+ * The RenderBin for this object
+ */
+ RenderBin renderBin = null;
+
+ /**
* The EnvirionmentSet that this AttributeBin resides
*/
EnvironmentSet environmentSet = null;
@@ -40,21 +45,14 @@ class AttributeBin extends Object implements ObjectUpdate {
AttributeBin prev = null;
/**
- * The list of TextureBins in this AttributeBin
+ * The list of ShaderBins in this AttributeBin
*/
- TextureBin textureBinList = null;
-
+ ShaderBin shaderBinList = null;
/**
- * The list of TextureBins to be added for the next frame
+ * List of shaderBins to be added next frame
*/
- ArrayList addTextureBins = new ArrayList();
-
- /**
- * List of TextureBins to be added next frame
- */
- ArrayList addTBs = new ArrayList();
-
+ ArrayList addShaderBins = new ArrayList();
/**
* If the RenderingAttribute component of the appearance will be changed
@@ -63,11 +61,6 @@ class AttributeBin extends Object implements ObjectUpdate {
boolean soleUser = false;
AppearanceRetained app = null;
- /**
- * List of TextureBins to be removeded next frame
- */
- ArrayList removeTBs = new ArrayList();
-
int onUpdateList = 0;
static int ON_OBJ_UPDATE_LIST = 0x1;
static int ON_CHANGED_FREQUENT_UPDATE_LIST = 0x2;
@@ -76,44 +69,45 @@ class AttributeBin extends Object implements ObjectUpdate {
// for whether the definingRendering attrs is non-null;
boolean ignoreVertexColors = false;
- // TODO: use definingMaterial etc. instead of these
+ // XXXX: use definingMaterial etc. instead of these
// when sole user is completely implement
RenderingAttributesRetained renderingAttrs;
- int numEditingTextureBins = 0;
-
-
+ int numEditingShaderBins = 0;
AttributeBin(AppearanceRetained app, RenderingAttributesRetained renderingAttributes, RenderBin rBin) {
+
reset(app, renderingAttributes, rBin);
}
void reset(AppearanceRetained app, RenderingAttributesRetained renderingAttributes, RenderBin rBin) {
prev = null;
next = null;
- textureBinList = null;
+ shaderBinList = null;
onUpdateList = 0;
- numEditingTextureBins = 0;
+ numEditingShaderBins = 0;
renderingAttrs = renderingAttributes;
+ renderBin = rBin;
+
if (app != null) {
soleUser = ((app.changedFrequent & AppearanceRetained.RENDERING) != 0);
}
else {
soleUser = false;
}
- // System.out.println("soleUser = "+soleUser+" renderingAttributes ="+renderingAttributes);
+ //System.out.println("soleUser = "+soleUser+" renderingAttributes ="+renderingAttributes);
// Set the appearance only for soleUser case
if (soleUser)
this.app = app;
else
app = null;
-
+
if (renderingAttributes != null) {
if (renderingAttributes.changedFrequent != 0) {
definingRenderingAttributes = renderingAttributes;
if ((onUpdateList & ON_CHANGED_FREQUENT_UPDATE_LIST) == 0 ) {
- rBin.aBinUpdateList.add(this);
+ renderBin.aBinUpdateList.add(this);
onUpdateList |= AttributeBin.ON_CHANGED_FREQUENT_UPDATE_LIST;
}
}
@@ -140,10 +134,9 @@ class AttributeBin extends Object implements ObjectUpdate {
// If the any reference to the appearance components that is cached renderMolecule
// can change frequently, make a separate bin
- // If the any reference to the appearance components that is cached renderMolecule
- // can change frequently, make a separate bin
if (soleUser || (ra.geometryAtom.source.appearance != null &&
- ((ra.geometryAtom.source.appearance.changedFrequent & AppearanceRetained.RENDERING) != 0))) {
+ ((ra.geometryAtom.source.appearance.changedFrequent &
+ AppearanceRetained.RENDERING) != 0))) {
if (app == (Object)ra.geometryAtom.source.appearance) {
// if this AttributeBin is currently on a zombie state,
@@ -156,9 +149,9 @@ class AttributeBin extends Object implements ObjectUpdate {
// attributes reference change would not have reflected to
// the AttributeBin
- if (numEditingTextureBins == 0) {
+ if (numEditingShaderBins == 0) {
if ((onUpdateList & ON_CHANGED_FREQUENT_UPDATE_LIST) == 0) {
- environmentSet.renderBin.aBinUpdateList.add(this);
+ renderBin.aBinUpdateList.add(this);
onUpdateList |=
AttributeBin.ON_CHANGED_FREQUENT_UPDATE_LIST;
}
@@ -180,7 +173,7 @@ class AttributeBin extends Object implements ObjectUpdate {
if (definingRenderingAttributes == renderingAttributes) {
if (definingRenderingAttributes.compChanged != 0) {
if ((onUpdateList & ON_CHANGED_FREQUENT_UPDATE_LIST) == 0 ) {
- environmentSet.renderBin.aBinUpdateList.add(this);
+ renderBin.aBinUpdateList.add(this);
onUpdateList |= AttributeBin.ON_CHANGED_FREQUENT_UPDATE_LIST;
}
}
@@ -196,127 +189,56 @@ class AttributeBin extends Object implements ObjectUpdate {
return false;
}
-
-
return (true);
}
-
public void updateObject() {
+ ShaderBin sb;
TextureBin t;
- int i;
+ int i, size;
- if (addTBs.size() > 0) {
- t = (TextureBin)addTBs.get(0);
- if (textureBinList == null) {
- textureBinList = t;
-
+ size = addShaderBins.size();
+ if (size > 0) {
+ sb = (ShaderBin)addShaderBins.get(0);
+ if (shaderBinList == null) {
+ shaderBinList = sb;
}
else {
- // Look for a TextureBin that has the same texture
- insertTextureBin(t);
- }
- for (i = 1; i < addTBs.size() ; i++) {
- t = (TextureBin)addTBs.get(i);
- // Look for a TextureBin that has the same texture
- insertTextureBin(t);
-
+ sb.next = shaderBinList;
+ shaderBinList.prev = sb;
+ shaderBinList = sb;
}
- }
- addTBs.clear();
- onUpdateList &= ~ON_OBJ_UPDATE_LIST;
- }
-
- void insertTextureBin(TextureBin t) {
- TextureBin tb;
- int i;
- TextureRetained texture = null;
-
- if (t.texUnitState != null && t.texUnitState.length > 0) {
- if (t.texUnitState[0] != null) {
- texture = t.texUnitState[0].texture;
+
+ for (i = 1; i < size ; i++) {
+ sb = (ShaderBin)addShaderBins.get(i);
+ sb.next = shaderBinList;
+ shaderBinList.prev = sb;
+ shaderBinList = sb;
}
}
-
- // use the texture in the first texture unit as the sorting criteria
- if (texture != null) {
- tb = textureBinList;
- while (tb != null) {
- if (tb.texUnitState == null || tb.texUnitState[0] == null ||
- tb.texUnitState[0].texture != texture) {
- tb = tb.next;
- } else {
- // put it here
- t.next = tb;
- t.prev = tb.prev;
- if (tb.prev == null) {
- textureBinList = t;
- }
- else {
- tb.prev.next = t;
- }
- tb.prev = t;
- return;
- }
- }
- }
- // Just put it up front
- t.prev = null;
- t.next = textureBinList;
- textureBinList.prev = t;
- textureBinList = t;
-
- t.tbFlag &= ~TextureBin.RESORT;
+ addShaderBins.clear();
+ onUpdateList &= ~ON_OBJ_UPDATE_LIST;
}
/**
- * reInsert textureBin if the first texture is different from
- * the previous bin and different from the next bin
+ * Adds the given shaderBin to this AttributeBin.
*/
- void reInsertTextureBin(TextureBin tb) {
-
- TextureRetained texture = null,
- prevTexture = null,
- nextTexture = null;
-
- if (tb.texUnitState != null && tb.texUnitState[0] != null) {
- texture = tb.texUnitState[0].texture;
- }
-
- if (tb.prev != null && tb.prev.texUnitState != null) {
- prevTexture = tb.prev.texUnitState[0].texture;
- }
-
- if (texture != prevTexture) {
- if (tb.next != null && tb.next.texUnitState != null) {
- nextTexture = tb.next.texUnitState[0].texture;
- }
- if (texture != nextTexture) {
- if (tb.prev != null && tb.next != null) {
- tb.prev.next = tb.next;
- tb.next.prev = tb.prev;
- insertTextureBin(tb);
- }
- }
- }
- }
+ void addShaderBin(ShaderBin sb, RenderBin rb, ShaderAppearanceRetained sApp) {
+ sb.attributeBin = this;
- /**
- * Adds the given TextureBin to this AttributeBin.
- */
- void addTextureBin(TextureBin t, RenderBin rb, RenderAtom ra) {
- int i;
- t.attributeBin = this;
- AppearanceRetained raApp = ra.geometryAtom.source.appearance;
- RenderingAttributesRetained rAttrs =
- (raApp == null)? null : raApp.renderingAttributes;
- if (!soleUser && renderingAttrs != rAttrs) {
- // no longer sole user
- renderingAttrs = definingRenderingAttributes;
+ if(sApp != null) {
+ // ShaderBin should reference to the mirror components. -- JADA.
+ // System.out.println("AttributeBin : sApp.isMirror = " + sApp.isMirror);
+ assert(sApp.isMirror);
+ sb.shaderProgram = sApp.shaderProgram;
+ sb.shaderAttributeSet = sApp.shaderAttributeSet;
}
- addTBs.add(t);
+ sb.shaderAppearance = sApp;
+
+ // TODO : JADA - sort by ShaderProgram to avoid state trashing.
+ addShaderBins.add(sb);
if ((onUpdateList & ON_OBJ_UPDATE_LIST) == 0) {
onUpdateList |= ON_OBJ_UPDATE_LIST;
rb.objUpdateList.add(this);
@@ -324,41 +246,35 @@ class AttributeBin extends Object implements ObjectUpdate {
}
+
/**
- * Removes the given TextureBin from this AttributeBin.
+ * Removes the given shaderBin from this AttributeBin.
*/
- void removeTextureBin(TextureBin t) {
-
- int i;
- TextureRetained tex;
+ void removeShaderBin(ShaderBin sb) {
- t.attributeBin = null;
- // If the TextureBin being remove is contained in addTBs, then
- // remove the TextureBin from the addList
- if (addTBs.contains(t)) {
- addTBs.remove(addTBs.indexOf(t));
+ // If the shaderBin being remove is contained in addShaderBins,
+ // then remove the shadereBin from the addList
+ if (addShaderBins.contains(sb)) {
+ addShaderBins.remove(addShaderBins.indexOf(sb));
}
else {
- if (t.prev == null) { // At the head of the list
- textureBinList = t.next;
- if (t.next != null) {
- t.next.prev = null;
+ if (sb.prev == null) { // At the head of the list
+ shaderBinList = sb.next;
+ if (sb.next != null) {
+ sb.next.prev = null;
}
} else { // In the middle or at the end.
- t.prev.next = t.next;
- if (t.next != null) {
- t.next.prev = t.prev;
+ sb.prev.next = sb.next;
+ if (sb.next != null) {
+ sb.next.prev = sb.prev;
}
}
}
- t.prev = null;
- t.next = null;
- t.clear();
+ sb.clear();
+ renderBin.shaderBinFreelist.add(sb);
- environmentSet.renderBin.textureBinFreelist.add(t);
-
- if (textureBinList == null && addTBs.size() == 0 ) {
+ if (shaderBinList == null && addShaderBins.size() == 0 ) {
// Note: Removal of this attributebin as a user of the rendering
// atttrs is done during removeRenderAtom() in RenderMolecule.java
environmentSet.removeAttributeBin(this);
@@ -370,14 +286,14 @@ class AttributeBin extends Object implements ObjectUpdate {
*/
void render(Canvas3D cv) {
- TextureBin t;
+ ShaderBin sb;
boolean visible = (definingRenderingAttributes == null ||
definingRenderingAttributes.visible);
- if ( (environmentSet.renderBin.view.viewCache.visibilityPolicy
+ if ( (renderBin.view.viewCache.visibilityPolicy
== View.VISIBILITY_DRAW_VISIBLE && !visible) ||
- (environmentSet.renderBin.view.viewCache.visibilityPolicy
+ (renderBin.view.viewCache.visibilityPolicy
== View.VISIBILITY_DRAW_INVISIBLE && visible)) {
return;
}
@@ -386,15 +302,16 @@ class AttributeBin extends Object implements ObjectUpdate {
// include this AttributeBin to the to-be-updated list in Canvas
cv.setStateToUpdate(Canvas3D.ATTRIBUTEBIN_BIT, this);
- t = textureBinList;
- while (t != null) {
- t.render(cv);
- t = t.next;
+ sb = shaderBinList;
+ while (sb != null) {
+ sb.render(cv);
+ sb = sb.next;
}
}
void updateAttributes(Canvas3D cv) {
+
if ((cv.canvasDirty & Canvas3D.ATTRIBUTEBIN_DIRTY) != 0) {
// Update Attribute Bundles
if (definingRenderingAttributes == null) {
@@ -403,7 +320,7 @@ class AttributeBin extends Object implements ObjectUpdate {
cv.depthBufferEnableOverride);
} else {
definingRenderingAttributes.updateNative(
- cv.ctx,
+ cv,
cv.depthBufferWriteEnableOverride,
cv.depthBufferEnableOverride);
}
@@ -420,7 +337,7 @@ class AttributeBin extends Object implements ObjectUpdate {
cv.depthBufferEnableOverride);
} else {
definingRenderingAttributes.updateNative(
- cv.ctx,
+ cv,
cv.depthBufferWriteEnableOverride,
cv.depthBufferEnableOverride);
}
@@ -465,11 +382,23 @@ class AttributeBin extends Object implements ObjectUpdate {
onUpdateList &= ~ON_CHANGED_FREQUENT_UPDATE_LIST;
}
- void incrActiveTextureBin() {
- numEditingTextureBins++;
+ void incrActiveShaderBin() {
+ numEditingShaderBins++;
}
- void decrActiveTextureBin() {
- numEditingTextureBins--;
+ void decrActiveShaderBin() {
+ numEditingShaderBins--;
+ }
+
+ void updateFromShaderBin(RenderAtom ra) {
+
+ AppearanceRetained raApp = ra.geometryAtom.source.appearance;
+ RenderingAttributesRetained rAttrs =
+ (raApp == null)? null : raApp.renderingAttributes;
+
+ if (!soleUser && renderingAttrs != rAttrs) {
+ // no longer sole user
+ renderingAttrs = definingRenderingAttributes;
+ }
}
}
diff --git a/src/classes/share/javax/media/j3d/AuralAttributes.java b/src/classes/share/javax/media/j3d/AuralAttributes.java
index 89384e6..289383f 100644
--- a/src/classes/share/javax/media/j3d/AuralAttributes.java
+++ b/src/classes/share/javax/media/j3d/AuralAttributes.java
@@ -473,6 +473,24 @@ public class AuralAttributes extends NodeComponent {
public static final int
ALLOW_VELOCITY_SCALE_FACTOR_WRITE = CapabilityBits.AURAL_ATTRIBUTES_ALLOW_VELOCITY_SCALE_FACTOR_WRITE;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_ATTRIBUTE_GAIN_READ,
+ ALLOW_DECAY_FILTER_READ,
+ ALLOW_DECAY_TIME_READ,
+ ALLOW_DENSITY_READ,
+ ALLOW_DIFFUSION_READ,
+ ALLOW_DISTANCE_FILTER_READ,
+ ALLOW_FREQUENCY_SCALE_FACTOR_READ,
+ ALLOW_REFLECTION_COEFFICIENT_READ,
+ ALLOW_REFLECTION_DELAY_READ,
+ ALLOW_REVERB_COEFFICIENT_READ,
+ ALLOW_REVERB_DELAY_READ,
+ ALLOW_REVERB_ORDER_READ,
+ ALLOW_ROLLOFF_READ,
+ ALLOW_VELOCITY_SCALE_FACTOR_READ
+ };
+
/** *****************
*
* Constructors
@@ -501,6 +519,8 @@ public class AuralAttributes extends NodeComponent {
*/
public AuralAttributes() {
// Just use default values
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -523,6 +543,9 @@ public class AuralAttributes extends NodeComponent {
Point2f[] distanceFilter,
float frequencyScaleFactor,
float velocityScaleFactor) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((AuralAttributesRetained)this.retained).setAttributeGain(gain);
((AuralAttributesRetained)this.retained).setRolloff(rolloff);
((AuralAttributesRetained)this.retained).setReflectionCoefficient(
@@ -558,6 +581,9 @@ public class AuralAttributes extends NodeComponent {
float[] frequencyCutoff,
float frequencyScaleFactor,
float velocityScaleFactor) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((AuralAttributesRetained)this.retained).setAttributeGain(gain);
((AuralAttributesRetained)this.retained).setRolloff(rolloff);
((AuralAttributesRetained)this.retained).setReflectionCoefficient(
@@ -606,6 +632,9 @@ public class AuralAttributes extends NodeComponent {
float[] frequencyCutoff,
float frequencyScaleFactor,
float velocityScaleFactor) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((AuralAttributesRetained)this.retained).setAttributeGain(gain);
((AuralAttributesRetained)this.retained).setRolloff(rolloff);
((AuralAttributesRetained)this.retained).setReflectionCoefficient(
diff --git a/src/classes/share/javax/media/j3d/AuralAttributesRetained.java b/src/classes/share/javax/media/j3d/AuralAttributesRetained.java
index 3b23c51..eb88987 100644
--- a/src/classes/share/javax/media/j3d/AuralAttributesRetained.java
+++ b/src/classes/share/javax/media/j3d/AuralAttributesRetained.java
@@ -642,7 +642,7 @@ class AuralAttributesRetained extends NodeComponentRetained {
else
if (debugFlag)
debugPrint("reset aa; aa.frequencyCutoff = null");
- // TODO: (Enhancement) Why are these dirtyFlag cleared rather than aa->this
+ // XXXX: (Enhancement) Why are these dirtyFlag cleared rather than aa->this
this.aaDirty = false;
aa.aaDirty = false;
}
diff --git a/src/classes/share/javax/media/j3d/Background.java b/src/classes/share/javax/media/j3d/Background.java
index f50a9b3..c9a2bdd 100644
--- a/src/classes/share/javax/media/j3d/Background.java
+++ b/src/classes/share/javax/media/j3d/Background.java
@@ -228,6 +228,16 @@ public class Background extends Leaf {
*/
public static final int SCALE_NONE_CENTER = 5;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_APPLICATION_BOUNDS_READ,
+ ALLOW_COLOR_READ,
+ ALLOW_GEOMETRY_READ,
+ ALLOW_IMAGE_READ,
+ ALLOW_IMAGE_SCALE_MODE_READ
+ };
+
+
/**
* Constructs a Background node with default parameters. The default
* values are as follows:
@@ -242,6 +252,8 @@ public class Background extends Leaf {
*/
public Background () {
// Just use the defaults
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -250,7 +262,10 @@ public class Background extends Leaf {
* objects in the scene.
*/
public Background(Color3f color) {
- ((BackgroundRetained)this.retained).setColor(color);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((BackgroundRetained)this.retained).setColor(color);
}
/**
@@ -259,7 +274,10 @@ public class Background extends Leaf {
* objects in the scene.
*/
public Background(float r, float g, float b) {
- ((BackgroundRetained)this.retained).setColor(r, g, b);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((BackgroundRetained)this.retained).setColor(r, g, b);
}
/**
@@ -273,7 +291,10 @@ public class Background extends Leaf {
* @param image pixel array object used as the background image
*/
public Background(ImageComponent2D image) {
- ((BackgroundRetained)this.retained).setImage(image);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((BackgroundRetained)this.retained).setImage(image);
}
/**
@@ -290,7 +311,10 @@ public class Background extends Leaf {
* contains an illegal node.
*/
public Background(BranchGroup branch) {
- ((BackgroundRetained)this.retained).setGeometry(branch);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((BackgroundRetained)this.retained).setGeometry(branch);
}
/**
diff --git a/src/classes/share/javax/media/j3d/BehaviorStructure.java b/src/classes/share/javax/media/j3d/BehaviorStructure.java
index a8e9389..24a56c2 100644
--- a/src/classes/share/javax/media/j3d/BehaviorStructure.java
+++ b/src/classes/share/javax/media/j3d/BehaviorStructure.java
@@ -667,7 +667,7 @@ class BehaviorStructure extends J3dStructure {
if (awtCond.AwtId != 0) {
if (awtCond.AwtId == id) {
- // TODO: how do we clone this event (do we need to?)
+ // XXXX: how do we clone this event (do we need to?)
// Bug: 4181321
awtCond.addAWTEvent(evt);
}
diff --git a/src/classes/share/javax/media/j3d/BoundingBox.java b/src/classes/share/javax/media/j3d/BoundingBox.java
index 7e4e88a..3bd5e15 100644
--- a/src/classes/share/javax/media/j3d/BoundingBox.java
+++ b/src/classes/share/javax/media/j3d/BoundingBox.java
@@ -215,7 +215,7 @@ public class BoundingBox extends Bounds {
else if(bounds[i].boundId == BOUNDING_POLYTOPE) {
BoundingPolytope polytope = (BoundingPolytope)bounds[i];
- for(i=0;i<polytope.nVerts;i++) { // TODO handle polytope with no verts
+ for(i=0;i<polytope.nVerts;i++) { // XXXX: handle polytope with no verts
if( polytope.verts[i].x < lower.x )
lower.x = polytope.verts[i].x;
if( polytope.verts[i].y < lower.y )
diff --git a/src/classes/share/javax/media/j3d/BoundingLeaf.java b/src/classes/share/javax/media/j3d/BoundingLeaf.java
index 9015202..80c35a1 100644
--- a/src/classes/share/javax/media/j3d/BoundingLeaf.java
+++ b/src/classes/share/javax/media/j3d/BoundingLeaf.java
@@ -50,10 +50,18 @@ public class BoundingLeaf extends Leaf {
public static final int
ALLOW_REGION_WRITE = CapabilityBits.BOUNDING_LEAF_ALLOW_REGION_WRITE;
- /**
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_REGION_READ
+ };
+
+ /**
* Constructs a BoundingLeaf node with a null (empty) bounding region.
*/
public BoundingLeaf() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((BoundingLeafRetained)this.retained).createBoundingLeaf();
}
@@ -62,6 +70,9 @@ public class BoundingLeaf extends Leaf {
* @param region the bounding region of this leaf node
*/
public BoundingLeaf(Bounds region) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((BoundingLeafRetained)this.retained).createBoundingLeaf();
((BoundingLeafRetained)this.retained).initRegion(region);
}
diff --git a/src/classes/share/javax/media/j3d/BoundingPolytope.java b/src/classes/share/javax/media/j3d/BoundingPolytope.java
index 491f85a..fbed7f3 100644
--- a/src/classes/share/javax/media/j3d/BoundingPolytope.java
+++ b/src/classes/share/javax/media/j3d/BoundingPolytope.java
@@ -76,7 +76,7 @@ public class BoundingPolytope extends Bounds {
planes[i].z*invMag, planes[i].w*invMag );
}
- computeAllVerts(); // TODO lazy evaluate
+ computeAllVerts(); // XXXX: lazy evaluate
}
/**
@@ -111,7 +111,7 @@ public class BoundingPolytope extends Bounds {
mag[4] = 1.0;
mag[5] = 1.0;
- computeAllVerts(); // TODO lazy evaluate
+ computeAllVerts(); // XXXX: lazy evaluate
}
@@ -131,7 +131,7 @@ public class BoundingPolytope extends Bounds {
boundsIsEmpty = true;
boundsIsInfinite = false;
initEmptyPolytope();
- computeAllVerts(); // TODO lazy evaluate
+ computeAllVerts(); // XXXX: lazy evaluate
return;
}
@@ -156,7 +156,7 @@ public class BoundingPolytope extends Bounds {
mag[3] = 1.0;
mag[4] = 1.0;
mag[5] = 1.0;
- computeAllVerts(); // TODO lazy evaluate
+ computeAllVerts(); // XXXX: lazy evaluate
} else if( boundsObject.boundId == BOUNDING_BOX ){
BoundingBox box = (BoundingBox)boundsObject;
@@ -176,7 +176,7 @@ public class BoundingPolytope extends Bounds {
mag[3] = 1.0;
mag[4] = 1.0;
mag[5] = 1.0;
- computeAllVerts(); // TODO lazy evaluate
+ computeAllVerts(); // XXXX: lazy evaluate
} else if( boundsObject.boundId == BOUNDING_POLYTOPE ) {
BoundingPolytope polytope = (BoundingPolytope)boundsObject;
@@ -215,7 +215,7 @@ public class BoundingPolytope extends Bounds {
boundsIsEmpty = true;
boundsIsInfinite = false;
initEmptyPolytope();
- computeAllVerts(); // TODO lazy evaluate
+ computeAllVerts(); // XXXX: lazy evaluate
return;
}
// find first non empty bounds object
@@ -227,7 +227,7 @@ public class BoundingPolytope extends Bounds {
boundsIsEmpty = true;
boundsIsInfinite = false;
initEmptyPolytope();
- computeAllVerts(); // TODO lazy evaluate
+ computeAllVerts(); // XXXX: lazy evaluate
return;
}
@@ -253,7 +253,7 @@ public class BoundingPolytope extends Bounds {
mag[4] = 1.0;
mag[5] = 1.0;
- computeAllVerts(); // TODO lazy evaluate
+ computeAllVerts(); // XXXX: lazy evaluate
} else if( boundsObjects[i].boundId == BOUNDING_BOX ){
BoundingBox box = (BoundingBox)boundsObjects[i];
planes = new Vector4d[6];
@@ -273,7 +273,7 @@ public class BoundingPolytope extends Bounds {
mag[4] = 1.0;
mag[5] = 1.0;
- computeAllVerts(); // TODO lazy evaluate
+ computeAllVerts(); // XXXX: lazy evaluate
} else if( boundsObjects[i].boundId == BOUNDING_POLYTOPE ) {
BoundingPolytope polytope = (BoundingPolytope)boundsObjects[i];
planes = new Vector4d[polytope.planes.length];
@@ -320,7 +320,7 @@ public class BoundingPolytope extends Bounds {
if( planes.length <= 0 ) {
boundsIsEmpty = true;
boundsIsInfinite = false;
- computeAllVerts(); // TODO lazy evaluate
+ computeAllVerts(); // XXXX: lazy evaluate
return;
}
@@ -332,7 +332,7 @@ public class BoundingPolytope extends Bounds {
this.planes[i] = new Vector4d( planes[i].x*invMag, planes[i].y*invMag,
planes[i].z*invMag, planes[i].w*invMag );
}
- computeAllVerts(); // TODO lazy evaluate
+ computeAllVerts(); // XXXX: lazy evaluate
}
@@ -373,7 +373,7 @@ public class BoundingPolytope extends Bounds {
if( boundsObject == null ) {
boundsIsEmpty = true;
boundsIsInfinite = false;
- computeAllVerts(); // TODO lazy evaluate
+ computeAllVerts(); // XXXX: lazy evaluate
}else if( boundsObject.boundId == BOUNDING_SPHERE ) {
BoundingSphere sphere = (BoundingSphere)boundsObject;
@@ -391,7 +391,7 @@ public class BoundingPolytope extends Bounds {
boundsIsEmpty = boundsObject.boundsIsEmpty;
boundsIsInfinite = boundsObject.boundsIsInfinite;
- computeAllVerts(); // TODO lazy evaluate
+ computeAllVerts(); // XXXX: lazy evaluate
} else if( boundsObject.boundId == BOUNDING_BOX){
BoundingBox box = (BoundingBox)boundsObject;
@@ -422,7 +422,7 @@ public class BoundingPolytope extends Bounds {
boundsIsEmpty = boundsObject.boundsIsEmpty;
boundsIsInfinite = boundsObject.boundsIsInfinite;
- computeAllVerts(); // TODO lazy evaluate
+ computeAllVerts(); // XXXX: lazy evaluate
} else if(boundsObject.boundId == BOUNDING_POLYTOPE) {
BoundingPolytope polytope = (BoundingPolytope)boundsObject;
@@ -1627,7 +1627,7 @@ public class BoundingPolytope extends Bounds {
}
}
}
- // TODO correctly compute centroid
+ // XXXX: correctly compute centroid
x=y=z=0.0;
Point3d newVerts[] = new Point3d[nVerts];
diff --git a/src/classes/share/javax/media/j3d/BoundingSphere.java b/src/classes/share/javax/media/j3d/BoundingSphere.java
index 79dd8fb..67b9d5c 100644
--- a/src/classes/share/javax/media/j3d/BoundingSphere.java
+++ b/src/classes/share/javax/media/j3d/BoundingSphere.java
@@ -1073,7 +1073,7 @@ public class BoundingSphere extends Bounds {
Point3d dir = new Point3d(); // normalized direction of ray
Point3d oc = new Point3d(); // vector from sphere center to ray origin
- oc.x = center.x - origin.x; // TODO check if this method is still needed
+ oc.x = center.x - origin.x; // XXXX: check if this method is still needed
oc.y = center.y - origin.y;
oc.z = center.z - origin.z;
diff --git a/src/classes/share/javax/media/j3d/BranchGroup.java b/src/classes/share/javax/media/j3d/BranchGroup.java
index 92004fd..1c58feb 100644
--- a/src/classes/share/javax/media/j3d/BranchGroup.java
+++ b/src/classes/share/javax/media/j3d/BranchGroup.java
@@ -86,22 +86,63 @@ public class BranchGroup extends Group {
* Detaches this BranchGroup from its parent.
*/
public void detach() {
- Group parent;
-
- if (isLiveOrCompiled()) {
- if(!this.getCapability(ALLOW_DETACH))
- throw new CapabilityNotSetException(J3dI18N.getString("BranchGroup1"));
-
- if (((BranchGroupRetained)this.retained).parent != null) {
- parent = (Group)((BranchGroupRetained)this.retained).parent.source;
- if(!parent.getCapability(Group.ALLOW_CHILDREN_WRITE))
- throw new CapabilityNotSetException(J3dI18N.getString("BranchGroup2"));
- }
- }
+ Group parent;
+
+ if (isLiveOrCompiled()) {
+ if(!this.getCapability(ALLOW_DETACH))
+ throw new CapabilityNotSetException(J3dI18N.getString("BranchGroup1"));
+
+ if (((BranchGroupRetained)this.retained).parent != null) {
+ parent = (Group)((BranchGroupRetained)this.retained).parent.source;
+ if(!parent.getCapability(Group.ALLOW_CHILDREN_WRITE))
+ throw new CapabilityNotSetException(J3dI18N.getString("BranchGroup2"));
+ }
+ }
+
+ ((BranchGroupRetained)this.retained).detach();
+ }
+
+
+ void validateModeFlagAndPickShape(int mode, int flags, PickShape pickShape) {
- ((BranchGroupRetained)this.retained).detach();
- }
+ if(isLive()==false) {
+ throw new IllegalStateException(J3dI18N.getString("BranchGroup3"));
+ }
+
+ if((mode != PickInfo.PICK_BOUNDS) && (mode != PickInfo.PICK_GEOMETRY)) {
+
+ throw new IllegalArgumentException(J3dI18N.getString("BranchGroup4"));
+ }
+
+ if((pickShape instanceof PickPoint) && (mode == PickInfo.PICK_GEOMETRY)) {
+ throw new IllegalArgumentException(J3dI18N.getString("BranchGroup5"));
+ }
+
+ if(((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) &&
+ ((flags & PickInfo.ALL_GEOM_INFO) != 0)) {
+ throw new IllegalArgumentException(J3dI18N.getString("BranchGroup6"));
+ }
+
+ if((mode == PickInfo.PICK_BOUNDS) &&
+ (((flags & (PickInfo.CLOSEST_GEOM_INFO |
+ PickInfo.ALL_GEOM_INFO |
+ PickInfo.CLOSEST_DISTANCE |
+ PickInfo.CLOSEST_INTERSECTION_POINT)) != 0))) {
+
+ throw new IllegalArgumentException(J3dI18N.getString("BranchGroup7"));
+ }
+
+ if((pickShape instanceof PickBounds) &&
+ (((flags & (PickInfo.CLOSEST_GEOM_INFO |
+ PickInfo.ALL_GEOM_INFO |
+ PickInfo.CLOSEST_DISTANCE |
+ PickInfo.CLOSEST_INTERSECTION_POINT)) != 0))) {
+
+ throw new IllegalArgumentException(J3dI18N.getString("BranchGroup8"));
+ }
+ }
+
/**
* Returns an array referencing all the items that are pickable below this
* <code>BranchGroup</code> that intersect with PickShape.
@@ -116,12 +157,91 @@ public class BranchGroup extends Group {
*
*/
public SceneGraphPath[] pickAll( PickShape pickShape ) {
+
if(isLive()==false)
throw new IllegalStateException(J3dI18N.getString("BranchGroup3"));
+
+ return ((BranchGroupRetained)this.retained).pickAll(pickShape);
+
+ }
- return Picking.pickAll( this, pickShape );
+ /**
+ * Returns an array unsorted references to all the PickInfo objects that are
+ * pickable below this <code>BranchGroup</code> that intersect with PickShape.
+ * The accuracy of the pick is set by the pick mode. The mode include :
+ * PickInfo.PICK_BOUNDS and PickInfo.PICK_GEOMETRY. The amount of information returned
+ * is specified via a masked variable, flags, indicating which components are
+ * present in each returned PickInfo object.
+ *
+ * @param mode picking mode, one of <code>PickInfo.PICK_BOUNDS</code> or <code>PickInfo.PICK_GEOMETRY</code>.
+ *
+ * @param flags a mask indicating which components are present in each PickInfo object.
+ * This is specified as one or more individual bits that are bitwise "OR"ed together to
+ * describe the PickInfo data. The flags include :
+ * <ul>
+ * <code>PickInfo.SCENEGRAPHPATH</code> - request for computed SceneGraphPath.<br>
+ * <code>PickInfo.NODE</code> - request for computed intersected Node.<br>
+ * <code>PickInfo.LOCAL_TO_VWORLD</code> - request for computed local to virtual world transform.<br>
+ * <code>PickInfo.CLOSEST_INTERSECTION_POINT</code> - request for closest intersection point.<br>
+ * <code>PickInfo.CLOSEST_DISTANCE</code> - request for the distance of closest intersection.<br>
+ * <code>PickInfo.CLOSEST_GEOM_INFO</code> - request for only the closest intersection geometry information.<br>
+ * <code>PickInfo.ALL_GEOM_INFO</code> - request for all intersection geometry information.<br>
+ * </ul>
+ *
+ * @param pickShape the description of this picking volume or area.
+ *
+ * @exception IllegalArgumentException if flags contains both CLOSEST_GEOM_INFO and
+ * ALL_GEOM_INFO.
+ *
+ * @exception IllegalArgumentException if pickShape is a PickPoint and pick mode
+ * is set to PICK_GEOMETRY.
+ *
+ * @exception IllegalArgumentException if pick mode is neither PICK_BOUNDS
+ * nor PICK_GEOMETRY.
+ *
+ * @exception IllegalArgumentException if pick mode is PICK_BOUNDS
+ * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
+ * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
+ *
+ * @exception IllegalArgumentException if pickShape is PickBounds
+ * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
+ * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
+ *
+ * @exception IllegalStateException if BranchGroup is not live.
+ *
+ * @exception CapabilityNotSetException if the mode is
+ * PICK_GEOMETRY and the Geometry.ALLOW_INTERSECT capability bit
+ * is not set in any Geometry objects referred to by any shape
+ * node whose bounds intersects the PickShape.
+ *
+ * @exception CapabilityNotSetException if flags contains any of
+ * CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE, CLOSEST_GEOM_INFO
+ * or ALL_GEOM_INFO, and the capability bits that control reading of
+ * coordinate data are not set in any GeometryArray object referred
+ * to by any shape node that intersects the PickShape.
+ * The capability bits that must be set to avoid this exception are as follows :
+ * <ul>
+ * <li>By-copy geometry : GeometryArray.ALLOW_COORDINATE_READ</li>
+ * <li>By-reference geometry : GeometryArray.ALLOW_REF_DATA_READ</li>
+ * <li>Indexed geometry : IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ
+ * (in addition to one of the above)</li>
+ * </ul>
+ *
+ * @see Locale#pickAll(int,int,javax.media.j3d.PickShape)
+ * @see PickInfo
+ *
+ * @since Java 3D 1.4
+ *
+ */
+
+ public PickInfo[] pickAll( int mode, int flags, PickShape pickShape ) {
+
+ validateModeFlagAndPickShape(mode, flags, pickShape);
+ return ((BranchGroupRetained)this.retained).pickAll(mode, flags, pickShape);
+
}
+
/**
* Returns a sorted array of references to all the Pickable items that
* intersect with the pickShape. Element [0] references the item closest
@@ -139,10 +259,90 @@ public class BranchGroup extends Group {
*
*/
public SceneGraphPath[] pickAllSorted( PickShape pickShape ) {
+
if(isLive()==false)
- throw new IllegalStateException(J3dI18N.getString("BranchGroup3"));
-
- return Picking.pickAllSorted( this, pickShape );
+ throw new IllegalStateException(J3dI18N.getString("BranchGroup3"));
+
+ return ((BranchGroupRetained)this.retained).pickAllSorted(pickShape);
+
+ }
+
+
+ /**
+ * Returns a sorted array of PickInfo references to all the pickable
+ * items that intersect with the pickShape. Element [0] references
+ * the item closest to <i>origin</i> of PickShape successive array
+ * elements are further from the <i>origin</i>
+ * The accuracy of the pick is set by the pick mode. The mode include :
+ * PickInfo.PICK_BOUNDS and PickInfo.PICK_GEOMETRY. The amount of information returned
+ * is specified via a masked variable, flags, indicating which components are
+ * present in each returned PickInfo object.
+ *
+ * @param mode picking mode, one of <code>PickInfo.PICK_BOUNDS</code> or <code>PickInfo.PICK_GEOMETRY</code>.
+ *
+ * @param flags a mask indicating which components are present in each PickInfo object.
+ * This is specified as one or more individual bits that are bitwise "OR"ed together to
+ * describe the PickInfo data. The flags include :
+ * <ul>
+ * <code>PickInfo.SCENEGRAPHPATH</code> - request for computed SceneGraphPath.<br>
+ * <code>PickInfo.NODE</code> - request for computed intersected Node.<br>
+ * <code>PickInfo.LOCAL_TO_VWORLD</code> - request for computed local to virtual world transform.<br>
+ * <code>PickInfo.CLOSEST_INTERSECTION_POINT</code> - request for closest intersection point.<br>
+ * <code>PickInfo.CLOSEST_DISTANCE</code> - request for the distance of closest intersection.<br>
+ * <code>PickInfo.CLOSEST_GEOM_INFO</code> - request for only the closest intersection geometry information.<br>
+ * <code>PickInfo.ALL_GEOM_INFO</code> - request for all intersection geometry information.<br>
+ * </ul>
+ *
+ * @param pickShape the description of this picking volume or area.
+ *
+ * @exception IllegalArgumentException if flags contains both CLOSEST_GEOM_INFO and
+ * ALL_GEOM_INFO.
+ *
+ * @exception IllegalArgumentException if pickShape is a PickPoint and pick mode
+ * is set to PICK_GEOMETRY.
+ *
+ * @exception IllegalArgumentException if pick mode is neither PICK_BOUNDS
+ * nor PICK_GEOMETRY.
+ *
+ * @exception IllegalArgumentException if pick mode is PICK_BOUNDS
+ * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
+ * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
+ *
+ * @exception IllegalArgumentException if pickShape is PickBounds
+ * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
+ * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
+ *
+ * @exception IllegalStateException if BranchGroup is not live.
+ *
+ * @exception CapabilityNotSetException if the mode is
+ * PICK_GEOMETRY and the Geometry.ALLOW_INTERSECT capability bit
+ * is not set in any Geometry objects referred to by any shape
+ * node whose bounds intersects the PickShape.
+ *
+ * @exception CapabilityNotSetException if flags contains any of
+ * CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE, CLOSEST_GEOM_INFO
+ * or ALL_GEOM_INFO, and the capability bits that control reading of
+ * coordinate data are not set in any GeometryArray object referred
+ * to by any shape node that intersects the PickShape.
+ * The capability bits that must be set to avoid this exception are as follows :
+ * <ul>
+ * <li>By-copy geometry : GeometryArray.ALLOW_COORDINATE_READ</li>
+ * <li>By-reference geometry : GeometryArray.ALLOW_REF_DATA_READ</li>
+ * <li>Indexed geometry : IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ
+ * (in addition to one of the above)</li>
+ * </ul>
+ *
+ * @see Locale#pickAllSorted(int,int,javax.media.j3d.PickShape)
+ * @see PickInfo
+ *
+ * @since Java 3D 1.4
+ *
+ */
+ public PickInfo[] pickAllSorted( int mode, int flags, PickShape pickShape ) {
+
+ validateModeFlagAndPickShape(mode, flags, pickShape);
+ return ((BranchGroupRetained)this.retained).pickAllSorted(mode, flags, pickShape);
+
}
/**
@@ -160,17 +360,95 @@ public class BranchGroup extends Group {
*
*/
public SceneGraphPath pickClosest( PickShape pickShape ) {
+
if(isLive()==false)
throw new IllegalStateException(J3dI18N.getString("BranchGroup3"));
- return Picking.pickClosest( this, pickShape );
+ return ((BranchGroupRetained)this.retained).pickClosest(pickShape);
+
}
+ /**
+ * Returns a PickInfo which references the pickable item
+ * which is closest to the origin of <code>pickShape</code>.
+ * The accuracy of the pick is set by the pick mode. The mode include :
+ * PickInfo.PICK_BOUNDS and PickInfo.PICK_GEOMETRY. The amount of information returned
+ * is specified via a masked variable, flags, indicating which components are
+ * present in each returned PickInfo object.
+ *
+ * @param mode picking mode, one of <code>PickInfo.PICK_BOUNDS</code> or <code>PickInfo.PICK_GEOMETRY</code>.
+ *
+ * @param flags a mask indicating which components are present in each PickInfo object.
+ * This is specified as one or more individual bits that are bitwise "OR"ed together to
+ * describe the PickInfo data. The flags include :
+ * <ul>
+ * <code>PickInfo.SCENEGRAPHPATH</code> - request for computed SceneGraphPath.<br>
+ * <code>PickInfo.NODE</code> - request for computed intersected Node.<br>
+ * <code>PickInfo.LOCAL_TO_VWORLD</code> - request for computed local to virtual world transform.<br>
+ * <code>PickInfo.CLOSEST_INTERSECTION_POINT</code> - request for closest intersection point.<br>
+ * <code>PickInfo.CLOSEST_DISTANCE</code> - request for the distance of closest intersection.<br>
+ * <code>PickInfo.CLOSEST_GEOM_INFO</code> - request for only the closest intersection geometry information.<br>
+ * <code>PickInfo.ALL_GEOM_INFO</code> - request for all intersection geometry information.<br>
+ * </ul>
+ *
+ * @param pickShape the description of this picking volume or area.
+ *
+ * @exception IllegalArgumentException if flags contains both CLOSEST_GEOM_INFO and
+ * ALL_GEOM_INFO.
+ *
+ * @exception IllegalArgumentException if pickShape is a PickPoint and pick mode
+ * is set to PICK_GEOMETRY.
+ *
+ * @exception IllegalArgumentException if pick mode is neither PICK_BOUNDS
+ * nor PICK_GEOMETRY.
+ *
+ * @exception IllegalArgumentException if pick mode is PICK_BOUNDS
+ * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
+ * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
+ *
+ * @exception IllegalArgumentException if pickShape is PickBounds
+ * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
+ * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
+ *
+ * @exception IllegalStateException if BranchGroup is not live.
+ *
+ * @exception CapabilityNotSetException if the mode is
+ * PICK_GEOMETRY and the Geometry.ALLOW_INTERSECT capability bit
+ * is not set in any Geometry objects referred to by any shape
+ * node whose bounds intersects the PickShape.
+ *
+ * @exception CapabilityNotSetException if flags contains any of
+ * CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE, CLOSEST_GEOM_INFO
+ * or ALL_GEOM_INFO, and the capability bits that control reading of
+ * coordinate data are not set in any GeometryArray object referred
+ * to by any shape node that intersects the PickShape.
+ * The capability bits that must be set to avoid this exception are as follows :
+ * <ul>
+ * <li>By-copy geometry : GeometryArray.ALLOW_COORDINATE_READ</li>
+ * <li>By-reference geometry : GeometryArray.ALLOW_REF_DATA_READ</li>
+ * <li>Indexed geometry : IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ
+ * (in addition to one of the above)</li>
+ * </ul>
+ *
+ * @see Locale#pickClosest(int,int,javax.media.j3d.PickShape)
+ * @see PickInfo
+ *
+ * @since Java 3D 1.4
+ *
+ */
+ public PickInfo pickClosest( int mode, int flags, PickShape pickShape ) {
+
+ validateModeFlagAndPickShape(mode, flags, pickShape);
+ return ((BranchGroupRetained)this.retained).pickClosest(mode, flags, pickShape);
+
+ }
+
+
/**
* Returns a reference to any item that is Pickable below this BranchGroup that
* intersects with <code>pickShape</code>.
- *
* @param pickShape the PickShape object
+ *
* @see SceneGraphPath
* @see Locale#pickAny
* @see PickShape
@@ -178,12 +456,88 @@ public class BranchGroup extends Group {
*
*/
public SceneGraphPath pickAny( PickShape pickShape ) {
+
if(isLive()==false)
throw new IllegalStateException(J3dI18N.getString("BranchGroup3"));
+
+ return ((BranchGroupRetained)this.retained).pickAny(pickShape);
- return Picking.pickAny( this, pickShape );
}
+ /**
+ * Returns a PickInfo which references the pickable item below this
+ * BranchGroup that intersects with <code>pickShape</code>.
+ * The accuracy of the pick is set by the pick mode. The mode include :
+ * PickInfo.PICK_BOUNDS and PickInfo.PICK_GEOMETRY. The amount of information returned
+ * is specified via a masked variable, flags, indicating which components are
+ * present in each returned PickInfo object.
+ *
+ * @param mode picking mode, one of <code>PickInfo.PICK_BOUNDS</code> or <code>PickInfo.PICK_GEOMETRY</code>.
+ *
+ * @param flags a mask indicating which components are present in each PickInfo object.
+ * This is specified as one or more individual bits that are bitwise "OR"ed together to
+ * describe the PickInfo data. The flags include :
+ * <ul>
+ * <code>PickInfo.SCENEGRAPHPATH</code> - request for computed SceneGraphPath.<br>
+ * <code>PickInfo.NODE</code> - request for computed intersected Node.<br>
+ * <code>PickInfo.LOCAL_TO_VWORLD</code> - request for computed local to virtual world transform.<br>
+ * <code>PickInfo.CLOSEST_INTERSECTION_POINT</code> - request for closest intersection point.<br>
+ * <code>PickInfo.CLOSEST_DISTANCE</code> - request for the distance of closest intersection.<br>
+ * <code>PickInfo.CLOSEST_GEOM_INFO</code> - request for only the closest intersection geometry information.<br>
+ * <code>PickInfo.ALL_GEOM_INFO</code> - request for all intersection geometry information.<br>
+ * </ul>
+ *
+ * @param pickShape the description of this picking volume or area.
+ *
+ * @exception IllegalArgumentException if flags contains both CLOSEST_GEOM_INFO and
+ * ALL_GEOM_INFO.
+ *
+ * @exception IllegalArgumentException if pickShape is a PickPoint and pick mode
+ * is set to PICK_GEOMETRY.
+ *
+ * @exception IllegalArgumentException if pick mode is neither PICK_BOUNDS
+ * nor PICK_GEOMETRY.
+ *
+ * @exception IllegalArgumentException if pick mode is PICK_BOUNDS
+ * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
+ * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
+ *
+ * @exception IllegalArgumentException if pickShape is PickBounds
+ * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
+ * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
+ *
+ * @exception IllegalStateException if BranchGroup is not live.
+ *
+ * @exception CapabilityNotSetException if the mode is
+ * PICK_GEOMETRY and the Geometry.ALLOW_INTERSECT capability bit
+ * is not set in any Geometry objects referred to by any shape
+ * node whose bounds intersects the PickShape.
+ *
+ * @exception CapabilityNotSetException if flags contains any of
+ * CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE, CLOSEST_GEOM_INFO
+ * or ALL_GEOM_INFO, and the capability bits that control reading of
+ * coordinate data are not set in any GeometryArray object referred
+ * to by any shape node that intersects the PickShape.
+ * The capability bits that must be set to avoid this exception are as follows :
+ * <ul>
+ * <li>By-copy geometry : GeometryArray.ALLOW_COORDINATE_READ</li>
+ * <li>By-reference geometry : GeometryArray.ALLOW_REF_DATA_READ</li>
+ * <li>Indexed geometry : IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ
+ * (in addition to one of the above)</li>
+ * </ul>
+ *
+ * @see Locale#pickAny(int,int,javax.media.j3d.PickShape)
+ * @see PickInfo
+ *
+ * @since Java 3D 1.4
+ *
+ */
+ public PickInfo pickAny( int mode, int flags, PickShape pickShape ) {
+
+ validateModeFlagAndPickShape(mode, flags, pickShape);
+ return ((BranchGroupRetained)this.retained).pickAny(mode, flags, pickShape);
+
+ }
/**
* Creates a new instance of the node. This routine is called
@@ -200,8 +554,11 @@ public class BranchGroup extends Group {
* @see NodeComponent#setDuplicateOnCloneTree
*/
public Node cloneNode(boolean forceDuplicate) {
+
BranchGroup bg = new BranchGroup();
bg.duplicateNode(this, forceDuplicate);
return bg;
+
}
+
}
diff --git a/src/classes/share/javax/media/j3d/BranchGroupRetained.java b/src/classes/share/javax/media/j3d/BranchGroupRetained.java
index 5d1aa84..696ba49 100644
--- a/src/classes/share/javax/media/j3d/BranchGroupRetained.java
+++ b/src/classes/share/javax/media/j3d/BranchGroupRetained.java
@@ -58,11 +58,18 @@ class BranchGroupRetained extends GroupRetained {
if (universe != null) {
universe.resetWaitMCFlag();
synchronized (universe.sceneGraphLock) {
- if (source.isLive()) {
+ boolean isLive = source.isLive();
+ if (isLive) {
notifySceneGraphChanged(true);
}
+ GroupRetained oldParent = (GroupRetained)parent;
do_detach();
universe.setLiveState.clear();
+ if (isLive)
+ if (oldParent==null)
+ universe.notifyStructureChangeListeners(false,locale,(BranchGroup)this.source);
+ else
+ universe.notifyStructureChangeListeners(false,oldParent.source, (BranchGroup)this.source);
}
universe.waitForMC();
} else { // Not live yet, just do it.
@@ -106,7 +113,7 @@ class BranchGroupRetained extends GroupRetained {
setAuxData(s, j, hkIndex);
} else {
- // TODO: change this to an assertion exception
+ // XXXX: change this to an assertion exception
System.out.println("Can't Find matching hashKey in setNodeData.");
System.out.println("We're in TROUBLE!!!");
}
@@ -206,4 +213,145 @@ class BranchGroupRetained extends GroupRetained {
// without any capabilities set
mergeFlag = SceneGraphObjectRetained.DONT_MERGE;
}
+
+ SceneGraphPath[] pickAll(PickShape pickShape) {
+
+ PickInfo[] pickInfoArr = pickAll(PickInfo.PICK_BOUNDS,
+ PickInfo.SCENEGRAPHPATH, pickShape);
+
+ if(pickInfoArr == null) {
+ return null;
+ }
+
+ SceneGraphPath[] sgpArr = new SceneGraphPath[pickInfoArr.length];
+ for( int i=0; i<sgpArr.length; i++) {
+ sgpArr[i] = pickInfoArr[i].getSceneGraphPath();
+ }
+
+ return sgpArr;
+ }
+
+ PickInfo[] pickAll( int mode, int flags, PickShape pickShape ) {
+
+ if (inSharedGroup) {
+ throw new RestrictedAccessException(J3dI18N.getString("BranchGroup9"));
+ }
+
+ GeometryAtom geomAtoms[] =
+ locale.universe.geometryStructure.pickAll(locale, pickShape);
+
+ return PickInfo.pick(this, geomAtoms, mode, flags, pickShape, PickInfo.PICK_ALL);
+
+ }
+
+ SceneGraphPath[] pickAllSorted(PickShape pickShape) {
+
+ PickInfo[] pickInfoArr = pickAllSorted(PickInfo.PICK_BOUNDS,
+ PickInfo.SCENEGRAPHPATH, pickShape);
+
+ if(pickInfoArr == null) {
+ return null;
+ }
+
+ SceneGraphPath[] sgpArr = new SceneGraphPath[pickInfoArr.length];
+ for( int i=0; i<sgpArr.length; i++) {
+ sgpArr[i] = pickInfoArr[i].getSceneGraphPath();
+ }
+
+ return sgpArr;
+
+ }
+
+ PickInfo[] pickAllSorted( int mode, int flags, PickShape pickShape ) {
+
+ if (inSharedGroup) {
+ throw new RestrictedAccessException(J3dI18N.getString("BranchGroup9"));
+ }
+
+ GeometryAtom geomAtoms[] =
+ locale.universe.geometryStructure.pickAll(locale, pickShape);
+
+ PickInfo[] pickInfoArr = null;
+
+
+ if ((geomAtoms == null) || (geomAtoms.length == 0)) {
+ return null;
+ }
+
+ if (mode == PickInfo.PICK_GEOMETRY) {
+ // Need to have closestDistance set
+ flags |= PickInfo.CLOSEST_DISTANCE;
+ pickInfoArr= PickInfo.pick(this, geomAtoms, mode, flags,
+ pickShape, PickInfo.PICK_ALL);
+ if (pickInfoArr != null) {
+ PickInfo.sortPickInfoArray(pickInfoArr);
+ }
+ }
+ else {
+ PickInfo.sortGeomAtoms(geomAtoms, pickShape);
+ pickInfoArr= PickInfo.pick(this, geomAtoms, mode, flags,
+ pickShape, PickInfo.PICK_ALL);
+ }
+
+ return pickInfoArr;
+
+ }
+
+ SceneGraphPath pickClosest( PickShape pickShape ) {
+
+ PickInfo pickInfo = pickClosest( PickInfo.PICK_BOUNDS,
+ PickInfo.SCENEGRAPHPATH, pickShape);
+
+ if(pickInfo == null) {
+ return null;
+ }
+
+ return pickInfo.getSceneGraphPath();
+
+ }
+
+ PickInfo pickClosest( int mode, int flags, PickShape pickShape ) {
+
+ PickInfo[] pickInfoArr = null;
+
+ pickInfoArr = pickAllSorted( mode, flags, pickShape );
+
+ if(pickInfoArr == null) {
+ return null;
+ }
+
+ return pickInfoArr[0];
+
+ }
+
+ SceneGraphPath pickAny( PickShape pickShape ) {
+
+ PickInfo pickInfo = pickAny( PickInfo.PICK_BOUNDS,
+ PickInfo.SCENEGRAPHPATH, pickShape);
+
+ if(pickInfo == null) {
+ return null;
+ }
+ return pickInfo.getSceneGraphPath();
+ }
+
+ PickInfo pickAny( int mode, int flags, PickShape pickShape ) {
+
+ if (inSharedGroup) {
+ throw new RestrictedAccessException(J3dI18N.getString("BranchGroup9"));
+ }
+
+ GeometryAtom geomAtoms[] =
+ locale.universe.geometryStructure.pickAll(locale, pickShape);
+
+ PickInfo[] pickInfoArr = PickInfo.pick(this, geomAtoms, mode,
+ flags, pickShape, PickInfo.PICK_ANY);
+
+ if(pickInfoArr == null) {
+ return null;
+ }
+
+ return pickInfoArr[0];
+
+ }
}
diff --git a/src/classes/share/javax/media/j3d/Canvas3D.java b/src/classes/share/javax/media/j3d/Canvas3D.java
index 597fbd3..6d887b9 100644
--- a/src/classes/share/javax/media/j3d/Canvas3D.java
+++ b/src/classes/share/javax/media/j3d/Canvas3D.java
@@ -300,6 +300,7 @@ public class Canvas3D extends Canvas {
static final int FOG_DIRTY = 0x2000;
static final int MODELCLIP_DIRTY = 0x4000;
static final int VIEW_MATRIX_DIRTY = 0x8000;
+ // static final int SHADER_DIRTY = 0x10000; Not ready for this yet -- JADA
// Use to notify D3D Canvas when window change
static final int RESIZE = 1;
@@ -373,6 +374,18 @@ public class Canvas3D extends Canvas {
//
int monoscopicViewPolicy = View.CYCLOPEAN_EYE_VIEW;
+ // User requested stencil size
+ int requestedStencilSize;
+
+ // Actual stencil size return for this canvas
+ int actualStencilSize;
+
+ // True if stencil buffer is available for user
+ boolean userStencilAvailable;
+
+ // True if stencil buffer is available for system ( decal )
+ boolean systemStencilAvailable;
+
//
// Read-only flag that indicates whether double buffering is supported
// for this canvas. This is always false for off-screen canvases.
@@ -409,17 +422,11 @@ public class Canvas3D extends Canvas {
//
int textureColorTableSize;
-
- boolean multiTexAccelerated = false;
-
- // number of simultaneous Texture unit support for this canvas.
- int numTexUnitSupported = 1;
-
- // number of texture coords unit support for multi-texture.
- int numTexCoordSupported = 1;
-
// a mapping between underlying graphics library texture unit and
// texture unit state in j3d
+ //
+ // TODO: This mapping is now required to be 1-to-1, and it should be
+ // removed entirely in Java 3D 1.5
int[] texUnitStateMap = null;
// number of active/enabled texture unit
@@ -428,6 +435,10 @@ public class Canvas3D extends Canvas {
// index iof last enabled texture unit
int lastActiveTexUnit = -1;
+ // True if shadingLanguage is supported, otherwise false.
+ boolean shadingLanguageGLSL = false;
+ boolean shadingLanguageCg = false;
+
// Query properties
J3dQueryProps queryProps;
@@ -454,7 +465,10 @@ public class Canvas3D extends Canvas {
// View cache for this canvas and its associated view.
//
CanvasViewCache canvasViewCache = null;
-
+
+ // Issue 109: View cache for this canvas, for computing view frustum planes
+ CanvasViewCache canvasViewCacheFrustum = null;
+
// Since multiple renderAtomListInfo, share the same vecBounds
// we want to do the intersection test only once per renderAtom
// this flag is set to true after the first intersect and set to
@@ -488,7 +502,14 @@ public class Canvas3D extends Canvas {
BACKGROUND_DIRTY |
BACKGROUND_IMAGE_DIRTY);
- int cvDirtyMask = VIEW_INFO_DIRTY;
+ // Issue 163: Array of dirty bits is used because the Renderer and
+ // RenderBin run asynchronously. Now that they each have a separate
+ // instance of CanvasViewCache (due to the fix for Issue 109), they
+ // need separate dirty bits. Array element 0 is used for the Renderer and
+ // element 1 is used for the RenderBin.
+ static final int RENDERER_DIRTY_IDX = 0;
+ static final int RENDER_BIN_DIRTY_IDX = 1;
+ int[] cvDirtyMask = new int[2];
// This boolean informs the J3DGraphics2DImpl that the window is resized
boolean resizeGraphics2D = true;
@@ -574,7 +595,8 @@ public class Canvas3D extends Canvas {
// PixelFormat structure ( see also gldef.h ) to allow value such
// as offScreen's pixelformat, and ARB function pointers to be stored.
long fbConfig = 0;
-
+ GraphicsConfigInfo gcInfo = null;
+
// offScreenBufferInfo is a pointer to additional information about the
// offScreenBuffer in this Canvas.
//
@@ -587,6 +609,7 @@ public class Canvas3D extends Canvas {
// doesn't exist at the time getBestConfiguration() is called, and
// X11GraphicsConfig neither maintains this pointer nor provides a public
// constructor to allow Java 3D to extend it.
+ // static Hashtable fbConfigInfoTable = new Hashtable(); -- Chien
static Hashtable fbConfigTable = new Hashtable();
// The native graphics version, vendor, and renderer information
@@ -631,6 +654,7 @@ public class Canvas3D extends Canvas {
LightBin lightBin = null;
EnvironmentSet environmentSet = null;
AttributeBin attributeBin = null;
+ ShaderBin shaderBin = null;
RenderMolecule renderMolecule = null;
PolygonAttributesRetained polygonAttributes = null;
LineAttributesRetained lineAttributes = null;
@@ -641,7 +665,7 @@ public class Canvas3D extends Canvas {
ColoringAttributesRetained coloringAttributes = null;
Transform3D modelMatrix = null;
TextureBin textureBin = null;
-
+
/**
* cached RenderBin states for lazy native states update
@@ -652,7 +676,7 @@ public class Canvas3D extends Canvas {
FogRetained fog = null;
ModelClipRetained modelClip = null;
Color3f sceneAmbient = new Color3f();
- TextureUnitStateRetained texUnitState[] = null;
+ TextureUnitStateRetained[] texUnitState = null;
/**
* cached View states for lazy native states update
@@ -669,6 +693,8 @@ public class Canvas3D extends Canvas {
TexCoordGenerationRetained texCoordGeneration = null;
RenderingAttributesRetained renderingAttrs = null;
AppearanceRetained appearance = null;
+
+ ShaderProgramRetained shaderProgram = null;
// only used in Mixed Mode rendering
Object appHandle = null;
@@ -678,6 +704,8 @@ public class Canvas3D extends Canvas {
* Texture Generation linear mode. This is used for D3D
* temporary turn displayList off and do its own coordinate
* generation since D3D don't support it.
+ *
+ * TODO aces : is this still true in DX9?
*/
boolean texLinearMode = false;
@@ -701,7 +729,9 @@ public class Canvas3D extends Canvas {
// an unique bit to identify this canvas
int canvasBit = 0;
-
+ // an unique number to identify this canvas : ( canvasBit = 1 << canvasId)
+ int canvasId = 0;
+
// Avoid using this as lock, it cause deadlock
Object cvLock = new Object();
Object evaluateLock = new Object();
@@ -757,10 +787,10 @@ public class Canvas3D extends Canvas {
static final int ARB_MULTISAMPLE = 0x200;
static final int EXT_COMPILED_VERTEX_ARRAYS = 0x400;
static final int SUN_VIDEO_RESIZE = 0x800;
- static final int STENCIL_BUFFER = 0x1000;
- // The following three variables are set by
- // createNewContext()/createQueryContext() callback
+ // The following 10 variables are set by the native
+ // createNewContext()/createQueryContext() methods
+
// Supported Extensions
int extensionsSupported = 0;
@@ -770,6 +800,33 @@ public class Canvas3D extends Canvas {
// Texture Boundary Width Max
int textureBoundaryWidthMax = 0;
+ boolean multiTexAccelerated = false;
+
+ // Max number of texture coordinate sets
+ int maxTexCoordSets = 1;
+
+ // Max number of fixed-function texture units
+ int maxTextureUnits = 1;
+
+ // Max number of fragment shader texture units
+ int maxTextureImageUnits = 0;
+
+ // Max number of vertex shader texture units
+ int maxVertexTextureImageUnits = 0;
+
+ // Max number of combined shader texture units
+ int maxCombinedTextureImageUnits = 0;
+
+ // Max number of vertex attrs (not counting coord, etc.)
+ int maxVertexAttrs = 0;
+
+ // End of variables set by createNewContext()/createQueryContext()
+
+ // The total available number of texture units used by either the
+ // fixed-function or programmable shader pipeline.
+ // This is computed as: max(maxTextureUnits, maxTextureImageUnits)
+ int maxAvailableTextureUnits;
+
// Texture Width, Height Max
int textureWidthMax = 0;
int textureHeightMax = 0;
@@ -802,29 +859,31 @@ public class Canvas3D extends Canvas {
static final int TEXTUREBIN_BIT = 0x3;
static final int RENDERMOLECULE_BIT = 0x4;
static final int TRANSPARENCY_BIT = 0x5;
+ static final int SHADERBIN_BIT = 0x6;
// bitmask to specify if the corresponding "bin" needs to be updated
int stateUpdateMask = 0;
// the set of current "bins" that is to be updated, the stateUpdateMask
// specifies if each bin in this set is updated or not.
- Object curStateToUpdate[] = new Object[6];
-
+ Object curStateToUpdate[] = new Object[7];
- // Native method for determining the number of texture unit supported
- native int getTextureUnitCount(long ctx);
// Native method for determining the texture color table size
// in the underlying API for this Canvas3D.
/* native int getTextureColorTableSize(long ctx); */
// This is the native method for creating the underlying graphics context.
- native long createNewContext(long display, int window, int vid, long fbConfig,
- long shareCtx, boolean isSharedCtx,
- boolean offScreen);
+ private native long createNewContext(long display, int window, int vid,
+ long fbConfig, long shareCtx, boolean isSharedCtx,
+ boolean offScreen,
+ boolean glslLibraryAvailable,
+ boolean cgLibraryAvailable);
- native void createQueryContext(long display, int window, int vid, long fbConfig,
- boolean offScreen, int width, int height);
+ private native void createQueryContext(long display, int window, int vid,
+ long fbConfig, boolean offScreen, int width, int height,
+ boolean glslLibraryAvailable,
+ boolean cgLibraryAvailable);
native static void destroyContext(long display, int window, long context);
@@ -863,9 +922,6 @@ public class Canvas3D extends Canvas {
// The following three methods are used in multi-pass case
- // Native method for setting the depth func
- native void setDepthFunc(long ctx, int func);
-
// native method for setting blend color
native void setBlendColor(long ctx, float red, float green,
float blue, float alpha);
@@ -1001,7 +1057,7 @@ public class Canvas3D extends Canvas {
// native method for updating the texture unit state map
- native void updateTexUnitStateMap(long ctx, int numActiveTexUnit,
+ private native void updateTexUnitStateMap(long ctx, int numActiveTexUnit,
int[] texUnitStateMap);
/**
@@ -1082,7 +1138,7 @@ public class Canvas3D extends Canvas {
public Canvas3D(GraphicsConfiguration graphicsConfiguration) {
this(checkForValidGraphicsConfig(graphicsConfiguration), false);
- // TODO 1.4: remove call to checkForValidGraphicsConfig.
+ // XXXX: ENHANCEMENT -- remove call to checkForValidGraphicsConfig.
// Call should then be:
// this(graphicsConfiguration, false);
}
@@ -1135,14 +1191,22 @@ public class Canvas3D extends Canvas {
// Needed for Win32-D3D only.
vid = nativeWSobj.getCanvasVid(graphicsConfiguration);
+ // Issue 163 : Set dirty bits for both Renderer and RenderBin
+ cvDirtyMask[0] = VIEW_INFO_DIRTY;
+ cvDirtyMask[1] = VIEW_INFO_DIRTY;
+
// Fix for issue 20.
// Needed for Linux and Solaris.
- Object fbConfigObject;
- fbConfigObject = fbConfigTable.get(graphicsConfiguration);
- if ((fbConfigObject != null) &&
- (fbConfigObject instanceof Long)) {
- fbConfig = ((Long)fbConfigObject).longValue();
- /* System.out.println("Canvas3D creation FBConfig = " + fbConfig +
+ GraphicsConfigInfo gcInfo;
+ gcInfo = (GraphicsConfigInfo) fbConfigTable.get(graphicsConfiguration);
+ if (gcInfo != null) {
+ fbConfig = gcInfo.getFBConfig();
+ requestedStencilSize = gcInfo.getRequestedStencilSize();
+
+ /*
+ System.out.println("Canvas3D : requestedStencilSize is " +
+ requestedStencilSize);
+ System.out.println("Canvas3D creation FBConfig = " + fbConfig +
" offScreen is " + offScreen );
*/
// This check is needed for Unix and Win-ogl only. fbConfig should
@@ -1151,8 +1215,8 @@ public class Canvas3D extends Canvas {
throw new IllegalArgumentException
(J3dI18N.getString("Canvas3D23"));
}
- }
-
+ }
+
if (offScreen) {
screen = new Screen3D(graphicsConfiguration, offScreen);
@@ -1164,7 +1228,8 @@ public class Canvas3D extends Canvas {
// callback from AWT, set the added flag here
added = true;
synchronized(dirtyMaskLock) {
- cvDirtyMask |= Canvas3D.MOVED_OR_RESIZED_DIRTY;
+ cvDirtyMask[0] |= MOVED_OR_RESIZED_DIRTY;
+ cvDirtyMask[1] |= MOVED_OR_RESIZED_DIRTY;
}
// this canvas will not receive the paint callback either,
@@ -1343,11 +1408,14 @@ public class Canvas3D extends Canvas {
}
synchronized(dirtyMaskLock) {
- cvDirtyMask |= Canvas3D.MOVED_OR_RESIZED_DIRTY;
+ cvDirtyMask[0] |= MOVED_OR_RESIZED_DIRTY;
+ cvDirtyMask[1] |= MOVED_OR_RESIZED_DIRTY;
}
- canvasBit = VirtualUniverse.mc.getCanvasBit();
- validCanvas = true;
+ canvasId = VirtualUniverse.mc.getCanvasId();
+ canvasBit = 1 << canvasId;
+
+ validCanvas = true;
added = true;
// In case the same canvas is removed and add back,
@@ -1436,8 +1504,9 @@ public class Canvas3D extends Canvas {
screen.removeUser(this);
evaluateActive();
- VirtualUniverse.mc.freeCanvasBit(canvasBit);
+ VirtualUniverse.mc.freeCanvasId(canvasId);
canvasBit = 0;
+ canvasId = 0;
ra = null;
graphicsContext3D = null;
@@ -1812,7 +1881,7 @@ public class Canvas3D extends Canvas {
width = height = 0;
}
- // TODO: illegalSharing
+ // XXXX: illegalSharing
if ((offScreenCanvasSize.width != width) ||
(offScreenCanvasSize.height != height)) {
@@ -1842,7 +1911,8 @@ public class Canvas3D extends Canvas {
offScreenBuffer = buffer;
synchronized(dirtyMaskLock) {
- cvDirtyMask |= Canvas3D.MOVED_OR_RESIZED_DIRTY;
+ cvDirtyMask[0] |= MOVED_OR_RESIZED_DIRTY;
+ cvDirtyMask[1] |= MOVED_OR_RESIZED_DIRTY;
}
}
@@ -2033,7 +2103,7 @@ public class Canvas3D extends Canvas {
screen.renderer.doWork(0);
} else {
- // TODO:
+ // XXXX:
// Now we are in trouble, this will cause deadlock if
// waitForOffScreenRendering() is invoked
J3dMessage createMessage = VirtualUniverse.mc.getMessage();
@@ -2347,6 +2417,23 @@ public class Canvas3D extends Canvas {
}
/**
+ * Wrapper for native createNewContext method.
+ */
+ long createNewContext(long shareCtx, boolean isSharedCtx) {
+ long retVal = createNewContext(this.screen.display,
+ this.window,
+ this.vid,
+ this.fbConfig,
+ shareCtx, isSharedCtx,
+ this.offScreen,
+ VirtualUniverse.mc.glslLibraryAvailable,
+ VirtualUniverse.mc.cgLibraryAvailable);
+ // compute the max available texture units
+ maxAvailableTextureUnits = Math.max(maxTextureUnits, maxTextureImageUnits);
+ return retVal;
+ }
+
+ /**
* Make the context associated with the specified canvas current.
*/
final void makeCtxCurrent() {
@@ -2447,7 +2534,8 @@ public class Canvas3D extends Canvas {
this.leftManualEyeInImagePlate.set(position);
synchronized(dirtyMaskLock) {
- cvDirtyMask |= Canvas3D.EYE_IN_IMAGE_PLATE_DIRTY;
+ cvDirtyMask[0] |= EYE_IN_IMAGE_PLATE_DIRTY;
+ cvDirtyMask[1] |= EYE_IN_IMAGE_PLATE_DIRTY;
}
redraw();
}
@@ -2468,7 +2556,8 @@ public class Canvas3D extends Canvas {
this.rightManualEyeInImagePlate.set(position);
synchronized(dirtyMaskLock) {
- cvDirtyMask |= Canvas3D.EYE_IN_IMAGE_PLATE_DIRTY;
+ cvDirtyMask[0] |= EYE_IN_IMAGE_PLATE_DIRTY;
+ cvDirtyMask[1] |= EYE_IN_IMAGE_PLATE_DIRTY;
}
redraw();
}
@@ -2542,7 +2631,7 @@ public class Canvas3D extends Canvas {
* @param position the object that will receive the position
* @see #setMonoscopicViewPolicy
*/
- // TODO: This might not make sense for field-sequential HMD.
+ // XXXX: This might not make sense for field-sequential HMD.
public void getCenterEyeInImagePlate(Point3d position) {
if (canvasViewCache != null) {
synchronized(canvasViewCache) {
@@ -2851,17 +2940,22 @@ public class Canvas3D extends Canvas {
synchronized(cvLock) {
if (view == null) {
canvasViewCache = null;
+ canvasViewCacheFrustum = null;
} else {
canvasViewCache = new CanvasViewCache(this,
screen.screenViewCache,
- view.viewCache);
+ view.viewCache);
+ // Issue 109 : construct a separate canvasViewCache for
+ // computing view frustum
+ canvasViewCacheFrustum = new CanvasViewCache(this,
+ screen.screenViewCache,
+ view.viewCache);
synchronized (dirtyMaskLock) {
- cvDirtyMask = (STEREO_DIRTY | MONOSCOPIC_VIEW_POLICY_DIRTY
- | EYE_IN_IMAGE_PLATE_DIRTY |
- MOVED_OR_RESIZED_DIRTY);
+ cvDirtyMask[0] = VIEW_INFO_DIRTY;
+ cvDirtyMask[1] = VIEW_INFO_DIRTY;
}
- }
+ }
}
}
@@ -2904,7 +2998,8 @@ public class Canvas3D extends Canvas {
stereoEnable = flag;
useStereo = stereoEnable && stereoAvailable;
synchronized(dirtyMaskLock) {
- cvDirtyMask |= Canvas3D.STEREO_DIRTY;
+ cvDirtyMask[0] |= STEREO_DIRTY;
+ cvDirtyMask[1] |= STEREO_DIRTY;
}
redraw();
}
@@ -2956,7 +3051,8 @@ public class Canvas3D extends Canvas {
monoscopicViewPolicy = policy;
synchronized(dirtyMaskLock) {
- cvDirtyMask |= Canvas3D.MONOSCOPIC_VIEW_POLICY_DIRTY;
+ cvDirtyMask[0] |= MONOSCOPIC_VIEW_POLICY_DIRTY;
+ cvDirtyMask[1] |= MONOSCOPIC_VIEW_POLICY_DIRTY;
}
redraw();
}
@@ -3044,6 +3140,36 @@ public class Canvas3D extends Canvas {
/**
+ * Returns a flag indicating whether or not the specified shading
+ * language is supported. A ShaderError will be generated if an
+ * unsupported shading language is used.
+ *
+ * @param shadingLanguage the shading language being queried, one of:
+ * <code>Shader.SHADING_LANGUAGE_GLSL</code> or
+ * <code>Shader.SHADING_LANGUAGE_CG</code>.
+ *
+ * @return true if the specified shading language is supported,
+ * false otherwise.
+ *
+ * @since Java 3D 1.4
+ */
+ public boolean isShadingLanguageSupported(int shadingLanguage) {
+ // Call queryProperties to ensure that the shading language flags are valid
+ queryProperties();
+
+ // Return flag for specified shading language
+ switch (shadingLanguage) {
+ case Shader.SHADING_LANGUAGE_GLSL:
+ return shadingLanguageGLSL;
+ case Shader.SHADING_LANGUAGE_CG:
+ return shadingLanguageCg;
+ }
+
+ return false;
+ }
+
+
+ /**
* Returns a read-only Map object containing key-value pairs that define
* various properties for this Canvas3D. All of the keys are
* String objects. The values are key-specific, but most will be
@@ -3060,6 +3186,14 @@ public class Canvas3D extends Canvas {
* <td><b>Value Type</b></td>
* </tr>
* <tr>
+ * <td><code>shadingLanguageCg</code></td>
+ * <td>Boolean</td>
+ * </tr>
+ * <tr>
+ * <td><code>shadingLanguageGLSL</code></td>
+ * <td>Boolean</td>
+ * </tr>
+ * <tr>
* <td><code>doubleBufferAvailable</code></td>
* <td>Boolean</td>
* </tr>
@@ -3076,6 +3210,10 @@ public class Canvas3D extends Canvas {
* <td>Integer</td>
* </tr>
* <tr>
+ * <td><code>stencilSize</code></td>
+ * <td>Integer</td>
+ * </tr>
+ * <tr>
* <td><code>texture3DAvailable</code></td>
* <td>Boolean</td>
* </tr>
@@ -3116,10 +3254,26 @@ public class Canvas3D extends Canvas {
* <td>Boolean</td>
* </tr>
* <tr>
+ * <td><code>textureCoordSetsMax</code></td>
+ * <td>Integer</td>
+ * </tr>
+ * <tr>
* <td><code>textureUnitStateMax</code></td>
* <td>Integer</td>
* </tr>
* <tr>
+ * <td><code>textureImageUnitsMax</code></td>
+ * <td>Integer</td>
+ * </tr>
+ * <tr>
+ * <td><code>textureImageUnitsVertexMax</code></td>
+ * <td>Integer</td>
+ * </tr>
+ * <tr>
+ * <td><code>textureImageUnitsCombinedMax</code></td>
+ * <td>Integer</td>
+ * </tr>
+ * <tr>
* <td><code>textureCubeMapAvailable</code></td>
* <td>Boolean</td>
* </tr>
@@ -3140,6 +3294,10 @@ public class Canvas3D extends Canvas {
* <td>Float</td>
* </tr>
* <tr>
+ * <td><code>vertexAttrsMax</code></td>
+ * <td>Integer</td>
+ * </tr>
+ * <tr>
* <td><code>compressedGeometry.majorVersionNumber</code></td>
* <td>Integer</td>
* </tr>
@@ -3164,6 +3322,22 @@ public class Canvas3D extends Canvas {
* <p>
* <ul>
* <li>
+ * <code>shadingLanguageCg</code>
+ * <ul>
+ * A Boolean indicating whether or not Cg shading Language
+ * is available for this Canvas3D.
+ * </ul>
+ * </li>
+ *
+ * <li>
+ * <code>shadingLanguageGLSL</code>
+ * <ul>
+ * A Boolean indicating whether or not GLSL shading Language
+ * is available for this Canvas3D.
+ * </ul>
+ * </li>
+ *
+ * <li>
* <code>doubleBufferAvailable</code>
* <ul>
* A Boolean indicating whether or not double buffering
@@ -3195,7 +3369,6 @@ public class Canvas3D extends Canvas {
* </ul>
* </li>
*
- *
* <li>
* <code>sceneAntialiasingNumPasses</code>
* <ul>
@@ -3209,6 +3382,14 @@ public class Canvas3D extends Canvas {
* </li>
*
* <li>
+ * <code>stencilSize</code>
+ * <ul>
+ * An Integer indicating the number of stencil bits that are available
+ * for this Canvas3D.
+ * </ul>
+ * </li>
+ *
+ * <li>
* <code>texture3DAvailable</code>
* <ul>
* A Boolean indicating whether or not 3D Texture mapping
@@ -3329,14 +3510,48 @@ public class Canvas3D extends Canvas {
* </li>
*
* <li>
+ * <code>textureCoordSetsMax</code>
+ * <ul>
+ * An Integer indicating the maximum number of texture coordinate sets
+ * supported by the underlying rendering layer.
+ * </ul>
+ * </li>
+ *
+ * <li>
* <code>textureUnitStateMax</code>
* <ul>
- * An Integer indicating the maximum number of texture unit states
- * supported by the underlying rendering layer. Java3D allows an
- * application to specify number of texture unit states more than
- * what the underlying rendering layer supports; in this case, Java3D
- * will use multi-pass to support the specified number of texture
- * unit states.
+ * An Integer indicating the maximum number of fixed-function texture units
+ * supported by the underlying rendering layer. If the number of
+ * application-sepcified texture unit states exceeds the maximum number
+ * for a Canvas3D, and the fixed-function rendering pipeline is used, then
+ * the texture will be effectively disabled for that Canvas3D.
+ * </ul>
+ * </li>
+ *
+ * <li>
+ * <code>textureImageUnitsMax</code>
+ * <ul>
+ * An Integer indicating the maximum number of texture image units
+ * that can be accessed by the fragment shader when programmable shaders
+ * are used.
+ * </ul>
+ * </li>
+ *
+ * <li>
+ * <code>textureImageUnitsVertexMax</code>
+ * <ul>
+ * An Integer indicating the maximum number of texture image units
+ * that can be accessed by the vertex shader when programmable shaders
+ * are used.
+ * </ul>
+ * </li>
+ *
+ * <li>
+ * <code>textureImageUnitsCombinedMax</code>
+ * <ul>
+ * An Integer indicating the combined maximum number of texture image units
+ * that can be accessed by the vertex shader and the fragment shader when
+ * programmable shaders are used.
* </ul>
* </li>
*
@@ -3401,6 +3616,15 @@ public class Canvas3D extends Canvas {
* </li>
*
* <li>
+ * <code>vertexAttrsMax</code>
+ * <ul>
+ * An Integer indicating the maximum number of vertex attributes
+ * supported by the underlying rendering layer. This is in addition to
+ * the vertex coordinate (position), color, normal, and so forth.
+ * </ul>
+ * </li>
+ *
+ * <li>
* <code>compressedGeometry.majorVersionNumber</code><br>
* <code>compressedGeometry.minorVersionNumber</code><br>
* <code>compressedGeometry.minorMinorVersionNumber</code>
@@ -3451,7 +3675,11 @@ public class Canvas3D extends Canvas {
// inside the native code after setting the various
// fields in this object
createQueryContext(screen.display, window, vid,
- fbConfig, offScreen, 1, 1);
+ fbConfig, offScreen, 1, 1,
+ VirtualUniverse.mc.glslLibraryAvailable,
+ VirtualUniverse.mc.cgLibraryAvailable);
+ // compute the max available texture units
+ maxAvailableTextureUnits = Math.max(maxTextureUnits, maxTextureImageUnits);
}
/**
@@ -3480,8 +3708,12 @@ public class Canvas3D extends Canvas {
1: Renderer.NUM_ACCUMULATION_SAMPLES);
}
values.add(new Integer(pass));
-
- keys.add("compressedGeometry.majorVersionNumber");
+
+ keys.add("stencilSize");
+ // Return the actual stencil size.
+ values.add(new Integer(actualStencilSize));
+
+ keys.add("compressedGeometry.majorVersionNumber");
values.add(new Integer(GeometryDecompressor.majorVersionNumber));
keys.add("compressedGeometry.minorVersionNumber");
values.add(new Integer(GeometryDecompressor.minorVersionNumber));
@@ -3552,8 +3784,29 @@ public class Canvas3D extends Canvas {
values.add(new Boolean(
(textureExtendedFeatures & TEXTURE_LOD_OFFSET) != 0));
+ keys.add("textureCoordSetsMax");
+ values.add(new Integer(maxTexCoordSets));
+
keys.add("textureUnitStateMax");
- values.add(new Integer(numTexUnitSupported));
+ values.add(new Integer(maxTextureUnits));
+
+ keys.add("textureImageUnitsMax");
+ values.add(new Integer(maxTextureImageUnits));
+
+ keys.add("textureImageUnitsVertexMax");
+ values.add(new Integer(maxVertexTextureImageUnits));
+
+ keys.add("textureImageUnitsCombinedMax");
+ values.add(new Integer(maxCombinedTextureImageUnits));
+
+ keys.add("vertexAttrsMax");
+ values.add(new Integer(maxVertexAttrs));
+
+ keys.add("shadingLanguageGLSL");
+ values.add(new Boolean(shadingLanguageGLSL));
+
+ keys.add("shadingLanguageCg");
+ values.add(new Boolean(shadingLanguageCg));
keys.add("native.version");
values.add(nativeGraphicsVersion);
@@ -3587,12 +3840,21 @@ public class Canvas3D extends Canvas {
void updateViewCache(boolean flag, CanvasViewCache cvc,
BoundingBox frustumBBox, boolean doInfinite) {
+ assert cvc == null;
synchronized(cvLock) {
- if (firstPaintCalled && (canvasViewCache != null)) {
- canvasViewCache.snapshot();
- canvasViewCache.computeDerivedData(flag, cvc, frustumBBox,
- doInfinite);
- }
+ if (firstPaintCalled && (canvasViewCache != null)) {
+ assert canvasViewCacheFrustum != null;
+ // Issue 109 : choose the appropriate cvCache
+ if (frustumBBox != null) {
+ canvasViewCacheFrustum.snapshot(true);
+ canvasViewCacheFrustum.computeDerivedData(flag, null,
+ frustumBBox, doInfinite);
+ } else {
+ canvasViewCache.snapshot(false);
+ canvasViewCache.computeDerivedData(flag, null,
+ null, doInfinite);
+ }
+ }
}
}
@@ -3736,7 +3998,10 @@ public class Canvas3D extends Canvas {
reset();
- cvDirtyMask |= VIEW_INFO_DIRTY;
+ synchronized (dirtyMaskLock) {
+ cvDirtyMask[0] |= VIEW_INFO_DIRTY;
+ cvDirtyMask[1] |= VIEW_INFO_DIRTY;
+ }
needToRebuildDisplayList = true;
ctxTimeStamp = VirtualUniverse.mc.getContextTimeStamp();
@@ -3754,6 +4019,7 @@ public class Canvas3D extends Canvas {
lightBin = null;
environmentSet = null;
attributeBin = null;
+ shaderBin = null;
textureBin = null;
renderMolecule = null;
polygonAttributes = null;
@@ -3763,6 +4029,7 @@ public class Canvas3D extends Canvas {
enableLighting = false;
transparency = null;
coloringAttributes = null;
+ shaderProgram = null;
texture = null;
texAttrs = null;
if (texUnitState != null) {
@@ -3849,7 +4116,10 @@ public class Canvas3D extends Canvas {
updateMaterial(ctx, 1.0f, 1.0f, 1.0f, 1.0f);
resetRendering(NOCHANGE);
makeCtxCurrent();
- cvDirtyMask |= VIEW_INFO_DIRTY;
+ synchronized (dirtyMaskLock) {
+ cvDirtyMask[0] |= VIEW_INFO_DIRTY;
+ cvDirtyMask[1] |= VIEW_INFO_DIRTY;
+ }
needToRebuildDisplayList = true;
ctxTimeStamp = VirtualUniverse.mc.getContextTimeStamp();
@@ -3978,7 +4248,7 @@ public class Canvas3D extends Canvas {
} else {
if (rightStereoPass) {
// Only set cache in right stereo pass, otherwise
- // if the left stero pass set the cache value,
+ // if the left stereo pass set the cache value,
// setModelViewMatrix() in right stereo pass will not
// perform in RenderMolecules.
this.modelMatrix = mTrans;
@@ -3991,10 +4261,6 @@ public class Canvas3D extends Canvas {
setDepthBufferWriteEnable(ctx, mode);
}
- void setTexUnitStateMap(int texUnitStateIndex, int texUnitIndex) {
- texUnitStateMap[texUnitIndex] = texUnitStateIndex;
- }
-
void setNumActiveTexUnit(int n) {
numActiveTexUnit = n;
}
@@ -4011,6 +4277,29 @@ public class Canvas3D extends Canvas {
return lastActiveTexUnit;
}
+ // Create the texture state array
+ void createTexUnitState() {
+ texUnitState = new TextureUnitStateRetained[maxAvailableTextureUnits];
+ for (int t = 0; t < maxAvailableTextureUnits; t++) {
+ texUnitState[t] = new TextureUnitStateRetained();
+ texUnitState[t].texture = null;
+ texUnitState[t].mirror = null;
+ }
+ }
+
+ // Create the texture unit state map
+ void createTexUnitStateMap() {
+ // Create the texture unit state map array, which is a mapping from
+ // texture unit state to the actual underlying texture unit
+ // NOTE: since this is now required to be a 1-to-1 mapping, we will
+ // initialize it as such
+
+ texUnitStateMap = new int[maxAvailableTextureUnits];
+ for (int t = 0; t < maxAvailableTextureUnits; t++) {
+ texUnitStateMap[t] = t;
+ }
+ }
+
// update the underlying layer of the current texture unit state map
void updateTexUnitStateMap() {
updateTexUnitStateMap(ctx, numActiveTexUnit, texUnitStateMap);
@@ -4164,12 +4453,13 @@ public class Canvas3D extends Canvas {
curStateToUpdate[bit] = bin;
}
- // update LightBin, EnvironmentSet, & AttributeBin if neccessary
+ // update LightBin, EnvironmentSet, AttributeBin & ShaderBin if neccessary
// according to the stateUpdateMask
static int ENV_STATE_MASK = (1 << LIGHTBIN_BIT) |
- (1 << ENVIRONMENTSET_BIT) |
- (1 << ATTRIBUTEBIN_BIT);
+ (1 << ENVIRONMENTSET_BIT) |
+ (1 << ATTRIBUTEBIN_BIT) |
+ (1 << SHADERBIN_BIT);
void updateEnvState() {
@@ -4190,6 +4480,12 @@ public class Canvas3D extends Canvas {
curStateToUpdate[ATTRIBUTEBIN_BIT]).updateAttributes(this);
}
+ if ((stateUpdateMask & (1 << SHADERBIN_BIT)) != 0) {
+ ((ShaderBin)
+ curStateToUpdate[SHADERBIN_BIT]).updateAttributes(this);
+ }
+
+
// reset the state update mask for those environment state bits
stateUpdateMask &= ~ENV_STATE_MASK;
}
@@ -4317,7 +4613,7 @@ public class Canvas3D extends Canvas {
// it so there is no need to do so in
// Renderer.freeContextResources()
if (rdr.objectId > 0) {
- Canvas3D.freeTexture(ctx, rdr.objectId);
+ freeTexture(ctx, rdr.objectId);
VirtualUniverse.mc.freeTexture2DId(rdr.objectId);
rdr.objectId = -1;
@@ -4325,7 +4621,7 @@ public class Canvas3D extends Canvas {
// Free Graphics2D Texture
if ((graphics2D != null) &&
(graphics2D.objectId != -1)) {
- Canvas3D.freeTexture(ctx, graphics2D.objectId);
+ freeTexture(ctx, graphics2D.objectId);
VirtualUniverse.mc.freeTexture2DId(graphics2D.objectId);
graphics2D.objectId = -1;
}
diff --git a/src/classes/share/javax/media/j3d/CanvasViewCache.java b/src/classes/share/javax/media/j3d/CanvasViewCache.java
index 7e0ba88..db55ebc 100644
--- a/src/classes/share/javax/media/j3d/CanvasViewCache.java
+++ b/src/classes/share/javax/media/j3d/CanvasViewCache.java
@@ -342,10 +342,19 @@ class CanvasViewCache extends Object {
* NOTE: This is probably not needed, but we'll do it for symmetry
* with the ScreenViewCache and ViewCache objects.
*/
- synchronized void snapshot() {
- cvcDirtyMask = canvas.cvDirtyMask;
- canvas.cvDirtyMask = 0;
- useStereo = canvas.useStereo;
+ synchronized void snapshot(boolean computeFrustum) {
+ // Issue 109 : determine the the correct index to use -- either the
+ // Renderer or RenderBin
+ int dirtyIndex = computeFrustum ?
+ Canvas3D.RENDER_BIN_DIRTY_IDX : Canvas3D.RENDERER_DIRTY_IDX;
+
+ synchronized (canvas.dirtyMaskLock) {
+ // Issue 109 : read/clear the dirty bits for the correct index
+ cvcDirtyMask = canvas.cvDirtyMask[dirtyIndex];
+ canvas.cvDirtyMask[dirtyIndex] = 0;
+ }
+
+ useStereo = canvas.useStereo;
monoscopicViewPolicy = canvas.monoscopicViewPolicy;
leftManualEyeInImagePlate.set(canvas.leftManualEyeInImagePlate);
rightManualEyeInImagePlate.set(canvas.rightManualEyeInImagePlate);
@@ -384,13 +393,29 @@ class CanvasViewCache extends Object {
private void doComputeDerivedData(boolean currentFlag,
CanvasViewCache cvc, BoundingBox frustumBBox, boolean doInfinite) {
- if((J3dDebug.devPhase) && (J3dDebug.canvasViewCache >= J3dDebug.LEVEL_2)) {
+ // Issue 109 : determine the the correct index to use -- either the
+ // Renderer or RenderBin
+ int dirtyIndex = (frustumBBox != null) ?
+ Canvas3D.RENDER_BIN_DIRTY_IDX : Canvas3D.RENDERER_DIRTY_IDX;
+ int scrvcDirtyMask;
+
+ // Issue 109 : read/clear the dirty bits for the correct index
+ synchronized (screenViewCache) {
+ scrvcDirtyMask = screenViewCache.scrvcDirtyMask[dirtyIndex];
+ // reset screen view dirty mask if canvas is offScreen. Note:
+ // there is only one canvas per offscreen, so it is ok to
+ // do the reset here.
+ if (canvas.offScreen) {
+ screenViewCache.scrvcDirtyMask[dirtyIndex] = 0;
+ }
+ }
+
+ if((J3dDebug.devPhase) && (J3dDebug.canvasViewCache >= J3dDebug.LEVEL_2)) {
if(cvcDirtyMask != 0)
System.out.println("cvcDirtyMask : " + cvcDirtyMask);
- if(screenViewCache.scrvcDirtyMask != 0)
- System.out.println("scrvcDirtyMask : "+
- screenViewCache.scrvcDirtyMask);
+ if(scrvcDirtyMask != 0)
+ System.out.println("scrvcDirtyMask : "+ scrvcDirtyMask);
if(viewCache.vcDirtyMask != 0)
System.out.println("vcDirtyMask : " + viewCache.vcDirtyMask);
@@ -406,13 +431,13 @@ class CanvasViewCache extends Object {
// This flag is use to force a computation when a ViewPlatformTransform
// is detected. No sync. needed. We're doing a read of t/f.
- // TODO: Peeking at the dirty flag is a hack. Need to revisit this.
+ // XXXX: Peeking at the dirty flag is a hack. Need to revisit this.
boolean vprNotDirty = (viewCache.vpRetained.vprDirtyMask == 0);
if(!canvas.offScreen &&
(vprNotDirty) &&
(cvcDirtyMask == 0) &&
- (screenViewCache.scrvcDirtyMask == 0) &&
+ (scrvcDirtyMask == 0) &&
(viewCache.vcDirtyMask == 0) &&
!(updateLastTime && (doInfinite != lastDoInfinite))) {
if(frustumBBox != null)
@@ -439,7 +464,7 @@ class CanvasViewCache extends Object {
// System.out.println("vpcToVworld is \n" + vpcToVworld);
- try {
+ try {
vworldToVpc.invert(vpcToVworld);
}
catch (SingularMatrixException e) {
@@ -484,19 +509,13 @@ class CanvasViewCache extends Object {
if (frustumBBox != null)
computefrustumBBox(frustumBBox);
- // Copy the computed data into cvc.
+ // Issue 109: cvc should *always* be null
+ assert cvc == null;
if(cvc != null)
copyComputedCanvasViewCache(cvc, doInfinite);
canvas.canvasDirty |= Canvas3D.VIEW_MATRIX_DIRTY;
- // reset screen view dirty mask if canvas is offScreen. Note:
- // there is only one canvas per offscreen, so it is ok to
- // do the reset here.
- if (canvas.offScreen) {
- screenViewCache.scrvcDirtyMask = 0;
- }
-
if((J3dDebug.devPhase) && (J3dDebug.canvasViewCache >= J3dDebug.LEVEL_1)) {
// Print some data :
System.out.println("useStereo = " + useStereo);
@@ -908,7 +927,7 @@ class CanvasViewCache extends Object {
*/
private void cacheEyePosition() {
if (viewCache.compatibilityModeEnable) {
- // TODO: Compute compatibility mode eye position in ImagePlate???
+ // XXXX: Compute compatibility mode eye position in ImagePlate???
cacheEyePosScreenRelative(leftManualEyeInImagePlate,
rightManualEyeInImagePlate);
}
@@ -965,7 +984,7 @@ class CanvasViewCache extends Object {
private void computePlateToVworld() {
if (viewCache.compatibilityModeEnable) {
- // TODO: implement this correctly for compat mode
+ // XXXX: implement this correctly for compat mode
leftPlateToVworld.setIdentity();
vworldToLeftPlate.setIdentity();
}
@@ -1027,7 +1046,7 @@ class CanvasViewCache extends Object {
// Concatenate headToLeftImagePlate with leftPlateToVworld
if (viewCache.compatibilityModeEnable) {
- // TODO: implement this correctly for compat mode
+ // XXXX: implement this correctly for compat mode
headToVworld.setIdentity();
}
else {
@@ -1054,7 +1073,7 @@ class CanvasViewCache extends Object {
// Create a transform with the view platform to coexistence scale
tMat1.set(viewPlatformScale);
- // TODO: Is this really correct to ignore HMD?
+ // XXXX: Is this really correct to ignore HMD?
if (viewCache.viewPolicy != View.HMD_VIEW) {
switch (viewCache.coexistenceCenterInPworldPolicy) {
@@ -1161,7 +1180,7 @@ class CanvasViewCache extends Object {
private void computeCoexistenceToPlate() {
if (viewCache.compatibilityModeEnable) {
- // TODO: implement this correctly
+ // XXXX: implement this correctly
coexistenceToLeftPlate.setIdentity();
return;
}
@@ -1334,7 +1353,7 @@ class CanvasViewCache extends Object {
B = scale * -backClipDistance;
}
- // TODO: Can optimize for HMD case.
+ // XXXX: Can optimize for HMD case.
if (true /*viewCache.viewPolicy != View.HMD_VIEW*/) {
// Call buildProjView to build the projection and view matrices.
@@ -1392,7 +1411,7 @@ class CanvasViewCache extends Object {
}
}
}
- // TODO: The following code has never been ported
+ // XXXX: The following code has never been ported
// else {
// Point3d cen_eye;
//
@@ -1467,14 +1486,14 @@ class CanvasViewCache extends Object {
ecToCc.setIdentity();
- // TODO: we have no concept of glass correction in the Java 3D API
+ // XXXX: we have no concept of glass correction in the Java 3D API
//
// Correction in apparent 3D position of window due to glass/CRT
// and spherical/cylinderical curvarure of CRT.
// This boils down to producing modified values of Lx Ly Hx Hy
// and is different for hot spot vs. window center corrections.
//
- /* TODO:
+ /* XXXX:
double cx, cy;
if(viewPolicy != HMD_VIEW && enable_crt_glass_correction) {
if (correction_point == CORRECTION_POINT_WINDOW_CENTER) {
@@ -1812,20 +1831,20 @@ class CanvasViewCache extends Object {
}
Transform3D getImagePlateToVworld() {
- // TODO: Document -- This will return the transform of left plate.
+ // XXXX: Document -- This will return the transform of left plate.
return leftPlateToVworld;
}
Transform3D getLastVworldToImagePlate() {
- // TODO: Document -- This will return the transform of left plate.
+ // XXXX: Document -- This will return the transform of left plate.
return lastVworldToLeftPlate;
}
Transform3D getVworldToImagePlate() {
- // TODO: Document -- This will return the transform of left plate.
+ // XXXX: Document -- This will return the transform of left plate.
return vworldToLeftPlate;
}
diff --git a/src/classes/share/javax/media/j3d/CanvasViewEventCatcher.java b/src/classes/share/javax/media/j3d/CanvasViewEventCatcher.java
index 74dc617..2b723e0 100644
--- a/src/classes/share/javax/media/j3d/CanvasViewEventCatcher.java
+++ b/src/classes/share/javax/media/j3d/CanvasViewEventCatcher.java
@@ -42,7 +42,10 @@ class CanvasViewEventCatcher extends ComponentAdapter {
System.out.println("It is canvas!");
}
synchronized(canvas) {
- canvas.cvDirtyMask |= Canvas3D.MOVED_OR_RESIZED_DIRTY;
+ synchronized (canvas.dirtyMaskLock) {
+ canvas.cvDirtyMask[0] |= Canvas3D.MOVED_OR_RESIZED_DIRTY;
+ canvas.cvDirtyMask[1] |= Canvas3D.MOVED_OR_RESIZED_DIRTY;
+ }
canvas.resizeGraphics2D = true;
}
@@ -60,9 +63,12 @@ class CanvasViewEventCatcher extends ComponentAdapter {
System.out.println("Component moved " + e);
}
- synchronized(canvas) {
- canvas.cvDirtyMask |= Canvas3D.MOVED_OR_RESIZED_DIRTY;
- }
+ synchronized(canvas) {
+ synchronized (canvas.dirtyMaskLock) {
+ canvas.cvDirtyMask[0] |= Canvas3D.MOVED_OR_RESIZED_DIRTY;
+ canvas.cvDirtyMask[1] |= Canvas3D.MOVED_OR_RESIZED_DIRTY;
+ }
+ }
// Can't sync. with canvas lock since canvas.getLocationOnScreen()
// required Component lock. The order is reverse of
// removeNotify() lock sequence which required Component lock
diff --git a/src/classes/share/javax/media/j3d/CapabilityBits.java b/src/classes/share/javax/media/j3d/CapabilityBits.java
index c7844ae..0b7b41b 100644
--- a/src/classes/share/javax/media/j3d/CapabilityBits.java
+++ b/src/classes/share/javax/media/j3d/CapabilityBits.java
@@ -23,7 +23,7 @@ class CapabilityBits extends Object {
// Node extends SceneGraphObject
static final int NODE_ENABLE_COLLISION_REPORTING = 0;
static final int NODE_ENABLE_PICK_REPORTING = 1;
- static final int NODE_ALLOW_PICK = 2;
+ private static final int NODE_UNUSED_BIT = 2;
static final int NODE_ALLOW_BOUNDS_READ = 3;
static final int NODE_ALLOW_BOUNDS_WRITE = 4;
static final int NODE_ALLOW_PICKABLE_READ = 5;
@@ -241,6 +241,11 @@ class CapabilityBits extends Object {
static final int ALTERNATE_APPEARANCE_ALLOW_SCOPE_READ = 16;
static final int ALTERNATE_APPEARANCE_ALLOW_SCOPE_WRITE = 17;
+ // Additional Node bits (must go after all existing Node subclass bits)
+ static final int NODE_ALLOW_PARENT_READ = 46;
+ static final int NODE_ALLOW_LOCALE_READ = 47;
+
+
// NodeComponent extends SceneGraphObject
// Appearance extends NodeComponent
@@ -267,6 +272,12 @@ class CapabilityBits extends Object {
static final int APPEARANCE_ALLOW_TEXTURE_UNIT_STATE_READ = 20;
static final int APPEARANCE_ALLOW_TEXTURE_UNIT_STATE_WRITE = 21;
+ // ShaderAppearance extends Appearance
+ static final int SHADER_APPEARANCE_ALLOW_SHADER_PROGRAM_READ = 22;
+ static final int SHADER_APPEARANCE_ALLOW_SHADER_PROGRAM_WRITE = 23;
+ static final int SHADER_APPEARANCE_ALLOW_SHADER_ATTRIBUTE_SET_READ = 24;
+ static final int SHADER_APPEARANCE_ALLOW_SHADER_ATTRIBUTE_SET_WRITE = 25;
+
// AuralAttributes extends NodeComponent
static final int AURAL_ATTRIBUTES_ALLOW_ATTRIBUTE_GAIN_READ = 0;
static final int AURAL_ATTRIBUTES_ALLOW_ATTRIBUTE_GAIN_WRITE = 1;
@@ -362,6 +373,10 @@ class CapabilityBits extends Object {
static final int
RENDERING_ATTRIBUTES_ALLOW_IGNORE_VERTEX_COLORS_WRITE = 10;
static final int RENDERING_ATTRIBUTES_ALLOW_DEPTH_ENABLE_WRITE = 11;
+ static final int RENDERING_ATTRIBUTES_ALLOW_DEPTH_TEST_FUNCTION_READ = 12;
+ static final int RENDERING_ATTRIBUTES_ALLOW_DEPTH_TEST_FUNCTION_WRITE = 13;
+ static final int RENDERING_ATTRIBUTES_ALLOW_STENCIL_ATTRIBUTES_READ = 14;
+ static final int RENDERING_ATTRIBUTES_ALLOW_STENCIL_ATTRIBUTES_WRITE = 15;
// TexCoordGeneration extends NodeComponent
static final int TEX_COORD_GENERATION_ALLOW_ENABLE_READ = 0;
@@ -415,6 +430,20 @@ class CapabilityBits extends Object {
static final int TEXTURE_UNIT_STATE_ALLOW_STATE_READ = 0;
static final int TEXTURE_UNIT_STATE_ALLOW_STATE_WRITE = 1;
+ // ShaderProgram extends NodeComponent
+ static final int SHADER_PROGRAM_ALLOW_SHADERS_READ = 0;
+ static final int SHADER_PROGRAM_ALLOW_NAMES_READ = 1;
+
+ // ShaderAttributeSet extends NodeComponent
+ static final int SHADER_ATTRIBUTE_SET_ALLOW_ATTRIBUTES_READ = 0;
+ static final int SHADER_ATTRIBUTE_SET_ALLOW_ATTRIBUTES_WRITE = 1;
+
+ // ShaderAttribute extends NodeComponent
+
+ // ShaderAttributeObject extends ShaderAttribute
+ static final int SHADER_ATTRIBUTE_OBJECT_ALLOW_VALUE_READ = 0;
+ static final int SHADER_ATTRIBUTE_OBJECT_ALLOW_VALUE_WRITE = 1;
+
// Geometry extends NodeComponent
// NOTE: additional bits are below the subclasses
@@ -445,6 +474,12 @@ class CapabilityBits extends Object {
static final int GEOMETRY_ARRAY_ALLOW_REF_DATA_WRITE = 19;
static final int GEOMETRY_ARRAY_ALLOW_COUNT_WRITE = 20;
static final int GEOMETRY_ARRAY_ALLOW_REF_DATA_READ = 21;
+ static final int GEOMETRY_ARRAY_ALLOW_VERTEX_ATTR_READ = 22;
+ static final int GEOMETRY_ARRAY_ALLOW_VERTEX_ATTR_WRITE = 23;
+
+ // Additional GeometryArray bits (must go after IndexedGeometryArray bits)
+ static final int INDEXED_GEOMETRY_ARRAY_ALLOW_VERTEX_ATTR_INDEX_READ = 24;
+ static final int INDEXED_GEOMETRY_ARRAY_ALLOW_VERTEX_ATTR_INDEX_WRITE = 25;
// CompressedGeometry extends Geometry
static final int COMPRESSED_GEOMETRY_ALLOW_COUNT_READ = 0;
diff --git a/src/classes/share/javax/media/j3d/CgShaderProgram.java b/src/classes/share/javax/media/j3d/CgShaderProgram.java
new file mode 100644
index 0000000..c531073
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/CgShaderProgram.java
@@ -0,0 +1,173 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+/**
+ * The CgShaderProgram object is a concrete implementation of a
+ * ShaderProgram node component for NVIDIA's Cg shader language.
+ *
+ * @see SourceCodeShader
+ *
+ * @since Java 3D 1.4
+ */
+
+public class CgShaderProgram extends ShaderProgram {
+
+ /**
+ * Constructs a Cg shader program node component.
+ *
+ * <br>
+ * TODO: ADD MORE DOCUMENTATION HERE.
+ */
+ public CgShaderProgram() {
+ }
+
+ // Implement abstract setVertexAttrNames method (inherit javadoc from parent class)
+ public void setVertexAttrNames(String[] vertexAttrNames) {
+ checkForLiveOrCompiled();
+
+ if (vertexAttrNames != null) {
+ for (int i = 0; i < vertexAttrNames.length; i++) {
+ if (vertexAttrNames[i] == null) {
+ throw new NullPointerException();
+ }
+ }
+ }
+
+ ((CgShaderProgramRetained)this.retained).setVertexAttrNames(vertexAttrNames);
+ }
+
+ // Implement abstract getVertexAttrNames method (inherit javadoc from parent class)
+ public String[] getVertexAttrNames() {
+
+ if (isLiveOrCompiled()) {
+ if(!this.getCapability(ALLOW_NAMES_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("CgShaderProgram0"));
+ }
+ }
+
+ return ((CgShaderProgramRetained)this.retained).getVertexAttrNames();
+ }
+
+ // Implement abstract setShaderAttrNames method (inherit javadoc from parent class)
+ public void setShaderAttrNames(String[] shaderAttrNames) {
+ checkForLiveOrCompiled();
+
+ if (shaderAttrNames != null) {
+ for (int i = 0; i < shaderAttrNames.length; i++) {
+ if (shaderAttrNames[i] == null) {
+ throw new NullPointerException();
+ }
+ }
+ }
+
+ ((CgShaderProgramRetained)this.retained).setShaderAttrNames(shaderAttrNames);
+ }
+
+ // Implement abstract getShaderAttrNames method (inherit javadoc from parent class)
+ public String[] getShaderAttrNames() {
+
+ if (isLiveOrCompiled()) {
+ if(!this.getCapability(ALLOW_NAMES_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("CgShaderProgram0"));
+ }
+ }
+
+ return ((CgShaderProgramRetained)this.retained).getShaderAttrNames();
+ }
+
+ /**
+ * Copies the specified array of shaders into this shader
+ * program. This method makes a shallow copy of the array. The
+ * array of shaders may be null or empty (0 length), but the
+ * elements of the array must be non-null. The shading language of
+ * each shader in the array must be
+ * <code>SHADING_LANGUAGE_CG</code>. Each shader in the array must
+ * be a SourceCodeShader. There must be no more than one vertex shader
+ * and one fragment shader in the array.
+ *
+ * @param shaders array of Shader objects to be copied into this
+ * ShaderProgram
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @exception IllegalArgumentException if the shading language of
+ * any shader in the shaders array is <em>not</em>
+ * <code>SHADING_LANGUAGE_CG</code>.
+ *
+ * @exception IllegalArgumentException if there are more than one
+ * vertex shader or more than one fragment shader in the shaders
+ * array.
+ *
+ * @exception ClassCastException if any shader in the shaders
+ * array is <em>not</em> a SourceCodeShader.
+ */
+ public void setShaders(Shader[] shaders) {
+ checkForLiveOrCompiled();
+
+ if (shaders != null) {
+ // Check shaders for valid shading language, class type, etc.
+ for (int i = 0; i < shaders.length; i++) {
+ boolean hasVertexShader = false;
+ boolean hasFragmentShader = false;
+
+ // Check shading language
+ if (shaders[i].getShadingLanguage() != Shader.SHADING_LANGUAGE_CG) {
+ throw new IllegalArgumentException(J3dI18N.getString("CgShaderProgram2"));
+ }
+
+ // Check for more than one vertex shader or fragment shader
+ if (shaders[i].getShaderType() == Shader.SHADER_TYPE_VERTEX) {
+ if (hasVertexShader) {
+ throw new IllegalArgumentException(J3dI18N.getString("CgShaderProgram3"));
+ }
+ hasVertexShader = true;
+ }
+ else { // Shader.SHADER_TYPE_FRAGMENT
+ if (hasFragmentShader) {
+ throw new IllegalArgumentException(J3dI18N.getString("CgShaderProgram4"));
+ }
+ hasFragmentShader = true;
+ }
+
+ // Try to cast shader to SourceCodeShader; it will throw
+ // ClassCastException if it isn't.
+ SourceCodeShader shad = (SourceCodeShader)shaders[i];
+ }
+ }
+
+ ((CgShaderProgramRetained)this.retained).setShaders(shaders);
+ }
+
+ // Implement abstract getShaders method (inherit javadoc from parent class)
+ public Shader[] getShaders() {
+ if (isLiveOrCompiled()) {
+ if(!this.getCapability(ALLOW_SHADERS_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("CgShaderProgram1"));
+ }
+ }
+
+ return ((CgShaderProgramRetained)this.retained).getShaders();
+ }
+
+ /**
+ * Creates a retained mode CgShaderProgramRetained object that this
+ * CgShaderProgram component object will point to.
+ */
+ void createRetained() {
+ this.retained = new CgShaderProgramRetained();
+ this.retained.setSource(this);
+ }
+
+}
diff --git a/src/classes/share/javax/media/j3d/CgShaderProgramRetained.java b/src/classes/share/javax/media/j3d/CgShaderProgramRetained.java
new file mode 100644
index 0000000..eed2484
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/CgShaderProgramRetained.java
@@ -0,0 +1,283 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+/**
+ * The CgShaderProgram object is a concrete implementation of a
+ * ShaderProgram node component for NVIDIA's Cg shader language.
+ *
+ * @see SourceCodeShader
+ *
+ * @since Java 3D 1.4
+ */
+
+class CgShaderProgramRetained extends ShaderProgramRetained {
+
+ /**
+ * Constructs a Cg shader program node component.
+ *
+ * <br>
+ * TODO: ADD MORE DOCUMENTATION HERE.
+ */
+ CgShaderProgramRetained() {
+ }
+
+ synchronized void createMirrorObject() {
+ // System.out.println("CgShaderProgramRetained : createMirrorObject");
+ // This method should only call by setLive().
+ if (mirror == null) {
+ CgShaderProgramRetained mirrorCgSP = new CgShaderProgramRetained();
+ mirror = mirrorCgSP;
+ }
+ initMirrorObject();
+ }
+
+ // ShaderAttributeValue methods
+
+ native ShaderError setUniform1i(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int value);
+
+ native ShaderError setUniform1f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float value);
+
+ native ShaderError setUniform2i(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int[] value);
+
+ native ShaderError setUniform2f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+ native ShaderError setUniform3i(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int[] value);
+
+ native ShaderError setUniform3f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+ native ShaderError setUniform4i(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int[] value);
+
+ native ShaderError setUniform4f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+ native ShaderError setUniformMatrix3f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+ native ShaderError setUniformMatrix4f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+ // ShaderAttributeArray methods
+
+ native ShaderError setUniform1iArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ int[] value);
+
+ native ShaderError setUniform1fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ native ShaderError setUniform2iArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ int[] value);
+
+ native ShaderError setUniform2fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ native ShaderError setUniform3iArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ int[] value);
+
+ native ShaderError setUniform3fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ native ShaderError setUniform4iArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ int[] value);
+
+ native ShaderError setUniform4fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ native ShaderError setUniformMatrix3fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ native ShaderError setUniformMatrix4fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+
+
+ /* New native interfaces */
+ private native ShaderError createNativeShader(long ctx, int shaderType, long[] shaderId);
+ private native ShaderError destroyNativeShader(long ctx, long shaderId);
+ private native ShaderError compileNativeShader(long ctx, long shaderId, String program);
+
+ private native ShaderError createNativeShaderProgram(long ctx, long[] shaderProgramId);
+ private native ShaderError destroyNativeShaderProgram(long ctx, long shaderProgramId);
+ private native ShaderError linkNativeShaderProgram(long ctx, long shaderProgramId,
+ long[] shaderId);
+ private native void lookupNativeVertexAttrNames(long ctx, long shaderProgramId,
+ int numAttrNames, String[] attrNames, boolean[] errArr);
+ private native void lookupNativeShaderAttrNames(long ctx, long shaderProgramId,
+ int numAttrNames, String[] attrNames, long[] locArr,
+ int[] typeArr, int[] sizeArr, boolean[] isArrayArr);
+
+ private native ShaderError useShaderProgram(long ctx, long shaderProgramId);
+
+ /**
+ * Method to return a flag indicating whether this
+ * ShaderProgram is supported on the specified Canvas.
+ */
+ boolean isSupported(Canvas3D cv) {
+ return cv.shadingLanguageCg;
+ }
+
+ /**
+ * Method to create the native shader.
+ */
+ ShaderError createShader(long ctx, ShaderRetained shader, long[] shaderIdArr) {
+ return createNativeShader(ctx, shader.shaderType, shaderIdArr);
+ }
+
+ /**
+ * Method to destroy the native shader.
+ */
+ ShaderError destroyShader(long ctx, long shaderId) {
+ return destroyNativeShader(ctx, shaderId);
+ }
+
+ /**
+ * Method to compile the native shader.
+ */
+ ShaderError compileShader(long ctx, long shaderId, String source) {
+ return compileNativeShader(ctx, shaderId, source );
+ }
+
+ /**
+ * Method to create the native shader program.
+ */
+ ShaderError createShaderProgram(long ctx, long[] shaderProgramIdArr) {
+ return createNativeShaderProgram(ctx, shaderProgramIdArr);
+ }
+
+ /**
+ * Method to destroy the native shader program.
+ */
+ ShaderError destroyShaderProgram(long ctx, long shaderProgramId) {
+ return destroyNativeShaderProgram(ctx, shaderProgramId);
+ }
+
+ /**
+ * Method to link the native shader program.
+ */
+ ShaderError linkShaderProgram(long ctx, long shaderProgramId, long[] shaderIds) {
+ return linkNativeShaderProgram(ctx, shaderProgramId, shaderIds);
+ }
+
+ ShaderError bindVertexAttrName(long ctx, long shaderProgramId, String attrName, int attrIndex) {
+ // This is a no-op for Cg
+ return null;
+ }
+
+ void lookupVertexAttrNames(long ctx, long shaderProgramId, String[] attrNames, boolean[] errArr) {
+ lookupNativeVertexAttrNames(ctx, shaderProgramId, attrNames.length, attrNames, errArr);
+ }
+
+ void lookupShaderAttrNames(long ctx, long shaderProgramId,
+ String[] attrNames, AttrNameInfo[] attrNameInfoArr) {
+
+ int numAttrNames = attrNames.length;
+
+ long[] locArr = new long[numAttrNames];
+ int[] typeArr = new int[numAttrNames];
+ int[] sizeArr = new int[numAttrNames]; // currently unused
+ boolean[] isArrayArr = new boolean[numAttrNames];
+
+ // Initialize loc array to -1 (indicating no location)
+ for (int i = 0; i < numAttrNames; i++) {
+ locArr[i] = -1;
+ }
+
+ lookupNativeShaderAttrNames(ctx, shaderProgramId,
+ numAttrNames, attrNames, locArr, typeArr, sizeArr, isArrayArr);
+
+ for (int i = 0; i < numAttrNames; i++) {
+ attrNameInfoArr[i] = new AttrNameInfo();
+ attrNameInfoArr[i].setLocation(locArr[i]);
+ attrNameInfoArr[i].setArray(isArrayArr[i]);
+ attrNameInfoArr[i].setType(typeArr[i]);
+ System.err.println(attrNames[i] +
+ " : loc = " + locArr[i] +
+ ", type = " + typeArr[i] +
+ ", isArray = " + isArrayArr[i] +
+ ", size = " + sizeArr[i]);
+ }
+ }
+
+ /**
+ * Method to enable the native shader program.
+ */
+ ShaderError enableShaderProgram(long ctx, long shaderProgramId) {
+ return useShaderProgram(ctx, shaderProgramId);
+ }
+
+ /**
+ * Method to disable the native shader program.
+ */
+ ShaderError disableShaderProgram(long ctx) {
+ return useShaderProgram(ctx, 0);
+ }
+
+
+}
diff --git a/src/classes/share/javax/media/j3d/Clip.java b/src/classes/share/javax/media/j3d/Clip.java
index b32342b..e374ec3 100644
--- a/src/classes/share/javax/media/j3d/Clip.java
+++ b/src/classes/share/javax/media/j3d/Clip.java
@@ -61,6 +61,12 @@ public class Clip extends Leaf {
public static final int
ALLOW_BACK_DISTANCE_WRITE = CapabilityBits.CLIP_ALLOW_BACK_DISTANCE_WRITE;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_APPLICATION_BOUNDS_READ,
+ ALLOW_BACK_DISTANCE_READ
+ };
+
/**
* Constructs a Clip node with default parameters. The default
* values are as follows:
@@ -72,12 +78,17 @@ public class Clip extends Leaf {
*/
public Clip () {
// Just use the defaults
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
* Constructs a Clip node with the specified back clip distance.
*/
public Clip(double backDistance) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((ClipRetained)this.retained).initBackDistance(backDistance);
}
diff --git a/src/classes/share/javax/media/j3d/ColoringAttributes.java b/src/classes/share/javax/media/j3d/ColoringAttributes.java
index 996edf1..6858829 100644
--- a/src/classes/share/javax/media/j3d/ColoringAttributes.java
+++ b/src/classes/share/javax/media/j3d/ColoringAttributes.java
@@ -115,6 +115,12 @@ public class ColoringAttributes extends NodeComponent {
*/
public static final int SHADE_GOURAUD = 3;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_COLOR_READ,
+ ALLOW_SHADE_MODEL_READ
+ };
+
/**
* Constructs a ColoringAttributes node with default parameters.
* The default values are as follows:
@@ -125,6 +131,8 @@ public class ColoringAttributes extends NodeComponent {
*/
public ColoringAttributes() {
// Just use default attributes
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -134,7 +142,10 @@ public class ColoringAttributes extends NodeComponent {
* SHADE_FLAT, or SHADE_GOURAUD
*/
public ColoringAttributes(Color3f color, int shadeModel) {
- ((ColoringAttributesRetained)this.retained).initColor(color);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((ColoringAttributesRetained)this.retained).initColor(color);
((ColoringAttributesRetained)this.retained).initShadeModel(shadeModel);
}
@@ -149,7 +160,10 @@ public class ColoringAttributes extends NodeComponent {
*/
public ColoringAttributes(float red, float green, float blue,
int shadeModel) {
- ((ColoringAttributesRetained)this.retained).initColor(red, green,blue);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((ColoringAttributesRetained)this.retained).initColor(red, green,blue);
((ColoringAttributesRetained)this.retained).initShadeModel(shadeModel);
}
@@ -315,7 +329,8 @@ public class ColoringAttributes extends NodeComponent {
* Capability read bit set will be displayed.
*/
public String toString() {
- StringBuffer str=new StringBuffer("ColoringAttributes:");
+ StringBuffer str = new StringBuffer(getNamePrefix());
+ str.append("javax.media.j3d.ColoringAttributes: ");
String shadingModes[] = { "FASTEST", "NICEST", "SHADE_FLAT",
"SHADE_GOURAUD" };
diff --git a/src/classes/share/javax/media/j3d/CompressedGeometry.java b/src/classes/share/javax/media/j3d/CompressedGeometry.java
index 60541f9..8609349 100644
--- a/src/classes/share/javax/media/j3d/CompressedGeometry.java
+++ b/src/classes/share/javax/media/j3d/CompressedGeometry.java
@@ -14,11 +14,10 @@ package javax.media.j3d;
/**
* The compressed geometry object is used to store geometry in a
- * compressed format. Using compressed geometry reduces the amount
- * of memory needed by a Java 3D application and increases the speed
- * objects can be sent over the network. Once geometry decompression
- * hardware support becomes available, increased rendering performance
- * will also result from the use of compressed geometry.
+ * compressed format. Using compressed geometry may increase the speed
+ * objects can be sent over the network. Note that the geometry will
+ * be decompressed in memory, so the application will not see any
+ * memory savings.
* <p>
* Compressed geometry may be passed to this CompressedGeometry object
* in one of two ways: by copying the data into this object using the
@@ -49,6 +48,8 @@ package javax.media.j3d;
* the results are undefined.
* </li>
* </ul>
+ *
+ * @deprecated As of Java 3D version 1.4.
*/
public class CompressedGeometry extends Geometry {
@@ -87,10 +88,21 @@ public class CompressedGeometry extends Geometry {
ALLOW_REF_DATA_READ =
CapabilityBits.COMPRESSED_GEOMETRY_ALLOW_REF_DATA_READ;
+
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_COUNT_READ,
+ ALLOW_HEADER_READ,
+ ALLOW_GEOMETRY_READ,
+ ALLOW_REF_DATA_READ
+ };
+
/**
* Package scoped default constructor for use by cloneNodeComponent.
*/
CompressedGeometry() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -156,6 +168,9 @@ public class CompressedGeometry extends Geometry {
throw new IllegalArgumentException
(J3dI18N.getString("CompressedGeometry0")) ;
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
// Create a separate copy of the given header.
cgHeader = new CompressedGeometryHeader() ;
hdr.copy(cgHeader) ;
@@ -174,33 +189,10 @@ public class CompressedGeometry extends Geometry {
}
/**
- * Creates a new CompressedGeometry NodeComponent. The
- * specified compressed geometry data is accessed by reference
- * from the specified buffer.
- * If the version number of compressed geometry, as specified by
- * the CompressedGeometryHeader, is incompatible with the
- * supported version of compressed geometry in the current version
- * of Java 3D, the compressed geometry object will not be
- * rendered.
- *
- * @param hdr the compressed geometry header. This is copied
- * into the CompressedGeometry NodeComponent.
- *
- * @param compressedGeometry a buffer containing an NIO byte buffer
- * of compressed geometry data. The
- * geometry must conform to the format described in Appendix B of
- * the <i>Java 3D API Specification</i>.
+ * This constructor is not implemented.
*
- * @exception UnsupportedOperationException this method is not
- * yet implemented
- *
- * @exception IllegalArgumentException if a problem is detected with the
- * header,
- * or if the java.nio.Buffer contained in the specified J3DBuffer
- * is not a java.nio.ByteBuffer object.
- *
- * @see CompressedGeometryHeader
- * @see Canvas3D#queryProperties
+ * @exception UnsupportedOperationException this constructor is not
+ * implemented
*
* @since Java 3D 1.3
*/
@@ -323,7 +315,6 @@ public class CompressedGeometry extends Geometry {
// the same number of Shape3D objects as TriangleArray using 1/2
// to 2/3 of the vertices, with only a marginal performance penalty.
//
- // TODO revisit this
return decompressor.toTriangleStripArrays(cgr) ;
}
@@ -345,9 +336,7 @@ public class CompressedGeometry extends Geometry {
/**
* Gets the compressed geometry data reference.
*
- * @return the current compressed geometry data reference;
- * null is returned if this compressed geometry object was created
- * with a J3DBuffer reference rather than a byte array.
+ * @return the current compressed geometry data reference.
*
* @exception IllegalStateException if the data access mode for this
* object is not by-reference.
@@ -372,14 +361,11 @@ public class CompressedGeometry extends Geometry {
/**
- * Gets the compressed geometry data buffer reference.
+ * Gets the compressed geometry data buffer reference, which is
+ * always null since NIO buffers are not supported for
+ * CompressedGeometry objects.
*
- * @return the current compressed geometry data buffer reference;
- * null is returned if this compressed geometry object was created
- * with a byte array reference rather than a J3DBuffer.
- *
- * @exception IllegalStateException if the data access mode for this
- * object is not by-reference.
+ * @return null
*
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
@@ -392,11 +378,6 @@ public class CompressedGeometry extends Geometry {
throw new CapabilityNotSetException
(J3dI18N.getString("CompressedGeometry6")) ;
- if (!isByReference())
- throw new IllegalStateException
- (J3dI18N.getString("CompressedGeometry8")) ;
-
- // TODO: implement this when NIO buffer support is added
return null;
}
diff --git a/src/classes/share/javax/media/j3d/CompressedGeometryHeader.java b/src/classes/share/javax/media/j3d/CompressedGeometryHeader.java
index 39f409a..38876a9 100644
--- a/src/classes/share/javax/media/j3d/CompressedGeometryHeader.java
+++ b/src/classes/share/javax/media/j3d/CompressedGeometryHeader.java
@@ -25,6 +25,8 @@ import javax.vecmath.*;
* provided.
*
* @see CompressedGeometry
+ *
+ * @deprecated As of Java 3D version 1.4.
*/
public class CompressedGeometryHeader extends Object {
diff --git a/src/classes/share/javax/media/j3d/CompressedGeometryRetained.java b/src/classes/share/javax/media/j3d/CompressedGeometryRetained.java
index 6bd7164..737fa4d 100644
--- a/src/classes/share/javax/media/j3d/CompressedGeometryRetained.java
+++ b/src/classes/share/javax/media/j3d/CompressedGeometryRetained.java
@@ -81,23 +81,31 @@ class CompressedGeometryRetained extends GeometryRetained {
private GeometryRetained pickGeometry = null ;
/**
- * Native method that returns availability of a native by-reference
+ * Formerly native method that returns availability of a native by-reference
* rendering API for compressed geometry.
*/
- native boolean decompressByRef(long ctx) ;
+ private boolean decompressByRef(long ctx) {
+ return false;
+ }
/**
- * Native method that returns availability of hardware acceleration for
- * compressed geometry of the given version.
+ * Formerly native method that returns availability of hardware
+ * rendering (and acceleration) for compressed geometry of the
+ * given version.
*/
- native boolean decompressHW(long ctx, int majorVersion, int minorVersion) ;
+ private boolean decompressHW(long ctx, int majorVersion, int minorVersion) {
+ return false;
+ }
/**
- * Native method that does the rendering
+ * Formerly native method that does HW compressed geometry rendering
*/
- native void execute(long ctx, int version, int bufferType,
- int bufferContents, int renderFlags,
- int offset, int size, byte[] geometry) ;
+ private void execute(long ctx, int version, int bufferType,
+ int bufferContents, int renderFlags,
+ int offset, int size, byte[] geometry) {
+
+ assert false : "This method should never be called!";
+ }
/**
* Method for calling native execute() method on behalf of the J3D renderer.
@@ -107,7 +115,7 @@ class CompressedGeometryRetained extends GeometryRetained {
boolean multiScreen, int screen,
boolean ignoreVertexColors, int pass) {
- // TODO: alpha udpate
+ // XXXX: alpha udpate
execute(cv.ctx, packedVersion, bufferType, bufferContents,
renderFlags, offset, size, compressedGeometry) ;
}
@@ -313,12 +321,12 @@ class CompressedGeometryRetained extends GeometryRetained {
// The following intersect() methods are used to implement geometry-based
// picking and collision.
//
- boolean intersect(PickShape pickShape, double dist[], Point3d iPnt) {
+ boolean intersect(PickShape pickShape, PickInfo.IntersectionInfo iInfo, int flags, Point3d iPnt) {
GeometryRetained geom = getPickGeometry() ;
return (geom != null ?
- geom.intersect(pickShape, dist, iPnt) : false);
+ geom.intersect(pickShape, iInfo, flags, iPnt) : false);
}
-
+
boolean intersect(Bounds targetBound) {
GeometryRetained geom = getPickGeometry() ;
return (geom != null ? geom.intersect(targetBound) : false);
diff --git a/src/classes/share/javax/media/j3d/ConeSound.java b/src/classes/share/javax/media/j3d/ConeSound.java
index 8b57d27..424195b 100644
--- a/src/classes/share/javax/media/j3d/ConeSound.java
+++ b/src/classes/share/javax/media/j3d/ConeSound.java
@@ -147,6 +147,12 @@ public class ConeSound extends PointSound {
public static final int
ALLOW_ANGULAR_ATTENUATION_WRITE = CapabilityBits.CONE_SOUND_ALLOW_ANGULAR_ATTENUATION_WRITE;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_DIRECTION_READ,
+ ALLOW_ANGULAR_ATTENUATION_READ
+ };
+
/**
* Constructs and initializes a new ConeSound node using default
* parameters. The following default values are used:
@@ -159,6 +165,8 @@ public class ConeSound extends PointSound {
public ConeSound() {
// Uses default values defined in ConeSoundRetained.java
super();
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -177,6 +185,10 @@ public class ConeSound extends PointSound {
Vector3f direction) {
super(soundData, initialGain, position );
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((ConeSoundRetained)this.retained).setDirection(direction);
}
@@ -201,6 +213,10 @@ public class ConeSound extends PointSound {
float dirX, float dirY, float dirZ) {
super(soundData, initialGain, posX, posY, posZ );
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((ConeSoundRetained)this.retained).setDirection(dirX, dirY, dirZ);
}
@@ -248,6 +264,10 @@ public class ConeSound extends PointSound {
super(soundData, initialGain, loopCount, release, continuous, enable,
region, priority, position, frontDistanceAttenuation );
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((ConeSoundRetained)this.retained).setBackDistanceGain(
backDistanceAttenuation);
((ConeSoundRetained)this.retained).setDirection(direction);
@@ -301,6 +321,10 @@ public class ConeSound extends PointSound {
super(soundData, initialGain, loopCount, release, continuous, enable,
region, priority, posX, posY, posZ,
frontDistance, frontDistanceGain );
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((ConeSoundRetained)this.retained).setDirection(dirX, dirY, dirZ);
((ConeSoundRetained)this.retained).setBackDistanceGain(
backDistance, backDistanceGain );
@@ -346,6 +370,10 @@ public class ConeSound extends PointSound {
super(soundData, initialGain, loopCount, release, continuous, enable,
region, priority, position, distanceAttenuation );
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((ConeSoundRetained)this.retained).setDirection(direction);
((ConeSoundRetained)this.retained).setAngularAttenuation(
angularAttenuation);
@@ -402,6 +430,10 @@ public class ConeSound extends PointSound {
super(soundData, initialGain, loopCount, release, continuous, enable,
region, priority, posX, posY, posZ,
distance, distanceGain );
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((ConeSoundRetained)this.retained).setDirection(dirX, dirY, dirZ);
((ConeSoundRetained)this.retained).setAngularAttenuation(angle,
angularGain, frequencyCutoff);
@@ -444,6 +476,10 @@ public class ConeSound extends PointSound {
super(soundData, initialGain, loopCount, release, continuous, enable,
region, priority, position, frontDistanceAttenuation );
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((ConeSoundRetained)this.retained).setBackDistanceGain(
backDistanceAttenuation);
((ConeSoundRetained)this.retained).setDirection(direction);
@@ -497,6 +533,10 @@ public class ConeSound extends PointSound {
super(soundData, initialGain, loopCount, release, continuous, enable,
region, priority, posX, posY, posZ,
frontDistance, frontDistanceGain );
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((ConeSoundRetained)this.retained).setBackDistanceGain(
backDistance, backDistanceGain );
((ConeSoundRetained)this.retained).setDirection(dirX, dirY, dirZ);
diff --git a/src/classes/share/javax/media/j3d/DepthComponent.java b/src/classes/share/javax/media/j3d/DepthComponent.java
index 97f6af1..ad3212d 100644
--- a/src/classes/share/javax/media/j3d/DepthComponent.java
+++ b/src/classes/share/javax/media/j3d/DepthComponent.java
@@ -31,10 +31,18 @@ public abstract class DepthComponent extends NodeComponent {
public static final int
ALLOW_DATA_READ = CapabilityBits.DEPTH_COMPONENT_ALLOW_DATA_READ;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_SIZE_READ,
+ ALLOW_DATA_READ
+ };
+
/**
* default constructor
*/
DepthComponent() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
diff --git a/src/classes/share/javax/media/j3d/DirectionalLight.java b/src/classes/share/javax/media/j3d/DirectionalLight.java
index 987e014..a858cd1 100644
--- a/src/classes/share/javax/media/j3d/DirectionalLight.java
+++ b/src/classes/share/javax/media/j3d/DirectionalLight.java
@@ -41,6 +41,11 @@ public class DirectionalLight extends Light {
public static final int
ALLOW_DIRECTION_WRITE = CapabilityBits.DIRECTIONAL_LIGHT_ALLOW_DIRECTION_WRITE;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_DIRECTION_READ
+ };
+
/**
* Constructs a DirectionalLight node with default parameters.
* The default values are as follows:
@@ -49,6 +54,8 @@ public class DirectionalLight extends Light {
* </ul>
*/
public DirectionalLight() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -59,6 +66,10 @@ public class DirectionalLight extends Light {
*/
public DirectionalLight(Color3f color, Vector3f direction) {
super(color);
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((DirectionalLightRetained)this.retained).initDirection(direction);
}
@@ -71,6 +82,10 @@ public class DirectionalLight extends Light {
*/
public DirectionalLight(boolean lightOn, Color3f color, Vector3f direction) {
super(lightOn, color);
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((DirectionalLightRetained)this.retained).initDirection(direction);
}
diff --git a/src/classes/share/javax/media/j3d/DisplayListRenderMethod.java b/src/classes/share/javax/media/j3d/DisplayListRenderMethod.java
index 012f30a..b3f8625 100644
--- a/src/classes/share/javax/media/j3d/DisplayListRenderMethod.java
+++ b/src/classes/share/javax/media/j3d/DisplayListRenderMethod.java
@@ -155,7 +155,7 @@ class DisplayListRenderMethod implements RenderMethod {
Transform3D staticNormalTransform;
if ((rm.primaryRenderAtomList != null) &&
- (rm.texCoordSetMapLen <= cv.numTexCoordSupported)) {
+ (rm.texCoordSetMapLen <= cv.maxTexCoordSets)) {
cv.newDisplayList(cv.ctx, rm.displayListId);
@@ -195,7 +195,7 @@ class DisplayListRenderMethod implements RenderMethod {
geo = (GeometryArrayRetained)ra.geometry();
if ((geo.texCoordSetMap != null) &&
- (geo.texCoordSetMap.length > cv.numTexCoordSupported)) {
+ (geo.texCoordSetMap.length > cv.maxTexCoordSets)) {
return;
}
@@ -224,7 +224,7 @@ class DisplayListRenderMethod implements RenderMethod {
geo = (GeometryArrayRetained)ra.geometry();
if ((rm.primaryRenderAtomList != null) &&
- (rm.texCoordSetMapLen <= cv.numTexCoordSupported)) {
+ (rm.texCoordSetMapLen <= cv.maxTexCoordSets)) {
id = ra.renderAtom.dlistIds[ra.index];
cv.newDisplayList(cv.ctx, id);
diff --git a/src/classes/share/javax/media/j3d/ExceptionStrings.properties b/src/classes/share/javax/media/j3d/ExceptionStrings.properties
index c3e8674..b1541ba 100644
--- a/src/classes/share/javax/media/j3d/ExceptionStrings.properties
+++ b/src/classes/share/javax/media/j3d/ExceptionStrings.properties
@@ -153,6 +153,12 @@ BranchGroup0=Cannot compile a live BranchGroup
BranchGroup1=BranchGroup: no capability to detach
BranchGroup2=Group: no capability to write children
BranchGroup3=Picking can only work if BranchGroup is alive
+BranchGroup4=BranchGroup: Mode has to be either PickInfo.PICK_BOUNDS or PickInfo.PICK_GEOMETRY
+BranchGroup5=BranchGroup: Mode can't be PickInfo.PICK_GEOMETRY if PickShape is PickPoint
+BranchGroup6=BranchGroup: CLOSEST_GEOM_INFO and ALL_GEOM_INFO can't be set together.
+BranchGroup7=BranchGroup: Mode can't be PICK_BOUNDS if geometry information is needed
+BranchGroup8=BranchGroup: PickShape can't be PickBounds if geometry information is needed
+BranchGroup9=BranchGroup: Cannot call picking under a SharedGroup node
CachedFrustum0=Frustum must have aleast 6 planes
CachedFrustum1=Frustum must have 6 planes
Clip0=Clip: no capability to set back distance
@@ -172,7 +178,7 @@ CompressedGeometry5=CompressedGeometry: no capability to get geometry
CompressedGeometry6=CompressedGeometry: no capability to get data reference
CompressedGeometry7=CompressedGeometry: cannot directly access data in byReference mode
CompressedGeometry8=CompressedGeometry: must be in byReference mode to use this method
-CompressedGeometry9=CompressedGeometry: NIO buffer support is not currently implemented
+CompressedGeometry9=CompressedGeometry: NIO buffer support is not implemented
ClipRetained0=Clip: Immediate mode clip may not be in scene graph
ClipRetained1=Clip: illegal node under Background geometry Branch
ClipRetained2=Clip: illegal node under SharedGroup Branch
@@ -268,7 +274,7 @@ GeometryArray103=GeometryArray: initial tex coord index + valid vertex count > v
GeometryArray104=GeometryArray: initial coord index + valid vertex count > vertex count
GeometryArray105=GeometryArray: must not be in BY_REFERENCE mode to use this method
GeometryArray106=GeometryArray: texCoord set mapping is not specified
-GeometryArray107=GeometryArray: must specify at least one set of tex coord
+GeometryArray107=GeometryArray: must specify at least one set of texture coordinates
GeometryArray108=GeometryArray: invalid texCoord set mapping
GeometryArray109=GeometryArray: must be in TEXTURE_COORDINATE_4 mode to use this method
GeometryArray110=GeometryArray: validVertexCount should be greater than or equal to zero
@@ -285,6 +291,18 @@ GeometryArray120=GeometryArray: must be direct nio buffer
GeometryArray121=GeometryArray: None of the TEXTURE_COORDINATE bits are set in vertexFormat
GeometryArray122=GeometryArray: NORMALS bit is not set in vertexFormat
GeometryArray123=GeometryArray: None of the COLOR bits are set in vertexFormat
+GeometryArray124=GeometryArray: texCoordSetCount < 0
+GeometryArray125=GeometryArray: vertexAttrCount < 0
+GeometryArray126=GeometryArray: no capability to set vertex attributes
+GeometryArray127=GeometryArray: no capability to read vertex attributes
+GeometryArray128=GeometryArray: VERTEX_ATTRIBUTES flag must not be set in INTERLEAVED mode
+GeometryArray129=GeometryArray: vertex attr array length is incorrect
+GeometryArray130=GeometryArray: initial vertex attr index + valid vertex count > vertex count
+GeometryArray131=GeometryArray: vertexAttrCount > 0, but VERTEX_ATTRIBUTES flag is not set
+GeometryArray132=GeometryArray: vertexAttrCount != vertexAttrSizes.length
+GeometryArray133=GeometryArray: vertexAttrSize value out of range
+GeometryArray134=GeometryArray: vertexAttrSize invalid for this method
+GeometryArray135=GeometryArray: USE_COORD_INDEX_ONLY bit cannot be set for non-indexed geometry
GeometryDecompressor0=GeometryDecompressor: start+length > data array size
GeometryDecompressor1=GeometryDecompressor: bad delta normal in compressed buffer
GeometryDecompressorRetained0=GeometryDecompressorRetained: bad buffer data type
@@ -318,6 +336,7 @@ GeometryStripArray4=GeometryStripArray: initial color index + valid vertex count
GeometryStripArray5=GeometryStripArray: initial normal index + valid vertex count > vertex count
GeometryStripArray6=GeometryStripArray: initial tex coord index + valid vertex count > vertex count
GeometryStripArray7=GeometryStripArray: initial coord index + valid vertex count > vertex count
+GeometryStripArray8=GeometryStripArray: initial vertex attr index + valid vertex count > vertex count
GraphicsContext3D11=Background: Scene Graph background may not be in immediate mode
GraphicsContext3D12=Fog: Scene Graph fog may not be in immediate mode
GraphicsContext3D13=GraphicsContext3D: Light object is null
@@ -358,6 +377,11 @@ Locale0=Locale.addBranchGraph: Branch Group already has a parent
Locale1=Locale: no capability to detach BranchGroup
Locale3=Locale.replaceBranchGraph: Branch Group already has a parent
Locale4=Locale has been removed from its VirtualUniverse
+Locale5=Locale: Mode has to be either PickInfo.PICK_BOUNDS or PickInfo.PICK_GEOMETRY
+Locale6=Locale: Mode can't be PickInfo.PICK_GEOMETRY if PickShape is PickPoint
+Locale7=Locale: CLOSEST_GEOM_INFO and ALL_GEOM_INFO can't be set together.
+Locale8=Locale: Mode can't be PICK_BOUNDS if geometry information is needed
+Locale9=Locale: PickShape can't be PickBounds if geometry information is needed
IndexedLineStripArray0=IndexedLineStripArray: illegal vertexCount
IndexedLineStripArray1=IndexedLineStripArray: illegal indexCount
IndexedGeometryArray0=IndexedGeometryArray: no capability to get index count
@@ -381,12 +405,11 @@ IndexedGeometryArray24=IndexedGeometryArray: index color value greater than the
IndexedGeometryArray25=IndexedGeometryArray: index texcoord value greater than the array length
IndexedGeometryArray26=IndexedGeometryArray: index normal value greater than the array length
IndexedGeometryArray27=IndexedGeometryArray: index value less than zero
+IndexedGeometryArray28=IndexedGeometryArray: no capability to set vertex attribute index
+IndexedGeometryArray29=IndexedGeometryArray: no capability to get vertex attribute index
+IndexedGeometryArray30=IndexedGeometryArray: index vertexAttr value greater than the array length
IndexedLineArray0=IndexedLineArray: illegal vertexCount
IndexedLineArray1=IndexedLineArray: illegal indexCount
-IndexedGeometryArrayRetained0=execute() called on indexed geometry
-IndexedGeometryArrayRetained1=WARNING: Memory redundantly allocated for Color Indices array since the USE_COORD_INDEX_ONLY flag has been specified. This will throw a NPE in a subsequent version
-IndexedGeometryArrayRetained2=WARNING: Memory redundantly allocated for Normal Indices array since the USE_COORD_INDEX_ONLY flag has been specified. This will throw a NPE in a subsequent version
-IndexedGeometryArrayRetained3=WARNING: Memory redundantly allocated for TextureCoordinate Indices array since the USE_COORD_INDEX_ONLY flag has been specified. This will throw a NPE in a subsequent version
IndexedGeometryStripArray0=IndexedGeometryStripArray: no capability to get number of strips
IndexedGeometryStripArray1=IndexedGeometryStripArray: no capability to get strip index counts
IndexedGeometryStripArray2=IndexedGeometryStripArray: no capability to set strip index counts
@@ -466,14 +489,15 @@ MorphRetained2=Morph: All GeometryArrays must be of same type
MorphRetained5=Invalid SceneGraphPath encountered : localToVworld is null.
MorphRetained7=Morph: number of weights not same as number of GeometryArrays
MorphRetained8=Morph: sum of all weights is NOT 1.0
-Node0=Cannot get the parent of a live or compiled node
+MorphRetained9=Morph: vertex attributes are not supported
+Node0=Node: no capability to read parent
Node1=Node: no capability to set bounds
Node2=Node: no capability to read user bounds
Node3=Node: no capability to read Pickable
Node4=Node: no capability to set Collidable
Node5=Node: no capability to set user auto compute bounds
Node6=Node: no capability to read user auto compute bounds
-Node7=Node: local to vworld transform is undefined for a node that is not part of a live scene graph
+Node7=Node: local to vworld transform is undefined for a node that is compiled but not live
Node8=Node: no capability to read local to vworld transform
Node9=Node: Invalid geometric bounds
Node11=cloneTree: should be overridden in child
@@ -482,6 +506,14 @@ Node13=Node: Cannot clone a live or compiled scenegraph
Node14=Node: no capability to set Pickable
Node15=Node: Cannot compile, clone or getBounds on a scene graph that contains a cycle.
Node16=Node: no capability to read Collidable
+Node17=Node: no capability to read locale
+PickInfo0=PickInfo: PICK_GEOMETRY mode - no capability to ALLOW_GEOMETRY_READ
+PickInfo1=PickInfo: PICK_GEOMETRY mode - no capability to ALLOW_INTERSECT
+PickInfo2=PickInfo: PICK_GEOMETRY mode - no capability to ALLOW_COORDINATE_READ
+PickInfo3=PickInfo: PICK_GEOMETRY mode - no capability to ALLOW_COUNT_READ
+PickInfo4=PickInfo: PICK_GEOMETRY mode - no capability to ALLOW_FORMAT_READ
+PickInfo5=PickInfo: PICK_GEOMETRY mode - no capability to ALLOW_COORDINATE_INDEX_READ
+PickInfo6=PickInfo: PICK_GEOMETRY mode - no capability to ALLOW_GEOMETRY_ARRAY_READ
Picking0=Cannot call picking under a SharedGroup node
Picking2=Picking: Node has no parent and locale. This is illegal!
NodeComponent0=NodeComponent:cloneNodeComponent must be defined in subclass
@@ -572,6 +604,10 @@ RenderingAttributes10=RenderingAttributes: no capability to set raster op
RenderingAttributes11=RenderingAttributes: no capability to get raster op
RenderingAttributes12=RenderingAttributes: no capability to set ignore vertex colors flag
RenderingAttributes13=RenderingAttributes: no capability to get ignore vertex colors flag
+RenderingAttributes14=RenderingAttributes: no capability to set depth test function
+RenderingAttributes15=RenderingAttributes: no capability to get depth test function
+RenderingAttributes16=RenderingAttributes: no capability to set stencil attributes
+RenderingAttributes17=RenderingAttributes: no capability to get stencil attributes
TriangleStripArrayRetained0=PickPoint doesn't make sense for geometry-based picking. Java 3D doesn't have spatial information of the surface. Should use PickBounds with BoundingSphere and set radius to a epsilon tolerance.
TriangleStripArrayRetained1=stripVertexCounts element less than 3
RotationPathInterpolator0=RotationPathInterpolator: length of knots and quats must be of the same length
@@ -891,6 +927,26 @@ ModelClip14=ModelClip: no capability to read influencing bounding leaf
ModelClipRetained1=ModelClip: illegal node under SharedGroup Branch
MasterControl0=OpenGL is not MT safe
MasterControl1=Green threads are not supported
+MasterControl2=NOTE: simulated multi-texture will not work for programmable shaders
+MasterControl3=and will be removed entirely in the next release of Java 3D
J3DBuffer0=Native access to NIO buffer not supported
J3DBuffer1=NIO buffer must be a direct buffer
J3DBuffer2=NIO buffer must match native byte order of underlying platform
+GLSLShaderProgram0=GLSLShaderProgram: no capability to read names
+GLSLShaderProgram1=GLSLShaderProgram: no capability to read shaders
+GLSLShaderProgram2=GLSLShaderProgram: Shader has incompatible shading language
+CgShaderProgram0=CgShaderProgram: no capability to read names
+CgShaderProgram1=CgShaderProgram: no capability to read shaders
+CgShaderProgram2=CgShaderProgram: Shader has incompatible shading language
+CgShaderProgram3=CgShaderProgram: must not specify more than one vertex shader
+CgShaderProgram4=CgShaderProgram: must not specify more than one fragment shader
+ShaderAppearance0=ShaderAppearance: no capability to set shader program
+ShaderAppearance1=ShaderAppearance: no capability to get shader program
+ShaderAppearance2=ShaderAppearance: no capability to set shader attribute set
+ShaderAppearance3=ShaderAppearance: no capability to get shader attribute set
+ShaderAttributeBinding0=ShaderAttributeBinding is not supported
+ShaderProgramRetained0=Shading language not supported
+ShaderAttributeObject0=ShaderAttributeObject: no capability to get value
+ShaderAttributeObject1=ShaderAttributeObject: no capability to set value
+ShaderAttributeSet0=ShaderAttributeSet: no capability to get attribute
+ShaderAttributeSet1=ShaderAttributeSet: no capability to set attribute
diff --git a/src/classes/share/javax/media/j3d/ExponentialFog.java b/src/classes/share/javax/media/j3d/ExponentialFog.java
index 75b17e1..9d95a32 100644
--- a/src/classes/share/javax/media/j3d/ExponentialFog.java
+++ b/src/classes/share/javax/media/j3d/ExponentialFog.java
@@ -46,6 +46,11 @@ public class ExponentialFog extends Fog {
public static final int
ALLOW_DENSITY_WRITE = CapabilityBits.EXPONENTIAL_FOG_ALLOW_DENSITY_WRITE;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_DENSITY_READ
+ };
+
/**
* Constructs an ExponentialFog node with default parameters.
* The default values are as follows:
@@ -55,6 +60,8 @@ public class ExponentialFog extends Fog {
*/
public ExponentialFog() {
// Just use the defaults
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -63,6 +70,9 @@ public class ExponentialFog extends Fog {
*/
public ExponentialFog(Color3f color) {
super(color);
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -73,6 +83,10 @@ public class ExponentialFog extends Fog {
*/
public ExponentialFog(Color3f color, float density) {
super(color);
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((ExponentialFogRetained)this.retained).initDensity(density);
}
@@ -84,6 +98,9 @@ public class ExponentialFog extends Fog {
*/
public ExponentialFog(float r, float g, float b) {
super(r, g, b);
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -96,6 +113,10 @@ public class ExponentialFog extends Fog {
*/
public ExponentialFog(float r, float g, float b, float density) {
super(r, g, b);
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((ExponentialFogRetained)this.retained).initDensity(density);
}
diff --git a/src/classes/share/javax/media/j3d/ExponentialFogRetained.java b/src/classes/share/javax/media/j3d/ExponentialFogRetained.java
index 512e521..b82efd9 100644
--- a/src/classes/share/javax/media/j3d/ExponentialFogRetained.java
+++ b/src/classes/share/javax/media/j3d/ExponentialFogRetained.java
@@ -21,7 +21,10 @@ import java.util.ArrayList;
*/
class ExponentialFogRetained extends FogRetained {
// Fog density
- float density = 1.0f;
+ private float density = 1.0f;
+
+ // Issue 144: density in Eye Coordinates (EC)
+ private float densityInEc;
// dirty bits for ExponentialFog
static final int DENSITY_CHANGED = FogRetained.LAST_DEFINED_BIT << 1;
@@ -108,7 +111,9 @@ class ExponentialFogRetained extends FogRetained {
native void update(long ctx, float red, float green, float blue, float density);
void update(long ctx, double scale) {
- update(ctx, color.x, color.y, color.z, density);
+ // Issue 144: recompute the density in EC, and send it to native code
+ validateDistancesInEc(scale);
+ update(ctx, color.x, color.y, color.z, densityInEc);
}
@@ -128,6 +133,8 @@ class ExponentialFogRetained extends FogRetained {
((ExponentialFogRetained)mirrorFog).density = ((Float)((Object[])objs[4])[4]).floatValue();
}
+ // Issue 144: store the local to vworld scale used to transform the density
+ ((ExponentialFogRetained)mirrorFog).setLocalToVworldScale(getLastLocalToVworld().getDistanceScale());
super.updateMirrorObject(objs);
}
@@ -142,6 +149,18 @@ class ExponentialFogRetained extends FogRetained {
return efr;
}
-
+
+ // Issue 144: method to recompute the density in EC by multiplying the specified
+ // density by the inverse of the local to EC scale
+ /**
+ * Scale distances from local to eye coordinate.
+ */
+ protected void validateDistancesInEc(double vworldToCoexistenceScale) {
+ // vworldToCoexistenceScale can be used here since
+ // CoexistenceToEc has a unit scale
+ double localToEcScale = getLocalToVworldScale() * vworldToCoexistenceScale;
+
+ densityInEc = (float)(density / localToEcScale);
+ }
}
diff --git a/src/classes/share/javax/media/j3d/Fog.java b/src/classes/share/javax/media/j3d/Fog.java
index cb5e517..ffd2292 100644
--- a/src/classes/share/javax/media/j3d/Fog.java
+++ b/src/classes/share/javax/media/j3d/Fog.java
@@ -77,6 +77,13 @@ public abstract class Fog extends Leaf {
public static final int
ALLOW_SCOPE_WRITE = CapabilityBits.FOG_ALLOW_SCOPE_WRITE;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_INFLUENCING_BOUNDS_READ,
+ ALLOW_COLOR_READ,
+ ALLOW_SCOPE_READ
+ };
+
/**
* Constructs a Fog node with default parameters. The default
* values are as follows:
@@ -89,6 +96,8 @@ public abstract class Fog extends Leaf {
*/
public Fog() {
// Just use the defaults
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -96,7 +105,10 @@ public abstract class Fog extends Leaf {
* @param color the fog color
*/
public Fog(Color3f color) {
- ((FogRetained)this.retained).initColor(color);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((FogRetained)this.retained).initColor(color);
}
/**
@@ -106,7 +118,10 @@ public abstract class Fog extends Leaf {
* @param b the blue component of the fog color
*/
public Fog(float r, float g, float b) {
- ((FogRetained)this.retained).initColor(r, g, b);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((FogRetained)this.retained).initColor(r, g, b);
}
/**
diff --git a/src/classes/share/javax/media/j3d/FogRetained.java b/src/classes/share/javax/media/j3d/FogRetained.java
index 9c84fd5..9ab5ec6 100644
--- a/src/classes/share/javax/media/j3d/FogRetained.java
+++ b/src/classes/share/javax/media/j3d/FogRetained.java
@@ -90,6 +90,9 @@ abstract class FogRetained extends LeafRetained{
// Is true, if the mirror fog is viewScoped
boolean isViewScoped = false;
+ // Scale value extracted from localToVworld transform
+ private double localToVworldScale = 1.0;
+
FogRetained() {
localBounds = new BoundingBox();
((BoundingBox)localBounds).setLower( 1.0, 1.0, 1.0);
@@ -750,6 +753,8 @@ abstract class FogRetained extends LeafRetained{
}
void updateTransformChange() {
+ super.updateTransformChange();
+ setLocalToVworldScale(sgFog.getLastLocalToVworld().getDistanceScale());
}
// Called on mirror object
@@ -785,5 +790,19 @@ abstract class FogRetained extends LeafRetained{
void getMirrorObjects(ArrayList leafList, HashKey key) {
leafList.add(mirrorFog);
}
-
+
+ /**
+ * Scale distances from local to eye coordinate
+ */
+ protected void validateDistancesInEc(double vworldToCoexistenceScale) {
+ assert false : "subclasses should override this method";
+ }
+
+ double getLocalToVworldScale() {
+ return localToVworldScale;
+ }
+
+ void setLocalToVworldScale(double localToVworldScale) {
+ this.localToVworldScale = localToVworldScale;
+ }
}
diff --git a/src/classes/share/javax/media/j3d/Font3D.java b/src/classes/share/javax/media/j3d/Font3D.java
index 5e440f8..d706abe 100644
--- a/src/classes/share/javax/media/j3d/Font3D.java
+++ b/src/classes/share/javax/media/j3d/Font3D.java
@@ -178,6 +178,49 @@ public class Font3D extends NodeComponent {
bounds.setUpper(upper);
}
+ // BY MIK OF CLASSX
+ /**
+ * Returns a GeometryArray of a glyph in this Font3D.
+ *
+ * @param c character from which to generate a tessellated glyph.
+ *
+ * @return a GeometryArray
+ *
+ * @since Java 3D 1.4
+ */
+ public GeometryArray getGlyphGeometry(char c) {
+ char code[] = { c };
+ GlyphVector gv = font.createGlyphVector(frc, code);
+
+ // triangulate the glyph
+ GeometryArrayRetained glyph_gar = triangulateGlyphs(gv, code[0]);
+
+ // Assume that triangulateGlyphs returns a triangle array with only coords & normals
+ // (and without by-ref, interleaved, etc.)
+ assert glyph_gar instanceof TriangleArrayRetained :
+ "Font3D: GeometryArray is not an instance of TrangleArray";
+ assert glyph_gar.getVertexFormat() == (GeometryArray.COORDINATES | GeometryArray.NORMALS) :
+ "Font3D: Illegal GeometryArray format -- only coordinates and normals expected";
+
+ // create a correctly sized TriangleArray
+ TriangleArray ga = new TriangleArray(glyph_gar.getVertexCount(),glyph_gar.getVertexFormat());
+
+ // temp storage for coords, normals
+ float tmp[] = new float[3];
+
+ int vertexCount = ga.getVertexCount();
+ for(int i=0; i<vertexCount; i++) {
+ // copy the glyph geometry to the TriangleArray
+ glyph_gar.getCoordinate(i,tmp);
+ ga.setCoordinate(i,tmp);
+
+ glyph_gar.getNormal(i,tmp);
+ ga.setNormal(i,tmp);
+ }
+
+ return ga;
+ }
+
// Triangulate glyph with 'unicode' if not already done.
GeometryArrayRetained triangulateGlyphs(GlyphVector gv, char c) {
@@ -415,7 +458,7 @@ public class Font3D extends NodeComponent {
}
}
- // TODO: Should use IndexedTriangleArray to avoid
+ // XXXX: Should use IndexedTriangleArray to avoid
// duplication of vertices. To create triangles for
// side faces, every vertex is duplicated currently.
TriangleArray triAry = new TriangleArray(vertCnt,
diff --git a/src/classes/share/javax/media/j3d/FreeListManager.java b/src/classes/share/javax/media/j3d/FreeListManager.java
index f5c10c5..0233669 100644
--- a/src/classes/share/javax/media/j3d/FreeListManager.java
+++ b/src/classes/share/javax/media/j3d/FreeListManager.java
@@ -25,10 +25,9 @@ class FreeListManager {
static final int DISPLAYLIST = 4;
static final int TEXTURE2D = 5;
static final int TEXTURE3D = 6;
- static final int CANVASBIT = 7;
- static final int VECTOR3D = 8;
- static final int POINT3D = 9;
- static int MAXINT = 9;
+ static final int VECTOR3D = 7;
+ static final int POINT3D = 8;
+ static int MAXINT = 8;
// what list we are going to shrink next
private static int currlist = 0;
@@ -44,7 +43,6 @@ class FreeListManager {
freelist[DISPLAYLIST] = new IntegerFreeList();
freelist[TEXTURE2D] = new IntegerFreeList();
freelist[TEXTURE3D] = new IntegerFreeList();
- freelist[CANVASBIT] = new IntegerFreeList();
freelist[POINT3D] = new MemoryFreeList("javax.vecmath.Point3d");
freelist[VECTOR3D] = new MemoryFreeList("javax.vecmath.Vector3d");
}
diff --git a/src/classes/share/javax/media/j3d/GLSLShaderProgram.java b/src/classes/share/javax/media/j3d/GLSLShaderProgram.java
new file mode 100644
index 0000000..5608cb8
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/GLSLShaderProgram.java
@@ -0,0 +1,158 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+/**
+ * The GLSLShaderProgram object is a concrete implementation of a
+ * ShaderProgram node component for the OpenGL GLSL shading language.
+ *
+ * @see SourceCodeShader
+ *
+ * @since Java 3D 1.4
+ */
+
+public class GLSLShaderProgram extends ShaderProgram {
+
+ /**
+ * Constructs a GLSL shader program node component.
+ *
+ * <br>
+ * TODO: ADD MORE DOCUMENTATION HERE.
+ */
+ public GLSLShaderProgram() {
+ }
+
+ // Implement abstract setVertexAttrNames method (inherit javadoc from parent class)
+ public void setVertexAttrNames(String[] vertexAttrNames) {
+ checkForLiveOrCompiled();
+
+ if (vertexAttrNames != null) {
+ for (int i = 0; i < vertexAttrNames.length; i++) {
+ if (vertexAttrNames[i] == null) {
+ throw new NullPointerException();
+ }
+ }
+ }
+
+ ((GLSLShaderProgramRetained)this.retained).setVertexAttrNames(vertexAttrNames);
+ }
+
+ // Implement abstract getVertexAttrNames method (inherit javadoc from parent class)
+ public String[] getVertexAttrNames() {
+
+ if (isLiveOrCompiled()) {
+ if(!this.getCapability(ALLOW_NAMES_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GLSLShaderProgram0"));
+ }
+ }
+
+ return ((GLSLShaderProgramRetained)this.retained).getVertexAttrNames();
+
+ }
+
+ // Implement abstract setShaderAttrNames method (inherit javadoc from parent class)
+ public void setShaderAttrNames(String[] shaderAttrNames) {
+ checkForLiveOrCompiled();
+
+ if (shaderAttrNames != null) {
+ for (int i = 0; i < shaderAttrNames.length; i++) {
+ if (shaderAttrNames[i] == null) {
+ throw new NullPointerException();
+ }
+ }
+ }
+
+ ((GLSLShaderProgramRetained)this.retained).setShaderAttrNames(shaderAttrNames);
+ }
+
+ // Implement abstract getShaderAttrNames method (inherit javadoc from parent class)
+ public String[] getShaderAttrNames() {
+
+ if (isLiveOrCompiled()) {
+ if(!this.getCapability(ALLOW_NAMES_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GLSLShaderProgram0"));
+ }
+ }
+
+ return ((GLSLShaderProgramRetained)this.retained).getShaderAttrNames();
+
+ }
+
+ /**
+ * Copies the specified array of shaders into this shader
+ * program. This method makes a shallow copy of the array. The
+ * array of shaders may be null or empty (0 length), but the
+ * elements of the array must be non-null. The shading language of
+ * each shader in the array must be
+ * <code>SHADING_LANGUAGE_GLSL</code>. Each shader in the array must
+ * be a SourceCodeShader.
+ *
+ * @param shaders array of Shader objects to be copied into this
+ * ShaderProgram
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @exception IllegalArgumentException if the shading language of
+ * any shader in the shaders array is <em>not</em>
+ * <code>SHADING_LANGUAGE_GLSL</code>.
+ *
+ * @exception ClassCastException if any shader in the shaders
+ * array is <em>not</em> a SourceCodeShader.
+ *
+ * @exception NullPointerException if any element in the
+ * shaders array is null.
+ */
+ public void setShaders(Shader[] shaders) {
+ checkForLiveOrCompiled();
+
+ if(shaders != null) {
+ // Check shaders for valid shading language and class type
+ for (int i = 0; i < shaders.length; i++) {
+ if (shaders[i].getShadingLanguage() != Shader.SHADING_LANGUAGE_GLSL) {
+ throw new IllegalArgumentException(J3dI18N.getString("GLSLShaderProgram2"));
+ }
+
+ // Try to cast shader to SourceCodeShader; it will throw
+ // ClassCastException if it isn't.
+ SourceCodeShader shad = (SourceCodeShader)shaders[i];
+ }
+
+ }
+
+ ((GLSLShaderProgramRetained)this.retained).setShaders(shaders);
+ }
+
+ // Implement abstract getShaders method (inherit javadoc from parent class)
+ public Shader[] getShaders() {
+
+ if (isLiveOrCompiled()) {
+ if(!this.getCapability(ALLOW_SHADERS_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GLSLShaderProgram1"));
+ }
+ }
+
+ return ((GLSLShaderProgramRetained)this.retained).getShaders();
+ }
+
+ /**
+ * Creates a retained mode GLSLShaderProgramRetained object that this
+ * GLSLShaderProgram component object will point to.
+ */
+ void createRetained() {
+ this.retained = new GLSLShaderProgramRetained();
+ this.retained.setSource(this);
+ }
+
+
+}
diff --git a/src/classes/share/javax/media/j3d/GLSLShaderProgramRetained.java b/src/classes/share/javax/media/j3d/GLSLShaderProgramRetained.java
new file mode 100644
index 0000000..7d4e10b
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/GLSLShaderProgramRetained.java
@@ -0,0 +1,281 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+/**
+ * The GLSLShaderProgram object is a concrete implementation of a
+ * ShaderProgram node component for the OpenGL GLSL shading language.
+ *
+ * @see SourceCodeShader
+ *
+ * @since Java 3D 1.4
+ */
+
+class GLSLShaderProgramRetained extends ShaderProgramRetained {
+
+ /**
+ * Constructs a GLSL shader program node component.
+ *
+ * <br>
+ * TODO: ADD MORE DOCUMENTATION HERE.
+ */
+ GLSLShaderProgramRetained() {
+ }
+
+ synchronized void createMirrorObject() {
+ // System.out.println("GLSLShaderProgramRetained : createMirrorObject");
+ // This method should only call by setLive().
+ if (mirror == null) {
+ GLSLShaderProgramRetained mirrorGLSLSP = new GLSLShaderProgramRetained();
+ mirror = mirrorGLSLSP;
+ mirror.source = source;
+ }
+ initMirrorObject();
+ }
+
+ // ShaderAttributeValue methods
+
+ native ShaderError setUniform1i(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int value);
+
+ native ShaderError setUniform1f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float value);
+
+ native ShaderError setUniform2i(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int[] value);
+
+ native ShaderError setUniform2f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+ native ShaderError setUniform3i(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int[] value);
+
+ native ShaderError setUniform3f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+ native ShaderError setUniform4i(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int[] value);
+
+ native ShaderError setUniform4f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+ native ShaderError setUniformMatrix3f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+ native ShaderError setUniformMatrix4f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+ // ShaderAttributeArray methods
+
+ native ShaderError setUniform1iArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ int[] value);
+
+ native ShaderError setUniform1fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ native ShaderError setUniform2iArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ int[] value);
+
+ native ShaderError setUniform2fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ native ShaderError setUniform3iArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ int[] value);
+
+ native ShaderError setUniform3fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ native ShaderError setUniform4iArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ int[] value);
+
+ native ShaderError setUniform4fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ native ShaderError setUniformMatrix3fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ native ShaderError setUniformMatrix4fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ /* New native interfaces */
+ private native ShaderError createNativeShader(long ctx, int shaderType, long[] shaderId);
+ private native ShaderError destroyNativeShader(long ctx, long shaderId);
+ private native ShaderError compileNativeShader(long ctx, long shaderId, String program);
+
+ private native ShaderError createNativeShaderProgram(long ctx, long[] shaderProgramId);
+ private native ShaderError destroyNativeShaderProgram(long ctx, long shaderProgramId);
+ private native ShaderError linkNativeShaderProgram(long ctx, long shaderProgramId,
+ long[] shaderId);
+ private native ShaderError bindNativeVertexAttrName(long ctx, long shaderProgramId,
+ String attrName, int attrIndex);
+ private native void lookupNativeShaderAttrNames(long ctx, long shaderProgramId,
+ int numAttrNames, String[] attrNames, long[] locArr,
+ int[] typeArr, int[] sizeArr, boolean[] isArrayArr);
+
+ private native ShaderError useShaderProgram(long ctx, long shaderProgramId);
+
+ /**
+ * Method to return a flag indicating whether this
+ * ShaderProgram is supported on the specified Canvas.
+ */
+ boolean isSupported(Canvas3D cv) {
+ return cv.shadingLanguageGLSL;
+ }
+
+ /**
+ * Method to create the native shader.
+ */
+ ShaderError createShader(long ctx, ShaderRetained shader, long[] shaderIdArr) {
+ return createNativeShader(ctx, shader.shaderType, shaderIdArr);
+ }
+
+ /**
+ * Method to destroy the native shader.
+ */
+ ShaderError destroyShader(long ctx, long shaderId) {
+ return destroyNativeShader(ctx, shaderId);
+ }
+
+ /**
+ * Method to compile the native shader.
+ */
+ ShaderError compileShader(long ctx, long shaderId, String source) {
+ return compileNativeShader(ctx, shaderId, source );
+ }
+
+ /**
+ * Method to create the native shader program.
+ */
+ ShaderError createShaderProgram(long ctx, long[] shaderProgramIdArr) {
+ return createNativeShaderProgram(ctx, shaderProgramIdArr);
+ }
+
+ /**
+ * Method to destroy the native shader program.
+ */
+ ShaderError destroyShaderProgram(long ctx, long shaderProgramId) {
+ return destroyNativeShaderProgram(ctx, shaderProgramId);
+ }
+
+ /**
+ * Method to link the native shader program.
+ */
+ ShaderError linkShaderProgram(long ctx, long shaderProgramId, long[] shaderIds) {
+ return linkNativeShaderProgram(ctx, shaderProgramId, shaderIds);
+ }
+
+ ShaderError bindVertexAttrName(long ctx, long shaderProgramId, String attrName, int attrIndex) {
+ return bindNativeVertexAttrName(ctx, shaderProgramId, attrName, attrIndex);
+ }
+
+ void lookupVertexAttrNames(long ctx, long shaderProgramId, String[] attrNames, boolean[] errArr) {
+ // This method is a no-op for GLSL
+ }
+
+ void lookupShaderAttrNames(long ctx, long shaderProgramId,
+ String[] attrNames, AttrNameInfo[] attrNameInfoArr) {
+
+ int numAttrNames = attrNames.length;
+
+ long[] locArr = new long[numAttrNames];
+ int[] typeArr = new int[numAttrNames];
+ int[] sizeArr = new int[numAttrNames]; // currently unused
+ boolean[] isArrayArr = new boolean[numAttrNames];
+
+ // Initialize loc array to -1 (indicating no location)
+ for (int i = 0; i < numAttrNames; i++) {
+ locArr[i] = -1;
+ }
+
+ lookupNativeShaderAttrNames(ctx, shaderProgramId,
+ numAttrNames, attrNames, locArr, typeArr, sizeArr, isArrayArr);
+
+ for (int i = 0; i < numAttrNames; i++) {
+ attrNameInfoArr[i] = new AttrNameInfo();
+ attrNameInfoArr[i].setLocation(locArr[i]);
+ attrNameInfoArr[i].setArray(isArrayArr[i]);
+ attrNameInfoArr[i].setType(typeArr[i]);
+// System.err.println(attrNames[i] +
+// " : loc = " + locArr[i] +
+// ", type = " + typeArr[i] +
+// ", isArray = " + isArrayArr[i] +
+// ", size = " + sizeArr[i]);
+ }
+ }
+
+ /**
+ * Method to enable the native shader program.
+ */
+ ShaderError enableShaderProgram(long ctx, long shaderProgramId) {
+ return useShaderProgram(ctx, shaderProgramId);
+ }
+
+ /**
+ * Method to disable the native shader program.
+ */
+ ShaderError disableShaderProgram(long ctx) {
+ return useShaderProgram(ctx, 0);
+ }
+
+
+}
diff --git a/src/classes/share/javax/media/j3d/Geometry.java b/src/classes/share/javax/media/j3d/Geometry.java
index 042b366..89391b1 100644
--- a/src/classes/share/javax/media/j3d/Geometry.java
+++ b/src/classes/share/javax/media/j3d/Geometry.java
@@ -32,14 +32,22 @@ package javax.media.j3d;
public abstract class Geometry extends NodeComponent {
/**
- * Specifies that this Geometry allows intersect operation.
+ * Specifies that this Geometry allows intersect operation. This
+ * capability bit is set (true) by default for all Geometry objects.
*/
public static final int
ALLOW_INTERSECT = CapabilityBits.GEOMETRY_ALLOW_INTERSECT;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_INTERSECT
+ };
+
/**
* Constructs a new Geometry object.
*/
public Geometry() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
}
diff --git a/src/classes/share/javax/media/j3d/GeometryArray.java b/src/classes/share/javax/media/j3d/GeometryArray.java
index 8851569..b784a11 100644
--- a/src/classes/share/javax/media/j3d/GeometryArray.java
+++ b/src/classes/share/javax/media/j3d/GeometryArray.java
@@ -17,7 +17,8 @@ import javax.vecmath.*;
/**
* The GeometryArray object contains separate arrays of positional
- * coordinates, colors, normals, and texture coordinates that
+ * coordinates, colors, normals, texture coordinates, and vertex
+ * attributes that
* describe point, line, or polygon geometry. This class is extended
* to create the various primitive types (such as lines,
* triangle strips, etc.).
@@ -29,7 +30,8 @@ import javax.vecmath.*;
* <li>
* <b>By Copying:</b>
* The existing methods for setting positional coordinates, colors,
- * normals, and texture coordinates (such as <code>setCoordinate</code>,
+ * normals, texture coordinates, and vertex attributes
+ * (such as <code>setCoordinate</code>,
* <code>setColors</code>, etc.) copy the data into this
* GeometryArray. This is appropriate for many applications and
* offers an application much flexibility in organizing its data.
@@ -41,9 +43,11 @@ import javax.vecmath.*;
* this feature, set the <code>BY_REFERENCE</code> bit in the
* <code>vertexFormat</code> field of the constructor for this
* GeometryArray. In this mode, the various set methods for
- * coordinates, normals, colors, and texture coordinates are not used.
+ * coordinates, normals, colors, texture coordinates, and vertex attributes
+ * are not used.
* Instead, new methods are used to set a reference to user-supplied
- * coordinate, color, normal, and texture coordinate arrays (such as
+ * coordinate, color, normal, texture coordinate, and vertex attribute
+ * arrays (such as
* <code>setCoordRefFloat</code>, <code>setColorRefFloat</code>,
* etc.). Data in any array that is referenced by a live or compiled
* GeometryArray object may only be modified via the
@@ -133,6 +137,24 @@ public abstract class GeometryArray extends Geometry {
ALLOW_TEXCOORD_WRITE = CapabilityBits.GEOMETRY_ARRAY_ALLOW_TEXCOORD_WRITE;
/**
+ * Specifies that this GeometryArray allows reading the array of
+ * vertex attributes.
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int
+ ALLOW_VERTEX_ATTR_READ = CapabilityBits.GEOMETRY_ARRAY_ALLOW_VERTEX_ATTR_READ;
+
+ /**
+ * Specifies that this GeometryArray allows writing the array of
+ * vertex attributes.
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int
+ ALLOW_VERTEX_ATTR_WRITE = CapabilityBits.GEOMETRY_ARRAY_ALLOW_VERTEX_ATTR_WRITE;
+
+ /**
* Specifies that this GeometryArray allows reading the count or
* initial index information for this object.
*/
@@ -268,15 +290,12 @@ public abstract class GeometryArray extends Geometry {
* is only valid in conjunction with the <code>BY_REFERENCE</code>
* flag.
*
- * <p>
- * NOTE: Use of this class requires version 1.4 of the
- * Java<sup><font size="-2">TM</font></sup>&nbsp;2 Platform.
- *
* @see J3DBuffer
* @see #setCoordRefBuffer(J3DBuffer)
* @see #setColorRefBuffer(J3DBuffer)
* @see #setNormalRefBuffer(J3DBuffer)
* @see #setTexCoordRefBuffer(int,J3DBuffer)
+ * @see #setVertexAttrRefBuffer(int,J3DBuffer)
* @see #setInterleavedVertexBuffer(J3DBuffer)
*
* @since Java 3D 1.3
@@ -287,17 +306,30 @@ public abstract class GeometryArray extends Geometry {
* Specifies that only the coordinate indices are used for indexed
* geometry arrays. In this mode, the values from the coordinate
* index array are used as a single set of index values to access
- * the vertex data for all four vertex components (coord, color,
- * normal, and texCoord). The color, normal, and texCoord index arrays
- * are ignored. This flag is only valid for indexed geometry arrays
+ * the vertex data for all five vertex components (coord, color,
+ * normal, texCoord, and vertexAttr). The color, normal, texCoord,
+ * and vertexAttr index arrays are neither allocated nor used. Any
+ * attempt to access the color, normal, texCoord,
+ * or vertexAttr index arrays will result in a NullPointerException.
+ * This flag is only valid for indexed geometry arrays
* (subclasses of IndexedGeometryArray).
*
* @since Java 3D 1.3
*/
public static final int USE_COORD_INDEX_ONLY = 0x200;
+ /**
+ * Specifies that this GeometryArray contains one or more arrays of
+ * vertex attributes. These attributes are used in programmable
+ * shading.
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int VERTEX_ATTRIBUTES = 0x1000;
+
+
// Used to keep track of the last bit (for adding new bits only)
- private static final int LAST_FORMAT_BIT = 0x800;
+ private static final int LAST_FORMAT_BIT = 0x1000;
// Scratch arrays for converting Point[234]f to TexCoord[234]f
@@ -306,11 +338,26 @@ public abstract class GeometryArray extends Geometry {
private TexCoord4f [] texCoord4fArray = null;
private TexCoord2f texCoord2fScratch = null;
private TexCoord3f texCoord3fScratch = null;
-
-
+
+ private static final int[] defTexCoordMap = { 0 };
+
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_COLOR_READ,
+ ALLOW_COORDINATE_READ,
+ ALLOW_COUNT_READ,
+ ALLOW_FORMAT_READ,
+ ALLOW_NORMAL_READ,
+ ALLOW_REF_DATA_READ,
+ ALLOW_TEXCOORD_READ,
+ ALLOW_VERTEX_ATTR_READ
+ };
+
// non-public, no parameter constructor
GeometryArray() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
@@ -321,12 +368,15 @@ public abstract class GeometryArray extends Geometry {
* <ul>
* texCoordSetCount : 1<br>
* texCoordSetMap : { 0 }<br>
+ * vertexAttrCount : 0<br>
+ * vertexAttrSizes : null<br>
* validVertexCount : vertexCount<br>
* initialVertexIndex : 0<br>
* initialCoordIndex : 0<br>
* initialColorIndex : 0<br>
* initialNormalIndex : 0<br>
* initialTexCoordIndex : 0<br>
+ * initialVertexAttrIndex : 0<br>
* all data array values : 0.0<br>
* all data array references : null<br>
* </ul>
@@ -355,46 +405,29 @@ public abstract class GeometryArray extends Geometry {
* <code>USE_COORD_INDEX_ONLY</code>,
* to indicate that only the coordinate indices are used for indexed
* geometry arrays.
- * @exception IllegalArgumentException if vertexCount < 0, if
- * vertexFormat does NOT include <code>COORDINATES</code>,
- * if the <code>USE_COORD_INDEX_ONLY</code> bit is set for non-indexed
- * geometry arrays (that is, GeometryArray objects that are not a
- * subclass of IndexedGeometryArray),
- * if the <code>INTERLEAVED</code> bit is set without the
- * <code>BY_REFERENCE</code> bit being set,
- * or if the <code>USE_NIO_BUFFER</code> bit is set without the
- * <code>BY_REFERENCE</code> bit being set.
+ *
+ * @exception IllegalArgumentException if vertexCount &lt; 0
+ *
+ * @exception IllegalArgumentException if vertexFormat does <b>not</b>
+ * include <code>COORDINATES</code>
+ *
+ * @exception IllegalArgumentException if the <code>USE_COORD_INDEX_ONLY</code>
+ * bit is set for non-indexed geometry arrays (that is, GeometryArray objects
+ * that are not a subclass of IndexedGeometryArray)
+ *
+ * @exception IllegalArgumentException if the <code>INTERLEAVED</code>
+ * bit is set without the <code>BY_REFERENCE</code> bit being set
+ *
+ * @exception IllegalArgumentException if the <code>USE_NIO_BUFFER</code>
+ * bit is set without the <code>BY_REFERENCE</code> bit being set
+ *
+ * @exception IllegalArgumentException if the <code>INTERLEAVED</code>
+ * bit and the <code>VERTEX_ATTRIBUTES</code> bit are both set
*/
public GeometryArray(int vertexCount, int vertexFormat) {
-
- if (vertexCount < 0)
- throw new IllegalArgumentException(J3dI18N.getString("GeometryArray96"));
-
- if ((vertexFormat & COORDINATES) == 0)
- throw new IllegalArgumentException(J3dI18N.getString("GeometryArray0"));
-
- if ((vertexFormat & INTERLEAVED) != 0 &&
- (vertexFormat & BY_REFERENCE) == 0)
- throw new IllegalArgumentException(J3dI18N.getString("GeometryArray80"));
-
- if ((vertexFormat & USE_NIO_BUFFER) != 0 &&
- (vertexFormat & BY_REFERENCE) == 0)
- throw new IllegalArgumentException(J3dI18N.getString("GeometryArray117"));
-
- if ((vertexFormat & TEXTURE_COORDINATE) != 0) {
- if ((vertexFormat & TEXTURE_COORDINATE_2) != 0) {
- texCoord2fArray = new TexCoord2f[1];
- texCoord2fScratch = new TexCoord2f();
- }
- else if ((vertexFormat & TEXTURE_COORDINATE_3) != 0) {
- texCoord3fArray = new TexCoord3f[1];
- texCoord3fScratch = new TexCoord3f();
- } else if ((vertexFormat & TEXTURE_COORDINATE_4) != 0) {
- texCoord4fArray = new TexCoord4f[1];
- }
- }
-
- ((GeometryArrayRetained)this.retained).createGeometryArrayData(vertexCount, vertexFormat);
+ this(vertexCount, vertexFormat,
+ ((vertexFormat & TEXTURE_COORDINATE) != 0 ? 1 : 0),
+ ((vertexFormat & TEXTURE_COORDINATE) != 0 ? defTexCoordMap : null));
}
@@ -467,48 +500,59 @@ public abstract class GeometryArray extends Geometry {
*
* <p>
* <ul>
- * <table BORDER=1 CELLSPACING=1 CELLPADDING=1>
+ * <table BORDER=1 CELLSPACING=2 CELLPADDING=2>
* <tr>
* <td><center><b>Index</b></center></td>
* <td><center><b>Element</b></center></td>
- * <td><center><b>Description</b></center></td>
+ * <td><b>Description</b></td>
* </tr>
* <tr>
* <td><center>0</center></td>
* <td><center>1</center></td>
- * <td><center>Use tex coord set 1 for tex unit 0</center></td>
+ * <td>Use tex coord set 1 for tex unit 0</td>
* </tr>
* <tr>
* <td><center>1</center></td>
* <td><center>-1</center></td>
- * <td><center>Use no tex coord set for tex unit 1</center></td>
+ * <td>Use no tex coord set for tex unit 1</td>
* </tr>
* <tr>
* <td><center>2</center></td>
* <td><center>0</center></td>
- * <td><center>Use tex coord set 0 for tex unit 2</center></td>
+ * <td>Use tex coord set 0 for tex unit 2</td>
* </tr>
* <tr>
* <td><center>3</center></td>
* <td><center>1</center></td>
- * <td><center>Reuse tex coord set 1 for tex unit 3</center></td>
+ * <td>Reuse tex coord set 1 for tex unit 3</td>
* </tr>
* </table>
* </ul>
* <p>
*
+ * @exception IllegalArgumentException if vertexCount &lt; 0
+ *
+ * @exception IllegalArgumentException if vertexFormat does <b>not</b>
+ * include <code>COORDINATES</code>
+ *
+ * @exception IllegalArgumentException if the <code>USE_COORD_INDEX_ONLY</code>
+ * bit is set for non-indexed geometry arrays (that is, GeometryArray objects
+ * that are not a subclass of IndexedGeometryArray)
+ *
+ * @exception IllegalArgumentException if the <code>INTERLEAVED</code>
+ * bit is set without the <code>BY_REFERENCE</code> bit being set
+ *
+ * @exception IllegalArgumentException if the <code>USE_NIO_BUFFER</code>
+ * bit is set without the <code>BY_REFERENCE</code> bit being set
+ *
+ * @exception IllegalArgumentException if the <code>INTERLEAVED</code>
+ * bit and the <code>VERTEX_ATTRIBUTES</code> bit are both set
+ *
* @exception IllegalArgumentException if
- * <code>vertexCount&nbsp;<&nbsp;0</code>, if vertexFormat does
- * NOT include <code>COORDINATES</code>, if the
- * <code>INTERLEAVED</code> bit is set without the
- * <code>BY_REFERENCE</code> bit being set, if the
- * <code>USE_NIO_BUFFER</code> bit is set without the
- * <code>BY_REFERENCE</code> bit being set, if
- * the <code>USE_COORD_INDEX_ONLY</code> bit is set for non-indexed
- * geometry arrays (that is, GeometryArray objects that are not a
- * subclass of IndexedGeometryArray), if
- * <code>texCoordSetCount&nbsp;<&nbsp;0</code>, or if any element
- * in <code>texCoordSetMap[]&nbsp;>=&nbsp;texCoordSetCount</code>.
+ * <code>texCoordSetCount&nbsp;&lt;&nbsp;0</code>
+ *
+ * @exception IllegalArgumentException if any element in
+ * <code>texCoordSetMap[]&nbsp;&gt;=&nbsp;texCoordSetCount</code>.
*
* @since Java 3D 1.2
*/
@@ -516,20 +560,196 @@ public abstract class GeometryArray extends Geometry {
int vertexFormat,
int texCoordSetCount,
int[] texCoordSetMap) {
+ this(vertexCount, vertexFormat, texCoordSetCount, texCoordSetMap, 0, null);
+ }
+
+
+ /**
+ * Constructs an empty GeometryArray object with the specified
+ * number of vertices, vertex format, number of texture coordinate
+ * sets, texture coordinate mapping array, vertex attribute count,
+ * and vertex attribute sizes array.
+ *
+ * @param vertexCount the number of vertex elements in this
+ * GeometryArray<p>
+ *
+ * @param vertexFormat a mask indicating which components are
+ * present in each vertex. This is specified as one or more
+ * individual flags that are bitwise "OR"ed together to describe
+ * the per-vertex data.
+ * The flags include: <code>COORDINATES</code>, to signal the inclusion of
+ * vertex positions--always present; <code>NORMALS</code>, to signal
+ * the inclusion of per vertex normals; one of <code>COLOR_3</code> or
+ * <code>COLOR_4</code>, to signal the inclusion of per vertex
+ * colors (without or with alpha information); one of
+ * <code>TEXTURE_COORDINATE_2</code> or <code>TEXTURE_COORDINATE_3</code>
+ * or <code>TEXTURE_COORDINATE_4</code>,
+ * to signal the
+ * inclusion of per-vertex texture coordinates (2D , 3D or 4D);
+ * <code>VERTEX_ATTRIBUTES</code>, to signal
+ * the inclusion of one or more arrays of vertex attributes;
+ * <code>BY_REFERENCE</code>, to indicate that the data is passed
+ * by reference
+ * rather than by copying; <code>INTERLEAVED</code>, to indicate
+ * that the referenced
+ * data is interleaved in a single array;
+ * <code>USE_NIO_BUFFER</code>, to indicate that the referenced data
+ * is accessed via a J3DBuffer object that wraps an NIO buffer;
+ * <code>USE_COORD_INDEX_ONLY</code>,
+ * to indicate that only the coordinate indices are used for indexed
+ * geometry arrays.<p>
+ *
+ * @param texCoordSetCount the number of texture coordinate sets
+ * in this GeometryArray object. If <code>vertexFormat</code>
+ * does not include one of <code>TEXTURE_COORDINATE_2</code> or
+ * <code>TEXTURE_COORDINATE_3</code>, the
+ * <code>texCoordSetCount</code> parameter is not used.<p>
+ *
+ * <a name="texCoordSetMap">
+ * @param texCoordSetMap an array that maps texture coordinate
+ * sets to texture units. The array is indexed by texture unit
+ * number for each texture unit in the associated Appearance
+ * object. The values in the array specify the texture coordinate
+ * set within this GeometryArray object that maps to the
+ * corresponding texture
+ * unit. All elements within the array must be less than
+ * <code>texCoordSetCount</code>. A negative value specifies that
+ * no texture coordinate set maps to the texture unit
+ * corresponding to the index. If there are more texture units in
+ * any associated Appearance object than elements in the mapping
+ * array, the extra elements are assumed to be -1. The same
+ * texture coordinate set may be used for more than one texture
+ * unit. Each texture unit in every associated Appearance must
+ * have a valid source of texture coordinates: either a
+ * non-negative texture coordinate set must be specified in the
+ * mapping array or texture coordinate generation must be enabled.
+ * Texture coordinate generation will take precedence for those
+ * texture units for which a texture coordinate set is specified
+ * and texture coordinate generation is enabled. If
+ * <code>vertexFormat</code> does not include one of
+ * <code>TEXTURE_COORDINATE_2</code> or
+ * <code>TEXTURE_COORDINATE_3</code> or
+ * <code>TEXTURE_COORDINATE_4</code>, the
+ * <code>texCoordSetMap</code> array is not used. The following example
+ * illustrates the use of the <code>texCoordSetMap</code> array.
+ *
+ * <p>
+ * <ul>
+ * <table BORDER=1 CELLSPACING=2 CELLPADDING=2>
+ * <tr>
+ * <td><center><b>Index</b></center></td>
+ * <td><center><b>Element</b></center></td>
+ * <td><b>Description</b></td>
+ * </tr>
+ * <tr>
+ * <td><center>0</center></td>
+ * <td><center>1</center></td>
+ * <td>Use tex coord set 1 for tex unit 0</td>
+ * </tr>
+ * <tr>
+ * <td><center>1</center></td>
+ * <td><center>-1</center></td>
+ * <td>Use no tex coord set for tex unit 1</td>
+ * </tr>
+ * <tr>
+ * <td><center>2</center></td>
+ * <td><center>0</center></td>
+ * <td>Use tex coord set 0 for tex unit 2</td>
+ * </tr>
+ * <tr>
+ * <td><center>3</center></td>
+ * <td><center>1</center></td>
+ * <td>Reuse tex coord set 1 for tex unit 3</td>
+ * </tr>
+ * </table>
+ * </ul>
+ * <p>
+ *
+ * @param vertexAttrCount the number of vertex attributes
+ * in this GeometryArray object. If <code>vertexFormat</code>
+ * does not include <code>VERTEX_ATTRIBUTES</code>, the
+ * <code>vertexAttrCount</code> parameter must be 0.<p>
+ *
+ * @param vertexAttrSizes is an array that specifes the size of
+ * each vertex attribute. Each element in the array specifies the
+ * number of components in the attribute, from 1 to 4. The length
+ * of the array must be equal to <code>vertexAttrCount</code>.<p>
+ *
+ * @exception IllegalArgumentException if vertexCount &lt; 0
+ *
+ * @exception IllegalArgumentException if vertexFormat does <b>not</b>
+ * include <code>COORDINATES</code>
+ *
+ * @exception IllegalArgumentException if the <code>USE_COORD_INDEX_ONLY</code>
+ * bit is set for non-indexed geometry arrays (that is, GeometryArray objects
+ * that are not a subclass of IndexedGeometryArray)
+ *
+ * @exception IllegalArgumentException if the <code>INTERLEAVED</code>
+ * bit is set without the <code>BY_REFERENCE</code> bit being set
+ *
+ * @exception IllegalArgumentException if the <code>USE_NIO_BUFFER</code>
+ * bit is set without the <code>BY_REFERENCE</code> bit being set
+ *
+ * @exception IllegalArgumentException if the <code>INTERLEAVED</code>
+ * bit and the <code>VERTEX_ATTRIBUTES</code> bit are both set
+ *
+ * @exception IllegalArgumentException if
+ * <code>texCoordSetCount&nbsp;&lt;&nbsp;0</code>
+ *
+ * @exception IllegalArgumentException if any element in
+ * <code>texCoordSetMap[]&nbsp;&gt;=&nbsp;texCoordSetCount</code>.
+ *
+ * @exception IllegalArgumentException if
+ * <code>vertexAttrCount&nbsp;&gt;&nbsp;0</code> and the
+ * <code>VERTEX_ATTRIBUTES</code> bit is not set
+ *
+ * @exception IllegalArgumentException if
+ * <code>vertexAttrCount&nbsp;&lt;&nbsp;0</code>
+ *
+ * @exception IllegalArgumentException if
+ * <code>vertexAttrSizes.length&nbsp;!=&nbsp;vertexAttrCount</code>
+ *
+ * @exception IllegalArgumentException if any element in
+ * <code>vertexAttrSizes[]</code> is <code>&lt; 1</code> or
+ * <code>&gt; 4</code>.
+ *
+ * @since Java 3D 1.4
+ */
+ public GeometryArray(int vertexCount,
+ int vertexFormat,
+ int texCoordSetCount,
+ int[] texCoordSetMap,
+ int vertexAttrCount,
+ int[] vertexAttrSizes) {
if (vertexCount < 0)
throw new IllegalArgumentException(J3dI18N.getString("GeometryArray96"));
+ if (texCoordSetCount < 0)
+ throw new IllegalArgumentException(J3dI18N.getString("GeometryArray124"));
+
+ if (vertexAttrCount < 0)
+ throw new IllegalArgumentException(J3dI18N.getString("GeometryArray125"));
+
if ((vertexFormat & COORDINATES) == 0)
- throw new IllegalArgumentException(J3dI18N.getString("GeometryArray0"
-));
+ throw new IllegalArgumentException(J3dI18N.getString("GeometryArray0"));
if ((vertexFormat & INTERLEAVED) != 0 &&
(vertexFormat & BY_REFERENCE) == 0)
throw new IllegalArgumentException(J3dI18N.getString("GeometryArray80"));
+ if ((vertexFormat & INTERLEAVED) != 0 &&
+ (vertexFormat & VERTEX_ATTRIBUTES) != 0) {
+ throw new IllegalArgumentException(J3dI18N.getString("GeometryArray128"));
+ }
+
+ if ((vertexFormat & USE_COORD_INDEX_ONLY) != 0 &&
+ !(this instanceof IndexedGeometryArray)) {
+ throw new IllegalArgumentException(J3dI18N.getString("GeometryArray135"));
+ }
+
if ((vertexFormat & USE_NIO_BUFFER) != 0 &&
- (vertexFormat & BY_REFERENCE) == 0)
+ (vertexFormat & BY_REFERENCE) == 0)
throw new IllegalArgumentException(J3dI18N.getString("GeometryArray117"));
if ((vertexFormat & TEXTURE_COORDINATE) != 0) {
@@ -556,8 +776,36 @@ public abstract class GeometryArray extends Geometry {
texCoord4fArray = new TexCoord4f[1];
}
}
-
- ((GeometryArrayRetained)this.retained).createGeometryArrayData(vertexCount, vertexFormat, texCoordSetCount, texCoordSetMap);
+
+ if ((vertexFormat & VERTEX_ATTRIBUTES) != 0) {
+ if (vertexAttrCount > 0) {
+ if (vertexAttrCount != vertexAttrSizes.length) {
+ throw new IllegalArgumentException(J3dI18N.getString("GeometryArray132"));
+ }
+
+ for (int i = 0; i < vertexAttrSizes.length; i++) {
+ if (vertexAttrSizes[i] < 1 || vertexAttrSizes[i] > 4) {
+ throw new IllegalArgumentException(J3dI18N.getString("GeometryArray133"));
+ }
+ }
+ } else {
+ if (vertexAttrSizes != null && vertexAttrSizes.length != 0) {
+ throw new IllegalArgumentException(J3dI18N.getString("GeometryArray132"));
+ }
+ }
+ } else {
+ if (vertexAttrCount > 0) {
+ throw new IllegalArgumentException(J3dI18N.getString("GeometryArray131"));
+ }
+ }
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((GeometryArrayRetained)this.retained).createGeometryArrayData(
+ vertexCount, vertexFormat,
+ texCoordSetCount, texCoordSetMap,
+ vertexAttrCount, vertexAttrSizes);
}
@@ -636,7 +884,35 @@ public abstract class GeometryArray extends Geometry {
*/
public void getTexCoordSetMap(int[] texCoordSetMap) {
((GeometryArrayRetained)this.retained).getTexCoordSetMap(texCoordSetMap);
- return;
+ }
+
+
+ /**
+ * Retrieves the number of vertex attributes in this GeometryArray
+ * object.
+ *
+ * @return the number of vertex attributes in this GeometryArray
+ * object
+ *
+ * @since Java 3D 1.4
+ */
+ public int getVertexAttrCount() {
+ return ((GeometryArrayRetained)this.retained).getVertexAttrCount();
+ }
+
+
+ /**
+ * Retrieves the vertex attribute sizes array from this
+ * GeometryArray object.
+ *
+ * @param vertexAttrSizes an array that will receive a copy of
+ * the vertex attribute sizes array. The array must hold at least
+ * <code>vertexAttrCount</code> elements.
+ *
+ * @since Java 3D 1.4
+ */
+ public void getVertexAttrSizes(int[] vertexAttrSizes) {
+ ((GeometryArrayRetained)this.retained).getVertexAttrSizes(vertexAttrSizes);
}
@@ -688,27 +964,30 @@ public abstract class GeometryArray extends Geometry {
* @exception IllegalArgumentException if any of the following are
* true:
* <ul>
- * <code>validVertexCount < 0</code>,<br>
- * <code>initialVertexIndex + validVertexCount > vertexCount</code>,<br>
- * <code>initialCoordIndex + validVertexCount > vertexCount</code>,<br>
- * <code>initialColorIndex + validVertexCount > vertexCount</code>,<br>
- * <code>initialNormalIndex + validVertexCount > vertexCount</code>,<br>
- * <code>initialTexCoordIndex + validVertexCount > vertexCount</code>
+ * <code>validVertexCount &lt; 0</code>,<br>
+ * <code>initialVertexIndex + validVertexCount &gt; vertexCount</code>,<br>
+ * <code>initialCoordIndex + validVertexCount &gt; vertexCount</code>,<br>
+ * <code>initialColorIndex + validVertexCount &gt; vertexCount</code>,<br>
+ * <code>initialNormalIndex + validVertexCount &gt; vertexCount</code>,<br>
+ * <code>initialTexCoordIndex + validVertexCount &gt; vertexCount</code>,<br>
+ * <code>initialVertexAttrIndex + validVertexCount &gt; vertexCount</code>
* </ul>
* <p>
* @exception ArrayIndexOutOfBoundsException if the geometry data format
* is <code>BY_REFERENCE</code> and any the following
* are true for non-null array references:
* <ul>
- * <code>CoordRef.length</code> < <i>num_words</i> *
+ * <code>CoordRef.length</code> &lt; <i>num_words</i> *
* (<code>initialCoordIndex + validVertexCount</code>),<br>
- * <code>ColorRef.length</code> < <i>num_words</i> *
+ * <code>ColorRef.length</code> &lt; <i>num_words</i> *
* (<code>initialColorIndex + validVertexCount</code>),<br>
- * <code>NormalRef.length</code> < <i>num_words</i> *
+ * <code>NormalRef.length</code> &lt; <i>num_words</i> *
* (<code>initialNormalIndex + validVertexCount</code>),<br>
- * <code>TexCoordRef.length</code> < <i>num_words</i> *
+ * <code>TexCoordRef.length</code> &lt; <i>num_words</i> *
* (<code>initialTexCoordIndex + validVertexCount</code>),<br>
- * <code>InterleavedVertices.length</code> < <i>words_per_vertex</i> *
+ * <code>VertexAttrRef.length</code> &lt; <i>num_words</i> *
+ * (<code>initialVertexAttrIndex + validVertexCount</code>),<br>
+ * <code>InterleavedVertices.length</code> &lt; <i>words_per_vertex</i> *
* (<code>initialVertexIndex + validVertexCount</code>)<br>
* </ul>
* where <i>num_words</i> depends on which variant of
@@ -727,7 +1006,7 @@ public abstract class GeometryArray extends Geometry {
throw new IllegalArgumentException(J3dI18N.getString("GeometryArray96"));
((GeometryArrayRetained)this.retained).setValidVertexCount(validVertexCount);
- // NOTE: the checks for initial*Index + validVertexCount >
+ // NOTE: the checks for initial*Index + validVertexCount &gt;
// vertexCount need to be done in the retained method
}
@@ -770,61 +1049,99 @@ public abstract class GeometryArray extends Geometry {
* @see NodeComponent#setDuplicateOnCloneTree
*/
void duplicateAttributes(NodeComponent originalNodeComponent,
- boolean forceDuplicate) {
-
- super.duplicateAttributes(originalNodeComponent, forceDuplicate);
- // vertexFormat and vertexCount are copied in subclass when constructor
- // public GeometryArray(int vertexCount, int vertexFormat) is used
- // in cloneNodeComponent()
- GeometryArrayRetained src = (GeometryArrayRetained) originalNodeComponent.retained;
- GeometryArrayRetained dst = (GeometryArrayRetained) retained;
- int format = src.getVertexFormat();
- if ((format & BY_REFERENCE) == 0) {
- System.arraycopy(src.vertexData, 0, dst.vertexData, 0,
- src.vertexData.length);
- dst.setInitialVertexIndex(src.getInitialVertexIndex());
-
- } else {
- dst.setInitialCoordIndex(src.getInitialCoordIndex());
- dst.setInitialColorIndex(src.getInitialColorIndex());
- dst.setInitialNormalIndex(src.getInitialNormalIndex());
- int setCount = src.getTexCoordSetCount();
- for (int i=0; i < setCount; i++) {
- dst.setInitialTexCoordIndex(i, src.getInitialTexCoordIndex(i));
- }
- if ((format & INTERLEAVED) == 0) {
- dst.setCoordRefFloat(src.getCoordRefFloat());
- dst.setCoordRefDouble(src.getCoordRefDouble());
- dst.setCoordRef3f(src.getCoordRef3f());
- dst.setCoordRef3d(src.getCoordRef3d());
- dst.setColorRefFloat(src.getColorRefFloat());
- dst.setColorRefByte(src.getColorRefByte());
- if ((format & WITH_ALPHA) == 0) {
- dst.setColorRef3f(src.getColorRef3f());
- dst.setColorRef3b(src.getColorRef3b());
- } else {
- dst.setColorRef4f(src.getColorRef4f());
- dst.setColorRef4b(src.getColorRef4b());
- }
- dst.setNormalRefFloat(src.getNormalRefFloat());
- dst.setNormalRef3f(src.getNormalRef3f());
- for (int i=0; i < setCount; i++) {
- dst.setTexCoordRefFloat(i, src.getTexCoordRefFloat(i));
- }
- if ((format & TEXTURE_COORDINATE_2) != 0) {
- for (int i=0; i < setCount; i++) {
- dst.setTexCoordRef2f(i, src.getTexCoordRef2f(i));
- }
- }
- if ((format & TEXTURE_COORDINATE_3) != 0) {
- for (int i=0; i < setCount; i++) {
- dst.setTexCoordRef3f(i, src.getTexCoordRef3f(i));
- }
- }
- } else {
- dst.setInterleavedVertices(src.getInterleavedVertices());
- }
- }
+ boolean forceDuplicate) {
+
+ super.duplicateAttributes(originalNodeComponent, forceDuplicate);
+ // vertexFormat and vertexCount are copied in subclass when constructor
+ // public GeometryArray(int vertexCount, int vertexFormat) is used
+ // in cloneNodeComponent()
+ GeometryArrayRetained src = (GeometryArrayRetained) originalNodeComponent.retained;
+ GeometryArrayRetained dst = (GeometryArrayRetained) retained;
+ int format = src.getVertexFormat();
+ if ((format & BY_REFERENCE) == 0) {
+ System.arraycopy(src.vertexData, 0, dst.vertexData, 0,
+ src.vertexData.length);
+ dst.setInitialVertexIndex(src.getInitialVertexIndex());
+
+ } else {
+ dst.setInitialCoordIndex(src.getInitialCoordIndex());
+ dst.setInitialColorIndex(src.getInitialColorIndex());
+ dst.setInitialNormalIndex(src.getInitialNormalIndex());
+ int setCount = src.getTexCoordSetCount();
+ int vAttrCount = src.getVertexAttrCount();
+ for (int i=0; i < setCount; i++) {
+ dst.setInitialTexCoordIndex(i, src.getInitialTexCoordIndex(i));
+ }
+ if ((format & INTERLEAVED) == 0) {
+ if ((format & USE_NIO_BUFFER) == 0) {
+ // Java arrays
+ dst.setCoordRefFloat(src.getCoordRefFloat());
+ dst.setCoordRefDouble(src.getCoordRefDouble());
+ dst.setCoordRef3f(src.getCoordRef3f());
+ dst.setCoordRef3d(src.getCoordRef3d());
+ dst.setColorRefFloat(src.getColorRefFloat());
+ dst.setColorRefByte(src.getColorRefByte());
+ if ((format & WITH_ALPHA) == 0) {
+ dst.setColorRef3f(src.getColorRef3f());
+ dst.setColorRef3b(src.getColorRef3b());
+ } else {
+ dst.setColorRef4f(src.getColorRef4f());
+ dst.setColorRef4b(src.getColorRef4b());
+ }
+ dst.setNormalRefFloat(src.getNormalRefFloat());
+ dst.setNormalRef3f(src.getNormalRef3f());
+
+ switch (src.getVertexAttrType()) {
+ case GeometryArrayRetained.AF:
+ for (int i=0; i < vAttrCount; i++) {
+ dst.setVertexAttrRefFloat(i, src.getVertexAttrRefFloat(i));
+ }
+ break;
+ }
+
+ switch (src.getTexCoordType()) {
+ case GeometryArrayRetained.TF:
+ for (int i=0; i < setCount; i++) {
+ dst.setTexCoordRefFloat(i, src.getTexCoordRefFloat(i));
+ }
+ break;
+ case GeometryArrayRetained.T2F:
+ for (int i=0; i < setCount; i++) {
+ dst.setTexCoordRef2f(i, src.getTexCoordRef2f(i));
+ }
+ break;
+ case GeometryArrayRetained.T3F:
+ for (int i=0; i < setCount; i++) {
+ dst.setTexCoordRef3f(i, src.getTexCoordRef3f(i));
+ }
+ break;
+ }
+ } else {
+ // NIO buffer
+ dst.setCoordRefBuffer(src.getCoordRefBuffer());
+ dst.setColorRefBuffer(src.getColorRefBuffer());
+ dst.setNormalRefBuffer(src.getNormalRefBuffer());
+
+ switch (src.getVertexAttrType()) {
+ case GeometryArrayRetained.AF:
+ for (int i=0; i < vAttrCount; i++) {
+ dst.setVertexAttrRefBuffer(i, src.getVertexAttrRefBuffer(i));
+ }
+ break;
+ }
+
+ switch (src.getTexCoordType()) {
+ case GeometryArrayRetained.TF:
+ for (int i=0; i < setCount; i++) {
+ dst.setTexCoordRefBuffer(i, src.getTexCoordRefBuffer(i));
+ }
+ break;
+ }
+ }
+ } else {
+ dst.setInterleavedVertices(src.getInterleavedVertices());
+ }
+ }
}
@@ -848,15 +1165,15 @@ public abstract class GeometryArray extends Geometry {
* @exception IllegalArgumentException if either of the following are
* true:
* <ul>
- * <code>initialVertexIndex < 0</code> or<br>
- * <code>initialVertexIndex + validVertexCount > vertexCount</code><br>
+ * <code>initialVertexIndex &lt; 0</code> or<br>
+ * <code>initialVertexIndex + validVertexCount &gt; vertexCount</code><br>
* </ul>
*
* @exception ArrayIndexOutOfBoundsException if the geometry data format
* is <code>INTERLEAVED</code>, the InterleavedVertices array is
* non-null, and:
* <ul>
- * <code>InterleavedVertices.length</code> < <i>num_words</i> *
+ * <code>InterleavedVertices.length</code> &lt; <i>num_words</i> *
* (<code>initialVertexIndex + validVertexCount</code>)<br>
* </ul>
* where <i>num_words</i> depends on which vertex formats are enabled.
@@ -2271,7 +2588,7 @@ public abstract class GeometryArray extends Geometry {
if (((((GeometryArrayRetained)this.retained).vertexFormat) &
- (TEXTURE_COORDINATE_2 | TEXTURE_COORDINATE_3)) != 0)
+ (TEXTURE_COORDINATE_2 | TEXTURE_COORDINATE_4)) != 0)
throw new IllegalStateException(J3dI18N.getString("GeometryArray95"));
((GeometryArrayRetained)this.retained).setTextureCoordinates(
@@ -2338,7 +2655,7 @@ public abstract class GeometryArray extends Geometry {
*
* @param index starting destination vertex index in this geometry array
* @param texCoords source array of 2*n , 3*n or 4*n values containing
- * n new * texture coordinates
+ * n new texture coordinates
* @param start starting source vertex index in <code>texCoords</code>
* array.
* @param length number of texture Coordinates to be copied.
@@ -2531,6 +2848,581 @@ public abstract class GeometryArray extends Geometry {
texCoordSet, index, texCoords, start, length);
}
+
+ /**
+ * Sets the vertex attribute associated with the vertex at the
+ * specified index in the specified vertex attribute number for
+ * this object.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index destination vertex index in this geometry array
+ * @param vertexAttr source array of 1, 2, 3 or 4 values containing
+ * the new vertex attribute
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ *
+ * @exception ArrayIndexOutOfBoundsException if the index or
+ * vertexAttrNum is out of range, or if the vertexAttr array is
+ * too small.
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE</code>.
+ *
+ * @since Java 3D 1.4
+ */
+ public void setVertexAttr(int vertexAttrNum, int index,
+ float[] vertexAttr) {
+
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_VERTEX_ATTR_WRITE)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray126"));
+ }
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray82"));
+ }
+
+ ((GeometryArrayRetained)this.retained).setVertexAttrs(
+ vertexAttrNum, index, vertexAttr, 0, 1);
+ }
+
+ /**
+ * Sets the vertex attribute associated with the vertex at the
+ * specified index in the specified vertex attribute number for
+ * this object.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index destination vertex index in this geometry array
+ * @param vertexAttr the Point2f containing the new vertex attribute
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ *
+ * @exception ArrayIndexOutOfBoundsException if the index or
+ * vertexAttrNum is out of range.
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE</code>.
+ *
+ * @exception IllegalStateException if the size of the specified
+ * vertex attribute number is not 2.
+ *
+ * @since Java 3D 1.4
+ */
+ public void setVertexAttr(int vertexAttrNum, int index,
+ Point2f vertexAttr) {
+
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_VERTEX_ATTR_WRITE)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray126"));
+ }
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray82"));
+ }
+
+ int size = ((GeometryArrayRetained)this.retained).vertexAttrSizes[vertexAttrNum];
+ if (size != 2) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray134"));
+ }
+
+ ((GeometryArrayRetained)this.retained).setVertexAttr(
+ vertexAttrNum, index, vertexAttr);
+ }
+
+ /**
+ * Sets the vertex attribute associated with the vertex at the
+ * specified index in the specified vertex attribute number for
+ * this object.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index destination vertex index in this geometry array
+ * @param vertexAttr the Point3f containing the new vertex attribute
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ *
+ * @exception ArrayIndexOutOfBoundsException if the index or
+ * vertexAttrNum is out of range.
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE</code>.
+ *
+ * @exception IllegalStateException if the size of the specified
+ * vertex attribute number is not 3.
+ *
+ * @since Java 3D 1.4
+ */
+ public void setVertexAttr(int vertexAttrNum, int index,
+ Point3f vertexAttr) {
+
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_VERTEX_ATTR_WRITE)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray126"));
+ }
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray82"));
+ }
+
+ int size = ((GeometryArrayRetained)this.retained).vertexAttrSizes[vertexAttrNum];
+ if (size != 3) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray134"));
+ }
+
+ ((GeometryArrayRetained)this.retained).setVertexAttr(
+ vertexAttrNum, index, vertexAttr);
+ }
+
+ /**
+ * Sets the vertex attribute associated with the vertex at the
+ * specified index in the specified vertex attribute number for
+ * this object.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index destination vertex index in this geometry array
+ * @param vertexAttr the Point4f containing the new vertex attribute
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ *
+ * @exception ArrayIndexOutOfBoundsException if the index or
+ * vertexAttrNum is out of range.
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE</code>.
+ *
+ * @exception IllegalStateException if the size of the specified
+ * vertex attribute number is not 4.
+ *
+ * @since Java 3D 1.4
+ */
+ public void setVertexAttr(int vertexAttrNum, int index,
+ Point4f vertexAttr) {
+
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_VERTEX_ATTR_WRITE)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray126"));
+ }
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray82"));
+ }
+
+ int size = ((GeometryArrayRetained)this.retained).vertexAttrSizes[vertexAttrNum];
+ if (size != 4) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray134"));
+ }
+
+ ((GeometryArrayRetained)this.retained).setVertexAttr(
+ vertexAttrNum, index, vertexAttr);
+ }
+
+ /**
+ * Sets the vertex attributes associated with the vertices starting at
+ * the specified index in the specified vertex attribute number
+ * for this object. The entire source array is copied to this
+ * geometry array.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index starting destination vertex index in this geometry array
+ * @param vertexAttrs source array of 1*n, 2*n, 3*n, or 4*n values
+ * containing n new vertex attributes
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ *
+ * @exception ArrayIndexOutOfBoundsException if the index or
+ * vertexAttrNum is out of range, or if the vertexAttr array is
+ * too large.
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE</code>.
+ *
+ * @since Java 3D 1.4
+ */
+ public void setVertexAttrs(int vertexAttrNum, int index,
+ float[] vertexAttrs) {
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_VERTEX_ATTR_WRITE)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray126"));
+ }
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray82"));
+ }
+
+ int size = ((GeometryArrayRetained)this.retained).vertexAttrSizes[vertexAttrNum];
+ ((GeometryArrayRetained)this.retained).setVertexAttrs(
+ vertexAttrNum, index, vertexAttrs, 0, vertexAttrs.length / size);
+ }
+
+ /**
+ * Sets the vertex attributes associated with the vertices starting at
+ * the specified index in the specified vertex attribute number
+ * for this object. The entire source array is copied to this
+ * geometry array.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index starting destination vertex index in this geometry array
+ * @param vertexAttrs source array of Point2f objects containing new
+ * vertex attributes
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ *
+ * @exception ArrayIndexOutOfBoundsException if the index or
+ * vertexAttrNum is out of range, or if the vertexAttr array is
+ * too large.
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE</code>.
+ *
+ * @exception IllegalStateException if the size of the specified
+ * vertex attribute number is not 2.
+ *
+ * @since Java 3D 1.4
+ */
+ public void setVertexAttrs(int vertexAttrNum, int index,
+ Point2f[] vertexAttrs) {
+
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_VERTEX_ATTR_WRITE)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray126"));
+ }
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray82"));
+ }
+
+ int size = ((GeometryArrayRetained)this.retained).vertexAttrSizes[vertexAttrNum];
+ if (size != 2) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray134"));
+ }
+
+ ((GeometryArrayRetained)this.retained).setVertexAttrs(
+ vertexAttrNum, index, vertexAttrs, 0, vertexAttrs.length);
+ }
+
+ /**
+ * Sets the vertex attributes associated with the vertices starting at
+ * the specified index in the specified vertex attribute number
+ * for this object. The entire source array is copied to this
+ * geometry array.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index starting destination vertex index in this geometry array
+ * @param vertexAttrs source array of Point3f objects containing new
+ * vertex attributes
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ *
+ * @exception ArrayIndexOutOfBoundsException if the index or
+ * vertexAttrNum is out of range, or if the vertexAttr array is
+ * too large.
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE</code>.
+ *
+ * @exception IllegalStateException if the size of the specified
+ * vertex attribute number is not 3.
+ *
+ * @since Java 3D 1.4
+ */
+ public void setVertexAttrs(int vertexAttrNum, int index,
+ Point3f[] vertexAttrs) {
+
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_VERTEX_ATTR_WRITE)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray126"));
+ }
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray82"));
+ }
+
+ int size = ((GeometryArrayRetained)this.retained).vertexAttrSizes[vertexAttrNum];
+ if (size != 3) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray134"));
+ }
+
+ ((GeometryArrayRetained)this.retained).setVertexAttrs(
+ vertexAttrNum, index, vertexAttrs, 0, vertexAttrs.length);
+ }
+
+ /**
+ * Sets the vertex attributes associated with the vertices starting at
+ * the specified index in the specified vertex attribute number
+ * for this object. The entire source array is copied to this
+ * geometry array.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index starting destination vertex index in this geometry array
+ * @param vertexAttrs source array of Point4f objects containing new
+ * vertex attributes
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ *
+ * @exception ArrayIndexOutOfBoundsException if the index or
+ * vertexAttrNum is out of range, or if the vertexAttr array is
+ * too large.
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE</code>.
+ *
+ * @exception IllegalStateException if the size of the specified
+ * vertex attribute number is not 4.
+ *
+ * @since Java 3D 1.4
+ */
+ public void setVertexAttrs(int vertexAttrNum, int index,
+ Point4f[] vertexAttrs) {
+
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_VERTEX_ATTR_WRITE)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray126"));
+ }
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray82"));
+ }
+
+ int size = ((GeometryArrayRetained)this.retained).vertexAttrSizes[vertexAttrNum];
+ if (size != 4) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray134"));
+ }
+
+ ((GeometryArrayRetained)this.retained).setVertexAttrs(
+ vertexAttrNum, index, vertexAttrs, 0, vertexAttrs.length);
+ }
+
+ /**
+ * Sets the vertex attributes associated with the vertices
+ * starting at the specified index in the specified vertex
+ * attribute number for this object using data in
+ * <code>vertexAttrs</code> starting at index <code>start</code> and
+ * ending at index <code>start+length</code>.
+ *
+ * @param index starting destination vertex index in this geometry array
+ * @param vertexAttrs source array of 1*n, 2*n, 3*n, or 4*n values
+ * containing n new vertex attributes
+ * @param start starting source vertex index in <code>vertexAttrs</code>
+ * array.
+ * @param length number of vertex attributes to be copied.
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ *
+ * @exception ArrayIndexOutOfBoundsException if any of index,
+ * (index+length), or vertexAttrNum are out of range, or if
+ * vertexAttrs is too small.
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE</code>.
+ *
+ * @since Java 3D 1.4
+ */
+ public void setVertexAttrs(int vertexAttrNum, int index,
+ float[] vertexAttrs,
+ int start, int length) {
+
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_VERTEX_ATTR_WRITE)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray126"));
+ }
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray82"));
+ }
+
+ ((GeometryArrayRetained)this.retained).setVertexAttrs(
+ vertexAttrNum, index, vertexAttrs, start, length);
+ }
+
+ /**
+ * Sets the vertex attributes associated with the vertices
+ * starting at the specified index in the specified vertex
+ * attribute number for this object using data in
+ * <code>vertexAttrs</code> starting at index <code>start</code> and
+ * ending at index <code>start+length</code>.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index starting destination vertex index in this geometry array
+ * @param vertexAttrs source array of Point2f objects containing new
+ * vertex attributes
+ * @param start starting source vertex index in <code>vertexAttrs</code>
+ * array.
+ * @param length number of vertex attributes to be copied.
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ *
+ * @exception ArrayIndexOutOfBoundsException if any of index,
+ * (index+length), or vertexAttrNum are out of range, or if
+ * vertexAttrs is too small.
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE</code>.
+ *
+ * @exception IllegalStateException if the size of the specified
+ * vertex attribute number is not 2.
+ *
+ * @since Java 3D 1.4
+ */
+ public void setVertexAttrs(int vertexAttrNum, int index,
+ Point2f[] vertexAttrs,
+ int start, int length) {
+
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_VERTEX_ATTR_WRITE)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray126"));
+ }
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray82"));
+ }
+
+ int size = ((GeometryArrayRetained)this.retained).vertexAttrSizes[vertexAttrNum];
+ if (size != 2) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray134"));
+ }
+
+ ((GeometryArrayRetained)this.retained).setVertexAttrs(
+ vertexAttrNum, index, vertexAttrs, start, length);
+ }
+
+ /**
+ * Sets the vertex attributes associated with the vertices
+ * starting at the specified index in the specified vertex
+ * attribute number for this object using data in
+ * <code>vertexAttrs</code> starting at index <code>start</code> and
+ * ending at index <code>start+length</code>.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index starting destination vertex index in this geometry array
+ * @param vertexAttrs source array of Point3f objects containing new
+ * vertex attributes
+ * @param start starting source vertex index in <code>vertexAttrs</code>
+ * array.
+ * @param length number of vertex attributes to be copied.
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ *
+ * @exception ArrayIndexOutOfBoundsException if any of index,
+ * (index+length), or vertexAttrNum are out of range, or if
+ * vertexAttrs is too small.
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE</code>.
+ *
+ * @exception IllegalStateException if the size of the specified
+ * vertex attribute number is not 3.
+ *
+ * @since Java 3D 1.4
+ */
+ public void setVertexAttrs(int vertexAttrNum, int index,
+ Point3f[] vertexAttrs,
+ int start, int length) {
+
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_VERTEX_ATTR_WRITE)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray126"));
+ }
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray82"));
+ }
+
+ int size = ((GeometryArrayRetained)this.retained).vertexAttrSizes[vertexAttrNum];
+ if (size != 3) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray134"));
+ }
+
+ ((GeometryArrayRetained)this.retained).setVertexAttrs(
+ vertexAttrNum, index, vertexAttrs, start, length);
+ }
+
+ /**
+ * Sets the vertex attributes associated with the vertices
+ * starting at the specified index in the specified vertex
+ * attribute number for this object using data in
+ * <code>vertexAttrs</code> starting at index <code>start</code> and
+ * ending at index <code>start+length</code>.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index starting destination vertex index in this geometry array
+ * @param vertexAttrs source array of Point4f objects containing new
+ * vertex attributes
+ * @param start starting source vertex index in <code>vertexAttrs</code>
+ * array.
+ * @param length number of vertex attributes to be copied.
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ *
+ * @exception ArrayIndexOutOfBoundsException if any of index,
+ * (index+length), or vertexAttrNum are out of range, or if
+ * vertexAttrs is too small.
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE</code>.
+ *
+ * @exception IllegalStateException if the size of the specified
+ * vertex attribute number is not 4.
+ *
+ * @since Java 3D 1.4
+ */
+ public void setVertexAttrs(int vertexAttrNum, int index,
+ Point4f[] vertexAttrs,
+ int start, int length) {
+
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_VERTEX_ATTR_WRITE)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray126"));
+ }
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray82"));
+ }
+
+ int size = ((GeometryArrayRetained)this.retained).vertexAttrSizes[vertexAttrNum];
+ if (size != 4) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray134"));
+ }
+
+ ((GeometryArrayRetained)this.retained).setVertexAttrs(
+ vertexAttrNum, index, vertexAttrs, start, length);
+ }
+
+
/**
* Gets the coordinate associated with the vertex at
* the specified index for this object using data in <code>texCoords</code>
@@ -3714,6 +4606,384 @@ public abstract class GeometryArray extends Geometry {
texCoordSet, index, texCoords);
}
+ /**
+ * Gets the vertex attribute associated with the vertex at
+ * the specified index in the specified vertex attribute number
+ * for this object.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index source vertex index in this geometry array
+ * @param vertexAttr array of 1, 2, 3 or 4 values that will receive the
+ * vertex attribute
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ *
+ * @exception ArrayIndexOutOfBoundsException if the index or
+ * vertexAttrNum is out of range, or if the vertexAttr array is
+ * too small.
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE</code>.
+ *
+ * @since Java 3D 1.4
+ */
+ public void getVertexAttr(int vertexAttrNum, int index,
+ float[] vertexAttr) {
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_VERTEX_ATTR_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray127"));
+ }
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray82"));
+ }
+
+ ((GeometryArrayRetained)this.retained).getVertexAttr(
+ vertexAttrNum, index, vertexAttr);
+ }
+
+ /**
+ * Gets the vertex attribute associated with the vertex at
+ * the specified index in the specified vertex attribute number
+ * for this object.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index source vertex index in this geometry array
+ * @param vertexAttr the vector that will receive the vertex attributes
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ *
+ * @exception ArrayIndexOutOfBoundsException if the index or
+ * vertexAttrNum is out of range.
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE</code>.
+ *
+ * @exception IllegalStateException if the size of the specified
+ * vertex attribute number is not 2.
+ *
+ * @since Java 3D 1.4
+ */
+ public void getVertexAttr(int vertexAttrNum, int index,
+ Point2f vertexAttr) {
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_VERTEX_ATTR_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray127"));
+ }
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray82"));
+ }
+
+ int size = ((GeometryArrayRetained)this.retained).vertexAttrSizes[vertexAttrNum];
+ if (size != 2) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray134"));
+ }
+
+ ((GeometryArrayRetained)this.retained).getVertexAttr(
+ vertexAttrNum, index, vertexAttr);
+ }
+
+ /**
+ * Gets the vertex attribute associated with the vertex at
+ * the specified index in the specified vertex attribute number
+ * for this object.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index source vertex index in this geometry array
+ * @param vertexAttr the vector that will receive the vertex attributes
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ *
+ * @exception ArrayIndexOutOfBoundsException if the index or
+ * vertexAttrNum is out of range.
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE</code>.
+ *
+ * @exception IllegalStateException if the size of the specified
+ * vertex attribute number is not 3.
+ *
+ * @since Java 3D 1.4
+ */
+ public void getVertexAttr(int vertexAttrNum, int index,
+ Point3f vertexAttr) {
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_VERTEX_ATTR_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray127"));
+ }
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray82"));
+ }
+
+ int size = ((GeometryArrayRetained)this.retained).vertexAttrSizes[vertexAttrNum];
+ if (size != 3) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray134"));
+ }
+
+ ((GeometryArrayRetained)this.retained).getVertexAttr(
+ vertexAttrNum, index, vertexAttr);
+ }
+
+ /**
+ * Gets the vertex attribute associated with the vertex at
+ * the specified index in the specified vertex attribute number
+ * for this object.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index source vertex index in this geometry array
+ * @param vertexAttr the vector that will receive the vertex attributes
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ *
+ * @exception ArrayIndexOutOfBoundsException if the index or
+ * vertexAttrNum is out of range.
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE</code>.
+ *
+ * @exception IllegalStateException if the size of the specified
+ * vertex attribute number is not 4.
+ *
+ * @since Java 3D 1.4
+ */
+ public void getVertexAttr(int vertexAttrNum, int index,
+ Point4f vertexAttr) {
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_VERTEX_ATTR_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray127"));
+ }
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray82"));
+ }
+
+ int size = ((GeometryArrayRetained)this.retained).vertexAttrSizes[vertexAttrNum];
+ if (size != 4) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray134"));
+ }
+
+ ((GeometryArrayRetained)this.retained).getVertexAttr(
+ vertexAttrNum, index, vertexAttr);
+ }
+
+ /**
+ * Gets the vertex attributes associated with the vertices starting at
+ * the specified index in the specified vertex attribute number
+ * for this object. The length of the destination
+ * array determines the number of vertex attributes copied.
+ * A maximum of <code>vertexCount-index</code> vertex attributes
+ * are copied. If the destination array is larger than is needed
+ * to hold the vertex attributes, the excess locations in the
+ * array are not modified. If the destination array is smaller
+ * than is needed to hold the vertex attributes, only as
+ * many vertex attributes as the array will hold are copied.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index starting source vertex index in this geometry array
+ * @param vertexAttrs destination array of 1*n, 2*n, 3*n, or 4*n values
+ * that will receive n new vertex attributes
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ *
+ * @exception ArrayIndexOutOfBoundsException if the index or
+ * vertexAttrNum is out of range.
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE</code>.
+ *
+ * @since Java 3D 1.4
+ */
+ public void getVertexAttrs(int vertexAttrNum, int index,
+ float[] vertexAttrs) {
+
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_VERTEX_ATTR_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray127"));
+ }
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray82"));
+ }
+
+ ((GeometryArrayRetained)this.retained).getVertexAttrs(
+ vertexAttrNum, index, vertexAttrs);
+ }
+
+ /**
+ * Gets the vertex attributes associated with the vertices starting at
+ * the specified index in the specified vertex attribute number
+ * for this object. The length of the destination
+ * array determines the number of vertex attributes copied.
+ * A maximum of <code>vertexCount-index</code> vertex attributes
+ * are copied. If the destination array is larger than is needed
+ * to hold the vertex attributes, the excess locations in the
+ * array are not modified. If the destination array is smaller
+ * than is needed to hold the vertex attributes, only as
+ * many vertex attributes as the array will hold are copied.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index starting source vertex index in this geometry array
+ * @param vertexAttrs destination array of Point2f objects that will
+ * receive the vertex attributes
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ *
+ * @exception ArrayIndexOutOfBoundsException if the index or
+ * vertexAttrNum is out of range.
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE</code>.
+ *
+ * @exception IllegalStateException if the size of the specified
+ * vertex attribute number is not 2.
+ *
+ * @since Java 3D 1.4
+ */
+ public void getVertexAttrs(int vertexAttrNum, int index,
+ Point2f[] vertexAttrs) {
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_VERTEX_ATTR_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray127"));
+ }
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray82"));
+ }
+
+ int size = ((GeometryArrayRetained)this.retained).vertexAttrSizes[vertexAttrNum];
+ if (size != 2) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray134"));
+ }
+
+ ((GeometryArrayRetained)this.retained).getVertexAttrs(
+ vertexAttrNum, index, vertexAttrs);
+ }
+
+ /**
+ * Gets the vertex attributes associated with the vertices starting at
+ * the specified index in the specified vertex attribute number
+ * for this object. The length of the destination
+ * array determines the number of vertex attributes copied.
+ * A maximum of <code>vertexCount-index</code> vertex attributes
+ * are copied. If the destination array is larger than is needed
+ * to hold the vertex attributes, the excess locations in the
+ * array are not modified. If the destination array is smaller
+ * than is needed to hold the vertex attributes, only as
+ * many vertex attributes as the array will hold are copied.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index starting source vertex index in this geometry array
+ * @param vertexAttrs destination array of Point3f objects that will
+ * receive the vertex attributes
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ *
+ * @exception ArrayIndexOutOfBoundsException if the index or
+ * vertexAttrNum is out of range.
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE</code>.
+ *
+ * @exception IllegalStateException if the size of the specified
+ * vertex attribute number is not 3.
+ *
+ * @since Java 3D 1.4
+ */
+ public void getVertexAttrs(int vertexAttrNum, int index,
+ Point3f[] vertexAttrs) {
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_VERTEX_ATTR_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray127"));
+ }
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray82"));
+ }
+
+ int size = ((GeometryArrayRetained)this.retained).vertexAttrSizes[vertexAttrNum];
+ if (size != 3) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray134"));
+ }
+
+ ((GeometryArrayRetained)this.retained).getVertexAttrs(
+ vertexAttrNum, index, vertexAttrs);
+ }
+
+ /**
+ * Gets the vertex attributes associated with the vertices starting at
+ * the specified index in the specified vertex attribute number
+ * for this object. The length of the destination
+ * array determines the number of vertex attributes copied.
+ * A maximum of <code>vertexCount-index</code> vertex attributes
+ * are copied. If the destination array is larger than is needed
+ * to hold the vertex attributes, the excess locations in the
+ * array are not modified. If the destination array is smaller
+ * than is needed to hold the vertex attributes, only as
+ * many vertex attributes as the array will hold are copied.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index starting source vertex index in this geometry array
+ * @param vertexAttrs destination array of Point4f objects that will
+ * receive the vertex attributes
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ *
+ * @exception ArrayIndexOutOfBoundsException if the index or
+ * vertexAttrNum is out of range.
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is <code>BY_REFERENCE</code>.
+ *
+ * @exception IllegalStateException if the size of the specified
+ * vertex attribute number is not 4.
+ *
+ * @since Java 3D 1.4
+ */
+ public void getVertexAttrs(int vertexAttrNum, int index,
+ Point4f[] vertexAttrs) {
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_VERTEX_ATTR_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray127"));
+ }
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray82"));
+ }
+
+ int size = ((GeometryArrayRetained)this.retained).vertexAttrSizes[vertexAttrNum];
+ if (size != 4) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray134"));
+ }
+
+ ((GeometryArrayRetained)this.retained).getVertexAttrs(
+ vertexAttrNum, index, vertexAttrs);
+ }
+
//------------------------------------------------------------------
// By-reference methods
@@ -3742,14 +5012,14 @@ public abstract class GeometryArray extends Geometry {
* @exception IllegalArgumentException if either of the following are
* true:
* <ul>
- * <code>initialCoordIndex < 0</code> or<br>
- * <code>initialCoordIndex + validVertexCount > vertexCount</code><br>
+ * <code>initialCoordIndex &lt; 0</code> or<br>
+ * <code>initialCoordIndex + validVertexCount &gt; vertexCount</code><br>
* </ul>
* <p>
* @exception ArrayIndexOutOfBoundsException if
* the CoordRef array is non-null and:
* <ul>
- * <code>CoordRef.length</code> < <i>num_words</i> *
+ * <code>CoordRef.length</code> &lt; <i>num_words</i> *
* (<code>initialCoordIndex + validVertexCount</code>)<br>
* </ul>
* where <i>num_words</i> depends on which variant of
@@ -3820,14 +5090,14 @@ public abstract class GeometryArray extends Geometry {
* @exception IllegalArgumentException if either of the following are
* true:
* <ul>
- * <code>initialColorIndex < 0</code> or<br>
- * <code>initialColorIndex + validVertexCount > vertexCount</code><br>
+ * <code>initialColorIndex &lt; 0</code> or<br>
+ * <code>initialColorIndex + validVertexCount &gt; vertexCount</code><br>
* </ul>
* <p>
* @exception ArrayIndexOutOfBoundsException if
* the ColorRef array is non-null and:
* <ul>
- * <code>ColorRef.length</code> < <i>num_words</i> *
+ * <code>ColorRef.length</code> &lt; <i>num_words</i> *
* (<code>initialColorIndex + validVertexCount</code>)<br>
* </ul>
* where <i>num_words</i> depends on which variant of
@@ -3898,14 +5168,14 @@ public abstract class GeometryArray extends Geometry {
* @exception IllegalArgumentException if either of the following are
* true:
* <ul>
- * <code>initialNormalIndex < 0</code> or<br>
- * <code>initialNormalIndex + validVertexCount > vertexCount</code><br>
+ * <code>initialNormalIndex &lt; 0</code> or<br>
+ * <code>initialNormalIndex + validVertexCount &gt; vertexCount</code><br>
* </ul>
* <p>
* @exception ArrayIndexOutOfBoundsException if normals
* the NormalRef array is non-null and:
* <ul>
- * <code>NormalRef.length</code> < <i>num_words</i> *
+ * <code>NormalRef.length</code> &lt; <i>num_words</i> *
* (<code>initialNormalIndex + validVertexCount</code>)<br>
* </ul>
* where <i>num_words</i> depends on which variant of
@@ -3979,14 +5249,14 @@ public abstract class GeometryArray extends Geometry {
* @exception IllegalArgumentException if either of the following are
* true:
* <ul>
- * <code>initialTexCoordIndex < 0</code> or<br>
- * <code>initialTexCoordIndex + validVertexCount > vertexCount</code><br>
+ * <code>initialTexCoordIndex &lt; 0</code> or<br>
+ * <code>initialTexCoordIndex + validVertexCount &gt; vertexCount</code><br>
* </ul>
* <p>
* @exception ArrayIndexOutOfBoundsException if
* the TexCoordRef array is non-null and:
* <ul>
- * <code>TexCoordRef.length</code> < <i>num_words</i> *
+ * <code>TexCoordRef.length</code> &lt; <i>num_words</i> *
* (<code>initialTexCoordIndex + validVertexCount</code>)<br>
* </ul>
* where <i>num_words</i> depends on which variant of
@@ -4054,6 +5324,109 @@ public abstract class GeometryArray extends Geometry {
/**
+ * Sets the initial vertex attribute index for the specified
+ * vertex attribute number for this GeometryArray object. This
+ * index specifies the first vertex attribute within the array
+ * of vertex attributes referenced by this geometry array that
+ * is actually used in rendering or other operations such as
+ * picking and collision. This attribute is initialized to 0.
+ * This attribute is only used when the data mode for this
+ * geometry array object is <code>BY_REFERENCE</code>
+ * and is <i>not</i> </code>INTERLEAVED</code>.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param initialVertexAttrIndex the new initial vertex attribute index.
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ * <p>
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is not <code>BY_REFERENCE</code> or if the data mode
+ * is <code>INTERLEAVED</code>.
+ * <p>
+ * @exception IllegalArgumentException if either of the following are
+ * true:
+ * <ul>
+ * <code>initialVertexAttrIndex &lt; 0</code> or<br>
+ * <code>initialVertexAttrIndex + validVertexCount &gt; vertexCount</code><br>
+ * </ul>
+ * <p>
+ * @exception ArrayIndexOutOfBoundsException if
+ * the VertexAttrRef array is non-null and:
+ * <ul>
+ * <code>VertexAttrRef.length</code> &lt; <i>num_words</i> *
+ * (<code>initialVertexAttrIndex + validVertexCount</code>)<br>
+ * </ul>
+ * where <i>num_words</i> is the size of the specified
+ * vertexAttrNum (1, 2, 3, or 4).
+ * <p>
+ * @exception ArrayIndexOutOfBoundsException if vertexAttrNum is
+ * out of range.
+ *
+ * @since Java 3D 1.4
+ */
+ public void setInitialVertexAttrIndex(int vertexAttrNum,
+ int initialVertexAttrIndex) {
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_COUNT_WRITE)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray90"));
+ }
+ }
+
+ if (initialVertexAttrIndex < 0) {
+ throw new IllegalArgumentException(J3dI18N.getString("GeometryArray97"));
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE) == 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray83"));
+ }
+
+ if ((format & INTERLEAVED) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray84"));
+ }
+
+ ((GeometryArrayRetained)this.retained).setInitialVertexAttrIndex(
+ vertexAttrNum, initialVertexAttrIndex);
+
+ // NOTE: the check for initialVertexAttrIndex + validVertexCount >
+ // vertexCount needs to be done in the retained method
+ }
+
+
+ /**
+ * Gets the initial vertex attribute index for the specified
+ * vertex attribute number for this GeometryArray object.
+ * This attribute is only used when the data mode for this
+ * geometry array object is <code>BY_REFERENCE</code>
+ * and is <i>not</i> </code>INTERLEAVED</code>.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ *
+ * @return the current initial vertex attribute index for the specified
+ * vertex attribute number
+ *
+ * @exception ArrayIndexOutOfBoundsException if vertexAttrNum is
+ * out of range.
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ *
+ * @since Java 3D 1.4
+ */
+ public int getInitialVertexAttrIndex(int vertexAttrNum) {
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_COUNT_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray91"));
+ }
+ }
+
+ return ((GeometryArrayRetained)this.retained).getInitialVertexAttrIndex(
+ vertexAttrNum);
+ }
+
+
+ /**
* Sets the coordinate buffer reference to the specified
* buffer object. The buffer contains either a java.nio.FloatBuffer
* or java.nio.DoubleBuffer object containing single or double
@@ -4081,7 +5454,7 @@ public abstract class GeometryArray extends Geometry {
* java.nio.FloatBuffer or a java.nio.DoubleBuffer object.
*
* @exception ArrayIndexOutOfBoundsException if
- * <code>coords.getBuffer().limit() <
+ * <code>coords.getBuffer().limit() &lt;
* 3 * (initialCoordIndex + validVertexCount)</code>.
*
* @exception ArrayIndexOutOfBoundsException if this GeometryArray
@@ -4164,7 +5537,7 @@ public abstract class GeometryArray extends Geometry {
* @exception IllegalArgumentException if the specified array is
* non-null and any other coordinate reference is also non-null.
* @exception ArrayIndexOutOfBoundsException if
- * <code>coords.length < 3 * (initialCoordIndex + validVertexCount)</code>.
+ * <code>coords.length &lt; 3 * (initialCoordIndex + validVertexCount)</code>.
*
* @exception ArrayIndexOutOfBoundsException if this GeometryArray
* object is a subclass of IndexedGeometryArray, and any element
@@ -4253,7 +5626,7 @@ public abstract class GeometryArray extends Geometry {
* @exception IllegalArgumentException if the specified array is
* non-null and any other coordinate reference is also non-null.
* @exception ArrayIndexOutOfBoundsException if
- * <code>coords.length < 3 * (initialCoordIndex + validVertexCount)</code>.
+ * <code>coords.length &lt; 3 * (initialCoordIndex + validVertexCount)</code>.
*
* @exception ArrayIndexOutOfBoundsException if this GeometryArray
* object is a subclass of IndexedGeometryArray, and any element
@@ -4456,7 +5829,7 @@ public abstract class GeometryArray extends Geometry {
* @exception ArrayIndexOutOfBoundsException if none of the
* <code>COLOR</code> bits are set in the
* <code>vertexFormat</code>, or if
- * <code>colors.getBuffer().limit() < </code> <i>num_words</i> <code> *
+ * <code>colors.getBuffer().limit() &lt; </code> <i>num_words</i> <code> *
* (initialColorIndex + validVertexCount)</code>,
* where <i>num_words</i> is 3 or 4 depending on the vertex color format.
*
@@ -4549,7 +5922,7 @@ public abstract class GeometryArray extends Geometry {
* @exception ArrayIndexOutOfBoundsException if none of the
* <code>COLOR</code> bits are set in the
* <code>vertexFormat</code>, or if
- * <code>colors.length < </code> <i>num_words</i> <code> *
+ * <code>colors.length &lt; </code> <i>num_words</i> <code> *
* (initialColorIndex + validVertexCount)</code>,
* where <i>num_words</i> is 3 or 4 depending on the vertex color format.
*
@@ -4646,7 +6019,7 @@ public abstract class GeometryArray extends Geometry {
* @exception ArrayIndexOutOfBoundsException if none of the
* <code>COLOR</code> bits are set in the
* <code>vertexFormat</code>, or if
- * <code>colors.length < </code> <i>num_words</i> <code> *
+ * <code>colors.length &lt; </code> <i>num_words</i> <code> *
* (initialColorIndex + validVertexCount)</code>,
* where <i>num_words</i> is 3 or 4 depending on the vertex color format.
*
@@ -4978,7 +6351,7 @@ public abstract class GeometryArray extends Geometry {
* @exception ArrayIndexOutOfBoundsException if
* <code>NORMALS</code> bit is not set in the
* <code>vertexFormat</code>, or if
- * <code>normals.getBuffer().limit() <
+ * <code>normals.getBuffer().limit() &lt;
* 3 * (initialNormalIndex + validVertexCount)</code>.
*
* @exception ArrayIndexOutOfBoundsException if this GeometryArray
@@ -5064,7 +6437,7 @@ public abstract class GeometryArray extends Geometry {
* @exception ArrayIndexOutOfBoundsException if
* <code>NORMALS</code> bit is not set in the
* <code>vertexFormat</code>, or if
- * <code>normals.length < 3 * (initialNormalIndex + validVertexCount)</code>.
+ * <code>normals.length &lt; 3 * (initialNormalIndex + validVertexCount)</code>.
*
* @exception ArrayIndexOutOfBoundsException if this GeometryArray
* object is a subclass of IndexedGeometryArray, and any element
@@ -5186,7 +6559,7 @@ public abstract class GeometryArray extends Geometry {
/**
- * Sets the texture coordinate array reference for the specified
+ * Sets the texture coordinate buffer reference for the specified
* texture coordinate set to the
* specified buffer object. The buffer contains a java.nio.FloatBuffer
* object containing <i>s</i>,
@@ -5223,7 +6596,7 @@ public abstract class GeometryArray extends Geometry {
* <code>TEXTURE_COORDINATE</code> bits are set in the
* <code>vertexFormat</code>, or if texCoordSet is out of range,
* or if
- * <code>texCoords.getBuffer().limit() < </code> <i>num_words</i>
+ * <code>texCoords.getBuffer().limit() &lt; </code> <i>num_words</i>
* <code> * (initialTexCoordIndex + validVertexCount)</code>,
* where <i>num_words</i> is 2, 3, or 4 depending on the vertex
* texture coordinate format.
@@ -5336,7 +6709,7 @@ public abstract class GeometryArray extends Geometry {
* <code>TEXTURE_COORDINATE</code> bits are set in the
* <code>vertexFormat</code>, or if texCoordSet is out of range,
* or if
- * <code>texCoords.length < </code> <i>num_words</i> <code> *
+ * <code>texCoords.length &lt; </code> <i>num_words</i> <code> *
* (initialTexCoordIndex + validVertexCount)</code>,
* where <i>num_words</i> is 2, 3, or 4 depending on the vertex
* texture coordinate format.
@@ -5543,11 +6916,265 @@ public abstract class GeometryArray extends Geometry {
texCoordSet);
}
+
+ /**
+ * Sets the vertex attribute buffer reference for the specified
+ * vertex attribute number to the specified buffer object. The
+ * buffer contains a java.nio.FloatBuffer object containing 1, 2,
+ * 3, or 4 values for each vertex (for a total of 1*<i>n</i>,
+ * 2*<i>n</i>, 3*<i>n</i>, or 4*<i>n</i> values, where <i>n</i> is
+ * the number of vertices).
+ * If the vertexAttr buffer reference is null and vertex
+ * attributes are enabled (that is, the vertexFormat includes
+ * <code>VERTEX_ATTRIBUTES</code>), the entire geometry array
+ * object is treated as if it were null--any Shape3D node that
+ * uses this geometry array will not be drawn.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ *
+ * @param vertexAttrs a J3DBuffer object to which a reference will
+ * be set. The buffer contains an NIO buffer of 1*<i>n</i>,
+ * 2*<i>n</i>, 3*<i>n</i>, or 4*<i>n</i> float values.
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is not <code>BY_REFERENCE</code>,
+ * is not <code>USE_NIO_BUFFER</code>, or is <code>INTERLEAVED</code>.
+ *
+ * @exception IllegalArgumentException if the java.nio.Buffer
+ * contained in the specified J3DBuffer is not a
+ * java.nio.FloatBuffer object.
+ *
+ * @exception ArrayIndexOutOfBoundsException if vertexAttrNum is out of
+ * range, or if
+ * <code>vertexAttrs.getBuffer().limit() &lt; </code> <i>num_words</i>
+ * <code> * (initialVertexAttrIndex + validVertexCount)</code>,
+ * where <i>num_words</i> is the size of the specified
+ * vertexAttrNum (1, 2, 3, or 4).
+ *
+ * @exception ArrayIndexOutOfBoundsException if this GeometryArray
+ * object is a subclass of IndexedGeometryArray, and any element
+ * in the range
+ * <code>[initialIndexIndex, initialIndexIndex+validIndexCount-1]</code>
+ * in the vertex attribute index array is greater than or equal to the
+ * number of vertices defined by the vertexAttrs object,
+ * <code>vertexAttrs.getBuffer().limit() / </code> <i>num_words</i>.
+ *
+ * @since Java 3D 1.4
+ */
+ public void setVertexAttrRefBuffer(int vertexAttrNum, J3DBuffer vertexAttrs) {
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_REF_DATA_WRITE)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray86"));
+ }
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+
+ if ((format & USE_NIO_BUFFER) == 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray118"));
+ }
+
+ if ((format & INTERLEAVED) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray84"));
+ }
+
+ ((GeometryArrayRetained)this.retained).setVertexAttrRefBuffer(
+ vertexAttrNum, vertexAttrs);
+ }
+
+
+ /**
+ * Gets the vertex attribute array buffer reference for the specified
+ * vertex attribute number.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ *
+ * @return the current vertex attribute array buffer reference
+ * for the specified vertex attribute number
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is not <code>BY_REFERENCE</code>,
+ * is not <code>USE_NIO_BUFFER</code>, or is <code>INTERLEAVED</code>.
+ *
+ * @exception ArrayIndexOutOfBoundsException if vertexAttrNum is out
+ * of range.
+ *
+ * @since Java 3D 1.4
+ */
+ public J3DBuffer getVertexAttrRefBuffer(int vertexAttrNum) {
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_REF_DATA_READ) &&
+ !this.getCapability(J3D_1_2_ALLOW_REF_DATA_READ)) {
+
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray87"));
+ }
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+
+ if ((format & USE_NIO_BUFFER) == 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray118"));
+ }
+
+ if ((format & INTERLEAVED) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray84"));
+ }
+
+ return ((GeometryArrayRetained)this.retained).getVertexAttrRefBuffer(vertexAttrNum);
+ }
+
+
+ /*
+ * XXXX: add the following to the javadoc if we ever add double-precision
+ * methods for vertex attribtues.
+ *
+ *-----------------------------------------------------------------
+ * Only one of <code>vertexAttrRefFloat</code>, or
+ * <code>vertexAttrRefDouble</code> may be non-null (or they may
+ * all be null). An attempt to set more than one of these
+ * attributes to a non-null reference will result in an exception
+ * being thrown.
+ *
+ * If all vertexAttr array references are null and vertex
+ * ...
+ * @exception IllegalArgumentException if the specified array is
+ * non-null and any other vertexAttr reference is also non-null.
+ * ...
+ *-----------------------------------------------------------------
+ */
+
+ /**
+ * Sets the float vertex attribute array reference for the
+ * specified vertex attribute number to the specified array. The
+ * array contains 1, 2, 3, or 4 floating-point values for each
+ * vertex (for a total of 1*<i>n</i>, 2*<i>n</i>, 3*<i>n</i>, or
+ * 4*<i>n</i> values, where <i>n</i> is the number of vertices).
+ *
+ * If the vertexAttr array reference is null and vertex
+ * attributes are enabled (that is, the vertexFormat includes
+ * <code>VERTEX_ATTRIBUTES</code>), the entire geometry array
+ * object is treated as if it were null--any Shape3D node that
+ * uses this geometry array will not be drawn.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ *
+ * @param vertexAttrs an array of 1*<i>n</i>, 2*<i>n</i>,
+ * 3*<i>n</i>, or 4*<i>n</i> values to which a reference will be
+ * set.
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is not <code>BY_REFERENCE</code>,
+ * is <code>USE_NIO_BUFFER</code>, or is <code>INTERLEAVED</code>.
+ *
+ * @exception ArrayIndexOutOfBoundsException if vertexAttrNum is
+ * out of range, or if
+ * <code>vertexAttrs.length &lt; </code> <i>num_words</i> <code> *
+ * (initialVertexAttrIndex + validVertexCount)</code>,
+ * where <i>num_words</i> is the size of the specified
+ * vertexAttrNum (1, 2, 3, or 4).
+ *
+ * @exception ArrayIndexOutOfBoundsException if this GeometryArray
+ * object is a subclass of IndexedGeometryArray, and any element
+ * in the range
+ * <code>[initialIndexIndex, initialIndexIndex+validIndexCount-1]</code>
+ * in the vertex attribute index array is greater than or equal to the
+ * number of vertices defined by the vertexAttrs array,
+ * <code>vertexAttrs.length / </code> <i>num_words</i>.
+ *
+ * @since Java 3D 1.4
+ */
+ public void setVertexAttrRefFloat(int vertexAttrNum, float[] vertexAttrs) {
+
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_REF_DATA_WRITE)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray86"));
+ }
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE) == 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray83"));
+ }
+
+ if ((format & USE_NIO_BUFFER) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray119"));
+ }
+
+ if ((format & INTERLEAVED) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray84"));
+ }
+
+ ((GeometryArrayRetained)this.retained).setVertexAttrRefFloat(
+ vertexAttrNum, vertexAttrs);
+
+ // NOTE: the checks for multiple non-null references, and the
+ // array length check need to be done in the retained method
+ }
+
+
+ /**
+ * Gets the float vertex attribute array reference for the specified
+ * vertex attribute number.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ *
+ * @return the current float vertex attribute array reference
+ * for the specified vertex attribute number
+ *
+ * @exception CapabilityNotSetException if the appropriate capability is
+ * not set and this object is part of a live or compiled scene graph
+ *
+ * @exception IllegalStateException if the data mode for this geometry
+ * array object is not <code>BY_REFERENCE</code>,
+ * is <code>USE_NIO_BUFFER</code>, or is <code>INTERLEAVED</code>.
+ *
+ * @exception ArrayIndexOutOfBoundsException if vertexAttrNum is
+ * out of range.
+ *
+ * @since Java 3D 1.4
+ */
+ public float[] getVertexAttrRefFloat(int vertexAttrNum) {
+
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_REF_DATA_READ) &&
+ !this.getCapability(J3D_1_2_ALLOW_REF_DATA_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray87"));
+ }
+ }
+
+ int format = ((GeometryArrayRetained)this.retained).vertexFormat;
+ if ((format & BY_REFERENCE) == 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray83"));
+ }
+
+ if ((format & USE_NIO_BUFFER) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray119"));
+ }
+
+ if ((format & INTERLEAVED) != 0) {
+ throw new IllegalStateException(J3dI18N.getString("GeometryArray84"));
+ }
+
+ return ((GeometryArrayRetained)this.retained).getVertexAttrRefFloat(
+ vertexAttrNum);
+ }
+
+
/**
* Sets the interleaved vertex array reference to the specified
* array. The vertex components must be stored in a predetermined
* order in the array. The order is: texture coordinates, colors,
- * normals, and positional coordinates. In the case of texture
+ * normals, and positional coordinates.
+ * Vertex attributes are not supported in interleaved mode.
+ * In the case of texture
* coordinates, the values for each texture coordinate set
* are stored in order from 0 through texCoordSetCount-1. Only those
* components that are enabled appear in the vertex. The number
@@ -5584,7 +7211,7 @@ public abstract class GeometryArray extends Geometry {
* or is <code>USE_NIO_BUFFER</code>.
*
* @exception ArrayIndexOutOfBoundsException if
- * <code>vertexData.length</code> < <i>words_per_vertex</i> *
+ * <code>vertexData.length</code> &lt; <i>words_per_vertex</i> *
* (<code>initialVertexIndex + validVertexCount</code>),
* where <i>words_per_vertex</i> depends on which formats are enabled.
*
@@ -5652,7 +7279,9 @@ public abstract class GeometryArray extends Geometry {
* buffer object. The buffer must contain a java.nio.FloatBuffer object.
* The vertex components must be stored in a predetermined
* order in the buffer. The order is: texture coordinates, colors,
- * normals, and positional coordinates. In the case of texture
+ * normals, and positional coordinates.
+ * Vertex attributes are not supported in interleaved mode.
+ * In the case of texture
* coordinates, the values for each texture coordinate set
* are stored in order from 0 through texCoordSetCount-1. Only those
* components that are enabled appear in the vertex. The number
@@ -5696,7 +7325,7 @@ public abstract class GeometryArray extends Geometry {
* java.nio.FloatBuffer object.
*
* @exception ArrayIndexOutOfBoundsException if
- * <code>vertexData.getBuffer().limit()</code> < <i>words_per_vertex</i> *
+ * <code>vertexData.getBuffer().limit()</code> &lt; <i>words_per_vertex</i> *
* (<code>initialVertexIndex + validVertexCount</code>),
* where <i>words_per_vertex</i> depends on which formats are enabled.
*
diff --git a/src/classes/share/javax/media/j3d/GeometryArrayRetained.java b/src/classes/share/javax/media/j3d/GeometryArrayRetained.java
index fce41cd..dcc380c 100644
--- a/src/classes/share/javax/media/j3d/GeometryArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/GeometryArrayRetained.java
@@ -36,9 +36,7 @@ import com.sun.j3d.internal.DoubleBufferWrapper;
abstract class GeometryArrayRetained extends GeometryRetained{
-
-
- // TODO: Memory footprint reduction. Should have separate object to
+ // XXXX: Memory footprint reduction. Should have separate object to
// to contain specific data such as a ByRef object for
// all ByRef related data. So that incases where no
// ByRef is needed, the ByRef object reference is
@@ -89,6 +87,12 @@ abstract class GeometryArrayRetained extends GeometryRetained{
// Offset (in words) within each vertex of the texture coordinate
int textureOffset;
+ // Offset (in words) within each vertex of each vertex attribute
+ int[] vertexAttrOffsets;
+
+ // Stride (size) of all vertex attributes
+ int vertexAttrStride;
+
// alpha value for transparency and texture blending
float[] lastAlpha = new float[1];
float lastScreenAlpha = -1;
@@ -132,7 +136,8 @@ abstract class GeometryArrayRetained extends GeometryRetained{
int initialCoordIndex = 0;
int initialColorIndex = 0;
int initialNormalIndex = 0;
- int initialTexCoordIndex[] = null;
+ int[] initialTexCoordIndex = null;
+ int[] initialVertexAttrIndex = null;
int initialVertexIndex = 0;
@@ -174,6 +179,19 @@ abstract class GeometryArrayRetained extends GeometryRetained{
static final int T2F = 0x2000;
static final int T3F = 0x4000;
static final int TEXCOORD_DEFINED = TF | T2F | T3F;
+
+ static final int AF = 0x8000;
+ static final int VATTR_DEFINED = AF;
+
+ // Flag word indicating the type of by-ref texCoord. We will copy this to
+ // the vertexType field only when the references for all texture coordinate
+ // sets are set to non-null values.
+ private int texCoordType = 0;
+
+ // Flag word indicating the type of by-ref vertex attr. We will copy this to
+ // the vertexType field only when the references for all vertex attrs
+ // are set to non-null values.
+ private int vertexAttrType = 0;
// flag for execute geometry array when by reference
static final int COORD_FLOAT = 0x01;
@@ -181,9 +199,10 @@ abstract class GeometryArrayRetained extends GeometryRetained{
static final int COLOR_FLOAT = 0x04;
static final int COLOR_BYTE = 0x08;
static final int NORMAL_FLOAT = 0x10;
- static final int TEXCOORD_FLOAT = 0x20;
-
-
+ static final int TEXCOORD_FLOAT = 0x20;
+ static final int VATTR_FLOAT = 0x40;
+
+
// used by "by reference" normals
float[] floatRefNormals = null;
Vector3f[] v3fRefNormals = null;
@@ -192,6 +211,13 @@ abstract class GeometryArrayRetained extends GeometryRetained{
J3DBuffer normalRefBuffer = null;
FloatBufferWrapper floatBufferRefNormals = null;
+ // used for "by reference" vertex attrs
+ float[][] floatRefVertexAttrs = null;
+
+ // Used for NIO buffer vertex attrs
+ J3DBuffer[] vertexAttrsRefBuffer = null;
+ FloatBufferWrapper[] floatBufferRefVertexAttrs = null;
+ Object[] nioFloatBufferRefVertexAttrs = null;
// used by "by reference" tex coords
Object[] refTexCoords = null;
@@ -212,10 +238,10 @@ abstract class GeometryArrayRetained extends GeometryRetained{
// pointers used, when transparency is turned on
// or when its an object such as C3F, P3F etc ..
- // TODO: Update this for J3DBuffer
float[] mirrorFloatRefCoords = null;
double[] mirrorDoubleRefCoords = null;
float[] mirrorFloatRefNormals = null;
+ float[][] mirrorFloatRefVertexAttrs = null;
float[] mirrorFloatRefTexCoords = null;
Object[] mirrorRefTexCoords = null;
@@ -223,14 +249,9 @@ abstract class GeometryArrayRetained extends GeometryRetained{
byte[][] mirrorUnsignedByteRefColors= new byte[1][];
float[][] mirrorInterleavedColorPointer = null;
- // This native method builds a native representation of this object, then
- // returns the nativeId.
- native int build(int geoType);
-
// boolean to determine if a mirror was allocated
int mirrorVertexAllocated = 0;
int mirrorColorAllocated = 0;
- boolean mirrorTexCoordAllocated = false;
boolean mirrorNormalAllocated = false;
// Some dirty bits for GeometryArrays
@@ -240,12 +261,13 @@ abstract class GeometryArrayRetained extends GeometryRetained{
static final int TEXTURE_CHANGED = 0x08;
static final int BOUNDS_CHANGED = 0x10;
static final int INDEX_CHANGED = 0x20;
- static final int STRIPCOUNT_CHANGED = 0x40;
+ static final int STRIPCOUNT_CHANGED = 0x40;
+ static final int VATTR_CHANGED = 0x80;
static final int VERTEX_CHANGED = COORDINATE_CHANGED |
NORMAL_CHANGED |
COLOR_CHANGED |
- TEXTURE_CHANGED;
-
+ TEXTURE_CHANGED |
+ VATTR_CHANGED;
static final int defaultTexCoordSetMap[] = {0};
int texCoordSetCount = 0;
@@ -255,6 +277,11 @@ abstract class GeometryArrayRetained extends GeometryRetained{
// texture unit. -1 means no corresponding texCoord data offset
int [] texCoordSetMapOffset = null;
+ // Vertex attribute information
+ int vertexAttrCount = 0;
+ int[] vertexAttrSizes = null;
+
+
// This point to a list of VertexBuffers in a Vector structure
// Each element correspond to a D3D context that create this VB.
// Note that this GeometryArray can be used by multiple ctx.
@@ -936,26 +963,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
}
- // TODO: may not need this function in NIO buffer version
- // setup mirror vertex pointers for J3DBuffer version
- void setupMirrorVertexPointerNIOBuffer(int vType) {
- int i, index = 0;
- switch(vType) {
- case PF:
-
- break;
- case PD:
-
- break;
-
- // do not need to handle P3F and P3D case in NIO buffer version
- default:
- break;
-
- }
-
- }
-
// If turned transparent the first time, then force it to allocate
void setupMirrorInterleavedColorPointer(boolean force) {
int index, length, offset;
@@ -1266,7 +1273,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
vertexType |= CF;
vertexType &= ~CUB;
if (c4fAllocated == 0 && !force) {
- // TODO: make suren mirrorFloatRefColors[0] is set right
+ // NOTE: make suren mirrorFloatRefColors[0] is set right
mirrorFloatRefColors[0] = null;
mirrorColorAllocated &= ~CF;
}
@@ -1302,7 +1309,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
vertexType |= CUB;
vertexType &= ~CF;
if (c4fAllocated == 0 && !force) {
- // TODO: make suren mirrorUnsignedByteRefColors[0] is set right
+ // NOTE: make sure mirrorUnsignedByteRefColors[0] is set right
mirrorUnsignedByteRefColors[0] = null;
mirrorColorAllocated &= ~CUB;;
}
@@ -1387,42 +1394,58 @@ abstract class GeometryArrayRetained extends GeometryRetained{
void setupMirrorTexCoordPointer(int type) {
for (int i = 0; i < texCoordSetCount; i++) {
- setupMirrorTexCoordPointer(i, type);
+ doSetupMirrorTexCoordPointer(i, type);
}
- }
+ validateTexCoordPointerType();
+ }
+
void setupMirrorTexCoordPointer(int texCoordSet, int type) {
- int i, index;
+ doSetupMirrorTexCoordPointer(texCoordSet, type);
+ validateTexCoordPointerType();
+ }
+
+ // If all texCoord pointers are set to a non-null value, then set the
+ // texcoord type in the vertexType flag word, else clear the texcoord type
+ private void validateTexCoordPointerType() {
+ boolean allNonNull = true;
+ boolean allNull = true;
+ for (int i = 0; i < texCoordSetCount; i++) {
+ if (refTexCoords[i] == null) {
+ allNonNull = false;
+ } else {
+ allNull = false;
+ }
+ }
- if (mirrorRefTexCoords == null)
- mirrorRefTexCoords = new Object[texCoordSetCount];
+ // Reset texCoordType if all references are null
+ if (allNull) {
+ texCoordType = 0;
+ }
- switch (type) {
- case TF:
- if (refTexCoords[texCoordSet] == null) {
- if ((vertexType & TEXCOORD_DEFINED) == TF) {
- vertexType &= ~TF;
- mirrorRefTexCoords[texCoordSet] = null;
- mirrorTexCoordAllocated = false;
- }
- }
- else {
- vertexType |= TF;
- mirrorRefTexCoords[texCoordSet] = refTexCoords[texCoordSet];
- mirrorTexCoordAllocated = false;
- }
+ // Copy texCoordType to vertexType if all references are non-null
+ vertexType &= ~TEXCOORD_DEFINED;
+ if (allNonNull) {
+ vertexType |= texCoordType;
+ }
+ }
+
+ private void doSetupMirrorTexCoordPointer(int texCoordSet, int type) {
+ int i, index;
+
+ switch (type) {
+ case TF:
+ texCoordType = TF;
+ mirrorRefTexCoords[texCoordSet] = refTexCoords[texCoordSet];
break;
- case T2F:
+
+ case T2F:
+ texCoordType = T2F;
t2fRefTexCoords = (TexCoord2f[])refTexCoords[texCoordSet];
if (t2fRefTexCoords == null) {
- if ((vertexType & TEXCOORD_DEFINED) == T2F) {
- vertexType &= ~T2F;
- }
- return;
- }
- else {
- vertexType |= T2F;
+ mirrorRefTexCoords[texCoordSet] = null;
+ break;
}
mirrorFloatRefTexCoords = (float[])mirrorRefTexCoords[texCoordSet];
@@ -1441,19 +1464,15 @@ abstract class GeometryArrayRetained extends GeometryRetained{
mirrorFloatRefTexCoords[index++] = t2fRefTexCoords[i].x;
mirrorFloatRefTexCoords[index++] = t2fRefTexCoords[i].y;
}
- mirrorTexCoordAllocated = true;
break;
- case T3F:
+ case T3F:
+ texCoordType = T3F;
t3fRefTexCoords = (TexCoord3f[])refTexCoords[texCoordSet];
- if (t3fRefTexCoords == null) {
- if ((vertexType & TEXCOORD_DEFINED) == T3F) {
- vertexType &= ~T3F;
- }
- return;
- }
- else {
- vertexType |= T3F;
+
+ if (t3fRefTexCoords == null) {
+ mirrorRefTexCoords[texCoordSet] = null;
+ break;
}
mirrorFloatRefTexCoords = (float[])mirrorRefTexCoords[texCoordSet];
@@ -1473,142 +1492,240 @@ abstract class GeometryArrayRetained extends GeometryRetained{
mirrorFloatRefTexCoords[index++] = t3fRefTexCoords[i].y;
mirrorFloatRefTexCoords[index++] = t3fRefTexCoords[i].z;
}
- mirrorTexCoordAllocated = true;
break;
default:
break;
}
}
-
- void createGeometryArrayData(int vertexCount, int vertexFormat)
- {
+ void setupMirrorVertexAttrPointer(int type) {
+ for (int i = 0; i < vertexAttrCount; i++) {
+ doSetupMirrorVertexAttrPointer(i, type);
+ }
+
+ validateVertexAttrPointerType();
+ }
+
+ void setupMirrorVertexAttrPointer(int vertexAttrNum, int type) {
+ doSetupMirrorVertexAttrPointer(vertexAttrNum, type);
+ validateVertexAttrPointerType();
+ }
+
+ // If all vertex attr pointers are set to a non-null value, then set the
+ // vertex attr type in the vertexType flag word, else clear the
+ // vertex attr type
+ private void validateVertexAttrPointerType() {
+ boolean allNonNull = true;
+ boolean allNull = true;
+
+ if ((vertexFormat & GeometryArray.USE_NIO_BUFFER) == 0) {
+ for (int i = 0; i < vertexAttrCount; i++) {
+ if (floatRefVertexAttrs[i] == null) {
+ allNonNull = false;
+ } else {
+ allNull = false;
+ }
+ }
+ } else {
+ for (int i = 0; i < vertexAttrCount; i++) {
+ if (nioFloatBufferRefVertexAttrs[i] == null) {
+ allNonNull = false;
+ } else {
+ allNull = false;
+ }
+ }
+ }
+
+ // Reset vertexAttrType if all references are null
+ if (allNull) {
+ vertexAttrType = 0;
+ }
+
+ // Copy vertexAttrType to vertexType if all references are non-null
+ vertexType &= ~VATTR_DEFINED;
+ if (allNonNull) {
+ vertexType |= vertexAttrType;
+ }
+ }
+
+ private void doSetupMirrorVertexAttrPointer(int vertexAttrNum, int type) {
+ switch (type) {
+ case AF:
+ vertexAttrType = AF;
+ mirrorFloatRefVertexAttrs[vertexAttrNum] =
+ floatRefVertexAttrs[vertexAttrNum];
+ break;
+ default:
+ break;
+ }
+ }
+
+
+ void createGeometryArrayData(int vertexCount, int vertexFormat) {
if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
createGeometryArrayData(vertexCount, vertexFormat, 1,
- defaultTexCoordSetMap);
+ defaultTexCoordSetMap);
} else {
createGeometryArrayData(vertexCount, vertexFormat, 0, null);
}
}
void createGeometryArrayData(int vertexCount, int vertexFormat,
- int texCoordSetCount, int[] texCoordSetMap)
- {
+ int texCoordSetCount, int[] texCoordSetMap) {
+
+ createGeometryArrayData(vertexCount, vertexFormat,
+ texCoordSetCount, texCoordSetMap,
+ 0, null);
+ }
+
+ void createGeometryArrayData(int vertexCount, int vertexFormat,
+ int texCoordSetCount, int[] texCoordSetMap,
+ int vertexAttrCount, int[] vertexAttrSizes) {
this.vertexFormat = vertexFormat;
this.vertexCount = vertexCount;
this.validVertexCount = vertexCount;
+
this.texCoordSetCount = texCoordSetCount;
- this.texCoordSetMap = texCoordSetMap;
+ if (texCoordSetMap == null) {
+ this.texCoordSetMap = null;
+ }
+ else {
+ this.texCoordSetMap = (int[])texCoordSetMap.clone();
+ }
+
+ this.vertexAttrCount = vertexAttrCount;
+ if (vertexAttrSizes == null) {
+ this.vertexAttrSizes = null;
+ }
+ else {
+ this.vertexAttrSizes = (int[])vertexAttrSizes.clone();
+ }
+
+ this.vertexAttrStride = this.vertexAttrStride();
this.stride = this.stride();
+
+ this.vertexAttrOffsets = this.vertexAttrOffsets();
this.texCoordSetMapOffset = this.texCoordSetMapOffset();
- this.textureOffset = 0;
+ this.textureOffset = this.textureOffset();
this.colorOffset = this.colorOffset();
this.normalOffset = this.normalOffset();
this.coordinateOffset = this.coordinateOffset();
+
if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0) {
this.vertexData = new float[this.vertexCount * this.stride];
}
else { // By reference geometry
this.vertexData = null;
if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+ this.mirrorRefTexCoords = new Object[texCoordSetCount];
this.refTexCoords = new Object[texCoordSetCount]; // keep J3DBufferImp object in nio buffer case
if((vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0 )
this.refTexCoordsBuffer = new Object[texCoordSetCount]; // keep J3DBuffer object
}
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ this.floatRefVertexAttrs = new float[vertexAttrCount][];
+ this.mirrorFloatRefVertexAttrs = new float[vertexAttrCount][];
+ if ((vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0) {
+ this.vertexAttrsRefBuffer = new J3DBuffer[vertexAttrCount];
+ this.floatBufferRefVertexAttrs = new FloatBufferWrapper[vertexAttrCount];
+ this.nioFloatBufferRefVertexAttrs = new Object[vertexAttrCount];
+ }
+ }
}
if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
this.initialTexCoordIndex = new int[texCoordSetCount];
}
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ this.initialVertexAttrIndex = new int[vertexAttrCount];
+ }
noAlpha = ((vertexFormat & GeometryArray.WITH_ALPHA) == 0);
lastAlpha[0] = 1.0f;
}
// used for GeometryArrays by Copy or interleaved
- native void execute(long ctx,
- GeometryArrayRetained geo, int geo_type,
- boolean isNonUniformScale,
- boolean useAlpha,
- boolean multiScreen,
- boolean ignoreVertexColors,
- int startVIndex, int vcount, int vformat,
- int texCoordSetCount, int texCoordSetMap[],
- int texCoordSetMapLen,
- int[] texCoordSetOffset,
- int numActiveTexUnitState,
- int[] texUnitStateMap,
- float[] varray, float[] cdata, int texUnitIndex, int cdirty);
-
-
-
+ private native void execute(long ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean multiScreen,
+ boolean ignoreVertexColors,
+ int startVIndex, int vcount, int vformat,
+ int texCoordSetCount, int texCoordSetMap[],
+ int texCoordSetMapLen,
+ int[] texCoordSetOffset,
+ int numActiveTexUnitState,
+ int[] texUnitStateMap,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ float[] varray, float[] cdata, int texUnitIndex, int cdirty);
// used by GeometryArray by Reference with java arrays
- native void executeVA(long ctx,
- GeometryArrayRetained geo, int geo_type,
- boolean isNonUniformScale,
- boolean multiScreen,
- boolean ignoreVertexColors,
- int vcount,
- int vformat,
- int vdefined,
- int coordIndex, float[] vfcoords, double[] vdcoords,
- int colorIndex, float[] cfdata, byte[] cbdata,
- int normalIndex, float[] ndata,
- int pass, int texcoordmaplength,
- int[] texcoordoffset,
- int numActiveTexUnitState, int[] texunitstatemap,
- int[] texIndex, int texstride, Object[] texCoords,
- int cdirty);
-
-
+ private native void executeVA(long ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean multiScreen,
+ boolean ignoreVertexColors,
+ int vcount,
+ int vformat,
+ int vdefined,
+ int coordIndex, float[] vfcoords, double[] vdcoords,
+ int colorIndex, float[] cfdata, byte[] cbdata,
+ int normalIndex, float[] ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int[] vertexAttrIndex, float[][] vertexAttrData,
+ int pass, int texcoordmaplength,
+ int[] texcoordoffset,
+ int numActiveTexUnitState, int[] texunitstatemap,
+ int[] texIndex, int texstride, Object[] texCoords,
+ int cdirty);
// used by GeometryArray by Reference with NIO buffer
- native void executeVABuffer(long ctx,
- GeometryArrayRetained geo, int geo_type,
- boolean isNonUniformScale,
- boolean multiScreen,
- boolean ignoreVertexColors,
- int vcount,
- int vformat,
- int vdefined,
- int coordIndex,
- Object vcoords,
- int colorIndex,
- Object cdataBuffer,
- float[] cfdata, byte[] cbdata,
- int normalIndex, Object ndata,
- int pass, int texcoordmaplength,
- int[] texcoordoffset,
- int numActiveTexUnitState, int[] texunitstatemap,
- int[] texIndex, int texstride, Object[] texCoords,
- int cdirty);
+ private native void executeVABuffer(long ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean multiScreen,
+ boolean ignoreVertexColors,
+ int vcount,
+ int vformat,
+ int vdefined,
+ int coordIndex,
+ Object vcoords,
+ int colorIndex,
+ Object cdataBuffer,
+ float[] cfdata, byte[] cbdata,
+ int normalIndex, Object ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int[] vertexAttrIndex, Object[] vertexAttrData,
+ int pass, int texcoordmaplength,
+ int[] texcoordoffset,
+ int numActiveTexUnitState, int[] texunitstatemap,
+ int[] texIndex, int texstride, Object[] texCoords,
+ int cdirty);
// used by GeometryArray by Reference in interleaved format with NIO buffer
- native void executeInterleavedBuffer(long ctx,
- GeometryArrayRetained geo, int geo_type,
- boolean isNonUniformScale,
- boolean useAlpha,
- boolean multiScreen,
- boolean ignoreVertexColors,
- int startVIndex, int vcount, int vformat,
- int texCoordSetCount, int texCoordSetMap[],
- int texCoordSetMapLen,
- int[] texCoordSetOffset,
- int numActiveTexUnitState,
- int[] texUnitStateMap,
- Object varray, float[] cdata, int texUnitIndex, int cdirty);
-
-
-
- native void setVertexFormat(int vformat, boolean useAlpha,
- boolean ignoreVertexColors, long ctx);
- native void disableGlobalAlpha(long ctx, int vformat,
- boolean useAlpha,
- boolean ignoreVertexColors);
+ private native void executeInterleavedBuffer(long ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean multiScreen,
+ boolean ignoreVertexColors,
+ int startVIndex, int vcount, int vformat,
+ int texCoordSetCount, int texCoordSetMap[],
+ int texCoordSetMapLen,
+ int[] texCoordSetOffset,
+ int numActiveTexUnitState,
+ int[] texUnitStateMap,
+ Object varray, float[] cdata, int texUnitIndex, int cdirty);
+
+ private native void setVertexFormat(long ctx,
+ int vformat, boolean useAlpha, boolean ignoreVertexColors);
+
+ private native void disableGlobalAlpha(long ctx, int vformat,
+ boolean useAlpha, boolean ignoreVertexColors);
void setVertexFormat(boolean useAlpha, boolean ignoreVC, long ctx) {
- setVertexFormat(vertexFormat, useAlpha, ignoreVC, ctx);
+ setVertexFormat(ctx, vertexFormat, useAlpha, ignoreVC);
}
void disableGlobalAlpha(long ctx, boolean useAlpha, boolean ignoreVC) {
@@ -1628,6 +1745,12 @@ abstract class GeometryArrayRetained extends GeometryRetained{
return mirrorFloatRefColors[0];
}
+ // Issue 113
+ // TODO: Fix this for screen > 0, for now just ignore transparency
+ if (screen > 0) {
+ return mirrorFloatRefColors[0];
+ }
+
// update alpha only if vertex format includes alpha
if (((vertexFormat | c4fAllocated) & GeometryArray.WITH_ALPHA) == 0)
return mirrorFloatRefColors[0];
@@ -1796,6 +1919,12 @@ abstract class GeometryArrayRetained extends GeometryRetained{
return mirrorUnsignedByteRefColors[0];
}
+ // Issue 113
+ // TODO: Fix this for screen > 0, for now just ignore transparency
+ if (screen > 0) {
+ return mirrorUnsignedByteRefColors[0];
+ }
+
// update alpha only if vertex format includes alpha
if (((vertexFormat | c4fAllocated) & GeometryArray.WITH_ALPHA) == 0)
return mirrorUnsignedByteRefColors[0];
@@ -1951,6 +2080,13 @@ abstract class GeometryArrayRetained extends GeometryRetained{
return retVal;
}
+ // Issue 113
+ // TODO: Fix this for screen > 0, for now just ignore transparency
+ if (screen > 0) {
+ retVal[1] = vertexData;
+ return retVal;
+ }
+
// update alpha only if vertex format includes alpha
if ((vertexFormat & GeometryArray.COLOR) == 0) {
retVal[1] = vertexData;
@@ -1980,7 +2116,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
// allocate a copy of the vertex data for the screen if needed.
// this piece of code is mainly for multi-screens case
- // TODO: this might not too much data for just to update alpha
+ // NOTE: this might not too much data for just to update alpha
if (mvertexData == null || mvertexData.length <= screen) {
float[][] cfData = new float[screen + 1][];
@@ -2101,6 +2237,13 @@ abstract class GeometryArrayRetained extends GeometryRetained{
return retVal;
}
+ // Issue 113
+ // TODO: Fix this for screen > 0, for now just ignore transparency
+ if (screen > 0) {
+ retVal[1] = null;
+ return retVal;
+ }
+
// update alpha only if vertex format includes alpha
if (((vertexFormat | c4fAllocated) & GeometryArray.COLOR) == 0) {
retVal[1] = mirrorInterleavedColorPointer[0];
@@ -2131,7 +2274,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
// allocate a copy of the vertex data for the screen if needed.
// this piece of code is mainly for multi-screens case
- // TODO: this might not too much data for just to update alpha
+ // NOTE: this might not too much data for just to update alpha
if (mirrorInterleavedColorPointer.length <= screen) {
float[][] cfData = new float[screen + 1][];
@@ -2252,8 +2395,9 @@ abstract class GeometryArrayRetained extends GeometryRetained{
boolean useAlpha = false;
Object[] retVal;
+ // Check for by-copy case
if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0) {
- float[] vdata;
+ float[] vdata;
synchronized (this) {
cdirty = dirtyFlag;
@@ -2294,8 +2438,9 @@ abstract class GeometryArrayRetained extends GeometryRetained{
(texCoordSetMap == null) ? 0 : texCoordSetMap.length,
texCoordSetMapOffset,
cv.numActiveTexUnit, cv.texUnitStateMap,
- vdata, null,
- pass, cdirty);
+ vertexAttrCount, vertexAttrSizes,
+ vdata, null,
+ pass, cdirty);
}
//By reference with java array
@@ -2338,8 +2483,9 @@ abstract class GeometryArrayRetained extends GeometryRetained{
texCoordSetCount, texCoordSetMap,
(texCoordSetMap == null) ? 0 : texCoordSetMap.length,
texCoordSetMapOffset,
- cv.numActiveTexUnit, cv.texUnitStateMap,
- interLeavedVertexData, cdata,
+ cv.numActiveTexUnit, cv.texUnitStateMap,
+ vertexAttrCount, vertexAttrSizes,
+ interLeavedVertexData, cdata,
pass, cdirty);
} // end of interleaved case
@@ -2354,7 +2500,9 @@ abstract class GeometryArrayRetained extends GeometryRetained{
(((vertexFormat & GeometryArray.COLOR) != 0) &&
(vertexType & COLOR_DEFINED) == 0) ||
(((vertexFormat & GeometryArray.NORMALS) != 0) &&
- (vertexType & NORMAL_DEFINED) == 0) ||
+ (vertexType & NORMAL_DEFINED) == 0) ||
+ (((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) &&
+ (vertexType & VATTR_DEFINED) == 0) ||
(((vertexFormat& GeometryArray.TEXTURE_COORDINATE) != 0) &&
(vertexType & TEXCOORD_DEFINED) == 0)) {
return;
@@ -2419,6 +2567,8 @@ abstract class GeometryArrayRetained extends GeometryRetained{
vdefined |= COLOR_BYTE;
if((vertexType & NORMAL_DEFINED) != 0)
vdefined |= NORMAL_FLOAT;
+ if((vertexType & VATTR_DEFINED) != 0)
+ vdefined |= VATTR_FLOAT;
if((vertexType & TEXCOORD_DEFINED) != 0)
vdefined |= TEXCOORD_FLOAT;
@@ -2432,6 +2582,8 @@ abstract class GeometryArrayRetained extends GeometryRetained{
mirrorFloatRefCoords, mirrorDoubleRefCoords,
initialColorIndex, cfdata, cbdata,
initialNormalIndex, mirrorFloatRefNormals,
+ vertexAttrCount, vertexAttrSizes,
+ initialVertexAttrIndex, mirrorFloatRefVertexAttrs,
pass,
((texCoordSetMap == null) ? 0:texCoordSetMap.length),
texCoordSetMap,
@@ -2456,7 +2608,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
cdirty = dirtyFlag;
if (updateAlpha && !ignoreVertexColors) {
// update the alpha values
- // TODO: to handle alpha case
+ // XXXX: to handle alpha case
retVal = updateAlphaInInterLeavedData(cv, screen, alpha);
useAlpha = (retVal[0] == Boolean.TRUE);
cdata = (float[])retVal[1];
@@ -2466,7 +2618,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
cdirty |= COLOR_CHANGED;
}
} else {
- // TODO: to handle alpha case
+ // XXXX: to handle alpha case
cdata = null;
// if transparency switch between on/off
if (lastScreenAlpha != -1) {
@@ -2477,7 +2629,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
dirtyFlag = 0;
}
-
executeInterleavedBuffer(cv.ctx, this, geoType, isNonUniformScale,
useAlpha,
multiScreen,
@@ -2493,9 +2644,10 @@ abstract class GeometryArrayRetained extends GeometryRetained{
pass, cdirty);
} // end of interleaved case
-
+
// non interleaved data
else {
+
// Check if a vertexformat is set, but the array is null
// if yes, don't draw anything
if ((vertexType == 0) ||
@@ -2503,15 +2655,16 @@ abstract class GeometryArrayRetained extends GeometryRetained{
(((vertexFormat & GeometryArray.COLOR) != 0) &&
(vertexType & COLOR_DEFINED) == 0) ||
(((vertexFormat & GeometryArray.NORMALS) != 0) &&
- (vertexType & NORMAL_DEFINED) == 0) ||
+ (vertexType & NORMAL_DEFINED) == 0) ||
+ (((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) &&
+ (vertexType & VATTR_DEFINED) == 0) ||
(((vertexFormat& GeometryArray.TEXTURE_COORDINATE) != 0) &&
(vertexType & TEXCOORD_DEFINED) == 0)) {
return;
} else {
byte[] cbdata = null;
float[] cfdata = null;
-
-
+
if ((vertexType & CF ) != 0) {
synchronized (this) {
cdirty = dirtyFlag;
@@ -2523,7 +2676,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
cdirty |= COLOR_CHANGED;
}
} else {
- // TODO: handle transparency case
+ // XXXX: handle transparency case
//cfdata = null;
cfdata = mirrorFloatRefColors[0];
// if transparency switch between on/off
@@ -2547,7 +2700,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
cdirty |= COLOR_CHANGED;
}
} else {
- // TODO: handle transparency case
+ // XXXX: handle transparency case
//cbdata = null;
cbdata = mirrorUnsignedByteRefColors[0];
// if transparency switch between on/off
@@ -2585,9 +2738,13 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if((vertexType & NORMAL_DEFINED) != 0) {
vdefined |= NORMAL_FLOAT;
normal = floatBufferRefNormals.getBufferAsObject();
- }
+ }
- if((vertexType & TEXCOORD_DEFINED) != 0)
+ if ((vertexType & VATTR_DEFINED) != 0) {
+ vdefined |= VATTR_FLOAT;
+ }
+
+ if((vertexType & TEXCOORD_DEFINED) != 0)
vdefined |= TEXCOORD_FLOAT;
executeVABuffer(cv.ctx, this, geoType, isNonUniformScale,
@@ -2603,6 +2760,9 @@ abstract class GeometryArrayRetained extends GeometryRetained{
cfdata, cbdata,
initialNormalIndex,
normal,
+ vertexAttrCount, vertexAttrSizes,
+ initialVertexAttrIndex,
+ nioFloatBufferRefVertexAttrs,
pass,
((texCoordSetMap == null) ? 0:texCoordSetMap.length),
texCoordSetMap,
@@ -2616,60 +2776,68 @@ abstract class GeometryArrayRetained extends GeometryRetained{
}
// used for GeometryArrays
- native void buildGA(long ctx, GeometryArrayRetained geo, int geo_type,
- boolean isNonUniformScale, boolean updateAlpha,
- float alpha,
- boolean ignoreVertexColors,
- int startVIndex,
- int vcount, int vformat,
- int texCoordSetCount, int texCoordSetMap[],
- int texCoordSetMapLen,
- int[] texCoordSetMapOffset,
- double[] xform, double[] nxform,
- float[] varray);
-
- // used to Build Dlist GeometryArray by Reference with java arrays
- native void buildGAForByRef(long ctx,
- GeometryArrayRetained geo, int geo_type,
- boolean isNonUniformScale, boolean updateAlpha,
- float alpha,
- boolean ignoreVertexColors,
- int vcount,
- int vformat,
- int vdefined,
- int coordIndex, float[] vfcoords, double[] vdcoords,
- int colorIndex, float[] cfdata, byte[] cbdata,
- int normalIndex, float[] ndata,
- int texcoordmaplength,
- int[] texcoordoffset,
- int[] texIndex, int texstride, Object[] texCoords,
- double[] xform, double[] nxform);
-
-
- // used to Build Dlist GeometryArray by Reference with java arrays
- native void buildGAForBuffer(long ctx,
- GeometryArrayRetained geo, int geo_type,
- boolean isNonUniformScale, boolean updateAlpha,
- float alpha,
- boolean ignoreVertexColors,
- int vcount,
- int vformat,
- int vdefined,
- int coordIndex, Object vcoords,
- int colorIndex, Object cdata,
- int normalIndex, Object ndata,
- int texcoordmaplength,
- int[] texcoordoffset,
- int[] texIndex, int texstride, Object[] texCoords,
- double[] xform, double[] nxform);
-
-
+ private native void buildGA(long ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale, boolean updateAlpha,
+ float alpha,
+ boolean ignoreVertexColors,
+ int startVIndex,
+ int vcount, int vformat,
+ int texCoordSetCount, int texCoordSetMap[],
+ int texCoordSetMapLen, int[] texCoordSetMapOffset,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ double[] xform, double[] nxform,
+ float[] varray);
+
+ // used to Build Dlist GeometryArray by Reference with java arrays
+ private native void buildGAForByRef(long ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale, boolean updateAlpha,
+ float alpha,
+ boolean ignoreVertexColors,
+ int vcount,
+ int vformat,
+ int vdefined,
+ int coordIndex, float[] vfcoords, double[] vdcoords,
+ int colorIndex, float[] cfdata, byte[] cbdata,
+ int normalIndex, float[] ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int[] vertexAttrIndex, float[][] vertexAttrData,
+ int texcoordmaplength,
+ int[] texcoordoffset,
+ int[] texIndex, int texstride, Object[] texCoords,
+ double[] xform, double[] nxform);
+
+
+ // used to Build Dlist GeometryArray by Reference with NIO buffer
+ // NOTE: NIO buffers are no longer supported in display lists.
+ /*
+ private native void buildGAForBuffer(long ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale, boolean updateAlpha,
+ float alpha,
+ boolean ignoreVertexColors,
+ int vcount,
+ int vformat,
+ int vdefined,
+ int coordIndex, Object vcoords,
+ int colorIndex, Object cdata,
+ int normalIndex, Object ndata,
+ int texcoordmaplength,
+ int[] texcoordoffset,
+ int[] texIndex, int texstride, Object[] texCoords,
+ double[] xform, double[] nxform);
+ */
void buildGA(Canvas3D cv, RenderAtom ra, boolean isNonUniformScale,
boolean updateAlpha, float alpha, boolean ignoreVertexColors,
Transform3D xform, Transform3D nxform) {
- float[] vdata = null;
+
+ float[] vdata = null;
+
+ // NIO buffers are no longer supported in display lists
+ assert (vertexFormat & GeometryArray.USE_NIO_BUFFER) == 0;
if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0) {
vdata = vertexData;
@@ -2690,13 +2858,31 @@ abstract class GeometryArrayRetained extends GeometryRetained{
texCoordSetCount, texCoordSetMap,
(texCoordSetMap == null) ? 0 : texCoordSetMap.length,
texCoordSetMapOffset,
- (xform == null) ? null : xform.mat,
+ vertexAttrCount, vertexAttrSizes,
+ (xform == null) ? null : xform.mat,
(nxform == null) ? null : nxform.mat,
vdata);
}
else {
- // Either non-interleaved, by-ref or nio buffer
+ // Check if a vertexformat is set, but the array is null
+ // if yes, don't draw anything
+ if ((vertexType == 0) ||
+ ((vertexType & VERTEX_DEFINED) == 0) ||
+ (((vertexFormat & GeometryArray.COLOR) != 0) &&
+ (vertexType & COLOR_DEFINED) == 0) ||
+ (((vertexFormat & GeometryArray.NORMALS) != 0) &&
+ (vertexType & NORMAL_DEFINED) == 0) ||
+ (((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) &&
+ (vertexType & VATTR_DEFINED) == 0) ||
+ (((vertexFormat& GeometryArray.TEXTURE_COORDINATE) != 0) &&
+ (vertexType & TEXCOORD_DEFINED) == 0)) {
+
+ return;
+ }
+
+ // Either non-interleaved, by-ref or nio buffer
if ((vertexFormat & GeometryArray.USE_NIO_BUFFER) == 0) {
+ // Java array case
// setup vdefined to passed to native code
int vdefined = 0;
if((vertexType & (PF | P3F)) != 0)
@@ -2709,8 +2895,11 @@ abstract class GeometryArrayRetained extends GeometryRetained{
vdefined |= COLOR_BYTE;
if((vertexType & NORMAL_DEFINED) != 0)
vdefined |= NORMAL_FLOAT;
+ if((vertexType & VATTR_DEFINED) != 0)
+ vdefined |= VATTR_FLOAT;
if((vertexType & TEXCOORD_DEFINED) != 0)
vdefined |= TEXCOORD_FLOAT;
+
buildGAForByRef(cv.ctx, this, geoType, isNonUniformScale,
updateAlpha, alpha,
ignoreVertexColors,
@@ -2721,6 +2910,8 @@ abstract class GeometryArrayRetained extends GeometryRetained{
mirrorFloatRefCoords, mirrorDoubleRefCoords,
initialColorIndex, mirrorFloatRefColors[0], mirrorUnsignedByteRefColors[0],
initialNormalIndex, mirrorFloatRefNormals,
+ vertexAttrCount, vertexAttrSizes,
+ initialVertexAttrIndex, mirrorFloatRefVertexAttrs,
((texCoordSetMap == null) ? 0:texCoordSetMap.length),
texCoordSetMap,
initialTexCoordIndex,texCoordStride,
@@ -2728,50 +2919,60 @@ abstract class GeometryArrayRetained extends GeometryRetained{
(xform == null) ? null : xform.mat,
(nxform == null) ? null : nxform.mat);
}
+ /*
+ // NOTE: NIO buffers are no longer supported in display lists.
+ // This was never enabled by default anyway (only when the
+ // optimizeForSpace property was set to false), so it wasn't
+ // well-tested. If future support is desired, we will need to
+ // add vertex attributes to buildGAForBuffer. There are no plans
+ // to ever do this.
else {
- Object vcoord = null, cdataBuffer=null, normal=null;
-
- int vdefined = 0;
- if((vertexType & PF) != 0) {
- vdefined |= COORD_FLOAT;
- vcoord = floatBufferRefCoords.getBufferAsObject();
- } else if((vertexType & PD ) != 0) {
- vdefined |= COORD_DOUBLE;
- vcoord = doubleBufferRefCoords.getBufferAsObject();
- }
-
- if((vertexType & CF ) != 0) {
- vdefined |= COLOR_FLOAT;
- cdataBuffer = floatBufferRefColors.getBufferAsObject();
- } else if((vertexType & CUB) != 0) {
- vdefined |= COLOR_BYTE;
- cdataBuffer = byteBufferRefColors.getBufferAsObject();
- }
-
- if((vertexType & NORMAL_DEFINED) != 0) {
- vdefined |= NORMAL_FLOAT;
- normal = floatBufferRefNormals.getBufferAsObject();
- }
+ // NIO Buffer case
+ Object vcoord = null, cdataBuffer=null, normal=null;
+
+ int vdefined = 0;
+ if((vertexType & PF) != 0) {
+ vdefined |= COORD_FLOAT;
+ vcoord = floatBufferRefCoords.getBufferAsObject();
+ } else if((vertexType & PD ) != 0) {
+ vdefined |= COORD_DOUBLE;
+ vcoord = doubleBufferRefCoords.getBufferAsObject();
+ }
- if((vertexType & TEXCOORD_DEFINED) != 0)
- vdefined |= TEXCOORD_FLOAT;
- buildGAForBuffer(cv.ctx, this, geoType, isNonUniformScale,
- updateAlpha, alpha,
- ignoreVertexColors,
- validVertexCount,
- vertexFormat,
- vdefined,
- initialCoordIndex,
- vcoord,
- initialColorIndex,cdataBuffer,
- initialNormalIndex, normal,
- ((texCoordSetMap == null) ? 0:texCoordSetMap.length),
- texCoordSetMap,
- initialTexCoordIndex,texCoordStride,
- refTexCoords,
- (xform == null) ? null : xform.mat,
- (nxform == null) ? null : nxform.mat);
- }
+ if((vertexType & CF ) != 0) {
+ vdefined |= COLOR_FLOAT;
+ cdataBuffer = floatBufferRefColors.getBufferAsObject();
+ } else if((vertexType & CUB) != 0) {
+ vdefined |= COLOR_BYTE;
+ cdataBuffer = byteBufferRefColors.getBufferAsObject();
+ }
+
+ if((vertexType & NORMAL_DEFINED) != 0) {
+ vdefined |= NORMAL_FLOAT;
+ normal = floatBufferRefNormals.getBufferAsObject();
+ }
+
+ if((vertexType & TEXCOORD_DEFINED) != 0)
+ vdefined |= TEXCOORD_FLOAT;
+ // NOTE : need to add vertex attrs
+ buildGAForBuffer(cv.ctx, this, geoType, isNonUniformScale,
+ updateAlpha, alpha,
+ ignoreVertexColors,
+ validVertexCount,
+ vertexFormat,
+ vdefined,
+ initialCoordIndex,
+ vcoord,
+ initialColorIndex,cdataBuffer,
+ initialNormalIndex, normal,
+ ((texCoordSetMap == null) ? 0:texCoordSetMap.length),
+ texCoordSetMap,
+ initialTexCoordIndex,texCoordStride,
+ refTexCoords,
+ (xform == null) ? null : xform.mat,
+ (nxform == null) ? null : nxform.mat);
+ }
+ */
}
@@ -2786,8 +2987,10 @@ abstract class GeometryArrayRetained extends GeometryRetained{
}
}
- void unIndexifyJavaArray(IndexedGeometryArrayRetained src) {
- int vOffset = 0, srcOffset, tOffset = 0;
+ private void unIndexifyJavaArray(IndexedGeometryArrayRetained src) {
+// System.err.println("unIndexifyJavaArray");
+
+ int vOffset = 0, srcOffset, tOffset = 0;
int index, colorStride = 0;
float[] vdata = null;
int i;
@@ -2843,10 +3046,24 @@ abstract class GeometryArrayRetained extends GeometryRetained{
}
System.arraycopy(vdata,
- (((int[])src.indexTexCoord[i])[index])*src.stride + src.textureOffset + interleavedOffset,
+ (src.indexTexCoord[i][index])*src.stride + src.textureOffset + interleavedOffset,
vertexData, tcOffset, texCoordStride);
}
}
+
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ // vertex attributes can't be interleaved
+ assert (src.vertexFormat & GeometryArray.INTERLEAVED) == 0;
+
+ for (i = 0; i < vertexAttrCount; i++) {
+ int vaOffset = vOffset + vertexAttrOffsets[i];
+
+ System.arraycopy(vdata,
+ (src.indexVertexAttr[i][index])*src.stride + src.vertexAttrOffsets[i],
+ vertexData, vaOffset, vertexAttrSizes[i]);
+ }
+ }
+
if ((vertexFormat & GeometryArray.COORDINATES) != 0){
// System.out.println("===> copying coords");
System.arraycopy(vdata,
@@ -2859,7 +3076,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
}
} else {
- if ((vertexFormat & GeometryArray.NORMALS) != 0){
+ if ((vertexFormat & GeometryArray.NORMALS) != 0) {
vOffset = normalOffset;
switch ((src.vertexType & NORMAL_DEFINED)) {
case NF:
@@ -2884,7 +3101,8 @@ abstract class GeometryArrayRetained extends GeometryRetained{
break;
}
}
- if ((vertexFormat & GeometryArray.COLOR) != 0){
+
+ if ((vertexFormat & GeometryArray.COLOR) != 0) {
vOffset = colorOffset;
int multiplier = 3;
if ((src.vertexFormat & GeometryArray.WITH_ALPHA) != 0)
@@ -2968,6 +3186,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
break;
}
}
+
if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
vOffset = textureOffset;
switch ((src.vertexType & TEXCOORD_DEFINED)) {
@@ -2976,7 +3195,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
for (i = 0, tOffset = vOffset;
i < texCoordSetCount; i++) {
System.arraycopy(src.refTexCoords[i],
- ((int[])src.indexTexCoord[i])[index]*texCoordStride,
+ src.indexTexCoord[i][index]*texCoordStride,
vertexData, tOffset, texCoordStride);
tOffset += texCoordStride;
}
@@ -2987,7 +3206,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
for (index=start; index < end; index++) {
for (i = 0, tOffset = vOffset;
i < texCoordSetCount; i++) {
- srcOffset = ((int[])src.indexTexCoord[i])[index];
+ srcOffset = src.indexTexCoord[i][index];
vertexData[tOffset] =
((TexCoord2f[])src.refTexCoords[i])[srcOffset].x;
vertexData[tOffset+1] =
@@ -3001,7 +3220,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
for (index=start; index < end; index++) {
for (i = 0, tOffset = vOffset;
i < texCoordSetCount; i++) {
- srcOffset = ((int[])src.indexTexCoord[i])[index];
+ srcOffset = src.indexTexCoord[i][index];
vertexData[tOffset] =
((TexCoord3f[])src.refTexCoords[i])[srcOffset].x;
vertexData[tOffset+1] =
@@ -3016,8 +3235,26 @@ abstract class GeometryArrayRetained extends GeometryRetained{
default:
break;
}
- }
- if ((vertexFormat & GeometryArray.COORDINATES) != 0){
+ }
+
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ vOffset = 0;
+ switch (src.vertexType & VATTR_DEFINED) {
+ case AF:
+ for (index=start; index < end; index++) {
+ for (i = 0; i < vertexAttrCount; i++) {
+ int vaOffset = vOffset + vertexAttrOffsets[i];
+ System.arraycopy(src.floatRefVertexAttrs[i],
+ src.indexVertexAttr[i][index]*vertexAttrSizes[i],
+ vertexData, vaOffset, vertexAttrSizes[i]);
+ }
+ vOffset += stride;
+ }
+ break;
+ }
+ }
+
+ if ((vertexFormat & GeometryArray.COORDINATES) != 0) {
vOffset = coordinateOffset;
switch ((src.vertexType & VERTEX_DEFINED)) {
case PF:
@@ -3062,11 +3299,13 @@ abstract class GeometryArrayRetained extends GeometryRetained{
}
}
- }
+ }
+
+ private void unIndexifyNIOBuffer(IndexedGeometryArrayRetained src) {
+// System.err.println("unIndexifyNIOBuffer");
- void unIndexifyNIOBuffer(IndexedGeometryArrayRetained src) {
- int vOffset = 0, srcOffset, tOffset = 0;
+ int vOffset = 0, srcOffset, tOffset = 0;
int index, colorStride = 0;
float[] vdata = null;
int i;
@@ -3101,7 +3340,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
for (i = 0; i < texCoordSetCount;
i++, tcOffset += texCoordStride) {
- src.interleavedFloatBufferImpl.position((((int[])src.indexTexCoord[i])[index])*src.stride +
+ src.interleavedFloatBufferImpl.position((src.indexTexCoord[i][index])*src.stride +
src.textureOffset);
src.interleavedFloatBufferImpl.get(vertexData, tcOffset, texCoordStride);
}
@@ -3124,7 +3363,8 @@ abstract class GeometryArrayRetained extends GeometryRetained{
}
}
}
- if ((vertexFormat & GeometryArray.COLOR) != 0){
+
+ if ((vertexFormat & GeometryArray.COLOR) != 0){
vOffset = colorOffset;
int multiplier = 3;
if ((src.vertexFormat & GeometryArray.WITH_ALPHA) != 0)
@@ -3165,7 +3405,8 @@ abstract class GeometryArrayRetained extends GeometryRetained{
break;
}
}
- if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+
+ if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
vOffset = textureOffset;
FloatBufferWrapper texBuffer;
if ((src.vertexType & TEXCOORD_DEFINED) != 0) {
@@ -3173,15 +3414,31 @@ abstract class GeometryArrayRetained extends GeometryRetained{
for (i = 0, tOffset = vOffset;
i < texCoordSetCount; i++) {
texBuffer = (FloatBufferWrapper)(((J3DBuffer) (src.refTexCoordsBuffer[i])).getBufferImpl());
- texBuffer.position(((int[])src.indexTexCoord[i])[index]*texCoordStride);
+ texBuffer.position(src.indexTexCoord[i][index]*texCoordStride);
texBuffer.get(vertexData, tOffset, texCoordStride);
tOffset += texCoordStride;
}
vOffset += stride;
}
}
- }
- if ((vertexFormat & GeometryArray.COORDINATES) != 0){
+ }
+
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ vOffset = 0;
+ if ((src.vertexType & VATTR_DEFINED) == AF) {
+ for (index=start; index < end; index++) {
+ for (i = 0; i < vertexAttrCount; i++) {
+ int vaOffset = vOffset + vertexAttrOffsets[i];
+ FloatBufferWrapper vaBuffer = src.floatBufferRefVertexAttrs[i];
+ vaBuffer.position(src.indexVertexAttr[i][index]*vertexAttrSizes[i]);
+ vaBuffer.get(vertexData, vaOffset, vertexAttrSizes[i]);
+ }
+ vOffset += stride;
+ }
+ }
+ }
+
+ if ((vertexFormat & GeometryArray.COORDINATES) != 0){
vOffset = coordinateOffset;
switch ((src.vertexType & VERTEX_DEFINED)) {
case PF:
@@ -3206,7 +3463,8 @@ abstract class GeometryArrayRetained extends GeometryRetained{
}
}
- }
+ }
+
/**
* Returns the vertex stride in numbers of floats as a function
@@ -3250,6 +3508,11 @@ abstract class GeometryArrayRetained extends GeometryRetained{
stride += texCoordStride * texCoordSetCount;
}
+ if ((this.vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ stride += vertexAttrStride;
+ }
+
+ //System.err.println("stride() = " + stride);
return stride;
}
@@ -3270,6 +3533,61 @@ abstract class GeometryArrayRetained extends GeometryRetained{
}
/**
+ * Returns the stride of the set of vertex attributes. This is the
+ * sum of the sizes of each vertex attribute.
+ * @return the stride of the vertex attribute data
+ */
+ int vertexAttrStride() {
+ int sum = 0;
+ for (int i = 0; i < vertexAttrCount; i++) {
+ sum += vertexAttrSizes[i];
+ }
+ return sum;
+ }
+
+ /**
+ * Returns the offset in number of floats from the start of a vertex to
+ * each per-vertex vertex attribute.
+ * @return array of offsets in floats vertex start to the vertex attribute data
+ */
+ int[] vertexAttrOffsets() {
+ int[] offsets;
+
+ // Create array of offsets to the start of each vertex attribute.
+ // The offset of the first attribute is always 0. If no vertex attributes exist,
+ // then we will allocate an array of length 1 to avoid some checking elsewhere.
+ if (vertexAttrCount > 0) {
+ offsets = new int[vertexAttrCount];
+ }
+ else {
+ offsets = new int[1];
+ }
+ offsets[0] = 0;
+ for (int i = 1; i < vertexAttrCount; i++) {
+ offsets[i] = offsets[i-1] + vertexAttrSizes[i-1];
+ }
+
+ return offsets;
+ }
+
+ /**
+ * Returns the offset in number of floats from the start of a vertex to
+ * the per-vertex texture coordinate data.
+ * texture coordinate data always follows vertex attribute data
+ * @return the offset in floats vertex start to the tetxure data
+ */
+ int textureOffset()
+ {
+ int offset = vertexAttrOffsets[0];
+
+ if ((this.vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ offset += vertexAttrStride;
+ }
+
+ return offset;
+ }
+
+ /**
* Returns the offset in number of floats from the start of a vertex to
* the per-vertex color data.
* color data always follows texture data
@@ -3344,6 +3662,32 @@ abstract class GeometryArrayRetained extends GeometryRetained{
return vertexFormat;
}
+ /**
+ * Retrieves the number of vertex attributes in this GeometryArray
+ * object.
+ *
+ * @return the number of vertex attributes in this GeometryArray
+ * object
+ */
+ int getVertexAttrCount() {
+ return vertexAttrCount;
+ }
+
+
+ /**
+ * Retrieves the vertex attribute sizes array from this
+ * GeometryArray object.
+ *
+ * @param vertexAttrSizes an array that will receive a copy of
+ * the vertex attribute sizes array. The array must hold at least
+ * <code>vertexAttrCount</code> elements.
+ */
+ void getVertexAttrSizes(int[] vertexAttrSizes) {
+ for (int i = 0; i < vertexAttrCount; i++) {
+ vertexAttrSizes[i] = this.vertexAttrSizes[i];
+ }
+ }
+
void sendDataChangedMessage(boolean coordinatesChanged) {
@@ -3360,7 +3704,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
// Send a message to renderBin to rebuild the display list or
// process the vertex array accordingly
- // TODO: Should I send one per universe, isn't display list
+ // XXXX: Should I send one per universe, isn't display list
// shared by all context/universes?
int threads = J3dThread.UPDATE_RENDER;
// If the geometry type is Indexed then we need to clone the geometry
@@ -4890,7 +5234,259 @@ abstract class GeometryArrayRetained extends GeometryRetained{
geomLock.unLock();
sendDataChangedMessage(false);
- }
+ }
+
+
+ /**
+ * Sets the vertex attribute associated with the vertex at the
+ * specified index in the specified vertex attribute number for
+ * this object.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index destination vertex index in this geometry array
+ * @param vertexAttr the Point2f containing the new vertex attribute
+ */
+ void setVertexAttr(int vertexAttrNum, int index,
+ Point2f vertexAttr) {
+
+ int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum];
+
+ geomLock.getLock();
+ dirtyFlag |= VATTR_CHANGED;
+
+ this.vertexData[offset] = vertexAttr.x;
+ this.vertexData[offset+1] = vertexAttr.y;
+
+ if (source == null || !source.isLive()) {
+ geomLock.unLock();
+ return;
+ }
+
+ geomLock.unLock();
+ sendDataChangedMessage(false);
+ }
+
+ /**
+ * Sets the vertex attribute associated with the vertex at the
+ * specified index in the specified vertex attribute number for
+ * this object.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index destination vertex index in this geometry array
+ * @param vertexAttr the Point3f containing the new vertex attribute
+ */
+ void setVertexAttr(int vertexAttrNum, int index,
+ Point3f vertexAttr) {
+
+ int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum];
+
+ geomLock.getLock();
+ dirtyFlag |= VATTR_CHANGED;
+
+ this.vertexData[offset] = vertexAttr.x;
+ this.vertexData[offset+1] = vertexAttr.y;
+ this.vertexData[offset+2] = vertexAttr.z;
+
+ if (source == null || !source.isLive()) {
+ geomLock.unLock();
+ return;
+ }
+
+ geomLock.unLock();
+ sendDataChangedMessage(false);
+ }
+
+ /**
+ * Sets the vertex attribute associated with the vertex at the
+ * specified index in the specified vertex attribute number for
+ * this object.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index destination vertex index in this geometry array
+ * @param vertexAttr the Point4f containing the new vertex attribute
+ */
+ void setVertexAttr(int vertexAttrNum, int index,
+ Point4f vertexAttr) {
+
+ int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum];
+
+ geomLock.getLock();
+ dirtyFlag |= VATTR_CHANGED;
+
+ this.vertexData[offset] = vertexAttr.x;
+ this.vertexData[offset+1] = vertexAttr.y;
+ this.vertexData[offset+2] = vertexAttr.z;
+ this.vertexData[offset+3] = vertexAttr.w;
+
+ if (source == null || !source.isLive()) {
+ geomLock.unLock();
+ return;
+ }
+
+ geomLock.unLock();
+ sendDataChangedMessage(false);
+ }
+
+ /**
+ * Sets the vertex attributes associated with the vertices
+ * starting at the specified index in the specified vertex
+ * attribute number for this object using data in
+ * <code>vertexAttrs</code> starting at index <code>start</code> and
+ * ending at index <code>start+length</code>.
+ *
+ * @param index starting destination vertex index in this geometry array
+ * @param vertexAttrs source array of 1*n, 2*n, 3*n, or 4*n values
+ * containing n new vertex attributes
+ * @param start starting source vertex index in <code>vertexAttrs</code>
+ * array.
+ * @param length number of vertex attributes to be copied.
+ */
+ void setVertexAttrs(int vertexAttrNum, int index,
+ float[] vertexAttrs,
+ int start, int length) {
+
+ int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum];
+ int size = vertexAttrSizes[vertexAttrNum];
+ int i, j, k;
+
+ geomLock.getLock();
+ dirtyFlag |= VATTR_CHANGED;
+
+ for (i = start * size, j = offset, k = 0; k < length; i += size, j += this.stride, k++) {
+ for (int ii = 0; ii < size; ii++) {
+ this.vertexData[j+ii] = vertexAttrs[i+ii];
+ }
+ }
+
+ if (source == null || !source.isLive()) {
+ geomLock.unLock();
+ return;
+ }
+
+ geomLock.unLock();
+ sendDataChangedMessage(false);
+ }
+
+ /**
+ * Sets the vertex attributes associated with the vertices
+ * starting at the specified index in the specified vertex
+ * attribute number for this object using data in
+ * <code>vertexAttrs</code> starting at index <code>start</code> and
+ * ending at index <code>start+length</code>.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index starting destination vertex index in this geometry array
+ * @param vertexAttrs source array of Point2f objects containing new
+ * vertex attributes
+ * @param start starting source vertex index in <code>vertexAttrs</code>
+ * array.
+ * @param length number of vertex attributes to be copied.
+ */
+ void setVertexAttrs(int vertexAttrNum, int index,
+ Point2f[] vertexAttrs,
+ int start, int length) {
+
+ int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum];
+ int i, j, k;
+
+ geomLock.getLock();
+ dirtyFlag |= VATTR_CHANGED;
+
+ for (i = start, j = offset, k = 0; k < length; i++, j += this.stride, k++) {
+ this.vertexData[j] = vertexAttrs[i].x;
+ this.vertexData[j+1] = vertexAttrs[i].y;
+ }
+
+ if (source == null || !source.isLive()) {
+ geomLock.unLock();
+ return;
+ }
+
+ geomLock.unLock();
+ sendDataChangedMessage(false);
+ }
+
+ /**
+ * Sets the vertex attributes associated with the vertices
+ * starting at the specified index in the specified vertex
+ * attribute number for this object using data in
+ * <code>vertexAttrs</code> starting at index <code>start</code> and
+ * ending at index <code>start+length</code>.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index starting destination vertex index in this geometry array
+ * @param vertexAttrs source array of Point3f objects containing new
+ * vertex attributes
+ * @param start starting source vertex index in <code>vertexAttrs</code>
+ * array.
+ * @param length number of vertex attributes to be copied.
+ */
+ void setVertexAttrs(int vertexAttrNum, int index,
+ Point3f[] vertexAttrs,
+ int start, int length) {
+
+ int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum];
+ int i, j, k;
+
+ geomLock.getLock();
+ dirtyFlag |= VATTR_CHANGED;
+
+ for (i = start, j = offset, k = 0; k < length; i++, j += this.stride, k++) {
+ this.vertexData[j] = vertexAttrs[i].x;
+ this.vertexData[j+1] = vertexAttrs[i].y;
+ this.vertexData[j+2] = vertexAttrs[i].z;
+ }
+
+ if (source == null || !source.isLive()) {
+ geomLock.unLock();
+ return;
+ }
+
+ geomLock.unLock();
+ sendDataChangedMessage(false);
+ }
+
+ /**
+ * Sets the vertex attributes associated with the vertices
+ * starting at the specified index in the specified vertex
+ * attribute number for this object using data in
+ * <code>vertexAttrs</code> starting at index <code>start</code> and
+ * ending at index <code>start+length</code>.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index starting destination vertex index in this geometry array
+ * @param vertexAttrs source array of Point4f objects containing new
+ * vertex attributes
+ * @param start starting source vertex index in <code>vertexAttrs</code>
+ * array.
+ * @param length number of vertex attributes to be copied.
+ */
+ void setVertexAttrs(int vertexAttrNum, int index,
+ Point4f[] vertexAttrs,
+ int start, int length) {
+
+ int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum];
+ int i, j, k;
+
+ geomLock.getLock();
+ dirtyFlag |= VATTR_CHANGED;
+
+ for (i = start, j = offset, k = 0; k < length; i++, j += this.stride, k++) {
+ this.vertexData[j] = vertexAttrs[i].x;
+ this.vertexData[j+1] = vertexAttrs[i].y;
+ this.vertexData[j+2] = vertexAttrs[i].z;
+ this.vertexData[j+3] = vertexAttrs[i].w;
+ }
+
+ if (source == null || !source.isLive()) {
+ geomLock.unLock();
+ return;
+ }
+
+ geomLock.unLock();
+ sendDataChangedMessage(false);
+ }
+
/**
* Gets the coordinate associated with the vertex at
@@ -5505,6 +6101,158 @@ abstract class GeometryArrayRetained extends GeometryRetained{
/**
+ * Gets the vertex attribute associated with the vertex at
+ * the specified index in the specified vertex attribute number
+ * for this object.
+ */
+ public void getVertexAttr(int vertexAttrNum, int index,
+ float[] vertexAttr) {
+
+ int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum];
+ int size = vertexAttrSizes[vertexAttrNum];
+
+ for (int i = 0; i < size; i++) {
+ vertexAttr[i] = this.vertexData[offset+i];
+
+ }
+
+ }
+
+ /**
+ * Gets the vertex attribute associated with the vertex at
+ * the specified index in the specified vertex attribute number
+ * for this object.
+ */
+ public void getVertexAttr(int vertexAttrNum, int index,
+ Point2f vertexAttr) {
+
+ int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum];
+
+ vertexAttr.x = this.vertexData[offset];
+ vertexAttr.y = this.vertexData[offset+1];
+
+ }
+
+ /**
+ * Gets the vertex attribute associated with the vertex at
+ * the specified index in the specified vertex attribute number
+ * for this object.
+ */
+ public void getVertexAttr(int vertexAttrNum, int index,
+ Point3f vertexAttr) {
+
+ int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum];
+
+ vertexAttr.x = this.vertexData[offset];
+ vertexAttr.y = this.vertexData[offset+1];
+ vertexAttr.z = this.vertexData[offset+2];
+
+ }
+
+ /**
+ * Gets the vertex attribute associated with the vertex at
+ * the specified index in the specified vertex attribute number
+ * for this object.
+ */
+ public void getVertexAttr(int vertexAttrNum, int index,
+ Point4f vertexAttr) {
+
+ int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum];
+
+ vertexAttr.x = this.vertexData[offset];
+ vertexAttr.y = this.vertexData[offset+1];
+ vertexAttr.z = this.vertexData[offset+2];
+ vertexAttr.w = this.vertexData[offset+3];
+
+ }
+
+ /**
+ * Gets the vertex attributes associated with the vertices starting at
+ * the specified index in the specified vertex attribute number
+ * for this object.
+ */
+ public void getVertexAttrs(int vertexAttrNum, int index,
+ float[] vertexAttrs) {
+
+ int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum];
+ int size = vertexAttrSizes[vertexAttrNum];
+ int i, j, k;
+
+ for (i = 0, j = offset;
+ ((i < vertexAttrs.length) && (j < this.vertexData.length)) ;
+ i += size, j += this.stride) {
+ for (k = 0; k < size; k++) {
+ vertexAttrs[i+k] = this.vertexData[j+k];
+ }
+ }
+
+ }
+
+ /**
+ * Gets the vertex attributes associated with the vertices starting at
+ * the specified index in the specified vertex attribute number
+ * for this object.
+ */
+ public void getVertexAttrs(int vertexAttrNum, int index,
+ Point2f[] vertexAttrs) {
+
+ int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum];
+ int i, j;
+
+ for (i = 0, j = offset;
+ ((i < vertexAttrs.length) && (j < this.vertexData.length)) ;
+ i++, j += this.stride) {
+ vertexAttrs[i].x = this.vertexData[j];
+ vertexAttrs[i].y = this.vertexData[j+1];
+ }
+
+ }
+
+ /**
+ * Gets the vertex attributes associated with the vertices starting at
+ * the specified index in the specified vertex attribute number
+ * for this object.
+ */
+ public void getVertexAttrs(int vertexAttrNum, int index,
+ Point3f[] vertexAttrs) {
+
+ int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum];
+ int i, j;
+
+ for (i = 0, j = offset;
+ ((i < vertexAttrs.length) && (j < this.vertexData.length)) ;
+ i++, j += this.stride) {
+ vertexAttrs[i].x = this.vertexData[j];
+ vertexAttrs[i].y = this.vertexData[j+1];
+ vertexAttrs[i].z = this.vertexData[j+2];
+ }
+
+ }
+
+ /**
+ * Gets the vertex attributes associated with the vertices starting at
+ * the specified index in the specified vertex attribute number
+ * for this object.
+ */
+ public void getVertexAttrs(int vertexAttrNum, int index,
+ Point4f[] vertexAttrs) {
+
+ int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum];
+ int i, j;
+
+ for (i = 0, j = offset;
+ ((i < vertexAttrs.length) && (j < this.vertexData.length)) ;
+ i++, j += this.stride) {
+ vertexAttrs[i].x = this.vertexData[j];
+ vertexAttrs[i].y = this.vertexData[j+1];
+ vertexAttrs[i].z = this.vertexData[j+2];
+ vertexAttrs[i].w = this.vertexData[j+3];
+ }
+
+ }
+
+
+ /**
* Updates geometry array data.
*/
void updateData(GeometryUpdater updater) {
@@ -5519,7 +6267,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
inUpdater = false;
if ((vertexFormat & GeometryArray.BY_REFERENCE) != 0) {
if((vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0) {
- // TODO: handle the nio buffer
+ // XXXX: handle the nio buffer
if (!(this instanceof IndexedGeometryArrayRetained) ||
(vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) != 0) {
if (((vertexFormat & GeometryArray.INTERLEAVED) != 0)) {
@@ -5540,10 +6288,11 @@ abstract class GeometryArrayRetained extends GeometryRetained{
nullGeo = (interLeavedVertexData == null);
}
else {
- setupMirrorVertexPointer((vertexType & VERTEX_DEFINED));
+ setupMirrorVertexPointer(vertexType & VERTEX_DEFINED);
setupMirrorColorPointer((vertexType & COLOR_DEFINED), false);
- setupMirrorNormalPointer((vertexType & NORMAL_DEFINED));
- setupMirrorTexCoordPointer((vertexType & TEXCOORD_DEFINED));
+ setupMirrorNormalPointer(vertexType & NORMAL_DEFINED);
+ setupMirrorTexCoordPointer(texCoordType);
+ setupMirrorVertexAttrPointer(vertexAttrType);
nullGeo = ((vertexType & GeometryArrayRetained.VERTEX_DEFINED) == 0);
}
}
@@ -7254,7 +8003,12 @@ abstract class GeometryArrayRetained extends GeometryRetained{
direction.z = end.z - start.z;
result = intersectRayOrSegment(coordinates, direction, start, dist, iPnt, true);
freeVector3d(direction);
- return result;
+ if((result == true) && (dist[0] <= 1.0)) {
+ return true;
+ }
+
+ return false;
+
}
@@ -7435,7 +8189,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
// Note that by next round sign*lastSign = 0 so it will
// not pass the interest test. This should only happen once in the
// loop because we already check for degenerate geometry before.
- lastSign = 0;
}
}
}
@@ -7467,7 +8220,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
isIntersect = ((t > -EPS) && (t < 1+EPS));
break;
} else {
- lastSign = 0; //degenerate line=>point
+ //degenerate line=>point
}
}
}
@@ -7499,7 +8252,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
isIntersect = ((t > -EPS) && (t < 1+EPS));
break;
} else {
- lastSign = 0; //degenerate line=>point
+ //degenerate line=>point
}
}
}
@@ -7529,7 +8282,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
isIntersect = ((t > -EPS) && (t < 1+EPS));
break;
} else {
- lastSign = 0; //degenerate line=>point
+ //degenerate line=>point
}
}
}
@@ -8036,18 +8789,10 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if (coords != null) {
switch (coords.getBufferType()) {
case J3DBuffer.TYPE_FLOAT:
- if ( !((FloatBufferWrapper)coords.getBufferImpl()).isDirect())
- throw new IllegalArgumentException(J3dI18N.getString("GeometryArray120"));
-
- // TODO: may need to check whether it is direct and if so,
- // whether it is consistent with native byte order
+ assert ((FloatBufferWrapper)coords.getBufferImpl()).isDirect();
break;
case J3DBuffer.TYPE_DOUBLE:
- if ( !((DoubleBufferWrapper)coords.getBufferImpl()).isDirect())
- throw new IllegalArgumentException(J3dI18N.getString("GeometryArray120"));
-
- // TODO: may need to check whether it is direct and if so,
- // whether it is consistent with native byte order
+ assert ((DoubleBufferWrapper)coords.getBufferImpl()).isDirect();
break;
case J3DBuffer.TYPE_NULL:
throw new IllegalArgumentException(J3dI18N.getString("GeometryArray115"));
@@ -8066,7 +8811,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
}
}
- //throw new RuntimeException("method not implemeted");
// lock the geometry and start to do real work
geomLock.getLock();
dirtyFlag |= COORDINATE_CHANGED;
@@ -8074,7 +8818,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if(coords == null) {
floatBufferRefCoords = null;
doubleBufferRefCoords = null;
- // TODO: if not mix java array with nio buffer
+ // XXXX: if not mix java array with nio buffer
// vertexType can be used as vertexTypeBuffer
vertexType &= ~PD;
vertexType &= ~PF;
@@ -8101,7 +8845,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
// need not call setupMirrorVertexPointer() since
// we are not going to set mirror in NIO buffer case
- // TODO: if we need to mix java array with buffer,
+ // XXXX: if we need to mix java array with buffer,
// we may need to consider setupMirrorVertexPointer()
geomLock.unLock();
@@ -8375,12 +9119,10 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if (colors != null) {
switch(colors.getBufferType()) {
case J3DBuffer.TYPE_FLOAT:
- if ( !((FloatBufferWrapper)colors.getBufferImpl()).isDirect())
- throw new IllegalArgumentException(J3dI18N.getString("GeometryArray120"));
+ assert ((FloatBufferWrapper)colors.getBufferImpl()).isDirect();
break;
case J3DBuffer.TYPE_BYTE:
- if ( !((ByteBufferWrapper)colors.getBufferImpl()).isDirect())
- throw new IllegalArgumentException(J3dI18N.getString("GeometryArray120"));
+ assert ((ByteBufferWrapper)colors.getBufferImpl()).isDirect();
break;
case J3DBuffer.TYPE_NULL:
throw new IllegalArgumentException(J3dI18N.getString("GeometryArray115"));
@@ -8759,8 +9501,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
bufferImpl = (FloatBufferWrapper)normals.getBufferImpl();
- if ( ! bufferImpl.isDirect())
- throw new IllegalArgumentException(J3dI18N.getString("GeometryArray120"));
+ assert bufferImpl.isDirect();
if ((vertexFormat & GeometryArray.NORMALS) == 0) {
throw new IllegalStateException(J3dI18N.getString("GeometryArray122"));
@@ -8863,15 +9604,17 @@ abstract class GeometryArrayRetained extends GeometryRetained{
void setTexCoordRefFloat(int texCoordSet, float[] texCoords) {
- if (texCoords != null) {
+ if (texCoordType != 0 && texCoordType != TF) {
+ if (texCoords != null) {
+ throw new IllegalArgumentException(
+ J3dI18N.getString("GeometryArray98"));
+ }
+ return;
+ }
- if ((vertexType & TEXCOORD_DEFINED) != 0 &&
- (vertexType & TEXCOORD_DEFINED) != TF) {
- throw new IllegalArgumentException(
- J3dI18N.getString("GeometryArray98"));
- }
+ if (texCoords != null) {
- int ts = getTexStride();
+ int ts = getTexStride();
if (this instanceof IndexedGeometryArrayRetained) {
IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this;
@@ -8889,10 +9632,8 @@ abstract class GeometryArrayRetained extends GeometryRetained{
refTexCoords[texCoordSet] = texCoords;
if (inUpdater || (this instanceof IndexedGeometryArrayRetained &&
((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0))) {
- if (texCoords == null)
- vertexType &= ~TF;
- else
- vertexType |= TF;
+ texCoordType = TF;
+ validateTexCoordPointerType();
}
else {
setupMirrorTexCoordPointer(texCoordSet, TF);
@@ -8903,8 +9644,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
}
}
-
-
+
float[] getTexCoordRefFloat(int texCoordSet) {
return ((float[])refTexCoords[texCoordSet]);
}
@@ -8921,8 +9661,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
bufferImpl = (FloatBufferWrapper)texCoords.getBufferImpl();
int bufferSize = bufferImpl.limit();
- if ( ! bufferImpl.isDirect())
- throw new IllegalArgumentException(J3dI18N.getString("GeometryArray120"));
+ assert bufferImpl.isDirect();
int ts = getTexStride();
@@ -8941,14 +9680,14 @@ abstract class GeometryArrayRetained extends GeometryRetained{
// refTexCoordsBuffer contains J3DBuffer object for tex coord
refTexCoordsBuffer[texCoordSet] = texCoords;
if (texCoords == null) {
- vertexType &= ~TF;
refTexCoords[texCoordSet] = null;
}
else {
- vertexType |= TF;
// refTexCoords contains NIOBuffer object for tex coord
refTexCoords[texCoordSet] = bufferImpl.getBufferAsObject();
}
+ texCoordType = TF;
+ validateTexCoordPointerType();
geomLock.unLock();
if (!inUpdater && source != null && source.isLive()) {
sendDataChangedMessage(false);
@@ -8961,13 +9700,15 @@ abstract class GeometryArrayRetained extends GeometryRetained{
void setTexCoordRef2f(int texCoordSet, TexCoord2f[] texCoords) {
- if (texCoords != null) {
- if ((vertexType & TEXCOORD_DEFINED) != 0 &&
- (vertexType & TEXCOORD_DEFINED) != T2F) {
- throw new IllegalArgumentException(
- J3dI18N.getString("GeometryArray98"));
- }
-
+ if (texCoordType != 0 && texCoordType != T2F) {
+ if (texCoords != null) {
+ throw new IllegalArgumentException(
+ J3dI18N.getString("GeometryArray98"));
+ }
+ return;
+ }
+
+ if (texCoords != null) {
if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_2) == 0) {
throw new IllegalStateException(
J3dI18N.getString("GeometryArray94"));
@@ -8990,13 +9731,11 @@ abstract class GeometryArrayRetained extends GeometryRetained{
refTexCoords[texCoordSet] = texCoords;
if (inUpdater || (this instanceof IndexedGeometryArrayRetained &&
((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0))) {
- if (texCoords == null)
- vertexType &= ~T2F;
- else
- vertexType |= T2F;
+ texCoordType = T2F;
+ validateTexCoordPointerType();
}
else {
- setupMirrorTexCoordPointer(T2F);
+ setupMirrorTexCoordPointer(texCoordSet, T2F);
}
geomLock.unLock();
if (!inUpdater && source != null && source.isLive()) {
@@ -9017,14 +9756,16 @@ abstract class GeometryArrayRetained extends GeometryRetained{
void setTexCoordRef3f(int texCoordSet, TexCoord3f[] texCoords) {
+ if (texCoordType != 0 && texCoordType != T3F) {
+ if (texCoords != null) {
+ throw new IllegalArgumentException(
+ J3dI18N.getString("GeometryArray98"));
+ }
+ return;
+ }
+
if (texCoords != null) {
- if ((vertexType & TEXCOORD_DEFINED) != 0 &&
- (vertexType & TEXCOORD_DEFINED) != T3F) {
- throw new IllegalArgumentException(
- J3dI18N.getString("GeometryArray98"));
- }
-
if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_3) == 0) {
throw new IllegalStateException(
J3dI18N.getString("GeometryArray95"));
@@ -9048,13 +9789,11 @@ abstract class GeometryArrayRetained extends GeometryRetained{
refTexCoords[texCoordSet] = texCoords;
if (inUpdater || (this instanceof IndexedGeometryArrayRetained &&
((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0))) {
- if (texCoords == null)
- vertexType &= ~T3F;
- else
- vertexType |= T3F;
+ texCoordType = T3F;
+ validateTexCoordPointerType();
}
else {
- setupMirrorTexCoordPointer(T3F);
+ setupMirrorTexCoordPointer(texCoordSet, T3F);
}
geomLock.unLock();
if (!inUpdater && source != null && source.isLive()) {
@@ -9073,6 +9812,125 @@ abstract class GeometryArrayRetained extends GeometryRetained{
}
+ /**
+ * Sets the float vertex attribute array reference for the
+ * specified vertex attribute number to the specified array.
+ */
+ void setVertexAttrRefFloat(int vertexAttrNum, float[] vertexAttrs) {
+
+ // XXXX: Add the following test if we ever add double-precision types
+ /*
+ if (vertexAttrType != 0 && vertexAttrType != AF) {
+ if (vertexAttrs != null) {
+ // XXXX: new exception string
+ throw new IllegalArgumentException(
+ J3dI18N.getString("GeometryArray98-XXX"));
+ }
+ return;
+ }
+ */
+
+ if (vertexAttrs != null) {
+ int sz = vertexAttrSizes[vertexAttrNum];
+
+ if (this instanceof IndexedGeometryArrayRetained) {
+ IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this;
+
+ if (sz*idx.maxVertexAttrIndices[vertexAttrNum] >= vertexAttrs.length) {
+ throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray30"));
+ }
+
+ } else if (vertexAttrs.length < sz*(initialVertexAttrIndex[vertexAttrNum] + validVertexCount) ) {
+ throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray129"));
+ }
+ }
+
+ geomLock.getLock();
+ dirtyFlag |= VATTR_CHANGED;
+ floatRefVertexAttrs[vertexAttrNum] = vertexAttrs;
+ if (inUpdater || (this instanceof IndexedGeometryArrayRetained &&
+ ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0))) {
+ vertexAttrType = AF;
+ validateVertexAttrPointerType();
+ }
+ else {
+ setupMirrorVertexAttrPointer(vertexAttrNum, AF);
+ }
+ geomLock.unLock();
+ if (!inUpdater && source != null && source.isLive()) {
+ sendDataChangedMessage(false);
+ }
+ }
+
+ /**
+ * Gets the float vertex attribute array reference for the specified
+ * vertex attribute number.
+ */
+ float[] getVertexAttrRefFloat(int vertexAttrNum) {
+ return floatRefVertexAttrs[vertexAttrNum];
+ }
+
+
+ /**
+ * Sets the vertex attribute buffer reference for the specified
+ * vertex attribute number to the specified buffer object.
+ */
+ void setVertexAttrRefBuffer(int vertexAttrNum, J3DBuffer vertexAttrs) {
+
+ FloatBufferWrapper bufferImpl = null;
+
+ if (vertexAttrs != null) {
+ if(vertexAttrs.getBufferType() != J3DBuffer.TYPE_FLOAT)
+ throw new IllegalArgumentException(J3dI18N.getString("GeometryArray116"));
+
+ bufferImpl = (FloatBufferWrapper)vertexAttrs.getBufferImpl();
+ int bufferSize = bufferImpl.limit();
+
+ assert bufferImpl.isDirect();
+
+ int sz = vertexAttrSizes[vertexAttrNum];
+
+ if (this instanceof IndexedGeometryArrayRetained) {
+ IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this;
+
+ if (idx.maxVertexAttrIndices[vertexAttrNum] * sz >= bufferSize) {
+ throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray30"));
+ }
+ } else if (bufferSize < sz*(initialVertexAttrIndex[vertexAttrNum] + validVertexCount)) {
+ throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray129"));
+ }
+ }
+
+ geomLock.getLock();
+ dirtyFlag |= VATTR_CHANGED;
+ vertexAttrsRefBuffer[vertexAttrNum] = vertexAttrs;
+ if (vertexAttrs == null) {
+ floatBufferRefVertexAttrs[vertexAttrNum] = null;
+ nioFloatBufferRefVertexAttrs[vertexAttrNum] = null;
+ }
+ else {
+ floatBufferRefVertexAttrs[vertexAttrNum] = bufferImpl;
+ nioFloatBufferRefVertexAttrs[vertexAttrNum] =
+ bufferImpl.getBufferAsObject();
+ }
+ vertexAttrType = AF;
+ validateVertexAttrPointerType();
+ geomLock.unLock();
+ if (!inUpdater && source != null && source.isLive()) {
+ sendDataChangedMessage(false);
+ }
+
+ }
+
+ /**
+ * Gets the vertex attribute array buffer reference for the specified
+ * vertex attribute number.
+ */
+ J3DBuffer getVertexAttrRefBuffer(int vertexAttrNum) {
+ return vertexAttrsRefBuffer[vertexAttrNum];
+ }
+
+
void setInterleavedVertices(float[] vertexData) {
if (vertexData != null) {
@@ -9135,10 +9993,9 @@ abstract class GeometryArrayRetained extends GeometryRetained{
throw new IllegalArgumentException(J3dI18N.getString("GeometryArray116"));
bufferImpl = (FloatBufferWrapper)vertexData.getBufferImpl();
-
- if (!bufferImpl.isDirect())
- throw new IllegalArgumentException(J3dI18N.getString("GeometryArray120"));
-
+
+ assert bufferImpl.isDirect();
+
int bufferSize = bufferImpl.limit();
if (this instanceof IndexedGeometryArrayRetained) {
@@ -9203,37 +10060,20 @@ abstract class GeometryArrayRetained extends GeometryRetained{
}
void setValidVertexCount(int validVertexCount) {
+
boolean nullGeo = false;
if (validVertexCount < 0) {
throw new IllegalArgumentException(J3dI18N.getString("GeometryArray110"));
}
- if ((initialVertexIndex + validVertexCount) > vertexCount) {
- throw new IllegalArgumentException(J3dI18N.getString("GeometryArray100"));
- }
- else if ((initialCoordIndex + validVertexCount) > vertexCount) {
- throw new IllegalArgumentException(J3dI18N.getString("GeometryArray104"));
- }
- else if ((initialColorIndex + validVertexCount) > vertexCount) {
- throw new IllegalArgumentException(J3dI18N.getString("GeometryArray101"));
- }
- else if ((initialNormalIndex + validVertexCount) > vertexCount) {
- throw new IllegalArgumentException(J3dI18N.getString("GeometryArray102"));
- }
- else {
- if ((vertexFormat & (GeometryArray.BY_REFERENCE|vertexFormat &GeometryArray.INTERLEAVED)) == GeometryArray.BY_REFERENCE) {
- if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
- for (int i = 0; i < texCoordSetCount; i++) {
- if ((initialTexCoordIndex[i] + validVertexCount)
- > vertexCount) {
- throw new IllegalArgumentException(J3dI18N.getString(
- "GeometryArray103"));
- }
- }
- }
- }
- }
- if ((vertexFormat & GeometryArray.INTERLEAVED) != 0) {
- // use nio buffer for interleaved data
+
+ if ((initialVertexIndex + validVertexCount) > vertexCount) {
+ throw new IllegalArgumentException(J3dI18N.getString("GeometryArray100"));
+ }
+
+ if ((vertexFormat & GeometryArray.INTERLEAVED) != 0) {
+ // Interleaved, by-ref
+
+ // use nio buffer for interleaved data
if(( vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0 && interleavedFloatBufferImpl != null){
if(interleavedFloatBufferImpl.limit() < stride * (initialVertexIndex + validVertexCount)) {
throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray114"));
@@ -9249,10 +10089,41 @@ abstract class GeometryArrayRetained extends GeometryRetained{
nullGeo = true;
}
} else if ((vertexFormat & GeometryArray.BY_REFERENCE) != 0) {
- if ((vertexType & GeometryArrayRetained.VERTEX_DEFINED) == 0)
+ // Non-interleaved, by-ref
+
+ if ((initialCoordIndex + validVertexCount) > vertexCount) {
+ throw new IllegalArgumentException(J3dI18N.getString("GeometryArray104"));
+ }
+ if ((initialColorIndex + validVertexCount) > vertexCount) {
+ throw new IllegalArgumentException(J3dI18N.getString("GeometryArray101"));
+ }
+ if ((initialNormalIndex + validVertexCount) > vertexCount) {
+ throw new IllegalArgumentException(J3dI18N.getString("GeometryArray102"));
+ }
+
+ if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+ for (int i = 0; i < texCoordSetCount; i++) {
+ if ((initialTexCoordIndex[i] + validVertexCount) > vertexCount) {
+ throw new IllegalArgumentException(J3dI18N.getString(
+ "GeometryArray103"));
+ }
+ }
+ }
+
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ for (int i = 0; i < vertexAttrCount; i++) {
+ if ((initialVertexAttrIndex[i] + validVertexCount) > vertexCount) {
+ throw new IllegalArgumentException(J3dI18N.getString(
+ "GeometryArray130"));
+ }
+ }
+ }
+
+ if ((vertexType & GeometryArrayRetained.VERTEX_DEFINED) == 0) {
nullGeo = true;
-
- if(( vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0) {
+ }
+
+ if (( vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0) {
// by reference with nio buffer
switch ((vertexType & GeometryArrayRetained.VERTEX_DEFINED)) {
case PF:
@@ -9324,6 +10195,18 @@ abstract class GeometryArrayRetained extends GeometryRetained{
}
break;
}
+ switch ((vertexType & GeometryArrayRetained.VATTR_DEFINED)) {
+ case AF:
+ for (int i = 0; i < vertexAttrCount; i++) {
+ int sz = vertexAttrSizes[i];
+ if (floatBufferRefVertexAttrs[i].limit() <
+ (sz * (initialVertexAttrIndex[i] + validVertexCount)) ) {
+ throw new ArrayIndexOutOfBoundsException(
+ J3dI18N.getString("GeometryArray129"));
+ }
+ }
+ break;
+ }
}
// By reference with java array
else {
@@ -9444,6 +10327,18 @@ abstract class GeometryArrayRetained extends GeometryRetained{
throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray111"));
}
}
+ switch ((vertexType & GeometryArrayRetained.VATTR_DEFINED)) {
+ case AF:
+ for (int i = 0; i < vertexAttrCount; i++) {
+ int sz = vertexAttrSizes[i];
+ if (floatRefVertexAttrs[i].length <
+ (sz * (initialVertexAttrIndex[i] + validVertexCount)) ) {
+ throw new ArrayIndexOutOfBoundsException(
+ J3dI18N.getString("GeometryArray129"));
+ }
+ }
+ break;
+ }
}
}
@@ -9455,7 +10350,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
processCoordsChanged(nullGeo);
sendDataChangedMessage(true);
}
-
}
@@ -9689,6 +10583,49 @@ abstract class GeometryArrayRetained extends GeometryRetained{
return initialNormalIndex;
}
+ /**
+ * Sets the initial vertex attribute index for the specified
+ * vertex attribute number for this GeometryArray object.
+ */
+ void setInitialVertexAttrIndex(int vertexAttrNum,
+ int initialVertexAttrIndex) {
+
+ if ((initialVertexAttrIndex + validVertexCount) > vertexCount) {
+ throw new IllegalArgumentException(J3dI18N.getString("GeometryArray130"));
+ }
+
+ int sz = vertexAttrSizes[vertexAttrNum];
+ int minLength = sz * (initialVertexAttrIndex + validVertexCount);
+ if ((vertexType & VATTR_DEFINED) == AF) {
+ if ((vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0) {
+ if (floatBufferRefVertexAttrs[vertexAttrNum].limit() < minLength) {
+ throw new ArrayIndexOutOfBoundsException(
+ J3dI18N.getString("GeometryArray129"));
+ }
+ } else {
+ if (floatRefVertexAttrs[vertexAttrNum].length < minLength ) {
+ throw new ArrayIndexOutOfBoundsException(
+ J3dI18N.getString("GeometryArray129"));
+ }
+ }
+ }
+ geomLock.getLock();
+ dirtyFlag |= VATTR_CHANGED;
+ this.initialVertexAttrIndex[vertexAttrNum] = initialVertexAttrIndex;
+ geomLock.unLock();
+ // There is no need to send message for by reference, since we
+ // use VA
+ }
+
+
+ /**
+ * Gets the initial vertex attribute index for the specified
+ * vertex attribute number for this GeometryArray object.
+ */
+ int getInitialVertexAttrIndex(int vertexAttrNum) {
+ return initialVertexAttrIndex[vertexAttrNum];
+ }
+
void setInitialTexCoordIndex(int texCoordSet, int initialTexCoordIndex) {
if ((initialTexCoordIndex + validVertexCount) > vertexCount) {
throw new IllegalArgumentException(J3dI18N.getString("GeometryArray103"));
@@ -9900,6 +10837,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
source.getCapability(GeometryArray.ALLOW_COLOR_WRITE) ||
source.getCapability(GeometryArray.ALLOW_NORMAL_WRITE) ||
source.getCapability(GeometryArray.ALLOW_TEXCOORD_WRITE) ||
+ source.getCapability(GeometryArray.ALLOW_VERTEX_ATTR_WRITE) ||
source.getCapability(GeometryArray.ALLOW_COUNT_WRITE) ||
source.getCapability(GeometryArray.ALLOW_REF_DATA_WRITE))
return false;
@@ -9963,7 +10901,8 @@ abstract class GeometryArrayRetained extends GeometryRetained{
float[] curVertexData;
int length, srcOffset;
int curOffset = 0;
- // We only merge if the texCoordSetCount is 1;
+ // We only merge if the texCoordSetCount is 1 and there are no
+ // vertex attrs
if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
texCoordSetCount = 1;
texCoordSetMap = new int[1];
@@ -10002,7 +10941,11 @@ abstract class GeometryArrayRetained extends GeometryRetained{
texCoordSetMap != null && texCoordSetMap.length > 1)) {
return false;
}
-
+
+ // We will avoid merging geometry if there are any vertex attributes.
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ return false;
+ }
// If intersect is allowed turn off merging
if (source.getCapability(Geometry.ALLOW_INTERSECT))
@@ -10011,32 +10954,6 @@ abstract class GeometryArrayRetained extends GeometryRetained{
return true;
}
- boolean isTextureGeometryMergeable(GeometryArrayRetained srcGeo) {
-
- if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
- if (texCoordSetCount != srcGeo.texCoordSetCount )
- return false;
-
- // If they are both non-null, then check if they are equivalent
- if (texCoordSetMap != null && srcGeo.texCoordSetMap != null) {
- if (texCoordSetMap.length != srcGeo.texCoordSetMap.length)
- return false;
-
- // Check the texCoordSetMap is same
- for (int j = 0; j < texCoordSetMap.length; j++) {
- if (texCoordSetMap[j] != srcGeo.texCoordSetMap[j])
- return false;
- }
- }
- // Check if they are both null;
- // if one is null and other is non-null return false
- else if (texCoordSetMap != srcGeo.texCoordSetMap)
- return false;
- }
-
- return true;
- }
-
void compile(CompileState compState) {
super.compile(compState);
@@ -10097,7 +11014,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
geomLock.getLock();
if (this instanceof IndexedGeometryArrayRetained) {
if ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0) {
- mirrorGeometry = (GeometryRetained)
+ mirrorGeometry =
((IndexedGeometryArrayRetained)this).cloneNonIndexedGeometry();
}
else {
@@ -10113,7 +11030,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
geomLock.getLock();
if (this instanceof IndexedGeometryArrayRetained) {
if (mirrorGeometry != null) {
- mirrorGeometry = (GeometryRetained)
+ mirrorGeometry =
((IndexedGeometryArrayRetained)this).cloneNonIndexedGeometry();
}
}
@@ -10261,7 +11178,7 @@ abstract class GeometryArrayRetained extends GeometryRetained{
if ((vertexFormat & GeometryArray.INTERLEAVED) == 0){
switch ((vertexType & GeometryArrayRetained.VERTEX_DEFINED)) {
case PF:
- count = floatBufferRefCoords.limit()/3; // TODO: limit or capacity
+ count = floatBufferRefCoords.limit()/3; // XXXX: limit or capacity?
break;
case PD:
count = doubleBufferRefCoords.limit()/3;
@@ -10437,8 +11354,12 @@ abstract class GeometryArrayRetained extends GeometryRetained{
}
}
return count;
- }
-
+ }
+
+ // NOTE: we don't need a getNumVertexAttrCount method, since getNum*Count
+ // is only called by Morph, which doesn't support vertex attrs
+
+
// Found the min distance from center to the point/line/tri/quad
// form by dist[]
void computeMinDistance(Point3d coordinates[], Point3d center,
@@ -10633,9 +11554,11 @@ abstract class GeometryArrayRetained extends GeometryRetained{
(((vertexFormat & GeometryArray.COLOR) != 0) &&
bit == GeometryArray.ALLOW_COLOR_WRITE)||
(((vertexFormat & GeometryArray.NORMALS) != 0) &&
- bit ==GeometryArray.ALLOW_NORMAL_WRITE) ||
- (((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0)&&
+ bit == GeometryArray.ALLOW_NORMAL_WRITE) ||
+ (((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) &&
bit == GeometryArray.ALLOW_TEXCOORD_WRITE) ||
+ (((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) &&
+ bit == GeometryArray.ALLOW_VERTEX_ATTR_WRITE) ||
(bit == GeometryArray.ALLOW_COUNT_WRITE)) {
mask = 1;
}
@@ -10649,5 +11572,12 @@ abstract class GeometryArrayRetained extends GeometryRetained{
}
}
+ int getTexCoordType() {
+ return texCoordType;
+ }
+
+ int getVertexAttrType() {
+ return vertexAttrType;
+ }
}
diff --git a/src/classes/share/javax/media/j3d/GeometryDecompressorRetained.java b/src/classes/share/javax/media/j3d/GeometryDecompressorRetained.java
index 6511553..e9cbdc8 100644
--- a/src/classes/share/javax/media/j3d/GeometryDecompressorRetained.java
+++ b/src/classes/share/javax/media/j3d/GeometryDecompressorRetained.java
@@ -57,7 +57,7 @@ class GeometryDecompressorRetained extends GeometryDecompressor {
// normal-per-vertex data collected from the HelloUniverse.cg file
// (seagull, '57 Chevy, dinosaur).
//
- // TODO: get fudge values for other vertex combinations
+ // XXXX: get fudge values for other vertex combinations
private static final float bytesPerVertexFudge = 5.3f ;
// Used for benchmarking if so configured.
diff --git a/src/classes/share/javax/media/j3d/GeometryRetained.java b/src/classes/share/javax/media/j3d/GeometryRetained.java
index 2b0a39d..3def9c3 100644
--- a/src/classes/share/javax/media/j3d/GeometryRetained.java
+++ b/src/classes/share/javax/media/j3d/GeometryRetained.java
@@ -229,12 +229,11 @@ abstract class GeometryRetained extends NodeComponentRetained {
return 0 ;
}
- abstract boolean intersect(PickShape pickShape, double dist[], Point3d iPnt);
+ abstract boolean intersect(PickShape pickShape, PickInfo.IntersectionInfo iInfo, int flags, Point3d iPnt);
abstract boolean intersect(Bounds targetBound);
abstract boolean intersect(Point3d[] pnts);
abstract boolean intersect(Transform3D thisToOtherVworld, GeometryRetained geom);
-
boolean intersect(Transform3D thisLocalToVworld,
Transform3D otherLocalToVworld, GeometryRetained geom) {
Transform3D tg = VirtualUniverse.mc.getTransform3D(null);
@@ -256,15 +255,69 @@ abstract class GeometryRetained extends NodeComponentRetained {
}
+ // Return a flag indicating whether or not this Geometry object can be in
+ // a display list.
+ //
+ // XXXX: Note that for IndexedGeometryArray objects, the original
+ // vertex format is used in making this determination, even when it has
+ // been unindexified. This should be fixed by using the vertex format of
+ // the mirror geometry if there is one.
boolean canBeInDisplayList(boolean alphaEditable) {
-
- return (VirtualUniverse.mc.isDisplayList) &&
- !(this.isEditable ||
- (!(this instanceof GeometryArrayRetained) && alphaEditable)||
- (alphaEditable && ((((GeometryArrayRetained)this).vertexFormat&
- GeometryArray.COLOR) != 0)) ||
- (((((GeometryArrayRetained)this).vertexFormat &
- GeometryArray.BY_REFERENCE) != 0) && !VirtualUniverse.mc.buildDisplayListIfPossible));
+ // Check global flag to see whether we can build display lists
+ if (!VirtualUniverse.mc.isDisplayList) {
+ return false;
+ }
+
+ // Can't build display lists if geometry is editable
+ // XXXX: should look at isFrequent bit and allow DL if
+ // infrequently writable
+ if (this.isEditable) {
+ return false;
+ }
+
+ if (this instanceof GeometryArrayRetained) {
+ int vFormat = ((GeometryArrayRetained)this).vertexFormat;
+
+ // If geometry has vertex attributes, check whether
+ // vertex attributes are allowed in display lists
+ if (((vFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) &&
+ !VirtualUniverse.mc.vertexAttrsInDisplayList) {
+ return false;
+ }
+
+ // Can't build display lists if alpha is editable and
+ // geometry array has colors
+ if (alphaEditable && ((vFormat & GeometryArray.COLOR) != 0)) {
+ return false;
+ }
+
+ // Only build DL for by-ref geometry when system property is set.
+ // Exclude NIO buffers and use-coord-index-only
+ if ((vFormat & GeometryArray.BY_REFERENCE) != 0) {
+ if (!VirtualUniverse.mc.buildDisplayListIfPossible) {
+ return false;
+ }
+
+ // XXXX: we could change this to allow display lists for
+ // non-interleaved NIO buffers, but we would first need to
+ // update the now-obsolete buildGAForBuffer method to handle
+ // vertex attrs
+ if ((vFormat & GeometryArray.USE_NIO_BUFFER) != 0) {
+ return false;
+ }
+
+ if ((vFormat & GeometryArray.USE_COORD_INDEX_ONLY) != 0) {
+ return false;
+ }
+ }
+
+ return true;
+ } else {
+ // Can't build display lists for other kind of geometry
+ // NOTE: This method is not called for any type of Geometry
+ // other than GeometryArray, so we shouldn't even get here.
+ return false;
+ }
}
void computeCentroid() {
diff --git a/src/classes/share/javax/media/j3d/GeometryStripArray.java b/src/classes/share/javax/media/j3d/GeometryStripArray.java
index 39c4dde..88d927f 100644
--- a/src/classes/share/javax/media/j3d/GeometryStripArray.java
+++ b/src/classes/share/javax/media/j3d/GeometryStripArray.java
@@ -31,18 +31,15 @@ public abstract class GeometryStripArray extends GeometryArray {
* Constructs an empty GeometryStripArray object with the specified
* number of vertices, vertex format, and
* array of per-strip vertex counts.
- * @param vertexCount the number of vertex elements in this array
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2 or TEXTURE_COORDINATE_3, to signal the
- * inclusion of per-vertex texture coordinates 2D or 3D.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
* @param stripVertexCounts array that specifies
* the count of the number of vertices for each separate strip.
* The length of this array is the number of separate strips.
@@ -50,7 +47,10 @@ public abstract class GeometryStripArray extends GeometryArray {
* of valid vertices that are rendered (validVertexCount).
*
* @exception IllegalArgumentException if
- * <code>validVertexCount > vertexCount</code>
+ * <code>validVertexCount &gt; vertexCount</code>
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int)}
+ * for more exceptions that can be thrown
*/
public GeometryStripArray(int vertexCount,
int vertexFormat,
@@ -66,50 +66,21 @@ public abstract class GeometryStripArray extends GeometryArray {
* sets, texture coordinate mapping array, and
* array of per-strip vertex counts.
*
- * @param vertexCount the number of vertex elements in this array<p>
- *
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2 or TEXTURE_COORDINATE_3, to signal the
- * inclusion of per-vertex texture coordinates 2D or 3D.<p>
- *
- * @param texCoordSetCount the number of texture coordinate sets
- * in this GeometryArray object. If <code>vertexFormat</code>
- * does not include one of <code>TEXTURE_COORDINATE_2</code> or
- * <code>TEXTURE_COORDINATE_3</code>, the
- * <code>texCoordSetCount</code> parameter is not used.<p>
- *
- * @param texCoordSetMap an array that maps texture coordinate
- * sets to texture units. The array is indexed by texture unit
- * number for each texture unit in the associated Appearance
- * object. The values in the array specify the texture coordinate
- * set within this GeometryArray object that maps to the
- * corresponding texture
- * unit. All elements within the array must be less than
- * <code>texCoordSetCount</code>. A negative value specifies that
- * no texture coordinate set maps to the texture unit
- * corresponding to the index. If there are more texture units in
- * any associated Appearance object than elements in the mapping
- * array, the extra elements are assumed to be -1. The same
- * texture coordinate set may be used for more than one texture
- * unit. Each texture unit in every associated Appearance must
- * have a valid source of texture coordinates: either a
- * non-negative texture coordinate set must be specified in the
- * mapping array or texture coordinate generation must be enabled.
- * Texture coordinate generation will take precedence for those
- * texture units for which a texture coordinate set is specified
- * and texture coordinate generation is enabled. If
- * <code>vertexFormat</code> does not include one of
- * <code>TEXTURE_COORDINATE_2</code> or
- * <code>TEXTURE_COORDINATE_3</code>, the
- * <code>texCoordSetMap</code> array is not used.<p>
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
*
* @param stripVertexCounts array that specifies
* the count of the number of vertices for each separate strip.
@@ -118,7 +89,10 @@ public abstract class GeometryStripArray extends GeometryArray {
* of valid vertices that are rendered (validVertexCount).
*
* @exception IllegalArgumentException if
- * <code>validVertexCount > vertexCount</code>
+ * <code>validVertexCount &gt; vertexCount</code>
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for more exceptions that can be thrown
*
* @since Java 3D 1.2
*/
@@ -134,6 +108,62 @@ public abstract class GeometryStripArray extends GeometryArray {
}
/**
+ * Constructs an empty GeometryStripArray object with the
+ * specified number of vertices, vertex format, number of texture
+ * coordinate sets, texture coordinate mapping array, vertex
+ * attribute count, vertex attribute sizes array, and array of
+ * per-strip vertex counts.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrSizes
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param stripVertexCounts array that specifies
+ * the count of the number of vertices for each separate strip.
+ * The length of this array is the number of separate strips.
+ * The sum of the elements in this array defines the total number
+ * of valid vertices that are rendered (validVertexCount).
+ *
+ * @exception IllegalArgumentException if
+ * <code>validVertexCount &gt; vertexCount</code>
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for more exceptions that can be thrown
+ *
+ * @since Java 3D 1.4
+ */
+ public GeometryStripArray(int vertexCount,
+ int vertexFormat,
+ int texCoordSetCount,
+ int[] texCoordSetMap,
+ int vertexAttrCount,
+ int[] vertexAttrSizes,
+ int[] stripVertexCounts) {
+
+ super(vertexCount, vertexFormat,
+ texCoordSetCount, texCoordSetMap,
+ vertexAttrCount, vertexAttrSizes);
+
+ ((GeometryStripArrayRetained)this.retained).setStripVertexCounts(stripVertexCounts);
+ }
+
+ /**
* Get number of strips in the GeometryStripArray.
* @return numStrips number of strips
*/
diff --git a/src/classes/share/javax/media/j3d/GeometryStripArrayRetained.java b/src/classes/share/javax/media/j3d/GeometryStripArrayRetained.java
index 1340be7..e6f83c0 100644
--- a/src/classes/share/javax/media/j3d/GeometryStripArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/GeometryStripArrayRetained.java
@@ -46,9 +46,9 @@ abstract class GeometryStripArrayRetained extends GeometryArrayRetained {
/**
* Set stripVertexCount data into local array
*/
- void setStripVertexCounts(int stripVertexCounts[]){
- boolean nullGeo = false;
-
+ void setStripVertexCounts(int stripVertexCounts[]) {
+ boolean nullGeo = false;
+
int i, num = stripVertexCounts.length, total = 0;
for (i=0; i < num; i++) {
total += stripVertexCounts[i];
@@ -72,28 +72,37 @@ abstract class GeometryStripArrayRetained extends GeometryArrayRetained {
if ((initialVertexIndex + total) > vertexCount) {
throw new IllegalArgumentException(J3dI18N.getString("GeometryStripArray3"));
}
- else if ((initialCoordIndex + total) > vertexCount) {
+ if ((initialCoordIndex + total) > vertexCount) {
throw new IllegalArgumentException(J3dI18N.getString("GeometryStripArray7"));
}
- else if ((initialColorIndex + total) > vertexCount) {
+ if ((initialColorIndex + total) > vertexCount) {
throw new IllegalArgumentException(J3dI18N.getString("GeometryStripArray4"));
}
- else if ((initialNormalIndex + total) > vertexCount) {
+ if ((initialNormalIndex + total) > vertexCount) {
throw new IllegalArgumentException(J3dI18N.getString("GeometryStripArray5"));
}
- else {
- if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
- if ((vertexFormat & (GeometryArray.BY_REFERENCE|vertexFormat &GeometryArray.INTERLEAVED)) == GeometryArray.BY_REFERENCE) {
- for (i = 0; i < texCoordSetCount; i++) {
- if ((initialTexCoordIndex[i] + total) > vertexCount) {
- throw new IllegalArgumentException(J3dI18N.getString(
- "GeometryStripArray6"));
- }
- }
- }
- }
- }
- geomLock.getLock();
+ if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+ if ((vertexFormat & (GeometryArray.BY_REFERENCE|vertexFormat &GeometryArray.INTERLEAVED)) == GeometryArray.BY_REFERENCE) {
+ for (i = 0; i < texCoordSetCount; i++) {
+ if ((initialTexCoordIndex[i] + total) > vertexCount) {
+ throw new IllegalArgumentException(
+ J3dI18N.getString("GeometryStripArray6"));
+ }
+ }
+ }
+ }
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ if ((vertexFormat & (GeometryArray.BY_REFERENCE|vertexFormat &GeometryArray.INTERLEAVED)) == GeometryArray.BY_REFERENCE) {
+ for (i = 0; i < vertexAttrCount; i++) {
+ if ((initialVertexAttrIndex[i] + total) > vertexCount) {
+ throw new IllegalArgumentException(
+ J3dI18N.getString("GeometryStripArray8"));
+ }
+ }
+ }
+ }
+
+ geomLock.getLock();
dirtyFlag |= STRIPCOUNT_CHANGED;
validVertexCount = total;
this.stripVertexCounts = new int[num];
@@ -139,7 +148,8 @@ abstract class GeometryStripArrayRetained extends GeometryArrayRetained {
unIndexifyNIOBuffer(src);
}
}
- void unIndexifyJavaArray(IndexedGeometryStripArrayRetained src) {
+
+ private void unIndexifyJavaArray(IndexedGeometryStripArrayRetained src) {
int vOffset = 0, srcOffset, tOffset = 0;
int base = src.initialIndexIndex;
int i,j, k, index, colorStride = 0;
@@ -169,7 +179,8 @@ abstract class GeometryStripArrayRetained extends GeometryArrayRetained {
src.indexNormal[index]*src.stride + src.normalOffset,
vertexData, vOffset + normalOffset, 3);
}
- if (colorStride == 4) {
+
+ if (colorStride == 4) {
/*
System.out.println("vdata.length = "+vdata.length);
System.out.println("vertexData.length = "+vertexData.length);
@@ -188,11 +199,12 @@ abstract class GeometryStripArrayRetained extends GeometryArrayRetained {
vertexData, vOffset + colorOffset, colorStride);
vertexData[vOffset + colorOffset + 3] = 1.0f;
}
- if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+
+ if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
for (k = 0; k < texCoordSetCount; k++) {
System.arraycopy(vdata,
- (((int[])src.indexTexCoord[k])[index])
- *src.stride + src.textureOffset +
+ (src.indexTexCoord[k][index])
+ * src.stride + src.textureOffset +
src.texCoordSetMapOffset[k],
vertexData,
vOffset + textureOffset +
@@ -201,7 +213,17 @@ abstract class GeometryStripArrayRetained extends GeometryArrayRetained {
}
}
- if ((vertexFormat & GeometryArray.COORDINATES) != 0){
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ for (k = 0; k < vertexAttrCount; k++) {
+ System.arraycopy(vdata,
+ src.indexVertexAttr[k][index] * src.stride + src.vertexAttrOffsets[k],
+ vertexData,
+ vOffset + vertexAttrOffsets[k],
+ vertexAttrSizes[k]);
+ }
+ }
+
+ if ((vertexFormat & GeometryArray.COORDINATES) != 0) {
System.arraycopy(vdata,
src.indexCoord[index]*src.stride + src.coordinateOffset,
vertexData, vOffset + coordinateOffset, 3);
@@ -245,7 +267,8 @@ abstract class GeometryStripArrayRetained extends GeometryArrayRetained {
break;
}
}
- if ((vertexFormat & GeometryArray.COLOR) != 0){
+
+ if ((vertexFormat & GeometryArray.COLOR) != 0){
base = src.initialIndexIndex;
vOffset = colorOffset;
int multiplier = 3;
@@ -351,7 +374,8 @@ abstract class GeometryStripArrayRetained extends GeometryArrayRetained {
break;
}
}
- if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+
+ if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
base = src.initialIndexIndex;
vOffset = textureOffset;
switch ((src.vertexType & TEXCOORD_DEFINED)) {
@@ -363,7 +387,7 @@ abstract class GeometryStripArrayRetained extends GeometryArrayRetained {
for (k = 0, tOffset = vOffset;
k < texCoordSetCount; k++) {
System.arraycopy(src.refTexCoords[k],
- ((int[])src.indexTexCoord[k])[index]
+ src.indexTexCoord[k][index]
*texCoordStride,
vertexData, tOffset, texCoordStride);
tOffset += texCoordStride;
@@ -380,7 +404,7 @@ abstract class GeometryStripArrayRetained extends GeometryArrayRetained {
for (k = 0, tOffset = vOffset;
k < texCoordSetCount; k++) {
srcOffset =
- ((int[])src.indexTexCoord[k])[index];
+ src.indexTexCoord[k][index];
vertexData[tOffset] = ((TexCoord2f[])
src.refTexCoords[k])[srcOffset].x;
vertexData[tOffset+1] = ((TexCoord2f[])
@@ -399,7 +423,7 @@ abstract class GeometryStripArrayRetained extends GeometryArrayRetained {
for (k = 0, tOffset = vOffset;
k < texCoordSetCount; k++) {
srcOffset =
- ((int[])src.indexTexCoord[k])[index];
+ src.indexTexCoord[k][index];
vertexData[tOffset] = ((TexCoord3f[])
src.refTexCoords[k])[srcOffset].x;
vertexData[tOffset+1] = ((TexCoord3f[])
@@ -417,7 +441,32 @@ abstract class GeometryStripArrayRetained extends GeometryArrayRetained {
default:
break;
}
- }
+ }
+
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ base = src.initialIndexIndex;
+ vOffset = 0;
+ switch (src.vertexType & VATTR_DEFINED) {
+ case AF:
+ for (i=0; i < src.stripIndexCounts.length; i++) {
+ for (j=0; j < src.stripIndexCounts[i]; j++) {
+ index = j+base;
+
+ for (k = 0; k < vertexAttrCount; k++) {
+ System.arraycopy(src.floatRefVertexAttrs[k],
+ src.indexVertexAttr[k][index]*vertexAttrSizes[k],
+ vertexData,
+ vOffset + vertexAttrOffsets[k],
+ vertexAttrSizes[k]);
+ }
+ vOffset += stride;
+ }
+ base += src.stripIndexCounts[i];
+ }
+ break;
+ }
+ }
+
if ((vertexFormat & GeometryArray.COORDINATES) != 0){
vOffset = coordinateOffset;
base = src.initialIndexIndex;
@@ -477,9 +526,9 @@ abstract class GeometryStripArrayRetained extends GeometryArrayRetained {
}
}
}
-
- void unIndexifyNIOBuffer(IndexedGeometryStripArrayRetained src) {
- int vOffset = 0, srcOffset, tOffset = 0;
+
+ private void unIndexifyNIOBuffer(IndexedGeometryStripArrayRetained src) {
+ int vOffset = 0, srcOffset, tOffset = 0;
int base = src.initialIndexIndex;
int i,j, k, index, colorStride = 0;
@@ -506,9 +555,10 @@ abstract class GeometryStripArrayRetained extends GeometryArrayRetained {
src.interleavedFloatBufferImpl.get(vertexData, vOffset + colorOffset, colorStride);
vertexData[vOffset + colorOffset + 3] = 1.0f;
}
- if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+
+ if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
for (k = 0; k < texCoordSetCount; k++) {
- src.interleavedFloatBufferImpl.position((((int[])src.indexTexCoord[k])[index])
+ src.interleavedFloatBufferImpl.position((src.indexTexCoord[k][index])
*src.stride + src.textureOffset +
src.texCoordSetMapOffset[k]);
@@ -527,7 +577,7 @@ abstract class GeometryStripArrayRetained extends GeometryArrayRetained {
}
}
else {
- if ((vertexFormat & GeometryArray.NORMALS) != 0){
+ if ((vertexFormat & GeometryArray.NORMALS) != 0) {
base = src.initialIndexIndex;
vOffset = normalOffset;
if((src.vertexType & NORMAL_DEFINED) != 0) {
@@ -542,7 +592,8 @@ abstract class GeometryStripArrayRetained extends GeometryArrayRetained {
}
}
}
- if ((vertexFormat & GeometryArray.COLOR) != 0){
+
+ if ((vertexFormat & GeometryArray.COLOR) != 0) {
base = src.initialIndexIndex;
vOffset = colorOffset;
int multiplier = 3;
@@ -593,7 +644,8 @@ abstract class GeometryStripArrayRetained extends GeometryArrayRetained {
break;
}
}
- if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+
+ if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
base = src.initialIndexIndex;
vOffset = textureOffset;
FloatBufferWrapper texBuffer;
@@ -605,7 +657,7 @@ abstract class GeometryStripArrayRetained extends GeometryArrayRetained {
for (k = 0, tOffset = vOffset;
k < texCoordSetCount; k++) {
texBuffer = (FloatBufferWrapper)(((J3DBuffer) (src.refTexCoordsBuffer[k])).getBufferImpl());
- texBuffer.position(((int[])src.indexTexCoord[k])[index]*texCoordStride);
+ texBuffer.position(src.indexTexCoord[k][index]*texCoordStride);
texBuffer.get(vertexData, tOffset, texCoordStride);
tOffset += texCoordStride;
}
@@ -614,8 +666,30 @@ abstract class GeometryStripArrayRetained extends GeometryArrayRetained {
base += src.stripIndexCounts[i];
}
}
- }
- if ((vertexFormat & GeometryArray.COORDINATES) != 0){
+ }
+
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ base = src.initialIndexIndex;
+ vOffset = 0;
+ if((src.vertexType & VATTR_DEFINED) == AF) {
+ for (i=0; i < src.stripIndexCounts.length; i++) {
+ for (j=0; j < src.stripIndexCounts[i]; j++) {
+ index = j+base;
+
+ for (k = 0; k < vertexAttrCount; k++) {
+ int vaOffset = vOffset + vertexAttrOffsets[k];
+ FloatBufferWrapper vaBuffer = src.floatBufferRefVertexAttrs[k];
+ vaBuffer.position(src.indexVertexAttr[k][index]*vertexAttrSizes[k]);
+ vaBuffer.get(vertexData, vaOffset, vertexAttrSizes[k]);
+ }
+ vOffset += stride;
+ }
+ base += src.stripIndexCounts[i];
+ }
+ }
+ }
+
+ if ((vertexFormat & GeometryArray.COORDINATES) != 0) {
vOffset = coordinateOffset;
base = src.initialIndexIndex;
switch ((src.vertexType & VERTEX_DEFINED)) {
diff --git a/src/classes/share/javax/media/j3d/GeometryStructure.java b/src/classes/share/javax/media/j3d/GeometryStructure.java
index 7bb9552..b8d7e0d 100644
--- a/src/classes/share/javax/media/j3d/GeometryStructure.java
+++ b/src/classes/share/javax/media/j3d/GeometryStructure.java
@@ -168,7 +168,6 @@ class GeometryStructure extends J3dStructure {
case J3dMessage.MORPH_CHANGED: {
int comp = ((Integer)m.args[1]).intValue();
if (comp == MorphRetained.GEOMETRY_CHANGED) {
- // TODO: Optimize this case.
processBoundsChanged((Object []) m.args[3], false);
}
else if (comp == MorphRetained.APPEARANCE_CHANGED) {
diff --git a/src/classes/share/javax/media/j3d/GraphStructureChangeListener.java b/src/classes/share/javax/media/j3d/GraphStructureChangeListener.java
new file mode 100755
index 0000000..c0a50a0
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/GraphStructureChangeListener.java
@@ -0,0 +1,54 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+/**
+ * Listener interface for monitoring structural changes to live scene
+ * graphs. BranchGroup additions, removals and moves are reported.
+ *
+ * @see VirtualUniverse#addGraphStructureChangeListener
+ *
+ * @since Java 3D 1.4
+ */
+public interface GraphStructureChangeListener {
+ /**
+ * Invoked when a branch group is added.
+ * Called just before the child is added to the parent.
+ * Parent can be either a BranchGroup or a Locale.
+ *
+ * @param parent the parent of the child being added
+ * @param child the child being added
+ */
+ public void branchGroupAdded(Object parent, BranchGroup child);
+
+ /**
+ * Invoked when a branch group is removed.
+ * Called just after the child has been removed from the parent.
+ * Parent can be either a BranchGroup or a Locale.
+ *
+ * @param parent the parent of the child being added
+ * @param child the child being added
+ */
+ public void branchGroupRemoved(Object parent, BranchGroup child);
+
+ /**
+ * Invoked when a branch group is moved.
+ * Called after a child has been moved to it's new parent. This call differs
+ * from the other methods in that the child is live when this method is called.
+ *
+ * @param oldParent the original parent of the child being moved
+ * @param newParent the new parent of the child being moved
+ * @param child the child being moved
+ */
+ public void branchGroupMoved(Object oldParent, Object newParent, BranchGroup child);
+}
diff --git a/src/classes/share/javax/media/j3d/GraphicsConfigInfo.java b/src/classes/share/javax/media/j3d/GraphicsConfigInfo.java
new file mode 100644
index 0000000..7d9e04f
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/GraphicsConfigInfo.java
@@ -0,0 +1,35 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+class GraphicsConfigInfo {
+ private int reqStencilSize = 0;
+ private long fbConfig = 0L;
+
+ int getRequestedStencilSize() {
+ return reqStencilSize;
+ }
+
+ void setRequestedStencilSize(int reqSS) {
+ reqStencilSize = reqSS;
+ }
+
+ long getFBConfig() {
+ return fbConfig;
+ }
+
+ void setFBConfig(long fbC) {
+ fbConfig = fbC;
+ }
+
+}
diff --git a/src/classes/share/javax/media/j3d/GraphicsConfigTemplate3D.java b/src/classes/share/javax/media/j3d/GraphicsConfigTemplate3D.java
index 8b59219..38e8156 100644
--- a/src/classes/share/javax/media/j3d/GraphicsConfigTemplate3D.java
+++ b/src/classes/share/javax/media/j3d/GraphicsConfigTemplate3D.java
@@ -39,6 +39,7 @@ public class GraphicsConfigTemplate3D extends GraphicsConfigTemplate {
int redSize;
int sceneAntialiasing;
int stereo;
+ int stencilSize;
// Temporary variables use for passing argument to/from Request Renderer
Object testCfg;
@@ -66,12 +67,14 @@ public class GraphicsConfigTemplate3D extends GraphicsConfigTemplate {
* redSize : 2<br>
* greenSize : 2<br>
* blueSize : 2<br>
+ * stencilSize : 0<br>
* </ul>
*/
public GraphicsConfigTemplate3D() {
doubleBuffer = REQUIRED;
stereo = UNNECESSARY;
depthSize = 16;
+ stencilSize = 0;
redSize = greenSize = blueSize = 2;
sceneAntialiasing = UNNECESSARY;
}
@@ -172,6 +175,35 @@ public class GraphicsConfigTemplate3D extends GraphicsConfigTemplate {
}
/**
+ * Sets the stencil buffer size requirement.
+ * This is the minimum requirement.
+ * If no GraphicsConfiguration is found that meets or
+ * exceeds this minimum requirement, null will be returned in
+ * getBestConfiguration().
+ *
+ * @param value the value to set this field to
+ *
+ * @since Java 3D 1.4
+ */
+ public void setStencilSize(int value) {
+ if (value < 0)
+ return;
+
+ stencilSize = value;
+ }
+
+ /**
+ * Retrieves the size of the stencil buffer.
+ *
+ * @return the current value of the stencilSize attribute
+ *
+ * @since Java 3D 1.4
+ */
+ public int getStencilSize() {
+ return stencilSize;
+ }
+
+ /**
* Sets the number of red bits required. This is the minimum requirement.
* If no GraphicsConfiguration is found that meets or
* exceeds this minimum requirement, null will be returned in
@@ -298,7 +330,8 @@ public class GraphicsConfigTemplate3D extends GraphicsConfigTemplate {
if (gc == null) {
return false;
}
- synchronized (globalLock) {
+
+ synchronized (globalLock) {
testCfg = gc;
threadWaiting = true;
if (Thread.currentThread() instanceof BehaviorScheduler) {
diff --git a/src/classes/share/javax/media/j3d/GraphicsContext3D.java b/src/classes/share/javax/media/j3d/GraphicsContext3D.java
index b5c7516..003134f 100644
--- a/src/classes/share/javax/media/j3d/GraphicsContext3D.java
+++ b/src/classes/share/javax/media/j3d/GraphicsContext3D.java
@@ -183,7 +183,7 @@ public class GraphicsContext3D extends Object {
boolean lightsChanged = false;
// A boolean that indicates the sounds have changed
- // TODO: the soundsChanged flag are set like lights methods set
+ // XXXX: the soundsChanged flag are set like lights methods set
// lightsChanged? but where is this supposed to be check???
// lightsChanged tested in 'draw'; but Sound are not processed
// in draw.
@@ -285,27 +285,29 @@ public class GraphicsContext3D extends Object {
// when a new command is to be
// added to the list
- static Integer commands[] = new Integer[NCOMMANDS];
- static Integer stereoModes[] = {new Integer(STEREO_LEFT),
- new Integer(STEREO_RIGHT),
- new Integer(STEREO_BOTH)};
+ private static Integer[] commands = new Integer[NCOMMANDS];
+ private static Integer[] stereoModes = {
+ new Integer(STEREO_LEFT),
+ new Integer(STEREO_RIGHT),
+ new Integer(STEREO_BOTH)
+ };
// dirty bits
- static final int BUFFER_MODE = 0x1;
+ private static final int BUFFER_MODE = 0x1;
private int dirtyMask = 0;
// multi-texture
- int numActiveTexUnit = 0;
- int lastActiveTexUnitIndex = 0;
- boolean toSimulateMultiTex = true;
+ private int numActiveTexUnit = 0;
+ private int lastActiveTexUnitIndex = 0;
+ private boolean toSimulateMultiTex = false;
// for read raster
- volatile boolean readRasterReady = false;
+ private volatile boolean readRasterReady = false;
// for runMonitor
- boolean gcReady = false;
- int waiting = 0;
+ private boolean gcReady = false;
+ private int waiting = 0;
/**
@@ -381,7 +383,12 @@ public class GraphicsContext3D extends Object {
enableLighting = false;
}
- if (((AppearanceRetained)appearance.retained).texUnitState != null) {
+ if (appearance instanceof ShaderAppearance) {
+ // TODO : handle ShaderProgram and ShaderAttributeSet
+ System.err.println("ShaderProgram not implemented for immediate mode rendering");
+ }
+
+ if (((AppearanceRetained)appearance.retained).texUnitState != null) {
TextureUnitStateRetained[] texUnitState =
((AppearanceRetained)appearance.retained).texUnitState;
@@ -626,9 +633,8 @@ public class GraphicsContext3D extends Object {
if (fog != null) {
((FogRetained)fog.retained).setInImmCtx(true);
-
- if (fog.retained instanceof LinearFogRetained)
- updateFogState((LinearFogRetained)fog.retained);
+ // Issue 144: updateFogState now called unconditionally
+ updateFogState((FogRetained)fog.retained);
}
}
@@ -912,8 +918,9 @@ public class GraphicsContext3D extends Object {
}
- void updateFogState(LinearFogRetained lfog) {
- lfog.localToVworldScale = modelTransform.getDistanceScale();
+ void updateFogState(FogRetained fogRet) {
+ // Issue 144: update localToVWorldScale for all types of Fog
+ fogRet.setLocalToVworldScale(modelTransform.getDistanceScale());
}
@@ -1280,7 +1287,7 @@ public class GraphicsContext3D extends Object {
if (view != null) {
SoundScheduler soundScheduler = getSoundScheduler();
if (soundScheduler == null) {
- // TODO: Re-implement
+ // XXXX: Re-implement
// start up SoundScheduler since it hasn't already been started
}
}
@@ -1291,13 +1298,13 @@ public class GraphicsContext3D extends Object {
this.modelTransform.transform(cs.direction, cs.xformDirection);
cs.xformDirection.normalize();
this.modelTransform.transform(cs.position, cs.xformPosition);
- // TODO (Question) Is drawTranform equivalent to Vworld-to-Local?
+ // XXXX (Question) Is drawTranform equivalent to Vworld-to-Local?
cs.trans.setWithLock(drawTransform);
} else if (sound instanceof PointSoundRetained) {
PointSoundRetained ps = (PointSoundRetained) sound;
this.modelTransform.transform(ps.position, ps.xformPosition);
- // TODO (Question) Is drawTranform equivalent to Vworld-to-Local?
+ // XXXX (Question) Is drawTranform equivalent to Vworld-to-Local?
ps.trans.setWithLock(drawTransform);
}
}
@@ -1559,7 +1566,7 @@ public class GraphicsContext3D extends Object {
else
back = this.black;
- // TODO: This should ideally be done by the renderer (or by the
+ // XXXX: This should ideally be done by the renderer (or by the
// canvas itself) when the canvas is first added to a view.
/*
if ((canvas3d.screen.renderer != null) &&
@@ -1575,7 +1582,7 @@ public class GraphicsContext3D extends Object {
try {
if (canvas3d.drawingSurfaceObject.renderLock()) {
- // TODO : Fix texture
+ // XXXX : Fix texture
/*
if (canvas3d.useSharedCtx) {
if (canvas3d.screen.renderer.sharedCtx == 0) {
@@ -1594,13 +1601,7 @@ public class GraphicsContext3D extends Object {
if (canvas3d.ctx == 0) {
synchronized (VirtualUniverse.mc.contextCreationLock) {
- canvas3d.ctx =
- canvas3d.createNewContext(canvas3d.screen.display,
- canvas3d.window,
- canvas3d.vid,
- canvas3d.fbConfig,
- 0, false,
- canvas3d.offScreen);
+ canvas3d.ctx = canvas3d.createNewContext(0, false);
if (canvas3d.ctx == 0) {
canvas3d.drawingSurfaceObject.unLock();
return;
@@ -1608,8 +1609,8 @@ public class GraphicsContext3D extends Object {
canvas3d.ctxTimeStamp =
VirtualUniverse.mc.getContextTimeStamp();
- canvas3d.screen.renderer.listOfCtxs.add(
- new Long(canvas3d.ctx));
+ canvas3d.screen.renderer.listOfCtxs.add(
+ new Long(canvas3d.ctx));
canvas3d.screen.renderer.listOfCanvases.add(canvas3d);
canvas3d.beginScene();
@@ -1618,43 +1619,21 @@ public class GraphicsContext3D extends Object {
canvas3d.graphics2D.init();
}
- // query for the number of texture units
- // supported
- if (canvas3d.multiTexAccelerated) {
- canvas3d.numTexUnitSupported =
- canvas3d.getTextureUnitCount(canvas3d.ctx);
- }
-
- // enable separate specular color
+ // enable separate specular color
canvas3d.enableSeparateSpecularColor();
}
// create the cache texture state in canvas
// for state download checking purpose
-
if (canvas3d.texUnitState == null) {
- canvas3d.texUnitState =
- new TextureUnitStateRetained[
- canvas3d.numTexUnitSupported];
- for (int t = 0; t < canvas3d.numTexUnitSupported; t++) {
- canvas3d.texUnitState[t] =
- new TextureUnitStateRetained();
- canvas3d.texUnitState[t].texture = null;
- canvas3d.texUnitState[t].mirror = null;
- }
+ canvas3d.createTexUnitState();
}
-
- // also create the texture unit state map
- // which is a mapping from texture unit state to
- // the actual underlying texture unit
-
+ // Create the texture unit state map
if (canvas3d.texUnitStateMap == null) {
- canvas3d.texUnitStateMap =
- new int[canvas3d.numTexUnitSupported];
+ canvas3d.createTexUnitStateMap();
}
-
canvas3d.drawingSurfaceObject.contextValidated();
canvas3d.screen.renderer.currentCtx = canvas3d.ctx;
initializeState();
@@ -1830,7 +1809,7 @@ public class GraphicsContext3D extends Object {
// rb.setVworldToVpc(vp.getVworldToVpc());
// rb.setVpcToVworld(vp.getVpcToVworld());
- // TODO: Fix this
+ // XXXX: Fix this
rb.vpcToVworld = vpR.getVpcToVworld();
rb.vworldToVpc = vpR.getVworldToVpc();
@@ -1890,7 +1869,7 @@ public class GraphicsContext3D extends Object {
switch(stereoMode) {
case STEREO_RIGHT:
vpcToEc = cvCache.getRightVpcToEc();
- // TODO: move this under check for
+ // XXXX: move this under check for
// (dirtyMask & BUFFER_MODE) above after testing
// PureImmediate mode
canvas3d.setProjectionMatrix(canvas3d.ctx,
@@ -1901,7 +1880,7 @@ public class GraphicsContext3D extends Object {
case STEREO_BOTH:
default:
vpcToEc = cvCache.getLeftVpcToEc();
- // TODO: move this under check for
+ // XXXX: move this under check for
// (dirtyMask & BUFFER_MODE) above after testing
// PureImmediate mode
canvas3d.setProjectionMatrix(canvas3d.ctx,
@@ -2000,7 +1979,7 @@ public class GraphicsContext3D extends Object {
if ((geometry.retained instanceof IndexedGeometryArrayRetained) &&
((((GeometryArrayRetained)geometry.retained).vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0)) {
if (geoRetained.dirtyFlag != 0) {
- geoRetained.mirrorGeometry = (GeometryRetained)
+ geoRetained.mirrorGeometry =
((IndexedGeometryArrayRetained)geoRetained).cloneNonIndexedGeometry();
// Change the source geometry dirtyFlag
// drawGeo.execute() will change the
@@ -2030,7 +2009,7 @@ public class GraphicsContext3D extends Object {
drawGeo = (GeometryRetained)geometry.retained;
}
- if (!toSimulateMultiTex) {
+ if (!toSimulateMultiTex) {
drawGeo.execute(canvas3d, null, isNonUniformScale,
false, alpha,
((canvas3d.view.getScreens()).length > 1),
@@ -2038,30 +2017,19 @@ public class GraphicsContext3D extends Object {
ignoreVertexColors,
-1);
} else {
- // TODO: need to leverage the code in textureBin
+ // NOTE: we really should leverage the code in textureBin
boolean startToSimulate = false;
- if (numActiveTexUnit < 1) {
- // no active texture unit
- drawGeo.execute(canvas3d, null, isNonUniformScale,
- false, alpha,
- ((canvas3d.view.getScreens()).length > 1),
- canvas3d.screen.screen,
- ignoreVertexColors,
- 0);
- } else if (numActiveTexUnit == 1) {
- // one active texture unit
- drawGeo.execute(canvas3d, null, isNonUniformScale,
- false, alpha,
- ((canvas3d.view.getScreens()).length > 1),
- canvas3d.screen.screen,
- ignoreVertexColors,
- lastActiveTexUnitIndex);
- } else {
+
// simulate multiple texture units
- AppearanceRetained app =
- (AppearanceRetained)appearance.retained;
+ AppearanceRetained app =
+ (AppearanceRetained)appearance.retained;
+
+ assert VirtualUniverse.mc.allowSimulatedMultiTexture;
+ assert numActiveTexUnit > 1;
+ assert app.texUnitState != null;
+ assert app.texUnitState.length > 1;
- // first turn off fog
+ // first turn off fog
if (fog != null)
canvas3d.setFogEnableFlag(canvas3d.ctx, false);
@@ -2088,16 +2056,20 @@ public class GraphicsContext3D extends Object {
// adjust the depth test back to what it was
// and adjust the blend func to what it it was
- if (startToSimulate) {
- app.transparencyAttributes.updateNative(
- canvas3d.ctx, alpha, geometryType,
- polygonMode, lineAA, pointAA);
- }
+ if (startToSimulate) {
+ if (app.transparencyAttributes != null) {
+ app.transparencyAttributes.updateNative(
+ canvas3d.ctx, alpha, geometryType,
+ polygonMode, lineAA, pointAA);
+ } else {
+ canvas3d.resetTransparency(canvas3d.ctx, geometryType,
+ polygonMode, lineAA, pointAA);
+ }
+ }
if (fog != null) {
canvas3d.setFogEnableFlag(canvas3d.ctx, true);
}
- }
}
if (geoRetained != null)
geoRetained.geomLock.unLock();
@@ -2229,7 +2201,7 @@ public class GraphicsContext3D extends Object {
throw new IllegalSharingException(J3dI18N.getString("GraphicsContext3D21"));
}
- // TODO: implement illegal argument exception
+ // XXXX: implement illegal argument exception
/*
if (ras.image.byReference &&
!(ras.image.imageReference instanceof BufferedImage)) {
@@ -2419,7 +2391,7 @@ public class GraphicsContext3D extends Object {
if (canvas3d.enableMask != enableMask) {
canvas3d.canvasDirty |= Canvas3D.LIGHTENABLES_DIRTY;
- // TODO: 32 => renderBin.maxLights
+ // XXXX: 32 => renderBin.maxLights
canvas3d.setLightEnables(canvas3d.ctx, enableMask, 32);
canvas3d.enableMask = enableMask;
}
@@ -2481,16 +2453,16 @@ public class GraphicsContext3D extends Object {
boolean updateState(RenderBin rb, int geometryType) {
- boolean useAlpha = false;;
- toSimulateMultiTex = true;
- numActiveTexUnit = 0;
+ boolean useAlpha = false;
+ toSimulateMultiTex = false;
+ numActiveTexUnit = 0;
lastActiveTexUnitIndex = 0;
// Update Appearance
if (appearance != null) {
AppearanceRetained app = (AppearanceRetained) appearance.retained;
- // If the material is not null then check if the one in the canvas
+ // If the material is not null then check if the one in the canvas
// is equivalent to the one being sent down. If Yes, do nothing
// Otherwise, cache the sent down material and mark the canvas
// dirty flag so that the compiled/compiled-retained rendering
@@ -2514,75 +2486,95 @@ public class GraphicsContext3D extends Object {
}
}
+ // Set flag indicating whether we are using shaders
+ boolean useShaders = false;
+ if (app instanceof ShaderAppearanceRetained) {
+ if (((ShaderAppearanceRetained)app).shaderProgram != null) {
+ useShaders = true;
+ }
+ }
+
+ // Set the number of available texture units; this depends on
+ // whether or not shaders are being used.
+ int availableTextureUnits =
+ useShaders ? canvas3d.maxTextureImageUnits : canvas3d.maxTextureUnits;
+
int prevNumActiveTexUnit = canvas3d.getNumActiveTexUnit();
+ // Get the number of active texture units.
+ // Note that this total number now includes disabled units.
if (app.texUnitState != null) {
- boolean d3dBlendMode = false;
-
TextureUnitStateRetained tus;
for (int i = 0; i < app.texUnitState.length; i++) {
tus = app.texUnitState[i];
if (tus != null && tus.isTextureEnabled()) {
- numActiveTexUnit++;
lastActiveTexUnitIndex = i;
- useAlpha = useAlpha ||
- (tus.texAttrs.textureMode ==
- TextureAttributes.BLEND);
- if (tus.needBlend2Pass(canvas3d)) {
- // use multi-pass if one of the stage use blend mode
- d3dBlendMode = true;
- }
+ numActiveTexUnit = i + 1;
+ if (tus.texAttrs != null) {
+ useAlpha = useAlpha ||
+ (tus.texAttrs.textureMode ==
+ TextureAttributes.BLEND);
+ }
}
}
- if (canvas3d.numTexUnitSupported >= numActiveTexUnit &&
- canvas3d.multiTexAccelerated && !d3dBlendMode) {
-
- int j = 0;
+ if (numActiveTexUnit <= availableTextureUnits) {
+ // Normal, single-pass rendering case
// update all active texture unit states
-
for (int i = 0; i < app.texUnitState.length; i++) {
- if ((app.texUnitState[i] != null) &&
+ if (i >= availableTextureUnits) {
+ // This can happen if there are disabled units at
+ // the end of the array
+ break;
+ }
+
+ if ((app.texUnitState[i] != null) &&
app.texUnitState[i].isTextureEnabled()) {
- app.texUnitState[i].updateNative(j, canvas3d,
+ app.texUnitState[i].updateNative(i, canvas3d,
false, false);
- canvas3d.setTexUnitStateMap(i, j++);
- }
+ } else {
+ canvas3d.resetTexture(canvas3d.ctx, i);
+ }
}
// reset the remaining texture units
-
- for (int i = j; i < prevNumActiveTexUnit; i++) {
- if (canvas3d.texUnitState[i].texture != null) {
- canvas3d.resetTexture(canvas3d.ctx, i);
- canvas3d.texUnitState[i].texture = null;
- }
+ for (int i = app.texUnitState.length; i < prevNumActiveTexUnit; i++) {
+ canvas3d.resetTexture(canvas3d.ctx, i);
}
// set the number active texture unit in Canvas3D
canvas3d.setNumActiveTexUnit(numActiveTexUnit);
- // set the active texture unit back to 0
- canvas3d.activeTextureUnit(canvas3d.ctx, 0);
-
- toSimulateMultiTex = false;
-
- } else {
+ } else if (!useShaders && VirtualUniverse.mc.allowSimulatedMultiTexture) {
+ // Simulated (multi-pass) multi-texture rendering
+
+ toSimulateMultiTex = true;
// will fall back to the multi-pass case;
// reset all the texture units first
+ for (int i = 0; i < prevNumActiveTexUnit; i++) {
+ canvas3d.resetTexture(canvas3d.ctx, i);
+ }
+ // set the number active texture unit in Canvas3D
+ canvas3d.setNumActiveTexUnit(1);
+ }
+ else {
+ // Exceeded limit, and not using simulated multi-texture
+
+ // disable all the texture units
for (int i = 0; i < prevNumActiveTexUnit; i++) {
- if (canvas3d.texUnitState[i].texture != null) {
- canvas3d.resetTexture(canvas3d.ctx, i);
- canvas3d.texUnitState[i].texture = null;
- }
+ canvas3d.resetTexture(canvas3d.ctx, i);
}
+ canvas3d.setNumActiveTexUnit(0);
}
+
+ // set the active texture unit back to 0
+ canvas3d.activeTextureUnit(canvas3d.ctx, 0);
} else {
- // if texUnitState is null, let's disable
+ // if texUnitState is null, let's disable
// all texture units first
if (canvas3d.multiTexAccelerated) {
if (canvas3d.texUnitState != null) {
@@ -2599,9 +2591,9 @@ public class GraphicsContext3D extends Object {
canvas3d.activeTextureUnit(canvas3d.ctx, 0);
}
- if ((canvas3d.texUnitState != null) &&
- (canvas3d.texUnitState[0] != null) &&
- (canvas3d.texUnitState[0].texture != app.texture)) {
+ if ((canvas3d.texUnitState != null) &&
+ (canvas3d.texUnitState[0] != null) &&
+ (canvas3d.texUnitState[0].texture != app.texture)) {
// If the image is by reference, check if the image
// should be processed
@@ -2616,7 +2608,6 @@ public class GraphicsContext3D extends Object {
}
}
app.texture.updateNative(canvas3d);
- canvas3d.setTexUnitStateMap(0, 0);
canvas3d.canvasDirty |= Canvas3D.TEXTUREBIN_DIRTY|Canvas3D.TEXTUREATTRIBUTES_DIRTY;
numActiveTexUnit = 1;
lastActiveTexUnitIndex = 0;
@@ -2728,7 +2719,7 @@ public class GraphicsContext3D extends Object {
if (app.renderingAttributes != null) {
ignoreVertexColors =app.renderingAttributes.ignoreVertexColors;
- app.renderingAttributes.updateNative(canvas3d.ctx,
+ app.renderingAttributes.updateNative(canvas3d,
canvas3d.depthBufferWriteEnableOverride,
canvas3d.depthBufferEnableOverride);
canvas3d.canvasDirty |= Canvas3D.ATTRIBUTEBIN_DIRTY|Canvas3D.TEXTUREATTRIBUTES_DIRTY;
diff --git a/src/classes/share/javax/media/j3d/Group.java b/src/classes/share/javax/media/j3d/Group.java
index c7a71f2..b5c763b 100644
--- a/src/classes/share/javax/media/j3d/Group.java
+++ b/src/classes/share/javax/media/j3d/Group.java
@@ -60,6 +60,13 @@ public class Group extends Node {
ALLOW_COLLISION_BOUNDS_WRITE =
CapabilityBits.GROUP_ALLOW_COLLISION_BOUNDS_WRITE;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_CHILDREN_READ,
+ ALLOW_COLLISION_BOUNDS_READ
+ };
+
+
/**
* Creates the retained mode GroupRetained object that this
* Group component object will point to.
@@ -528,5 +535,7 @@ public class Group extends Node {
* </ul>
*/
public Group() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
}
diff --git a/src/classes/share/javax/media/j3d/GroupRetained.java b/src/classes/share/javax/media/j3d/GroupRetained.java
index b300758..da9155a 100644
--- a/src/classes/share/javax/media/j3d/GroupRetained.java
+++ b/src/classes/share/javax/media/j3d/GroupRetained.java
@@ -238,6 +238,7 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
if(oldchildr != null) {
oldchildr.setParent(null);
checkClearLive(oldchildr, messages, 0, index, null);
+ universe.notifyStructureChangeListeners(false, this.source, (BranchGroup)oldchildr.source);
}
removeChildrenData(index);
@@ -249,6 +250,7 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
return;
}
+ universe.notifyStructureChangeListeners(true, this.source, (BranchGroup)child);
NodeRetained childr = (NodeRetained) child.retained;
childr.setParent(this);
children.set(index, childr);
@@ -276,6 +278,7 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
if (this.source.isLive()) {
universe.resetWaitMCFlag();
synchronized (universe.sceneGraphLock) {
+ universe.notifyStructureChangeListeners(true, this.source, (BranchGroup)child);
doInsertChild(child, index);
universe.setLiveState.clear();
}
@@ -324,8 +327,10 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
if (this.source.isLive()) {
universe.resetWaitMCFlag();
synchronized (universe.sceneGraphLock) {
+ NodeRetained childr = (NodeRetained)children.get(index);
doRemoveChild(index, null, 0);
universe.setLiveState.clear();
+ universe.notifyStructureChangeListeners(false, this.source, (BranchGroup)childr.source);
}
universe.waitForMC();
} else {
@@ -454,6 +459,7 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
if (this.source.isLive()) {
universe.resetWaitMCFlag();
synchronized (universe.sceneGraphLock) {
+ universe.notifyStructureChangeListeners(true, this.source, (BranchGroup)child);
doAddChild(child, null, 0);
universe.setLiveState.clear();
}
@@ -492,8 +498,13 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
if (this.source.isLive()) {
universe.resetWaitMCFlag();
synchronized (universe.sceneGraphLock) {
+ GroupRetained oldParent = (GroupRetained)((BranchGroupRetained)bg.retained).parent;
doMoveTo(bg);
universe.setLiveState.clear();
+ if (oldParent==null)
+ universe.notifyStructureChangeListeners(((BranchGroupRetained)bg.retained).locale, this.source, bg);
+ else
+ universe.notifyStructureChangeListeners(oldParent.source, this.source, bg);
}
universe.waitForMC();
} else {
@@ -632,7 +643,7 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
}
/*
- // TODO: lights may remove twice or more during clearLive(),
+ // XXXX: lights may remove twice or more during clearLive(),
// one from itself and one call from every LightRetained
// reference this. So there is case that this procedure get
// called when light already removed.
@@ -1828,7 +1839,7 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
}
s.transformTargets = newTargets;
- // TODO - optimization for targetThreads computation, require
+ // XXXX: optimization for targetThreads computation, require
// cleanup in GroupRetained.doSetLive()
//s.transformTargetThreads = 0;
}
@@ -2441,14 +2452,23 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
return super.getEffectiveBounds();
}
- // returns true if children cannot be read/written
+ // returns true if children cannot be read/written and none of the
+ // children can read their parent (i.e., "this") group node
boolean isStaticChildren() {
if (source.getCapability(Group.ALLOW_CHILDREN_READ) ||
source.getCapability(Group.ALLOW_CHILDREN_WRITE)) {
return false;
}
+
+ for (int i = children.size() - 1; i >= 0; i--) {
+ SceneGraphObjectRetained nodeR =
+ (SceneGraphObjectRetained) children.get(i);
+ if (nodeR != null && nodeR.source.getCapability(Node.ALLOW_PARENT_READ)) {
+ return false;
+ }
+ }
+
return true;
-
}
@@ -2644,7 +2664,7 @@ class GroupRetained extends NodeRetained implements BHLeafInterface {
}
}
// Has its own copy
- // TODO: Handle the case of
+ // XXXX: Handle the case of
// was non-zero, gone to zero?
if (savedParentLights != null) {
if (allocatedLights) {
diff --git a/src/classes/share/javax/media/j3d/ImageComponent.java b/src/classes/share/javax/media/j3d/ImageComponent.java
index 37f4530..4f927cf 100644
--- a/src/classes/share/javax/media/j3d/ImageComponent.java
+++ b/src/classes/share/javax/media/j3d/ImageComponent.java
@@ -195,10 +195,19 @@ public abstract class ImageComponent extends NodeComponent {
public static final int
ALLOW_IMAGE_WRITE = CapabilityBits.IMAGE_COMPONENT_ALLOW_IMAGE_WRITE;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_SIZE_READ,
+ ALLOW_SIZE_READ,
+ ALLOW_FORMAT_READ
+ };
+
/**
* Not a public constructor, for internal use
*/
ImageComponent() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -220,6 +229,9 @@ public abstract class ImageComponent extends NodeComponent {
* width or height are not positive.
*/
public ImageComponent(int format, int width, int height) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((ImageComponentRetained)this.retained).processParams(format, width, height, 1);
}
@@ -249,6 +261,8 @@ public abstract class ImageComponent extends NodeComponent {
int height,
boolean byReference,
boolean yUp) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
((ImageComponentRetained)this.retained).setYUp(yUp);
((ImageComponentRetained)this.retained).setByReference(byReference);
diff --git a/src/classes/share/javax/media/j3d/ImageComponent2DRetained.java b/src/classes/share/javax/media/j3d/ImageComponent2DRetained.java
index 809884d..6037355 100644
--- a/src/classes/share/javax/media/j3d/ImageComponent2DRetained.java
+++ b/src/classes/share/javax/media/j3d/ImageComponent2DRetained.java
@@ -171,7 +171,7 @@ class ImageComponent2DRetained extends ImageComponentRetained {
((biType == BufferedImage.TYPE_BYTE_GRAY) &&
(format == ImageComponent.FORMAT_CHANNEL8)) ||
(is4ByteRGBAOr3ByteRGB(ri))) {
- /* ||TODO: Don't do short for now!
+ /* ||XXXX: Don't do short for now!
((biType == BufferedImage.TYPE_USHORT_GRAY) &&
(format == ImageComponent.FORMAT_CHANNEL8)
*/
@@ -1293,7 +1293,7 @@ class ImageComponent2DRetained extends ImageComponentRetained {
if (source.isLive()) {
- //TODO: check whether this is needed
+ //XXXX: check whether this is needed
freeSurface();
// send a SUBIMAGE_CHANGED message in order to
@@ -1336,7 +1336,7 @@ class ImageComponent2DRetained extends ImageComponentRetained {
if (source.isLive()) {
- // TODO: check whether this is needed
+ // XXXX: check whether this is needed
freeSurface();
// send a SUBIMAGE_CHANGED message in order to
diff --git a/src/classes/share/javax/media/j3d/ImageComponent3D.java b/src/classes/share/javax/media/j3d/ImageComponent3D.java
index 1cb4d9b..224d1f5 100644
--- a/src/classes/share/javax/media/j3d/ImageComponent3D.java
+++ b/src/classes/share/javax/media/j3d/ImageComponent3D.java
@@ -622,7 +622,7 @@ public class ImageComponent3D extends ImageComponent {
rt.height,
rt.depth);
- // TODO : replace by this to duplicate other attributes
+ // XXXX : replace by this to duplicate other attributes
/*
ImageComponent3D img = new ImageComponent3D(rt.format,
rt.width,
diff --git a/src/classes/share/javax/media/j3d/IndexedGeometryArray.java b/src/classes/share/javax/media/j3d/IndexedGeometryArray.java
index c1c4254..00a9aa8 100644
--- a/src/classes/share/javax/media/j3d/IndexedGeometryArray.java
+++ b/src/classes/share/javax/media/j3d/IndexedGeometryArray.java
@@ -17,7 +17,8 @@ import javax.vecmath.*;
/**
* The IndexedGeometryArray object contains separate integer arrays
* that index into the arrays of positional coordinates, colors,
- * normals, and texture coordinates. These index arrays specify how
+ * normals, texture coordinates, and vertex attributes.
+ * These index arrays specify how
* vertices are connected to form geometry primitives. This class is
* extended to create the various indexed primitive types (e.g.,
* lines, triangle strips, etc.).
@@ -26,7 +27,10 @@ import javax.vecmath.*;
public abstract class IndexedGeometryArray extends GeometryArray {
// non-public, no parameter constructor
- IndexedGeometryArray() {}
+ IndexedGeometryArray() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+ }
/**
* Specifies that this IndexedGeometryArray allows reading the array of
@@ -85,6 +89,33 @@ public abstract class IndexedGeometryArray extends GeometryArray {
ALLOW_TEXCOORD_INDEX_WRITE = CapabilityBits.INDEXED_GEOMETRY_ARRAY_ALLOW_TEXCOORD_INDEX_WRITE;
/**
+ * Specifies that this IndexedGeometryArray allows reading the array of
+ * vertex attribute indices.
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int
+ ALLOW_VERTEX_ATTR_INDEX_READ = CapabilityBits.INDEXED_GEOMETRY_ARRAY_ALLOW_VERTEX_ATTR_INDEX_READ;
+
+ /**
+ * Specifies that this IndexedGeometryArray allows writing the array of
+ * vertex attribute indices.
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int
+ ALLOW_VERTEX_ATTR_INDEX_WRITE = CapabilityBits.INDEXED_GEOMETRY_ARRAY_ALLOW_VERTEX_ATTR_INDEX_WRITE;
+
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_COLOR_INDEX_READ,
+ ALLOW_COORDINATE_INDEX_READ,
+ ALLOW_NORMAL_INDEX_READ,
+ ALLOW_TEXCOORD_INDEX_READ,
+ ALLOW_VERTEX_ATTR_INDEX_READ
+ };
+
+ /**
* Constructs an empty IndexedGeometryArray object with the specified
* number of vertices, vertex format, and number of indices.
* Defaults are used for all other parameters. The default values
@@ -96,28 +127,31 @@ public abstract class IndexedGeometryArray extends GeometryArray {
* all index array values : 0<br>
* </ul>
*
- * @param vertexCount the number of vertex elements in this
- * IndexedGeometryArray
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or
- * TEXTURE_COORDINATE_4, to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
* @param indexCount the number of indices in this object. This
* count is the maximum number of vertices that will be rendered.
+ *
+ * @exception IllegalArgumentException if <code>indexCount &lt; 0</code>
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int)}
+ * for more exceptions that can be thrown
*/
public IndexedGeometryArray(int vertexCount,
int vertexFormat,
int indexCount) {
super(vertexCount, vertexFormat);
- ((IndexedGeometryArrayRetained)this.retained).createIndexedGeometryArrayData(indexCount);
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((IndexedGeometryArrayRetained)this.retained).createIndexedGeometryArrayData(indexCount);
}
/**
@@ -126,58 +160,30 @@ public abstract class IndexedGeometryArray extends GeometryArray {
* sets, texture coordinate mapping array, and number of indices.
* Defaults are used for all other parameters.
*
- * @param vertexCount the number of vertex elements in this
- * IndexedGeometryArray<p>
- *
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D , 3D or 4D.<p>
- *
- * @param texCoordSetCount the number of texture coordinate sets
- * in this GeometryArray object. If <code>vertexFormat</code>
- * does not include one of <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetCount</code> parameter is not used.<p>
- *
- * @param texCoordSetMap an array that maps texture coordinate
- * sets to texture units. The array is indexed by texture unit
- * number for each texture unit in the associated Appearance
- * object. The values in the array specify the texture coordinate
- * set within this GeometryArray object that maps to the
- * corresponding texture
- * unit. All elements within the array must be less than
- * <code>texCoordSetCount</code>. A negative value specifies that
- * no texture coordinate set maps to the texture unit
- * corresponding to the index. If there are more texture units in
- * any associated Appearance object than elements in the mapping
- * array, the extra elements are assumed to be -1. The same
- * texture coordinate set may be used for more than one texture
- * unit. Each texture unit in every associated Appearance must
- * have a valid source of texture coordinates: either a
- * non-negative texture coordinate set must be specified in the
- * mapping array or texture coordinate generation must be enabled.
- * Texture coordinate generation will take precedence for those
- * texture units for which a texture coordinate set is specified
- * and texture coordinate generation is enabled. If
- * <code>vertexFormat</code> does not include one of
- * <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetMap</code> array is not used.<p>
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
*
* @param indexCount the number of indices in this object. This
* count is the maximum number of vertices that will be rendered.
*
+ * @exception IllegalArgumentException if <code>indexCount &lt; 0</code>
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for more exceptions that can be thrown
+ *
* @since Java 3D 1.2
*/
public IndexedGeometryArray(int vertexCount,
@@ -185,7 +191,61 @@ public abstract class IndexedGeometryArray extends GeometryArray {
int texCoordSetCount,
int[] texCoordSetMap,
int indexCount) {
- super(vertexCount, vertexFormat, texCoordSetCount, texCoordSetMap);
+ this(vertexCount, vertexFormat, texCoordSetCount, texCoordSetMap, 0, null, indexCount);
+ }
+
+ /**
+ * Constructs an empty IndexedGeometryArray object with the
+ * specified number of vertices, vertex format, number of texture
+ * coordinate sets, texture coordinate mapping array, vertex
+ * attribute count, vertex attribute sizes array, and number of
+ * indices.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrSizes
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param indexCount the number of indices in this object. This
+ * count is the maximum number of vertices that will be rendered.
+ *
+ * @exception IllegalArgumentException if <code>indexCount &lt; 0</code>
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for more exceptions that can be thrown
+ *
+ * @since Java 3D 1.4
+ */
+ public IndexedGeometryArray(int vertexCount,
+ int vertexFormat,
+ int texCoordSetCount,
+ int[] texCoordSetMap,
+ int vertexAttrCount,
+ int[] vertexAttrSizes,
+ int indexCount) {
+
+ super(vertexCount, vertexFormat,
+ texCoordSetCount, texCoordSetMap,
+ vertexAttrCount, vertexAttrSizes);
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((IndexedGeometryArrayRetained)this.retained).createIndexedGeometryArrayData(indexCount);
}
@@ -384,6 +444,20 @@ public abstract class IndexedGeometryArray extends GeometryArray {
* This method is not supported for indexed geometry arrays.
* Indexed primitives use an array of indices to determine how
* to access the vertex array.
+ *
+ * @exception UnsupportedOperationException this method is not supported
+ *
+ * @since Java 3D 1.4
+ */
+ public void setInitialVertexAttrIndex(int vertexAttrNum,
+ int initialVertexAttrIndex) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * This method is not supported for indexed geometry arrays.
+ * Indexed primitives use an array of indices to determine how
+ * to access the vertex array.
* The validIndexCount attribute can be used to set the number of
* valid indexed vertices rendered.
*
@@ -468,6 +542,9 @@ public abstract class IndexedGeometryArray extends GeometryArray {
* colorIndex is out of range if it is less than 0 or is
* greater than or equal to the number of vertices actually
* defined for the color array.
+ *
+ * @exception NullPointerException if the <code>USE_COORD_INDEX_ONLY</code>
+ * bit is set in <code>vertexFormat</code>.
*/
public void setColorIndex(int index, int colorIndex) {
if (isLiveOrCompiled())
@@ -495,6 +572,9 @@ public abstract class IndexedGeometryArray extends GeometryArray {
* is out of range. An element is out of range if it is less than 0
* or is greater than or equal to the number of vertices actually
* defined for the color array.
+ *
+ * @exception NullPointerException if the <code>USE_COORD_INDEX_ONLY</code>
+ * bit is set in <code>vertexFormat</code>.
*/
public void setColorIndices(int index, int colorIndices[]) {
if (isLiveOrCompiled())
@@ -522,6 +602,9 @@ public abstract class IndexedGeometryArray extends GeometryArray {
* normalIndex is out of range if it is less than 0 or is
* greater than or equal to the number of vertices actually
* defined for the normal array.
+ *
+ * @exception NullPointerException if the <code>USE_COORD_INDEX_ONLY</code>
+ * bit is set in <code>vertexFormat</code>.
*/
public void setNormalIndex(int index, int normalIndex) {
if (isLiveOrCompiled())
@@ -549,6 +632,9 @@ public abstract class IndexedGeometryArray extends GeometryArray {
* is out of range. An element is out of range if it is less than 0
* or is greater than or equal to the number of vertices actually
* defined for the normal array.
+ *
+ * @exception NullPointerException if the <code>USE_COORD_INDEX_ONLY</code>
+ * bit is set in <code>vertexFormat</code>.
*/
public void setNormalIndices(int index, int normalIndices[]) {
if (isLiveOrCompiled())
@@ -590,13 +676,16 @@ public abstract class IndexedGeometryArray extends GeometryArray {
* greater than or equal to the number of vertices actually
* defined for the texture coordinate array.
*
+ * @exception NullPointerException if the <code>USE_COORD_INDEX_ONLY</code>
+ * bit is set in <code>vertexFormat</code>.
+ *
* @since Java 3D 1.2
*/
public void setTextureCoordinateIndex(int texCoordSet,
int index,
int texCoordIndex) {
if (isLiveOrCompiled())
- if(!this.getCapability(ALLOW_COORDINATE_INDEX_WRITE))
+ if(!this.getCapability(ALLOW_TEXCOORD_INDEX_WRITE))
throw new CapabilityNotSetException(J3dI18N.getString("IndexedGeometryArray7"));
((IndexedGeometryArrayRetained)this.retained).setTextureCoordinateIndex(texCoordSet, index, texCoordIndex);
@@ -634,18 +723,99 @@ public abstract class IndexedGeometryArray extends GeometryArray {
* or is greater than or equal to the number of vertices actually
* defined for the texture coordinate array.
*
+ * @exception NullPointerException if the <code>USE_COORD_INDEX_ONLY</code>
+ * bit is set in <code>vertexFormat</code>.
+ *
* @since Java 3D 1.2
*/
public void setTextureCoordinateIndices(int texCoordSet,
int index,
int texCoordIndices[]) {
if (isLiveOrCompiled())
- if(!this.getCapability(ALLOW_COORDINATE_INDEX_WRITE))
+ if(!this.getCapability(ALLOW_TEXCOORD_INDEX_WRITE))
throw new CapabilityNotSetException(J3dI18N.getString("IndexedGeometryArray7"));
((IndexedGeometryArrayRetained)this.retained).setTextureCoordinateIndices(texCoordSet, index, texCoordIndices);
}
+ /**
+ * Sets the vertex attribute index associated with the vertex at
+ * the specified index for the specified vertex attribute number
+ * for this object.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index the vertex index
+ * @param vertexAttrIndex the new vertex attribute index
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @exception ArrayIndexOutOfBoundsException if the index or
+ * vertexAttrNum is out of range.
+ *
+ * @exception ArrayIndexOutOfBoundsException if index is in the range
+ * <code>[initialIndexIndex, initialIndexIndex+validIndexCount-1]</code>
+ * and the specified vertexAttrIndex is out of range. The
+ * vertexAttrIndex is out of range if it is less than 0 or is
+ * greater than or equal to the number of vertices actually
+ * defined for the vertex attribute array.
+ *
+ * @exception NullPointerException if the <code>USE_COORD_INDEX_ONLY</code>
+ * bit is set in <code>vertexFormat</code>.
+ *
+ * @since Java 3D 1.4
+ */
+ public void setVertexAttrIndex(int vertexAttrNum,
+ int index,
+ int vertexAttrIndex) {
+ if (isLiveOrCompiled()) {
+ if(!this.getCapability(ALLOW_VERTEX_ATTR_INDEX_WRITE)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("IndexedGeometryArray28"));
+ }
+ }
+
+ ((IndexedGeometryArrayRetained)this.retained).setVertexAttrIndex(vertexAttrNum, index, vertexAttrIndex);
+ }
+
+ /**
+ * Sets the vertex attribute indices associated with the vertices
+ * starting at the specified index for the specified vertex attribute number
+ * for this object.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index the vertex index
+ * @param vertexAttrIndices an array of vertex attribute indices
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @exception ArrayIndexOutOfBoundsException if the index or
+ * vertexAttrNum is out of range.
+ *
+ * @exception ArrayIndexOutOfBoundsException if any element of the
+ * vertexAttrIndices array whose destination position is in the range
+ * <code>[initialIndexIndex, initialIndexIndex+validIndexCount-1]</code>
+ * is out of range. An element is out of range if it is less than 0
+ * or is greater than or equal to the number of vertices actually
+ * defined for the vertex attribute array.
+ *
+ * @exception NullPointerException if the <code>USE_COORD_INDEX_ONLY</code>
+ * bit is set in <code>vertexFormat</code>.
+ *
+ * @since Java 3D 1.4
+ */
+ public void setVertexAttrIndices(int vertexAttrNum,
+ int index,
+ int[] vertexAttrIndices) {
+ if (isLiveOrCompiled()) {
+ if(!this.getCapability(ALLOW_VERTEX_ATTR_INDEX_WRITE)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("IndexedGeometryArray28"));
+ }
+ }
+
+ ((IndexedGeometryArrayRetained)this.retained).setVertexAttrIndices(vertexAttrNum, index, vertexAttrIndices);
+ }
+
/**
* Retrieves the coordinate index associated with the vertex at
* the specified index for this object.
@@ -685,6 +855,9 @@ public abstract class IndexedGeometryArray extends GeometryArray {
* @return the color index
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
+ *
+ * @exception NullPointerException if the <code>USE_COORD_INDEX_ONLY</code>
+ * bit is set in <code>vertexFormat</code>.
*/
public int getColorIndex(int index) {
if (isLiveOrCompiled())
@@ -703,6 +876,9 @@ public abstract class IndexedGeometryArray extends GeometryArray {
* @param colorIndices array that will receive the color indices
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
+ *
+ * @exception NullPointerException if the <code>USE_COORD_INDEX_ONLY</code>
+ * bit is set in <code>vertexFormat</code>.
*/
public void getColorIndices(int index, int colorIndices[]) {
if (isLiveOrCompiled())
@@ -719,6 +895,9 @@ public abstract class IndexedGeometryArray extends GeometryArray {
* @return the normal index
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
+ *
+ * @exception NullPointerException if the <code>USE_COORD_INDEX_ONLY</code>
+ * bit is set in <code>vertexFormat</code>.
*/
public int getNormalIndex(int index) {
if (isLiveOrCompiled())
@@ -738,6 +917,9 @@ public abstract class IndexedGeometryArray extends GeometryArray {
* @param normalIndices array that will receive the normal indices
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
+ *
+ * @exception NullPointerException if the <code>USE_COORD_INDEX_ONLY</code>
+ * bit is set in <code>vertexFormat</code>.
*/
public void getNormalIndices(int index, int normalIndices[]) {
if (isLiveOrCompiled())
@@ -773,6 +955,9 @@ public abstract class IndexedGeometryArray extends GeometryArray {
* <code>vertexFormat</code> or if the index or
* texCoordSet is out of range.
*
+ * @exception NullPointerException if the <code>USE_COORD_INDEX_ONLY</code>
+ * bit is set in <code>vertexFormat</code>.
+ *
* @since Java 3D 1.2
*/
public int getTextureCoordinateIndex(int texCoordSet, int index) {
@@ -812,6 +997,9 @@ public abstract class IndexedGeometryArray extends GeometryArray {
* <code>vertexFormat</code> or if the index or
* texCoordSet is out of range.
*
+ * @exception NullPointerException if the <code>USE_COORD_INDEX_ONLY</code>
+ * bit is set in <code>vertexFormat</code>.
+ *
* @since Java 3D 1.2
*/
public void getTextureCoordinateIndices(int texCoordSet,
@@ -824,6 +1012,72 @@ public abstract class IndexedGeometryArray extends GeometryArray {
((IndexedGeometryArrayRetained)this.retained).getTextureCoordinateIndices(texCoordSet, index, texCoordIndices);
}
+ /**
+ * Retrieves the vertex attribute index associated with the vertex at
+ * the specified index for the specified vertex attribute number
+ * for this object.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index the vertex index
+ *
+ * @return the vertex attribute index
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @exception ArrayIndexOutOfBoundsException if the index or
+ * vertexAttrNum is out of range.
+ *
+ * @exception NullPointerException if the <code>USE_COORD_INDEX_ONLY</code>
+ * bit is set in <code>vertexFormat</code>.
+ *
+ * @since Java 3D 1.4
+ */
+ public int getVertexAttrIndex(int vertexAttrNum,
+ int index) {
+ if (isLiveOrCompiled()) {
+ if(!this.getCapability(ALLOW_VERTEX_ATTR_INDEX_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("IndexedGeometryArray29"));
+ }
+ }
+
+ return ((IndexedGeometryArrayRetained)this.retained).getVertexAttrIndex(vertexAttrNum, index);
+ }
+
+ /**
+ * Retrieves the vertex attribute indices associated with the vertices
+ * starting at the specified index for the specified vertex attribute number
+ * for this object. The vertex attribute indices
+ * are copied into the specified array. The array
+ * must be large enough to hold all of the indices.
+ *
+ * @param vertexAttrNum vertex attribute number in this geometry array
+ * @param index the vertex index
+ * @param vertexAttrIndices array that will receive the vertex attribute indices
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @exception ArrayIndexOutOfBoundsException if the index or
+ * vertexAttrNum is out of range.
+ *
+ * @exception NullPointerException if the <code>USE_COORD_INDEX_ONLY</code>
+ * bit is set in <code>vertexFormat</code>.
+ *
+ * @since Java 3D 1.4
+ */
+ public void getVertexAttrIndices(int vertexAttrNum,
+ int index,
+ int[] vertexAttrIndices) {
+ if (isLiveOrCompiled()) {
+ if(!this.getCapability(ALLOW_VERTEX_ATTR_INDEX_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("IndexedGeometryArray29"));
+ }
+ }
+
+ ((IndexedGeometryArrayRetained)this.retained).getVertexAttrIndices(vertexAttrNum, index, vertexAttrIndices);
+ }
+
/**
* Copies all node information from <code>originalNodeComponent</code> into
* the current node. This method is called from the
@@ -854,30 +1108,39 @@ public abstract class IndexedGeometryArray extends GeometryArray {
IndexedGeometryArrayRetained rt =
(IndexedGeometryArrayRetained) retained;
- int vformat = ga.getVertexFormat();
- int buffer[] = new int[ga.getIndexCount()];
-
- if ((vformat & GeometryArray.COORDINATES) != 0) {
- ga.getCoordinateIndices(0, buffer);
- rt.setCoordinateIndices(0, buffer);
- }
-
- if ((vformat & GeometryArray.NORMALS) != 0) {
- ga.getNormalIndices(0, buffer);
- rt.setNormalIndices(0, buffer);
- }
-
- if ((vformat & GeometryArray.COLOR) != 0) {
- ga.getColorIndices(0, buffer);
- rt.setColorIndices(0, buffer);
- }
-
- if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
- for (int i = 0; i < ga.texCoordSetCount; i++) {
- ga.getTextureCoordinateIndices(i, 0, buffer);
- rt.setTextureCoordinateIndices(i, 0, buffer);
- }
- }
+ int vformat = ga.getVertexFormat();
+ int buffer[] = new int[ga.getIndexCount()];
+
+ if ((vformat & COORDINATES) != 0) {
+ ga.getCoordinateIndices(0, buffer);
+ rt.setCoordinateIndices(0, buffer);
+ }
+
+ if ((vformat & USE_COORD_INDEX_ONLY) == 0) {
+ if ((vformat & NORMALS) != 0) {
+ ga.getNormalIndices(0, buffer);
+ rt.setNormalIndices(0, buffer);
+ }
+
+ if ((vformat & COLOR) != 0) {
+ ga.getColorIndices(0, buffer);
+ rt.setColorIndices(0, buffer);
+ }
+
+ if ((vformat & VERTEX_ATTRIBUTES) != 0) {
+ for (int i = 0; i < ga.vertexAttrCount; i++) {
+ ga.getVertexAttrIndices(i, 0, buffer);
+ rt.setVertexAttrIndices(i, 0, buffer);
+ }
+ }
+
+ if ((vformat & TEXTURE_COORDINATE) != 0) {
+ for (int i = 0; i < ga.texCoordSetCount; i++) {
+ ga.getTextureCoordinateIndices(i, 0, buffer);
+ rt.setTextureCoordinateIndices(i, 0, buffer);
+ }
+ }
+ }
}
}
diff --git a/src/classes/share/javax/media/j3d/IndexedGeometryArrayRetained.java b/src/classes/share/javax/media/j3d/IndexedGeometryArrayRetained.java
index 090de29..f6d443b 100644
--- a/src/classes/share/javax/media/j3d/IndexedGeometryArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/IndexedGeometryArrayRetained.java
@@ -30,11 +30,14 @@ import com.sun.j3d.internal.DoubleBufferWrapper;
abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
- // arrays to save indices for coord, color, normal, texcoord
- int indexCoord[], indexColor[], indexNormal[];
- Object indexTexCoord[];
+ // arrays to save indices for coord, color, normal, texcoord, vertexAttr
+ int[] indexCoord;
+ int[] indexColor;
+ int[] indexNormal;
+ int[][] indexTexCoord;
+ int[][] indexVertexAttr;
- int indexCount;
+ int indexCount = 0;
int initialIndexIndex = 0;
int validIndexCount = 0;
@@ -47,65 +50,77 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
int maxColorIndex = 0;
int maxNormalIndex = 0;
int[] maxTexCoordIndices = null;
-
- void createIndexedGeometryArrayData(int indexCount) {
- this.indexCount = indexCount;
- this.validIndexCount = indexCount;
+ int[] maxVertexAttrIndices = null;
+ void createIndexedGeometryArrayData(int indexCount) {
+ this.indexCount = indexCount;
+ this.validIndexCount = indexCount;
- boolean notUCIO = (this.vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0;
-
- if((this.vertexFormat & GeometryArray.COORDINATES) != 0)
- this.indexCoord = new int[indexCount];
-
- if(((this.vertexFormat & GeometryArray.NORMALS) != 0) && notUCIO)
- this.indexNormal = new int[indexCount];
-
- if(((this.vertexFormat & GeometryArray.COLOR) != 0) && notUCIO)
- this.indexColor = new int[indexCount];
-
- if((this.vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
- this.indexTexCoord = new Object[this.texCoordSetCount];
- if(notUCIO) {
- for (int i = 0; i < this.texCoordSetCount; i++) {
- this.indexTexCoord[i] = new int[indexCount];
+ // Only allocate color, normal, texCoord, and vertexAttr
+ // index arrays if USE_COORD_INDEX_ONLY is not set
+ boolean notUCIO = (this.vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0;
+
+ if((this.vertexFormat & GeometryArray.COORDINATES) != 0)
+ this.indexCoord = new int[indexCount];
+
+ if(((this.vertexFormat & GeometryArray.NORMALS) != 0) && notUCIO)
+ this.indexNormal = new int[indexCount];
+
+ if(((this.vertexFormat & GeometryArray.COLOR) != 0) && notUCIO)
+ this.indexColor = new int[indexCount];
+
+ if((this.vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
+ this.indexTexCoord = new int[this.texCoordSetCount][];
+ if(notUCIO) {
+ for (int i = 0; i < this.texCoordSetCount; i++) {
+ this.indexTexCoord[i] = new int[indexCount];
+ }
+ }
+ maxTexCoordIndices = new int[texCoordSetCount];
+ }
+
+ if ((this.vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ this.indexVertexAttr = new int[this.vertexAttrCount][];
+ if (notUCIO) {
+ for (int i = 0; i < this.vertexAttrCount; i++) {
+ this.indexVertexAttr[i] = new int[indexCount];
+ }
}
+ this.maxVertexAttrIndices = new int[this.vertexAttrCount];
}
- maxTexCoordIndices = new int[texCoordSetCount];
}
- }
-
- Object cloneNonIndexedGeometry() {
- GeometryArrayRetained obj = null;
- int vOffset;
-
- switch (this.geoType) {
- case GEO_TYPE_INDEXED_LINE_SET:
- obj = new LineArrayRetained();
- break;
- case GEO_TYPE_INDEXED_POINT_SET:
- obj = new PointArrayRetained();
- break;
- case GEO_TYPE_INDEXED_QUAD_SET:
- obj = new QuadArrayRetained();
- break;
- case GEO_TYPE_INDEXED_TRI_SET:
- obj = new TriangleArrayRetained();
- break;
- }
- obj.createGeometryArrayData(validIndexCount, (vertexFormat & ~(GeometryArray.BY_REFERENCE|GeometryArray.INTERLEAVED|GeometryArray.USE_NIO_BUFFER)),
- texCoordSetCount, texCoordSetMap);
- obj.cloneSourceArray = this;
- obj.unIndexify(this);
-
- return (Object)obj;
- }
- void execute(long ctx, RenderAtom ra, boolean isNonUniformScale,
- boolean updateAlpha, float alpha) {
- throw new RuntimeException(J3dI18N.getString("IndexedGeometryArrayRetained0"));
- }
+ GeometryArrayRetained cloneNonIndexedGeometry() {
+ GeometryArrayRetained obj = null;
+ int vOffset;
+
+ switch (this.geoType) {
+ case GEO_TYPE_INDEXED_LINE_SET:
+ obj = new LineArrayRetained();
+ break;
+ case GEO_TYPE_INDEXED_POINT_SET:
+ obj = new PointArrayRetained();
+ break;
+ case GEO_TYPE_INDEXED_QUAD_SET:
+ obj = new QuadArrayRetained();
+ break;
+ case GEO_TYPE_INDEXED_TRI_SET:
+ obj = new TriangleArrayRetained();
+ break;
+ default:
+ assert false; // Should never get here
+ }
+
+ obj.createGeometryArrayData(validIndexCount,
+ (vertexFormat & ~(GeometryArray.BY_REFERENCE|GeometryArray.INTERLEAVED|GeometryArray.USE_NIO_BUFFER)),
+ texCoordSetCount, texCoordSetMap,
+ vertexAttrCount, vertexAttrSizes);
+ obj.cloneSourceArray = this;
+ obj.unIndexify(this);
+
+ return obj;
+ }
/**
@@ -127,14 +142,19 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
doTexCoordCheck(newMax, i);
}
}
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ for (int i = 0; i < vertexAttrCount; i++) {
+ doVertexAttrCheck(newMax, i);
+ }
+ }
if ((vertexFormat & GeometryArray.NORMALS) != 0) {
doNormalCheck(newMax);
- }
- }
+ }
+ }
}
-
+
void doCoordCheck(int newMax) {
- // Check to make sure that the array length defined by the user is ateast maxCoordIndex long
+ // Check to make sure that the array length defined by the user is ateast maxCoordIndex long
if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0) {
if (newMax >= vertexCount) {
throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray23"));
@@ -404,6 +424,43 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
}
+ void doVertexAttrCheck(int newMax, int vertexAttrNum) {
+
+ // Check to make sure that the array length defined by the user is ateast maxVertexAttrIndex long
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) == 0) {
+ return;
+ }
+
+ // Vertex attributes must not be interleaved
+ assert (vertexFormat & GeometryArray.INTERLEAVED) == 0;
+
+ if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0) {
+ if (newMax >= vertexCount) {
+ throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray30"));
+ }
+ } else {
+ int multiplier = vertexAttrSizes[vertexAttrNum];
+
+ if(( vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0) {
+ switch (vertexType & VATTR_DEFINED) {
+ case AF:
+ if(multiplier * newMax >= floatBufferRefVertexAttrs[vertexAttrNum].limit()) {
+ throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray30"));
+ }
+ break;
+ }
+ } else {
+ switch (vertexType & VATTR_DEFINED) {
+ case AF:
+ if (multiplier * newMax >= floatRefVertexAttrs[vertexAttrNum].length) {
+ throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray30"));
+ }
+ break;
+ }
+ }
+ }
+ }
+
/**
* Sets the coordinate index associated with the vertex at
@@ -426,6 +483,11 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
maxTexCoordIndices[i] = newMax;
}
}
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ for (int i = 0; i < vertexAttrCount; i++) {
+ maxVertexAttrIndices[i] = newMax;
+ }
+ }
if ((vertexFormat & GeometryArray.NORMALS) != 0) {
maxNormalIndex = newMax;
}
@@ -542,6 +604,11 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
maxTexCoordIndices[i] = newMax;
}
}
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ for (i = 0; i < vertexAttrCount; i++) {
+ maxVertexAttrIndices[i] = newMax;
+ }
+ }
if ((vertexFormat & GeometryArray.NORMALS) != 0) {
maxNormalIndex = newMax;
}
@@ -568,33 +635,21 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
final void setColorIndex(int index, int colorIndex) {
int newMax = maxColorIndex;
- if ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0) {
- newMax = doIndexCheck(index, maxColorIndex, indexColor, colorIndex);
- if (newMax > maxColorIndex) {
- doColorCheck(newMax);
- }
- geomLock.getLock();
- // No need to set INDEX_CHANGED since IndexBuffer
- // is used only when USE_COORD_INDEX_ONLY specified.
- // In this case only coordinate index array is
- // considered.
- this.indexColor[index] = colorIndex;
- maxColorIndex = newMax;
- geomLock.unLock();
- if (!inUpdater && source != null && source.isLive()) {
- sendDataChangedMessage(false);
- }
- }
- else {
- if ((vertexFormat & GeometryArray.COLOR) != 0) {
- if (this.indexColor == null) {
- this.indexColor = new int[indexCount];
- System.err.println(J3dI18N.getString("IndexedGeometryArrayRetained1"));
- }
- }
- this.indexColor[index] = colorIndex;
- }
-
+ newMax = doIndexCheck(index, maxColorIndex, indexColor, colorIndex);
+ if (newMax > maxColorIndex) {
+ doColorCheck(newMax);
+ }
+ geomLock.getLock();
+ // No need to set INDEX_CHANGED since IndexBuffer
+ // is used only when USE_COORD_INDEX_ONLY specified.
+ // In this case only coordinate index array is
+ // considered.
+ this.indexColor[index] = colorIndex;
+ maxColorIndex = newMax;
+ geomLock.unLock();
+ if (!inUpdater && source != null && source.isLive()) {
+ sendDataChangedMessage(false);
+ }
}
/**
@@ -606,34 +661,20 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
final void setColorIndices(int index, int colorIndices[]) {
int i, j, num = colorIndices.length;
int newMax;
-
- if ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0) {
- newMax = doIndicesCheck(index, maxColorIndex, indexColor, colorIndices);
- if (newMax > maxColorIndex) {
- doColorCheck(newMax);
- }
- geomLock.getLock();
- maxColorIndex = newMax;
- for (i=0, j = index; i < num;i++, j++) {
- this.indexColor[j] = colorIndices[i];
- }
- geomLock.unLock();
- if (!inUpdater && source != null && source.isLive()) {
- sendDataChangedMessage(false);
- }
- }
- else {
- if ((vertexFormat & GeometryArray.COLOR) != 0) {
- if (this.indexColor == null) {
- this.indexColor = new int[indexCount];
- System.err.println(J3dI18N.getString("IndexedGeometryArrayRetained1"));
- }
- }
- for (i=0, j = index; i < num;i++, j++) {
- this.indexColor[j] = colorIndices[i];
- }
- }
+ newMax = doIndicesCheck(index, maxColorIndex, indexColor, colorIndices);
+ if (newMax > maxColorIndex) {
+ doColorCheck(newMax);
+ }
+ geomLock.getLock();
+ maxColorIndex = newMax;
+ for (i=0, j = index; i < num;i++, j++) {
+ this.indexColor[j] = colorIndices[i];
+ }
+ geomLock.unLock();
+ if (!inUpdater && source != null && source.isLive()) {
+ sendDataChangedMessage(false);
+ }
}
/**
@@ -644,30 +685,18 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
*/
final void setNormalIndex(int index, int normalIndex) {
int newMax;
-
- if ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0) {
- newMax = doIndexCheck(index, maxNormalIndex, indexNormal, normalIndex);
- if (newMax > maxNormalIndex) {
- doNormalCheck(newMax);
- }
- geomLock.getLock();
- maxNormalIndex = newMax;
- this.indexNormal[index] = normalIndex;
- geomLock.unLock();
- if (!inUpdater && source != null && source.isLive()) {
- sendDataChangedMessage(false);
- }
- }
- else {
- if ((vertexFormat & GeometryArray.NORMALS) != 0) {
- if (this.indexNormal == null) {
- this.indexNormal = new int[indexCount];
- System.err.println(J3dI18N.getString("IndexedGeometryArrayRetained2"));
- }
- }
- this.indexNormal[index] = normalIndex;
- }
+ newMax = doIndexCheck(index, maxNormalIndex, indexNormal, normalIndex);
+ if (newMax > maxNormalIndex) {
+ doNormalCheck(newMax);
+ }
+ geomLock.getLock();
+ maxNormalIndex = newMax;
+ this.indexNormal[index] = normalIndex;
+ geomLock.unLock();
+ if (!inUpdater && source != null && source.isLive()) {
+ sendDataChangedMessage(false);
+ }
}
/**
@@ -679,34 +708,20 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
final void setNormalIndices(int index, int normalIndices[]) {
int i, j, num = normalIndices.length;
int newMax;
-
- if ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0) {
- newMax = doIndicesCheck(index, maxNormalIndex, indexNormal, normalIndices);
- if (newMax > maxNormalIndex) {
- doNormalCheck(newMax);
- }
- geomLock.getLock();
- for (i=0, j = index; i < num;i++, j++) {
- this.indexNormal[j] = normalIndices[i];
- }
- maxNormalIndex = newMax;
- geomLock.unLock();
- if (!inUpdater && source != null && source.isLive()) {
- sendDataChangedMessage(false);
- }
- }
- else {
- if ((vertexFormat & GeometryArray.NORMALS) != 0) {
- if (this.indexNormal == null) {
- this.indexNormal = new int[indexCount];
- System.err.println(J3dI18N.getString("IndexedGeometryArrayRetained2"));
- }
- }
- for (i=0, j = index; i < num;i++, j++) {
- this.indexNormal[j] = normalIndices[i];
- }
- }
+ newMax = doIndicesCheck(index, maxNormalIndex, indexNormal, normalIndices);
+ if (newMax > maxNormalIndex) {
+ doNormalCheck(newMax);
+ }
+ geomLock.getLock();
+ for (i=0, j = index; i < num;i++, j++) {
+ this.indexNormal[j] = normalIndices[i];
+ }
+ maxNormalIndex = newMax;
+ geomLock.unLock();
+ if (!inUpdater && source != null && source.isLive()) {
+ sendDataChangedMessage(false);
+ }
}
/**
@@ -718,33 +733,19 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
*/
final void setTextureCoordinateIndex(int texCoordSet, int index, int texCoordIndex) {
int newMax;
- int [] indices = (int[])this.indexTexCoord[texCoordSet];
-
- if ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0) {
- newMax = doIndexCheck(index, maxTexCoordIndices[texCoordSet],indices, texCoordIndex);
- if (newMax > maxTexCoordIndices[texCoordSet]) {
- doTexCoordCheck(newMax, texCoordSet);
- }
- geomLock.getLock();
- maxTexCoordIndices[texCoordSet] = newMax;
- indices[index] = texCoordIndex;
- geomLock.unLock();
- if (!inUpdater && source != null && source.isLive()) {
- sendDataChangedMessage(false);
- }
- }
- else {
- if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
- if (indices == null) {
- indices = new int[indexCount];
- this.indexTexCoord[texCoordSet] = indices;
- System.err.println(J3dI18N.getString("IndexedGeometryArrayRetained3"));
- }
- }
- indices[index] = texCoordIndex;
- }
-
+ int [] indices = this.indexTexCoord[texCoordSet];
+ newMax = doIndexCheck(index, maxTexCoordIndices[texCoordSet],indices, texCoordIndex);
+ if (newMax > maxTexCoordIndices[texCoordSet]) {
+ doTexCoordCheck(newMax, texCoordSet);
+ }
+ geomLock.getLock();
+ maxTexCoordIndices[texCoordSet] = newMax;
+ indices[index] = texCoordIndex;
+ geomLock.unLock();
+ if (!inUpdater && source != null && source.isLive()) {
+ sendDataChangedMessage(false);
+ }
}
/**
@@ -754,42 +755,80 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
* @param index the vertex index
* @param texCoordIndices an array of texture coordinate indices
*/
- final void setTextureCoordinateIndices(int texCoordSet, int index, int texCoordIndices[]) {
- int i, j, num = texCoordIndices.length;
- int [] indices = (int[])this.indexTexCoord[texCoordSet];
+ final void setTextureCoordinateIndices(int texCoordSet, int index, int texCoordIndices[]) {
+ int i, j, num = texCoordIndices.length;
+ int [] indices = this.indexTexCoord[texCoordSet];
- int newMax;
-
- if ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0) {
- newMax = doIndicesCheck(index, maxTexCoordIndices[texCoordSet], indices, texCoordIndices);
- if (newMax > maxTexCoordIndices[texCoordSet]) {
- doTexCoordCheck(newMax, texCoordSet);
- }
- geomLock.getLock();
- maxTexCoordIndices[texCoordSet] = newMax;
- for (i=0, j = index; i < num;i++, j++) {
- indices[j] = texCoordIndices[i];
- }
- geomLock.unLock();
- if (!inUpdater && source != null && source.isLive()) {
- sendDataChangedMessage(false);
- }
-
- }
- else {
- if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
- if (indices == null) {
- indices = new int[indexCount];
- this.indexTexCoord[texCoordSet] = indices;
- System.err.println(J3dI18N.getString("IndexedGeometryArrayRetained3"));
- }
- }
- for (i=0, j = index; i < num;i++, j++) {
- indices[j] = texCoordIndices[i];
- }
- }
+ int newMax;
- }
+ newMax = doIndicesCheck(index, maxTexCoordIndices[texCoordSet], indices, texCoordIndices);
+ if (newMax > maxTexCoordIndices[texCoordSet]) {
+ doTexCoordCheck(newMax, texCoordSet);
+ }
+ geomLock.getLock();
+ maxTexCoordIndices[texCoordSet] = newMax;
+ for (i=0, j = index; i < num;i++, j++) {
+ indices[j] = texCoordIndices[i];
+ }
+ geomLock.unLock();
+ if (!inUpdater && source != null && source.isLive()) {
+ sendDataChangedMessage(false);
+ }
+ }
+
+ /**
+ * Sets the vertex attribute index associated with the vertex at
+ * the specified index for the specified vertex attribute number
+ * for this object.
+ */
+ public void setVertexAttrIndex(int vertexAttrNum,
+ int index,
+ int vertexAttrIndex) {
+
+ int newMax;
+ int [] indices = this.indexVertexAttr[vertexAttrNum];
+
+ newMax = doIndexCheck(index, maxVertexAttrIndices[vertexAttrNum],indices, vertexAttrIndex);
+ if (newMax > maxVertexAttrIndices[vertexAttrNum]) {
+ doVertexAttrCheck(newMax, vertexAttrNum);
+ }
+ geomLock.getLock();
+ maxVertexAttrIndices[vertexAttrNum] = newMax;
+ indices[index] = vertexAttrIndex;
+ geomLock.unLock();
+ if (!inUpdater && source != null && source.isLive()) {
+ sendDataChangedMessage(false);
+ }
+ }
+
+ /**
+ * Sets the vertex attribute indices associated with the vertices
+ * starting at the specified index for the specified vertex attribute number
+ * for this object.
+ */
+ public void setVertexAttrIndices(int vertexAttrNum,
+ int index,
+ int[] vertexAttrIndices) {
+
+ int i, j, num = vertexAttrIndices.length;
+ int [] indices = this.indexVertexAttr[vertexAttrNum];
+
+ int newMax;
+
+ newMax = doIndicesCheck(index, maxVertexAttrIndices[vertexAttrNum], indices, vertexAttrIndices);
+ if (newMax > maxVertexAttrIndices[vertexAttrNum]) {
+ doVertexAttrCheck(newMax, vertexAttrNum);
+ }
+ geomLock.getLock();
+ maxVertexAttrIndices[vertexAttrNum] = newMax;
+ for (i=0, j = index; i < num;i++, j++) {
+ indices[j] = vertexAttrIndices[i];
+ }
+ geomLock.unLock();
+ if (!inUpdater && source != null && source.isLive()) {
+ sendDataChangedMessage(false);
+ }
+ }
/**
* Retrieves the coordinate index associated with the vertex at
@@ -807,14 +846,13 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
* @param index the vertex index
* @param coordinateIndices array that will receive the coordinate indices
*/
- final void getCoordinateIndices(int index, int coordinateIndices[]) {
- int i, j, num = coordinateIndices.length;
+ final void getCoordinateIndices(int index, int coordinateIndices[]) {
+ int i, j, num = coordinateIndices.length;
- for (i=0, j = index;i < num;i++, j++)
- {
- coordinateIndices[i] = this.indexCoord[j];
- }
- }
+ for (i=0, j = index;i < num;i++, j++) {
+ coordinateIndices[i] = this.indexCoord[j];
+ }
+ }
/**
* Retrieves the color index associated with the vertex at
@@ -823,13 +861,6 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
* @return the color index
*/
final int getColorIndex(int index) {
- if (((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) != 0) &&
- ((vertexFormat & GeometryArray.COLOR) != 0)) {
- if (this.indexColor == null) {
- this.indexColor = new int[indexCount];
- System.err.println(J3dI18N.getString("IndexedGeometryArrayRetained1"));
- }
- }
return this.indexColor[index];
}
@@ -839,22 +870,14 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
* @param index the vertex index
* @param colorIndices array that will receive the color indices
*/
- final void getColorIndices(int index, int colorIndices[]) {
- int i, j, num = colorIndices.length;
- if (((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) != 0) &&
- ((vertexFormat & GeometryArray.COLOR) != 0)) {
- if (this.indexColor == null) {
- this.indexColor = new int[indexCount];
- System.err.println(J3dI18N.getString("IndexedGeometryArrayRetained1"));
+ final void getColorIndices(int index, int colorIndices[]) {
+ int i, j, num = colorIndices.length;
+
+ for (i=0, j = index;i < num;i++, j++) {
+ colorIndices[i] = this.indexColor[j];
}
}
- for (i=0, j = index;i < num;i++, j++)
- {
- colorIndices[i] = this.indexColor[j];
- }
- }
-
/**
* Retrieves the normal index associated with the vertex at
* the specified index for this object.
@@ -862,13 +885,6 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
* @return the normal index
*/
final int getNormalIndex(int index) {
- if (((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) != 0) &&
- ((vertexFormat & GeometryArray.NORMALS) != 0)) {
- if (this.indexNormal == null) {
- this.indexNormal = new int[indexCount];
- System.err.println(J3dI18N.getString("IndexedGeometryArrayRetained2"));
- }
- }
return this.indexNormal[index];
}
@@ -878,22 +894,14 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
* @param index the vertex index
* @param normalIndices array that will receive the normal indices
*/
- final void getNormalIndices(int index, int normalIndices[]) {
- int i, j, num = normalIndices.length;
- if (((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) != 0) &&
- ((vertexFormat & GeometryArray.NORMALS) != 0)) {
- if (this.indexNormal == null) {
- this.indexNormal = new int[indexCount];
- System.err.println(J3dI18N.getString("IndexedGeometryArrayRetained2"));
+ final void getNormalIndices(int index, int normalIndices[]) {
+ int i, j, num = normalIndices.length;
+
+ for (i=0, j = index;i < num;i++, j++) {
+ normalIndices[i] = this.indexNormal[j];
}
}
- for (i=0, j = index;i < num;i++, j++)
- {
- normalIndices[i] = this.indexNormal[j];
- }
- }
-
/**
* Retrieves the texture coordinate index associated with the vertex at
* the specified index for this object.
@@ -902,16 +910,9 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
* @return the texture coordinate index
*/
final int getTextureCoordinateIndex(int texCoordSet, int index) {
- int [] indices = (int[])this.indexTexCoord[texCoordSet];
- if (((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) != 0) &&
- ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0)) {
- if (indices == null) {
- indices = new int[indexCount];
- this.indexTexCoord[texCoordSet] = indices;
- System.err.println(J3dI18N.getString("IndexedGeometryArrayRetained3"));
- }
- }
- return indices[index];
+ int [] indices = this.indexTexCoord[texCoordSet];
+
+ return indices[index];
}
/**
@@ -921,120 +922,147 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
* @param index the vertex index
* @param texCoordIndices array that will receive the texture coordinate indices
*/
- final void getTextureCoordinateIndices(int texCoordSet, int index, int texCoordIndices[]) {
- int i, j, num = texCoordIndices.length;
- int [] indices = (int[])this.indexTexCoord[texCoordSet];
- if (((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) != 0) &&
- ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0)) {
- if (indices == null) {
- indices = new int[indexCount];
- this.indexTexCoord[texCoordSet] = indices;
- System.err.println(J3dI18N.getString("IndexedGeometryArrayRetained3"));
+ final void getTextureCoordinateIndices(int texCoordSet, int index, int texCoordIndices[]) {
+ int i, j, num = texCoordIndices.length;
+ int [] indices = this.indexTexCoord[texCoordSet];
+
+ for (i=0, j = index;i < num;i++, j++) {
+ texCoordIndices[i] = indices[j];
}
}
- for (i=0, j = index;i < num;i++, j++)
- {
- texCoordIndices[i] = indices[j];
- }
- }
+ /**
+ * Retrieves the vertex attribute index associated with the vertex at
+ * the specified index for the specified vertex attribute number
+ * for this object.
+ */
+ public int getVertexAttrIndex(int vertexAttrNum,
+ int index) {
+
+ int [] indices = this.indexVertexAttr[vertexAttrNum];
- // used for GeometryArrays
- native void executeIndexedGeometry(long ctx,
- GeometryArrayRetained geo, int geo_type,
- boolean isNonUniformScale,
- boolean useAlpha,
- boolean multiScreen,
- boolean ignoreVertexColors,
- int initialIndexIndex,
- int indexCount,
- int vertexCount, int vformat,
- int texCoordSetCount, int texCoordSetMap[],
- int texCoordSetMapLen,
- int[] texCoordSetOffset,
- int numActiveTexUnitState,
- int[] texUnitStateMap,
- float[] varray, float[] cdata,
- int texUnitIndex, int cdirty,
- int[] indexCoord);
-
- // used for interleaved, by reference, nio buffer
- native void executeIndexedGeometryBuffer(long ctx,
- GeometryArrayRetained geo, int geo_type,
- boolean isNonUniformScale,
- boolean useAlpha,
- boolean multiScreen,
- boolean ignoreVertexColors,
- int initialIndexIndex,
- int indexCount,
- int vertexCount, int vformat,
- int texCoordSetCount, int texCoordSetMap[],
- int texCoordSetMapLen,
- int[] texCoordSetOffset,
- int numActiveTexUnitState,
- int[] texUnitStateMap,
- Object varray, float[] cdata,
- int texUnitIndex, int cdirty,
- int[] indexCoord);
+ return indices[index];
+ }
+ /**
+ * Retrieves the vertex attribute indices associated with the vertices
+ * starting at the specified index for the specified vertex attribute number
+ * for this object.
+ */
+ public void getVertexAttrIndices(int vertexAttrNum,
+ int index,
+ int[] vertexAttrIndices) {
-
- native void executeIndexedGeometryVA(long ctx,
- GeometryArrayRetained geo, int geo_type,
- boolean isNonUniformScale,
- boolean multiScreen,
- boolean ignoreVertexColors,
- int initialIndexIndex,
- int validIndexCount,
- int vertexCount,
- int vformat,
- int vdefined,
- float[] vfcoords, double[] vdcoords,
- float[] cfdata, byte[] cbdata,
- float[] ndata,
- int pass, int texcoordmaplength,
- int[] texcoordoffset,
- int numActiveTexUnitState, int[] texunitstatemap,
- int texstride, Object[] texCoords,
- int cdirty,
- int[] indexCoord);
+ int i, j, num = vertexAttrIndices.length;
+ int [] indices = this.indexVertexAttr[vertexAttrNum];
+
+ for (i=0, j = index;i < num;i++, j++) {
+ vertexAttrIndices[i] = indices[j];
+ }
+ }
+
+ // by-copy or interleaved, by reference, Java arrays
+ private native void executeIndexedGeometry(long ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean multiScreen,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int indexCount,
+ int vertexCount, int vformat,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int texCoordSetCount, int texCoordSetMap[],
+ int texCoordSetMapLen,
+ int[] texCoordSetOffset,
+ int numActiveTexUnitState,
+ int[] texUnitStateMap,
+ float[] varray, float[] cdata,
+ int texUnitIndex, int cdirty,
+ int[] indexCoord);
+
+ // interleaved, by reference, nio buffer
+ private native void executeIndexedGeometryBuffer(long ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean useAlpha,
+ boolean multiScreen,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int indexCount,
+ int vertexCount, int vformat,
+ int texCoordSetCount, int texCoordSetMap[],
+ int texCoordSetMapLen,
+ int[] texCoordSetOffset,
+ int numActiveTexUnitState,
+ int[] texUnitStateMap,
+ Object varray, float[] cdata,
+ int texUnitIndex, int cdirty,
+ int[] indexCoord);
+
+ // non interleaved, by reference, Java arrays
+ private native void executeIndexedGeometryVA(long ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean multiScreen,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int validIndexCount,
+ int vertexCount,
+ int vformat,
+ int vdefined,
+ float[] vfcoords, double[] vdcoords,
+ float[] cfdata, byte[] cbdata,
+ float[] ndata,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ float[][] vertexAttrData,
+ int pass, int texcoordmaplength,
+ int[] texcoordoffset,
+ int numActiveTexUnitState, int[] texunitstatemap,
+ int texstride, Object[] texCoords,
+ int cdirty,
+ int[] indexCoord);
// non interleaved, by reference, nio buffer
- native void executeIndexedGeometryVABuffer(long ctx,
- GeometryArrayRetained geo, int geo_type,
- boolean isNonUniformScale,
- boolean multiScreen,
- boolean ignoreVertexColors,
- int initialIndexIndex,
- int validIndexCount,
- int vertexCount,
- int vformat,
- int vdefined,
- Object vcoords,
- Object cdataBuffer,
- float[] cfdata, byte[] cbdata,
- Object normal,
- int pass, int texcoordmaplength,
- int[] texcoordoffset,
- int numActiveTexUnitState, int[] texunitstatemap,
- int texstride, Object[] texCoords,
- int cdirty,
- int[] indexCoord);
-
- // used for IndexedGeometry
- native void buildIndexedGeometry(long ctx, GeometryArrayRetained geo, int geo_type,
- boolean isNonUniformScale, boolean updateAlpha,
- float alpha,
- boolean ignoreVertexColors,
- int initialIndexIndex,
- int validIndexCount,
- int vertexCount,
- int vformat,
- int texCoordSetCount, int texCoordSetMap[],
- int texCoordSetMapLen,
- int[] texCoordSetMapOffset,
- double[] xform, double[] nxform,
- float[] varray, int[] indexCoord);
+ private native void executeIndexedGeometryVABuffer(long ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale,
+ boolean multiScreen,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int validIndexCount,
+ int vertexCount,
+ int vformat,
+ int vdefined,
+ Object vcoords,
+ Object cdataBuffer,
+ float[] cfdata, byte[] cbdata,
+ Object normal,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ Object[] vertexAttrData,
+ int pass, int texcoordmaplength,
+ int[] texcoordoffset,
+ int numActiveTexUnitState, int[] texunitstatemap,
+ int texstride, Object[] texCoords,
+ int cdirty,
+ int[] indexCoord);
+
+ // by-copy geometry
+ private native void buildIndexedGeometry(long ctx,
+ GeometryArrayRetained geo, int geo_type,
+ boolean isNonUniformScale, boolean updateAlpha,
+ float alpha,
+ boolean ignoreVertexColors,
+ int initialIndexIndex,
+ int validIndexCount,
+ int vertexCount,
+ int vformat,
+ int vertexAttrCount, int[] vertexAttrSizes,
+ int texCoordSetCount, int texCoordSetMap[],
+ int texCoordSetMapLen,
+ int[] texCoordSetMapOffset,
+ double[] xform, double[] nxform,
+ float[] varray, int[] indexCoord);
void execute(Canvas3D cv, RenderAtom ra, boolean isNonUniformScale,
@@ -1081,23 +1109,24 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
// RenderBin render the geometry. So it is safe
// just to set the dirty flag here
dirtyFlag = 0;
- }
-
- executeIndexedGeometry(cv.ctx, this, geoType, isNonUniformScale,
- useAlpha,
- multiScreen,
- ignoreVertexColors,
- initialIndexIndex,
- validIndexCount,
- // Vertex Count is maxCoordIndex + 1
- maxCoordIndex + 1,
- ((vertexFormat & GeometryArray.COLOR) != 0)?(vertexFormat|GeometryArray.COLOR_4):vertexFormat,
- texCoordSetCount, texCoordSetMap,
- (texCoordSetMap == null) ? 0 : texCoordSetMap.length,
- texCoordSetMapOffset,
- cv.numActiveTexUnit, cv.texUnitStateMap,
- vdata, null,
- pass, cdirty, indexCoord);
+ }
+
+ executeIndexedGeometry(cv.ctx, this, geoType, isNonUniformScale,
+ useAlpha,
+ multiScreen,
+ ignoreVertexColors,
+ initialIndexIndex,
+ validIndexCount,
+ // Vertex Count is maxCoordIndex + 1
+ maxCoordIndex + 1,
+ ((vertexFormat & GeometryArray.COLOR) != 0)?(vertexFormat|GeometryArray.COLOR_4):vertexFormat,
+ vertexAttrCount, vertexAttrSizes,
+ texCoordSetCount, texCoordSetMap,
+ (texCoordSetMap == null) ? 0 : texCoordSetMap.length,
+ texCoordSetMapOffset,
+ cv.numActiveTexUnit, cv.texUnitStateMap,
+ vdata, null,
+ pass, cdirty, indexCoord);
} // end of non by reference
@@ -1127,31 +1156,34 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
}
dirtyFlag = 0;
}
-
- executeIndexedGeometry(cv.ctx, this, geoType, isNonUniformScale,
- useAlpha,
- multiScreen,
- ignoreVertexColors,
- initialIndexIndex,
- validIndexCount,
- maxCoordIndex + 1,
- vertexFormat,
- texCoordSetCount, texCoordSetMap,
- (texCoordSetMap == null) ? 0 : texCoordSetMap.length,
- texCoordSetMapOffset,
- cv.numActiveTexUnit, cv.texUnitStateMap,
- interLeavedVertexData, cdata,
- pass, cdirty, indexCoord);
+
+ executeIndexedGeometry(cv.ctx, this, geoType, isNonUniformScale,
+ useAlpha,
+ multiScreen,
+ ignoreVertexColors,
+ initialIndexIndex,
+ validIndexCount,
+ maxCoordIndex + 1,
+ vertexFormat,
+ vertexAttrCount, vertexAttrSizes,
+ texCoordSetCount, texCoordSetMap,
+ (texCoordSetMap == null) ? 0 : texCoordSetMap.length,
+ texCoordSetMapOffset,
+ cv.numActiveTexUnit, cv.texUnitStateMap,
+ interLeavedVertexData, cdata,
+ pass, cdirty, indexCoord);
} //end of interleaved
- else {
- // Check if a vertexformat is set, but the array is null
+ else {
+ // Check if a vertexformat is set, but the array is null
// if yes, don't draw anything
if ((vertexType == 0) ||
((vertexType & VERTEX_DEFINED) == 0) ||
(((vertexFormat & GeometryArray.COLOR) != 0) &&
(vertexType & COLOR_DEFINED) == 0) ||
(((vertexFormat & GeometryArray.NORMALS) != 0) &&
- (vertexType & NORMAL_DEFINED) == 0) ||
+ (vertexType & NORMAL_DEFINED) == 0) ||
+ (((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) &&
+ (vertexType & VATTR_DEFINED) == 0) ||
(((vertexFormat& GeometryArray.TEXTURE_COORDINATE) != 0) &&
(vertexType & TEXCOORD_DEFINED) == 0)) {
return;
@@ -1215,29 +1247,32 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
vdefined |= COLOR_BYTE;
if((vertexType & NORMAL_DEFINED) != 0)
vdefined |= NORMAL_FLOAT;
- if((vertexType & TEXCOORD_DEFINED) != 0)
- vdefined |= TEXCOORD_FLOAT;
-
- executeIndexedGeometryVA(cv.ctx, this, geoType, isNonUniformScale,
- multiScreen,
- ignoreVertexColors,
- initialIndexIndex,
- validIndexCount,
- maxCoordIndex + 1,
- (vertexFormat | c4fAllocated),
- vdefined,
- mirrorFloatRefCoords, mirrorDoubleRefCoords,
- cfdata, cbdata,
- mirrorFloatRefNormals,
- pass,
- ((texCoordSetMap == null) ? 0:texCoordSetMap.length),
- texCoordSetMap,
- cv.numActiveTexUnit,
- cv.texUnitStateMap,
- texCoordStride,
- mirrorRefTexCoords, cdirty, indexCoord);
-
- }
+ if((vertexType & VATTR_DEFINED) != 0)
+ vdefined |= VATTR_FLOAT;
+ if((vertexType & TEXCOORD_DEFINED) != 0)
+ vdefined |= TEXCOORD_FLOAT;
+
+ executeIndexedGeometryVA(cv.ctx, this, geoType, isNonUniformScale,
+ multiScreen,
+ ignoreVertexColors,
+ initialIndexIndex,
+ validIndexCount,
+ maxCoordIndex + 1,
+ (vertexFormat | c4fAllocated),
+ vdefined,
+ mirrorFloatRefCoords, mirrorDoubleRefCoords,
+ cfdata, cbdata,
+ mirrorFloatRefNormals,
+ vertexAttrCount, vertexAttrSizes,
+ mirrorFloatRefVertexAttrs,
+ pass,
+ ((texCoordSetMap == null) ? 0:texCoordSetMap.length),
+ texCoordSetMap,
+ cv.numActiveTexUnit,
+ cv.texUnitStateMap,
+ texCoordStride,
+ mirrorRefTexCoords, cdirty, indexCoord);
+ }
} // end of non interleaved and by reference
}//end of non io buffer
@@ -1284,15 +1319,17 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
interleavedFloatBufferImpl.getBufferAsObject(), cdata,
pass, cdirty, indexCoord);
} //end of interleaved
- else {
- // Check if a vertexformat is set, but the array is null
+ else {
+ // Check if a vertexformat is set, but the array is null
// if yes, don't draw anything
if ((vertexType == 0) ||
((vertexType & VERTEX_DEFINED) == 0) ||
(((vertexFormat & GeometryArray.COLOR) != 0) &&
(vertexType & COLOR_DEFINED) == 0) ||
(((vertexFormat & GeometryArray.NORMALS) != 0) &&
- (vertexType & NORMAL_DEFINED) == 0) ||
+ (vertexType & NORMAL_DEFINED) == 0) ||
+ (((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) &&
+ (vertexType & VATTR_DEFINED) == 0) ||
(((vertexFormat& GeometryArray.TEXTURE_COORDINATE) != 0) &&
(vertexType & TEXCOORD_DEFINED) == 0)) {
return;
@@ -1311,7 +1348,7 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
cdirty |= COLOR_CHANGED;
}
} else {
- // TODO: handle transparency case
+ // XXXX: handle transparency case
//cfdata = null;
cfdata = mirrorFloatRefColors[0];
// if transparency switch between on/off
@@ -1334,7 +1371,7 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
cdirty |= COLOR_CHANGED;
}
} else {
- // TODO: handle transparency case
+ // XXXX: handle transparency case
// cbdata = null;
cbdata = mirrorUnsignedByteRefColors[0];
// if transparency switch between on/off
@@ -1371,29 +1408,37 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
vdefined |= NORMAL_FLOAT;
normal = floatBufferRefNormals.getBufferAsObject();
}
-
- if((vertexType & TEXCOORD_DEFINED) != 0)
- vdefined |= TEXCOORD_FLOAT;
-
- executeIndexedGeometryVABuffer(cv.ctx, this, geoType, isNonUniformScale,
- multiScreen,
- ignoreVertexColors,
- initialIndexIndex,
- validIndexCount,
- maxCoordIndex + 1,
- (vertexFormat | c4fAllocated),
- vdefined,
- vcoord,
- cdataBuffer,
- cfdata, cbdata,
- normal,
- pass,
- ((texCoordSetMap == null) ? 0:texCoordSetMap.length),
- texCoordSetMap,
- cv.numActiveTexUnit,
- cv.texUnitStateMap,
- texCoordStride,
- refTexCoords, cdirty, indexCoord);
+
+ if ((vertexType & VATTR_DEFINED) != 0) {
+ vdefined |= VATTR_FLOAT;
+ }
+
+ if ((vertexType & TEXCOORD_DEFINED) != 0) {
+ vdefined |= TEXCOORD_FLOAT;
+ }
+
+ executeIndexedGeometryVABuffer(cv.ctx,
+ this, geoType, isNonUniformScale,
+ multiScreen,
+ ignoreVertexColors,
+ initialIndexIndex,
+ validIndexCount,
+ maxCoordIndex + 1,
+ (vertexFormat | c4fAllocated),
+ vdefined,
+ vcoord,
+ cdataBuffer,
+ cfdata, cbdata,
+ normal,
+ vertexAttrCount, vertexAttrSizes,
+ nioFloatBufferRefVertexAttrs,
+ pass,
+ ((texCoordSetMap == null) ? 0:texCoordSetMap.length),
+ texCoordSetMap,
+ cv.numActiveTexUnit,
+ cv.texUnitStateMap,
+ texCoordStride,
+ refTexCoords, cdirty, indexCoord);
}
} // end of non interleaved and by reference
@@ -1413,7 +1458,7 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
else {
if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0) {
- float[] vdata;
+ float[] vdata;
// System.out.println("by-copy");
synchronized (this) {
cdirty = dirtyFlag;
@@ -1443,19 +1488,26 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
dirtyFlag = 0;
}
- buildIndexedGeometry(cv.ctx, this, geoType, isNonUniformScale,
- updateAlpha, alpha, ignoreVertexColors,
- initialIndexIndex,
- validIndexCount,
- maxCoordIndex + 1,
- vertexFormat,
- texCoordSetCount, texCoordSetMap,
- (texCoordSetMap == null) ? 0 : texCoordSetMap.length,
- texCoordSetMapOffset,
- (xform == null) ? null : xform.mat,
- (nxform == null) ? null : nxform.mat,
- vdata, indexCoord);
+ buildIndexedGeometry(cv.ctx, this, geoType, isNonUniformScale,
+ updateAlpha, alpha, ignoreVertexColors,
+ initialIndexIndex,
+ validIndexCount,
+ maxCoordIndex + 1,
+ vertexFormat,
+ vertexAttrCount, vertexAttrSizes,
+ texCoordSetCount, texCoordSetMap,
+ (texCoordSetMap == null) ? 0 : texCoordSetMap.length,
+ texCoordSetMapOffset,
+ (xform == null) ? null : xform.mat,
+ (nxform == null) ? null : nxform.mat,
+ vdata, indexCoord);
}
+ // XXXX: Note that there is no "else" clause here, and no
+ // buildIndexedGeometryForByRef() method.
+ // We would need to create one if we ever wanted to support by-ref
+ // indexed geometry in display lists. Better yet, we could fix
+ // canBeInDisplayList so that unindexified by-ref geometry could
+ // go into a display list.
}
}
@@ -1478,11 +1530,12 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
indexColor = new int[indexCount];
if ((vertexFormat & GeometryArray.NORMALS) != 0)
indexNormal = new int[indexCount];
- // We only merge if texCoordSetCount = 1
+ // We only merge if the texCoordSetCount is 1 and there are no
+ // vertex attrs
if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
- indexTexCoord = new Object[1];
+ indexTexCoord = new int[1][];
indexTexCoord[0] = new int[indexCount];
- texCoord = (int[])indexTexCoord[0];
+ texCoord = indexTexCoord[0];
}
}
int curDataOffset = 0;
@@ -1500,7 +1553,7 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
if ((vertexFormat & GeometryArray.NORMALS) != 0)
indexNormal[j+curIndexOffset] = geo.indexNormal[j+geo.initialIndexIndex]+curDataOffset;
if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0)
- texCoord[j+curIndexOffset] = ((int[])geo.indexTexCoord[0])[j+geo.initialIndexIndex]+curDataOffset;
+ texCoord[j+curIndexOffset] = geo.indexTexCoord[0][j+geo.initialIndexIndex]+curDataOffset;
}
}
maxCoordIndex = geo.maxCoordIndex +curDataOffset;
@@ -1517,12 +1570,14 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
boolean isWriteStatic() {
- if (!super.isWriteStatic() ||
- source.getCapability(IndexedGeometryArray.ALLOW_COORDINATE_INDEX_WRITE ) ||
- source.getCapability(IndexedGeometryArray.ALLOW_COLOR_INDEX_WRITE) ||
- source.getCapability(IndexedGeometryArray.ALLOW_NORMAL_INDEX_WRITE) ||
- source.getCapability(IndexedGeometryArray.ALLOW_TEXCOORD_INDEX_WRITE))
- return false;
+ if (!super.isWriteStatic() ||
+ source.getCapability(IndexedGeometryArray.ALLOW_COORDINATE_INDEX_WRITE ) ||
+ source.getCapability(IndexedGeometryArray.ALLOW_COLOR_INDEX_WRITE) ||
+ source.getCapability(IndexedGeometryArray.ALLOW_NORMAL_INDEX_WRITE) ||
+ source.getCapability(IndexedGeometryArray.ALLOW_VERTEX_ATTR_INDEX_WRITE) ||
+ source.getCapability(IndexedGeometryArray.ALLOW_TEXCOORD_INDEX_WRITE)) {
+ return false;
+ }
return true;
}
@@ -1556,8 +1611,9 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
int newCoordMax =0;
int newColorIndex=0;
int newNormalIndex=0;
- int newTexCoordIndex[]=null;
-
+ int[] newTexCoordIndex = null;
+ int[] newVertexAttrIndex = null;
+
newCoordMax = computeMaxIndex(initialIndexIndex, validIndexCount,indexCoord );
doErrorCheck(newCoordMax);
if ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0) {
@@ -1569,10 +1625,19 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
newTexCoordIndex = new int[texCoordSetCount];
for (int i = 0; i < texCoordSetCount; i++) {
newTexCoordIndex[i] = computeMaxIndex(initialIndexIndex,validIndexCount,
- (int[])indexTexCoord[i]);
+ indexTexCoord[i]);
doTexCoordCheck(newTexCoordIndex[i], i);
}
}
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ newVertexAttrIndex = new int[vertexAttrCount];
+ for (int i = 0; i < vertexAttrCount; i++) {
+ newVertexAttrIndex[i] = computeMaxIndex(initialIndexIndex,
+ validIndexCount,
+ indexVertexAttr[i]);
+ doVertexAttrCheck(newVertexAttrIndex[i], i);
+ }
+ }
if ((vertexFormat & GeometryArray.NORMALS) != 0) {
newNormalIndex = computeMaxIndex(initialIndexIndex, validIndexCount, indexNormal);
doNormalCheck(newNormalIndex);
@@ -1589,6 +1654,11 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
maxTexCoordIndices[i] = newTexCoordIndex[i];
}
}
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ for (int i = 0; i < vertexAttrCount; i++) {
+ maxVertexAttrIndices[i] = newVertexAttrIndex[i];
+ }
+ }
maxNormalIndex = newNormalIndex;
}
else {
@@ -1599,6 +1669,11 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
maxTexCoordIndices[i] = maxCoordIndex;
}
}
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ for (int i = 0; i < vertexAttrCount; i++) {
+ maxVertexAttrIndices[i] = maxCoordIndex;
+ }
+ }
}
geomLock.unLock();
// bbox is computed for the entries list.
@@ -1616,8 +1691,9 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
int newCoordMax =0;
int newColorIndex=0;
int newNormalIndex=0;
- int newTexCoordIndex[]=null;
-
+ int[] newTexCoordIndex = null;
+ int[] newVertexAttrIndex = null;
+
newCoordMax = computeMaxIndex(initialIndexIndex, validIndexCount, indexCoord);
doErrorCheck(newCoordMax);
if ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0) {
@@ -1629,10 +1705,19 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
newTexCoordIndex = new int[texCoordSetCount];
for (int i = 0; i < texCoordSetCount; i++) {
newTexCoordIndex[i] = computeMaxIndex(initialIndexIndex,validIndexCount,
- (int[])indexTexCoord[i]);
+ indexTexCoord[i]);
doTexCoordCheck(newTexCoordIndex[i], i);
}
}
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ newVertexAttrIndex = new int[vertexAttrCount];
+ for (int i = 0; i < vertexAttrCount; i++) {
+ newVertexAttrIndex[i] = computeMaxIndex(initialIndexIndex,
+ validIndexCount,
+ indexVertexAttr[i]);
+ doVertexAttrCheck(newVertexAttrIndex[i], i);
+ }
+ }
if ((vertexFormat & GeometryArray.NORMALS) != 0) {
newNormalIndex = computeMaxIndex(initialIndexIndex, validIndexCount, indexNormal);
doNormalCheck(newNormalIndex);
@@ -1650,6 +1735,11 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
maxTexCoordIndices[i] = newTexCoordIndex[i];
}
}
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ for (int i = 0; i < vertexAttrCount; i++) {
+ maxVertexAttrIndices[i] = newVertexAttrIndex[i];
+ }
+ }
maxNormalIndex = newNormalIndex;
}
else {
@@ -1660,6 +1750,11 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
maxTexCoordIndices[i] = maxCoordIndex;
}
}
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ for (int i = 0; i < vertexAttrCount; i++) {
+ maxVertexAttrIndices[i] = maxCoordIndex;
+ }
+ }
}
geomLock.unLock();
// bbox is computed for the entries list.
@@ -1676,6 +1771,7 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
int getValidIndexCount() {
return validIndexCount;
}
+
void handleFrequencyChange(int bit) {
if ((bit == IndexedGeometryArray.ALLOW_COORDINATE_INDEX_WRITE) ||
(((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0) &&
@@ -1684,10 +1780,14 @@ abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained {
(((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0) &&
((vertexFormat & GeometryArray.NORMALS) != 0) &&
bit == IndexedGeometryArray.ALLOW_NORMAL_INDEX_WRITE) ||
+ (((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0)&&
+ ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0)&&
+ bit == IndexedGeometryArray.ALLOW_VERTEX_ATTR_INDEX_WRITE) ||
(((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0)&&
((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0)&&
bit == IndexedGeometryArray.ALLOW_TEXCOORD_INDEX_WRITE)) {
- setFrequencyChangeMask(bit, 0x1);
+
+ setFrequencyChangeMask(bit, 0x1);
}
else {
super.handleFrequencyChange(bit);
diff --git a/src/classes/share/javax/media/j3d/IndexedGeometryStripArray.java b/src/classes/share/javax/media/j3d/IndexedGeometryStripArray.java
index adce5e3..8f9073d 100644
--- a/src/classes/share/javax/media/j3d/IndexedGeometryStripArray.java
+++ b/src/classes/share/javax/media/j3d/IndexedGeometryStripArray.java
@@ -27,21 +27,19 @@ public abstract class IndexedGeometryStripArray extends IndexedGeometryArray {
* Constructs an empty IndexedGeometryStripArray object with the specified
* number of vertices, vertex format, number of indices, and
* array of per-strip index counts.
- * @param vertexCount the number of vertex elements in this array
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.
- * @param indexCount the number of indices in this object. This
- * count is the maximum number of vertices that will be rendered.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param indexCount
+ * see {@link IndexedGeometryArray#IndexedGeometryArray(int,int,int)}
+ * for a description of this parameter.
+ *
* @param stripIndexCounts array that specifies
* the count of the number of indices for each separate strip.
* The length of this array is the number of separate strips.
@@ -49,7 +47,10 @@ public abstract class IndexedGeometryStripArray extends IndexedGeometryArray {
* of valid indexed vertices that are rendered (validIndexCount).
*
* @exception IllegalArgumentException if
- * <code>validIndexCount > indexCount</code>
+ * <code>validIndexCount &gt; indexCount</code>
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int)}
+ * for more exceptions that can be thrown
*/
public IndexedGeometryStripArray(int vertexCount,
int vertexFormat,
@@ -67,56 +68,25 @@ public abstract class IndexedGeometryStripArray extends IndexedGeometryArray {
* sets, texture coordinate mapping array, number of indices, and
* array of per-strip index counts.
*
- * @param vertexCount the number of vertex elements in this object<p>
- *
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.<p>
- *
- * @param texCoordSetCount the number of texture coordinate sets
- * in this GeometryArray object. If <code>vertexFormat</code>
- * does not include one of <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetCount</code> parameter is not used.<p>
- *
- * @param texCoordSetMap an array that maps texture coordinate
- * sets to texture units. The array is indexed by texture unit
- * number for each texture unit in the associated Appearance
- * object. The values in the array specify the texture coordinate
- * set within this GeometryArray object that maps to the
- * corresponding texture
- * unit. All elements within the array must be less than
- * <code>texCoordSetCount</code>. A negative value specifies that
- * no texture coordinate set maps to the texture unit
- * corresponding to the index. If there are more texture units in
- * any associated Appearance object than elements in the mapping
- * array, the extra elements are assumed to be -1. The same
- * texture coordinate set may be used for more than one texture
- * unit. Each texture unit in every associated Appearance must
- * have a valid source of texture coordinates: either a
- * non-negative texture coordinate set must be specified in the
- * mapping array or texture coordinate generation must be enabled.
- * Texture coordinate generation will take precedence for those
- * texture units for which a texture coordinate set is specified
- * and texture coordinate generation is enabled. If
- * <code>vertexFormat</code> does not include one of
- * <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetMap</code> array is not used.<p>
- *
- * @param indexCount the number of indices in this object. This
- * count is the maximum number of vertices that will be rendered.<p>
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param indexCount
+ * see {@link IndexedGeometryArray#IndexedGeometryArray(int,int,int,int[],int)}
+ * for a description of this parameter.
*
* @param stripIndexCounts array that specifies
* the count of the number of indices for each separate strip.
@@ -125,7 +95,10 @@ public abstract class IndexedGeometryStripArray extends IndexedGeometryArray {
* of valid indexed vertices that are rendered (validIndexCount).
*
* @exception IllegalArgumentException if
- * <code>validIndexCount > indexCount</code>
+ * <code>validIndexCount &gt; indexCount</code>
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for more exceptions that can be thrown
*
* @since Java 3D 1.2
*/
@@ -143,6 +116,69 @@ public abstract class IndexedGeometryStripArray extends IndexedGeometryArray {
setStripIndexCounts(stripIndexCounts);
}
+ /**
+ * Constructs an empty IndexedGeometryStripArray object with the
+ * specified number of vertices, vertex format, number of texture
+ * coordinate sets, texture coordinate mapping array, vertex
+ * attribute count, vertex attribute sizes array, number of
+ * indices, and array of per-strip index counts.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrSizes
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param indexCount
+ * see {@link IndexedGeometryArray#IndexedGeometryArray(int,int,int,int[],int,int[],int)}
+ * for a description of this parameter.
+ *
+ * @param stripIndexCounts array that specifies
+ * the count of the number of indices for each separate strip.
+ * The length of this array is the number of separate strips.
+ * The sum of the elements in this array defines the total number
+ * of valid indexed vertices that are rendered (validIndexCount).
+ *
+ * @exception IllegalArgumentException if
+ * <code>validIndexCount &gt; indexCount</code>
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for more exceptions that can be thrown
+ *
+ * @since Java 3D 1.4
+ */
+ public IndexedGeometryStripArray(int vertexCount,
+ int vertexFormat,
+ int texCoordSetCount,
+ int[] texCoordSetMap,
+ int vertexAttrCount,
+ int[] vertexAttrSizes,
+ int indexCount,
+ int[] stripIndexCounts) {
+
+ super(vertexCount, vertexFormat,
+ texCoordSetCount, texCoordSetMap,
+ vertexAttrCount, vertexAttrSizes,
+ indexCount);
+
+ ((IndexedGeometryStripArrayRetained)this.retained).
+ setStripIndexCounts(stripIndexCounts);
+ }
+
/**
* Get number of strips in the GeometryStripArray
* @return numStrips number of strips
diff --git a/src/classes/share/javax/media/j3d/IndexedGeometryStripArrayRetained.java b/src/classes/share/javax/media/j3d/IndexedGeometryStripArrayRetained.java
index 0b7958a..7e6c09d 100644
--- a/src/classes/share/javax/media/j3d/IndexedGeometryStripArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/IndexedGeometryStripArrayRetained.java
@@ -32,15 +32,10 @@ abstract class IndexedGeometryStripArrayRetained extends IndexedGeometryArrayRet
/**
* Set stripIndexCount data into local array
*/
- void setStripIndexCounts(int stripIndexCounts[]){
-
+ void setStripIndexCounts(int stripIndexCounts[]) {
int i, num = stripIndexCounts.length, total = 0;
-
-
-
-
- for (i=0; i < num; i++) {
+ for (i=0; i < num; i++) {
total += stripIndexCounts[i];
if (this instanceof IndexedLineStripArrayRetained) {
if (stripIndexCounts[i] < 2) {
@@ -65,7 +60,8 @@ abstract class IndexedGeometryStripArrayRetained extends IndexedGeometryArrayRet
int newCoordMax =0;
int newColorIndex=0;
int newNormalIndex=0;
- int newTexCoordIndex[]=null;
+ int[] newTexCoordIndex = null;
+ int[] newVertexAttrIndex = null;
newCoordMax = computeMaxIndex(initialIndexIndex, total, indexCoord);
doErrorCheck(newCoordMax);
@@ -78,10 +74,19 @@ abstract class IndexedGeometryStripArrayRetained extends IndexedGeometryArrayRet
newTexCoordIndex = new int[texCoordSetCount];
for (i = 0; i < texCoordSetCount; i++) {
newTexCoordIndex[i] = computeMaxIndex(initialIndexIndex,total,
- (int[])indexTexCoord[i]);
+ indexTexCoord[i]);
doTexCoordCheck(newTexCoordIndex[i], i);
}
}
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ newVertexAttrIndex = new int[vertexAttrCount];
+ for (i = 0; i < vertexAttrCount; i++) {
+ newVertexAttrIndex[i] = computeMaxIndex(initialIndexIndex,
+ total,
+ indexVertexAttr[i]);
+ doTexCoordCheck(newVertexAttrIndex[i], i);
+ }
+ }
if ((vertexFormat & GeometryArray.NORMALS) != 0) {
newNormalIndex = computeMaxIndex(initialIndexIndex, total, indexNormal);
doNormalCheck(newNormalIndex);
@@ -103,6 +108,11 @@ abstract class IndexedGeometryStripArrayRetained extends IndexedGeometryArrayRet
maxTexCoordIndices[i] = newTexCoordIndex[i];
}
}
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ for (i = 0; i < vertexAttrCount; i++) {
+ maxVertexAttrIndices[i] = newVertexAttrIndex[i];
+ }
+ }
maxNormalIndex = newNormalIndex;
}
else {
@@ -113,6 +123,11 @@ abstract class IndexedGeometryStripArrayRetained extends IndexedGeometryArrayRet
maxTexCoordIndices[i] = maxCoordIndex;
}
}
+ if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ for (i = 0; i < vertexAttrCount; i++) {
+ maxVertexAttrIndices[i] = maxCoordIndex;
+ }
+ }
}
geomLock.unLock();
// bbox is computed for the entries list.
@@ -123,7 +138,7 @@ abstract class IndexedGeometryStripArrayRetained extends IndexedGeometryArrayRet
}
- Object cloneNonIndexedGeometry() {
+ GeometryArrayRetained cloneNonIndexedGeometry() {
GeometryStripArrayRetained obj = null;
int i;
switch (this.geoType) {
@@ -137,11 +152,14 @@ abstract class IndexedGeometryStripArrayRetained extends IndexedGeometryArrayRet
obj = new TriangleStripArrayRetained();
break;
}
- obj.createGeometryArrayData(validIndexCount, (vertexFormat & ~(GeometryArray.BY_REFERENCE|GeometryArray.INTERLEAVED|GeometryArray.USE_NIO_BUFFER)), texCoordSetCount, texCoordSetMap);
+ obj.createGeometryArrayData(validIndexCount,
+ (vertexFormat & ~(GeometryArray.BY_REFERENCE|GeometryArray.INTERLEAVED|GeometryArray.USE_NIO_BUFFER)),
+ texCoordSetCount, texCoordSetMap,
+ vertexAttrCount, vertexAttrSizes);
obj.unIndexify(this);
obj.setStripVertexCounts(stripIndexCounts);
- return (Object)obj;
+ return obj;
}
diff --git a/src/classes/share/javax/media/j3d/IndexedLineArray.java b/src/classes/share/javax/media/j3d/IndexedLineArray.java
index a28e613..28d267a 100644
--- a/src/classes/share/javax/media/j3d/IndexedLineArray.java
+++ b/src/classes/share/javax/media/j3d/IndexedLineArray.java
@@ -25,113 +25,142 @@ public class IndexedLineArray extends IndexedGeometryArray {
}
/**
- * Constructs an empty IndexedLineArray object with the specified
- * number of vertices, vertex format, and number of indices.
- * @param vertexCount the number of vertex elements in this object
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.
- * @param indexCount the number of indices in this object. This
- * count is the maximum number of vertices that will be rendered.
+ * Constructs an empty IndexedLineArray object using the specified
+ * parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param indexCount
+ * see {@link IndexedGeometryArray#IndexedGeometryArray(int,int,int)}
+ * for a description of this parameter.
+ *
* @exception IllegalArgumentException if vertexCount is less than 1,
* or indexCount is less than 2, or indexCount is <i>not</i>
* a multiple of 2
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int)}
+ * for more exceptions that can be thrown
*/
public IndexedLineArray(int vertexCount, int vertexFormat, int indexCount) {
super(vertexCount,vertexFormat, indexCount);
- if (vertexCount < 1)
- throw new IllegalArgumentException(J3dI18N.getString("IndexedLineArray0"));
+ if (vertexCount < 1)
+ throw new IllegalArgumentException(J3dI18N.getString("IndexedLineArray0"));
- if (indexCount < 2 || ((indexCount%2) != 0))
+ if (indexCount < 2 || ((indexCount%2) != 0))
throw new IllegalArgumentException(J3dI18N.getString("IndexedLineArray1"));
}
/**
- * Constructs an empty IndexedLineArray object with the specified
- * number of vertices, vertex format, number of texture coordinate
- * sets, texture coordinate mapping array, and number of indices.
- *
- * @param vertexCount the number of vertex elements in this object<p>
- *
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.<p>
- *
- * @param texCoordSetCount the number of texture coordinate sets
- * in this GeometryArray object. If <code>vertexFormat</code>
- * does not include one of <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3 or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetCount</code> parameter is not used.<p>
- *
- * @param texCoordSetMap an array that maps texture coordinate
- * sets to texture units. The array is indexed by texture unit
- * number for each texture unit in the associated Appearance
- * object. The values in the array specify the texture coordinate
- * set within this GeometryArray object that maps to the
- * corresponding texture
- * unit. All elements within the array must be less than
- * <code>texCoordSetCount</code>. A negative value specifies that
- * no texture coordinate set maps to the texture unit
- * corresponding to the index. If there are more texture units in
- * any associated Appearance object than elements in the mapping
- * array, the extra elements are assumed to be -1. The same
- * texture coordinate set may be used for more than one texture
- * unit. Each texture unit in every associated Appearance must
- * have a valid source of texture coordinates: either a
- * non-negative texture coordinate set must be specified in the
- * mapping array or texture coordinate generation must be enabled.
- * Texture coordinate generation will take precedence for those
- * texture units for which a texture coordinate set is specified
- * and texture coordinate generation is enabled. If
- * <code>vertexFormat</code> does not include one of
- * <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetMap</code> array is not used.<p>
- *
- * @param indexCount the number of indices in this object. This
- * count is the maximum number of vertices that will be rendered.
+ * Constructs an empty IndexedLineArray object using the specified
+ * parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param indexCount
+ * see {@link IndexedGeometryArray#IndexedGeometryArray(int,int,int,int[],int)}
+ * for a description of this parameter.
*
* @exception IllegalArgumentException if vertexCount is less than 1,
* or indexCount is less than 2, or indexCount is <i>not</i>
* a multiple of 2
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for more exceptions that can be thrown
*
* @since Java 3D 1.2
*/
public IndexedLineArray(int vertexCount,
+ int vertexFormat,
+ int texCoordSetCount,
+ int[] texCoordSetMap,
+ int indexCount) {
+
+ super(vertexCount, vertexFormat,
+ texCoordSetCount, texCoordSetMap,
+ indexCount);
+
+ if (vertexCount < 1)
+ throw new IllegalArgumentException(J3dI18N.getString("IndexedLineArray0"));
+
+ if (indexCount < 2 || ((indexCount%2) != 0))
+ throw new IllegalArgumentException(J3dI18N.getString("IndexedLineArray1"));
+ }
+
+ /**
+ * Constructs an empty IndexedLineArray object using the specified
+ * parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrSizes
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param indexCount
+ * see {@link IndexedGeometryArray#IndexedGeometryArray(int,int,int,int[],int,int[],int)}
+ * for a description of this parameter.
+ *
+ * @exception IllegalArgumentException if vertexCount is less than 1,
+ * or indexCount is less than 2, or indexCount is <i>not</i>
+ * a multiple of 2
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for more exceptions that can be thrown
+ *
+ * @since Java 3D 1.4
+ */
+ public IndexedLineArray(int vertexCount,
int vertexFormat,
int texCoordSetCount,
int[] texCoordSetMap,
+ int vertexAttrCount,
+ int[] vertexAttrSizes,
int indexCount) {
super(vertexCount, vertexFormat,
texCoordSetCount, texCoordSetMap,
+ vertexAttrCount, vertexAttrSizes,
indexCount);
- if (vertexCount < 1)
- throw new IllegalArgumentException(J3dI18N.getString("IndexedLineArray0"));
+ if (vertexCount < 1)
+ throw new IllegalArgumentException(J3dI18N.getString("IndexedLineArray0"));
- if (indexCount < 2 || ((indexCount%2) != 0))
+ if (indexCount < 2 || ((indexCount%2) != 0))
throw new IllegalArgumentException(J3dI18N.getString("IndexedLineArray1"));
}
@@ -148,22 +177,26 @@ public class IndexedLineArray extends IndexedGeometryArray {
* @deprecated replaced with cloneNodeComponent(boolean forceDuplicate)
*/
public NodeComponent cloneNodeComponent() {
- IndexedLineArrayRetained rt = (IndexedLineArrayRetained) retained;
- int texSetCount = rt.getTexCoordSetCount();
- IndexedLineArray l;
- if (texSetCount == 0) {
- l = new IndexedLineArray(rt.getVertexCount(),
- rt.getVertexFormat(),
- rt.getIndexCount());
- } else {
- int texMap[] = new int[rt.getTexCoordSetMapLength()];
- rt.getTexCoordSetMap(texMap);
- l = new IndexedLineArray(rt.getVertexCount(),
- rt.getVertexFormat(),
- texSetCount,
- texMap,
- rt.getIndexCount());
- }
+ IndexedLineArrayRetained rt = (IndexedLineArrayRetained) retained;
+ int texSetCount = rt.getTexCoordSetCount();
+ int[] texMap = null;
+ int vertexAttrCount = rt.getVertexAttrCount();
+ int[] vertexAttrSizes = null;
+ if (texSetCount > 0) {
+ texMap = new int[rt.getTexCoordSetMapLength()];
+ rt.getTexCoordSetMap(texMap);
+ }
+ if (vertexAttrCount > 0) {
+ vertexAttrSizes = new int[vertexAttrCount];
+ rt.getVertexAttrSizes(vertexAttrSizes);
+ }
+ IndexedLineArray l = new IndexedLineArray(rt.getVertexCount(),
+ rt.getVertexFormat(),
+ texSetCount,
+ texMap,
+ vertexAttrCount,
+ vertexAttrSizes,
+ rt.getIndexCount());
l.duplicateNodeComponent(this);
return l;
}
diff --git a/src/classes/share/javax/media/j3d/IndexedLineArrayRetained.java b/src/classes/share/javax/media/j3d/IndexedLineArrayRetained.java
index 54b4f14..bb9731f 100644
--- a/src/classes/share/javax/media/j3d/IndexedLineArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/IndexedLineArrayRetained.java
@@ -25,15 +25,16 @@ class IndexedLineArrayRetained extends IndexedGeometryArrayRetained {
IndexedLineArrayRetained() {
this.geoType = GEO_TYPE_INDEXED_LINE_SET;
}
-
- boolean intersect(PickShape pickShape, double dist[], Point3d iPnt) {
- Point3d pnts[] = new Point3d[2];
+
+ boolean intersect(PickShape pickShape, PickInfo.IntersectionInfo iInfo, int flags, Point3d iPnt) {
+ Point3d pnts[] = new Point3d[2];
double sdist[] = new double[1];
double minDist = Double.MAX_VALUE;
double x = 0, y = 0, z = 0;
- int i = ((vertexFormat & GeometryArray.BY_REFERENCE) == 0 ?
+ int count = 0;
+ int minICount = 0;
+ int i = ((vertexFormat & GeometryArray.BY_REFERENCE) == 0 ?
initialVertexIndex : initialCoordIndex);
-
pnts[0] = new Point3d();
pnts[1] = new Point3d();
@@ -44,15 +45,16 @@ class IndexedLineArrayRetained extends IndexedGeometryArrayRetained {
while (i < validVertexCount) {
getVertexData(indexCoord[i++], pnts[0]);
getVertexData(indexCoord[i++], pnts[1]);
-
+ count += 2;
if (intersectLineAndRay(pnts[0], pnts[1], pickRay.origin,
pickRay.direction, sdist,
iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -70,20 +72,21 @@ class IndexedLineArrayRetained extends IndexedGeometryArrayRetained {
while (i < validVertexCount) {
getVertexData(indexCoord[i++], pnts[0]);
getVertexData(indexCoord[i++], pnts[1]);
+ count += 2;
if (intersectLineAndRay(pnts[0], pnts[1],
pickSegment.start,
dir, sdist, iPnt) &&
(sdist[0] <= 1.0)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
}
-
}
}
break;
@@ -94,12 +97,14 @@ class IndexedLineArrayRetained extends IndexedGeometryArrayRetained {
while (i < validVertexCount) {
getVertexData(indexCoord[i++], pnts[0]);
getVertexData(indexCoord[i++], pnts[1]);
+ count += 2;
if (intersectBoundingBox(pnts, bbox, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -115,12 +120,14 @@ class IndexedLineArrayRetained extends IndexedGeometryArrayRetained {
while (i < validVertexCount) {
getVertexData(indexCoord[i++], pnts[0]);
getVertexData(indexCoord[i++], pnts[1]);
+ count += 2;
if (intersectBoundingSphere(pnts, bsphere, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -135,12 +142,14 @@ class IndexedLineArrayRetained extends IndexedGeometryArrayRetained {
while (i < validVertexCount) {
getVertexData(indexCoord[i++], pnts[0]);
getVertexData(indexCoord[i++], pnts[1]);
+ count += 2;
if (intersectBoundingPolytope(pnts, bpolytope, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -154,12 +163,14 @@ class IndexedLineArrayRetained extends IndexedGeometryArrayRetained {
while (i < validVertexCount) {
getVertexData(indexCoord[i++], pnts[0]);
getVertexData(indexCoord[i++], pnts[1]);
+ count += 2;
if (intersectCylinder(pnts, pickCylinder, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -173,12 +184,14 @@ class IndexedLineArrayRetained extends IndexedGeometryArrayRetained {
while (i < validVertexCount) {
getVertexData(indexCoord[i++], pnts[0]);
getVertexData(indexCoord[i++], pnts[1]);
+ count += 2;
if (intersectCone(pnts, pickCone, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -194,15 +207,22 @@ class IndexedLineArrayRetained extends IndexedGeometryArrayRetained {
}
if (minDist < Double.MAX_VALUE) {
- dist[0] = minDist;
+ assert(minICount >=2);
+ int[] vertexIndices = iInfo.getVertexIndices();
+ if (vertexIndices == null) {
+ vertexIndices = new int[2];
+ iInfo.setVertexIndices(vertexIndices);
+ }
+ vertexIndices[0] = minICount - 2;
+ vertexIndices[1] = minICount - 1;
iPnt.x = x;
iPnt.y = y;
iPnt.z = z;
- return true;
+ return true;
}
return false;
- }
+ }
boolean intersect(Point3d[] pnts) {
Point3d[] points = new Point3d[2];
diff --git a/src/classes/share/javax/media/j3d/IndexedLineStripArray.java b/src/classes/share/javax/media/j3d/IndexedLineStripArray.java
index 6a32086..34dbf3b 100644
--- a/src/classes/share/javax/media/j3d/IndexedLineStripArray.java
+++ b/src/classes/share/javax/media/j3d/IndexedLineStripArray.java
@@ -30,35 +30,36 @@ public class IndexedLineStripArray extends IndexedGeometryStripArray {
}
/**
- * Constructs an empty IndexedLineStripArray object with the specified
- * number of vertices, vertex format, number of indices, and
- * array of per-strip index counts.
- * @param vertexCount the number of vertex elements in this object
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.
- * @param indexCount the number of indices in this object. This
- * count is the maximum number of vertices that will be rendered.
- * @param stripIndexCounts array that specifies
- * the count of the number of indices for each separate strip.
- * The length of this array is the number of separate strips.
+ * Constructs an empty IndexedLineStripArray object using the
+ * specified parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param indexCount
+ * see {@link IndexedGeometryArray#IndexedGeometryArray(int,int,int)}
+ * for a description of this parameter.
+ *
+ * @param stripIndexCounts
+ * see {@link IndexedGeometryStripArray#IndexedGeometryStripArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
* @exception IllegalArgumentException if vertexCount is less than 1,
* or indexCount is less than 2,
* or any element in the stripIndexCounts array is less than 2
+ * ;<br>
+ * See {@link IndexedGeometryStripArray#IndexedGeometryStripArray(int,int,int,int[])}
+ * for more exceptions that can be thrown
*/
public IndexedLineStripArray(int vertexCount,
- int vertexFormat,
- int indexCount,
- int stripIndexCounts[]) {
+ int vertexFormat,
+ int indexCount,
+ int[] stripIndexCounts) {
super(vertexCount, vertexFormat, indexCount, stripIndexCounts);
@@ -70,81 +71,113 @@ public class IndexedLineStripArray extends IndexedGeometryStripArray {
}
/**
- * Constructs an empty IndexedLineStripArray object with the specified
- * number of vertices, vertex format, number of texture coordinate
- * sets, texture coordinate mapping array, number of indices, and
- * array of per-strip index counts.
- *
- * @param vertexCount the number of vertex elements in this object<p>
- *
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.<p>
- *
- * @param texCoordSetCount the number of texture coordinate sets
- * in this GeometryArray object. If <code>vertexFormat</code>
- * does not include one of <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetCount</code> parameter is not used.<p>
- *
- * @param texCoordSetMap an array that maps texture coordinate
- * sets to texture units. The array is indexed by texture unit
- * number for each texture unit in the associated Appearance
- * object. The values in the array specify the texture coordinate
- * set within this GeometryArray object that maps to the
- * corresponding texture
- * unit. All elements within the array must be less than
- * <code>texCoordSetCount</code>. A negative value specifies that
- * no texture coordinate set maps to the texture unit
- * corresponding to the index. If there are more texture units in
- * any associated Appearance object than elements in the mapping
- * array, the extra elements are assumed to be -1. The same
- * texture coordinate set may be used for more than one texture
- * unit. Each texture unit in every associated Appearance must
- * have a valid source of texture coordinates: either a
- * non-negative texture coordinate set must be specified in the
- * mapping array or texture coordinate generation must be enabled.
- * Texture coordinate generation will take precedence for those
- * texture units for which a texture coordinate set is specified
- * and texture coordinate generation is enabled. If
- * <code>vertexFormat</code> does not include one of
- * <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetMap</code> array is not used.<p>
- *
- * @param indexCount the number of indices in this object. This
- * count is the maximum number of vertices that will be rendered.<p>
- *
- * @param stripIndexCounts array that specifies
- * the count of the number of indices for each separate strip.
- * The length of this array is the number of separate strips.
+ * Constructs an empty IndexedLineStripArray object using the
+ * specified parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param indexCount
+ * see {@link IndexedGeometryArray#IndexedGeometryArray(int,int,int,int[],int)}
+ * for a description of this parameter.
+ *
+ * @param stripIndexCounts
+ * see {@link IndexedGeometryStripArray#IndexedGeometryStripArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
*
* @exception IllegalArgumentException if vertexCount is less than 1,
* or indexCount is less than 2,
* or any element in the stripIndexCounts array is less than 2
+ * ;<br>
+ * See {@link IndexedGeometryStripArray#IndexedGeometryStripArray(int,int,int,int[],int,int[])}
+ * for more exceptions that can be thrown
*
* @since Java 3D 1.2
*/
public IndexedLineStripArray(int vertexCount,
- int vertexFormat,
- int texCoordSetCount,
- int[] texCoordSetMap,
- int indexCount,
- int stripIndexCounts[]) {
+ int vertexFormat,
+ int texCoordSetCount,
+ int[] texCoordSetMap,
+ int indexCount,
+ int[] stripIndexCounts) {
+
+ super(vertexCount, vertexFormat,
+ texCoordSetCount, texCoordSetMap,
+ indexCount, stripIndexCounts);
+
+ if (vertexCount < 1)
+ throw new IllegalArgumentException(J3dI18N.getString("IndexedLineStripArray0"));
+
+ if (indexCount < 2 )
+ throw new IllegalArgumentException(J3dI18N.getString("IndexedLineStripArray1"));
+ }
+
+ /**
+ * Constructs an empty IndexedLineStripArray object using the
+ * specified parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrSizes
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param indexCount
+ * see {@link IndexedGeometryArray#IndexedGeometryArray(int,int,int,int[],int,int[],int)}
+ * for a description of this parameter.
+ *
+ * @param stripIndexCounts
+ * see {@link IndexedGeometryStripArray#IndexedGeometryStripArray(int,int,int,int[],int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @exception IllegalArgumentException if vertexCount is less than 1,
+ * or indexCount is less than 2,
+ * or any element in the stripIndexCounts array is less than 2
+ * ;<br>
+ * See {@link IndexedGeometryStripArray#IndexedGeometryStripArray(int,int,int,int[],int,int[],int,int[])}
+ * for more exceptions that can be thrown
+ *
+ * @since Java 3D 1.4
+ */
+ public IndexedLineStripArray(int vertexCount,
+ int vertexFormat,
+ int texCoordSetCount,
+ int[] texCoordSetMap,
+ int vertexAttrCount,
+ int[] vertexAttrSizes,
+ int indexCount,
+ int[] stripIndexCounts) {
super(vertexCount, vertexFormat,
texCoordSetCount, texCoordSetMap,
+ vertexAttrCount, vertexAttrSizes,
indexCount, stripIndexCounts);
if (vertexCount < 1)
@@ -168,29 +201,30 @@ public class IndexedLineStripArray extends IndexedGeometryStripArray {
* @deprecated replaced with cloneNodeComponent(boolean forceDuplicate)
*/
public NodeComponent cloneNodeComponent() {
- IndexedLineStripArrayRetained rt =
- (IndexedLineStripArrayRetained) retained;
+ IndexedLineStripArrayRetained rt =
+ (IndexedLineStripArrayRetained) retained;
int stripIndexCounts[] = new int[rt.getNumStrips()];
- rt.getStripIndexCounts(stripIndexCounts);
- int texSetCount = rt.getTexCoordSetCount();
- IndexedLineStripArray l;
-
- if (texSetCount == 0) {
- l = new IndexedLineStripArray(rt.getVertexCount(),
- rt.getVertexFormat(),
- rt.getIndexCount(),
- stripIndexCounts);
- } else {
- int texMap[] = new int[rt.getTexCoordSetMapLength()];
- rt.getTexCoordSetMap(texMap);
- l = new IndexedLineStripArray(rt.getVertexCount(),
- rt.getVertexFormat(),
- texSetCount,
- texMap,
- rt.getIndexCount(),
- stripIndexCounts);
-
- }
+ rt.getStripIndexCounts(stripIndexCounts);
+ int texSetCount = rt.getTexCoordSetCount();
+ int[] texMap = null;
+ int vertexAttrCount = rt.getVertexAttrCount();
+ int[] vertexAttrSizes = null;
+ if (texSetCount > 0) {
+ texMap = new int[rt.getTexCoordSetMapLength()];
+ rt.getTexCoordSetMap(texMap);
+ }
+ if (vertexAttrCount > 0) {
+ vertexAttrSizes = new int[vertexAttrCount];
+ rt.getVertexAttrSizes(vertexAttrSizes);
+ }
+ IndexedLineStripArray l = new IndexedLineStripArray(rt.getVertexCount(),
+ rt.getVertexFormat(),
+ texSetCount,
+ texMap,
+ vertexAttrCount,
+ vertexAttrSizes,
+ rt.getIndexCount(),
+ stripIndexCounts);
l.duplicateNodeComponent(this);
return l;
}
diff --git a/src/classes/share/javax/media/j3d/IndexedLineStripArrayRetained.java b/src/classes/share/javax/media/j3d/IndexedLineStripArrayRetained.java
index 7a91bd5..8791b9f 100644
--- a/src/classes/share/javax/media/j3d/IndexedLineStripArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/IndexedLineStripArrayRetained.java
@@ -29,14 +29,14 @@ class IndexedLineStripArrayRetained extends IndexedGeometryStripArrayRetained {
geoType = GEO_TYPE_INDEXED_LINE_STRIP_SET;
}
-
- boolean intersect(PickShape pickShape, double dist[], Point3d iPnt) {
+ boolean intersect(PickShape pickShape, PickInfo.IntersectionInfo iInfo, int flags, Point3d iPnt) {
Point3d pnts[] = new Point3d[2];
double sdist[] = new double[1];
double minDist = Double.MAX_VALUE;
double x = 0, y = 0, z = 0;
int scount, j, i = 0;
int count = 0;
+ int minICount = 0;
pnts[0] = new Point3d();
pnts[1] = new Point3d();
@@ -54,14 +54,15 @@ class IndexedLineStripArrayRetained extends IndexedGeometryStripArrayRetained {
if (intersectLineAndRay(pnts[0], pnts[1], pickRay.origin,
pickRay.direction, sdist,
iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[0].set(pnts[1]);
@@ -85,14 +86,15 @@ class IndexedLineStripArrayRetained extends IndexedGeometryStripArrayRetained {
pickSegment.start,
dir, sdist, iPnt) &&
(sdist[0] <= 1.0)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[0].set(pnts[1]);
@@ -111,14 +113,15 @@ class IndexedLineStripArrayRetained extends IndexedGeometryStripArrayRetained {
getVertexData(indexCoord[count++], pnts[1]);
if (intersectBoundingBox(pnts, bbox, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[0].set(pnts[1]);
@@ -138,14 +141,15 @@ class IndexedLineStripArrayRetained extends IndexedGeometryStripArrayRetained {
getVertexData(indexCoord[count++], pnts[1]);
if (intersectBoundingSphere(pnts, bsphere, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[0].set(pnts[1]);
@@ -164,14 +168,15 @@ class IndexedLineStripArrayRetained extends IndexedGeometryStripArrayRetained {
getVertexData(indexCoord[count++], pnts[1]);
if (intersectBoundingPolytope(pnts, bpolytope, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[0].set(pnts[1]);
@@ -189,14 +194,15 @@ class IndexedLineStripArrayRetained extends IndexedGeometryStripArrayRetained {
getVertexData(indexCoord[count++], pnts[1]);
if (intersectCylinder(pnts, pickCylinder, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[0].set(pnts[1]);
@@ -214,14 +220,15 @@ class IndexedLineStripArrayRetained extends IndexedGeometryStripArrayRetained {
getVertexData(indexCoord[count++], pnts[1]);
if (intersectCone(pnts, pickCone, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[0].set(pnts[1]);
@@ -236,14 +243,20 @@ class IndexedLineStripArrayRetained extends IndexedGeometryStripArrayRetained {
}
if (minDist < Double.MAX_VALUE) {
- dist[0] = minDist;
+ assert(minICount >=2);
+ int[] vertexIndices = iInfo.getVertexIndices();
+ if (vertexIndices == null) {
+ vertexIndices = new int[2];
+ iInfo.setVertexIndices(vertexIndices);
+ }
+ vertexIndices[0] = minICount - 2;
+ vertexIndices[1] = minICount - 1;
iPnt.x = x;
iPnt.y = y;
iPnt.z = z;
return true;
}
return false;
-
}
// intersect pnts[] with every triangle in this object
diff --git a/src/classes/share/javax/media/j3d/IndexedPointArray.java b/src/classes/share/javax/media/j3d/IndexedPointArray.java
index c780d34..7f01bd2 100644
--- a/src/classes/share/javax/media/j3d/IndexedPointArray.java
+++ b/src/classes/share/javax/media/j3d/IndexedPointArray.java
@@ -26,25 +26,26 @@ public class IndexedPointArray extends IndexedGeometryArray {
}
/**
- * Constructs an empty IndexedPointArray object with the specified
- * number of vertices, vertex format, and number of indices.
- * @param vertexCount the number of vertex elements in this object
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.
- * @param indexCount the number of indices in this object. This
- * count is the maximum number of vertices that will be rendered.
+ * Constructs an empty IndexedPointArray object using the specified
+ * parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param indexCount
+ * see {@link IndexedGeometryArray#IndexedGeometryArray(int,int,int)}
+ * for a description of this parameter.
+ *
* @exception IllegalArgumentException if vertexCount is less than 1
* or indexCount is less than 1
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int)}
+ * for more exceptions that can be thrown
*/
public IndexedPointArray(int vertexCount, int vertexFormat, int indexCount) {
super(vertexCount,vertexFormat, indexCount);
@@ -57,63 +58,34 @@ public class IndexedPointArray extends IndexedGeometryArray {
}
/**
- * Constructs an empty IndexedPointArray object with the specified
- * number of vertices, vertex format, number of texture coordinate
- * sets, texture coordinate mapping array, and number of indices.
- *
- * @param vertexCount the number of vertex elements in this object<p>
- *
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.<p>
- *
- * @param texCoordSetCount the number of texture coordinate sets
- * in this GeometryArray object. If <code>vertexFormat</code>
- * does not include one of <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3 or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetCount</code> parameter is not used.<p>
- *
- * @param texCoordSetMap an array that maps texture coordinate
- * sets to texture units. The array is indexed by texture unit
- * number for each texture unit in the associated Appearance
- * object. The values in the array specify the texture coordinate
- * set within this GeometryArray object that maps to the
- * corresponding texture
- * unit. All elements within the array must be less than
- * <code>texCoordSetCount</code>. A negative value specifies that
- * no texture coordinate set maps to the texture unit
- * corresponding to the index. If there are more texture units in
- * any associated Appearance object than elements in the mapping
- * array, the extra elements are assumed to be -1. The same
- * texture coordinate set may be used for more than one texture
- * unit. Each texture unit in every associated Appearance must
- * have a valid source of texture coordinates: either a
- * non-negative texture coordinate set must be specified in the
- * mapping array or texture coordinate generation must be enabled.
- * Texture coordinate generation will take precedence for those
- * texture units for which a texture coordinate set is specified
- * and texture coordinate generation is enabled. If
- * <code>vertexFormat</code> does not include one of
- * <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetMap</code> array is not used.<p>
- *
- * @param indexCount the number of indices in this object. This
- * count is the maximum number of vertices that will be rendered.
+ * Constructs an empty IndexedPointArray object using the specified
+ * parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param indexCount
+ * see {@link IndexedGeometryArray#IndexedGeometryArray(int,int,int,int[],int)}
+ * for a description of this parameter.
*
* @exception IllegalArgumentException if vertexCount is less than 1
* or indexCount is less than 1
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for more exceptions that can be thrown
*
* @since Java 3D 1.2
*/
@@ -135,6 +107,62 @@ public class IndexedPointArray extends IndexedGeometryArray {
}
/**
+ * Constructs an empty IndexedPointArray object using the specified
+ * parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrSizes
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param indexCount
+ * see {@link IndexedGeometryArray#IndexedGeometryArray(int,int,int,int[],int,int[],int)}
+ * for a description of this parameter.
+ *
+ * @exception IllegalArgumentException if vertexCount is less than 1
+ * or indexCount is less than 1
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for more exceptions that can be thrown
+ *
+ * @since Java 3D 1.4
+ */
+ public IndexedPointArray(int vertexCount,
+ int vertexFormat,
+ int texCoordSetCount,
+ int[] texCoordSetMap,
+ int vertexAttrCount,
+ int[] vertexAttrSizes,
+ int indexCount) {
+
+ super(vertexCount, vertexFormat,
+ texCoordSetCount, texCoordSetMap,
+ vertexAttrCount, vertexAttrSizes,
+ indexCount);
+
+ if (vertexCount < 1)
+ throw new IllegalArgumentException(J3dI18N.getString("IndexedPointArray0"));
+
+ if (indexCount < 1 )
+ throw new IllegalArgumentException(J3dI18N.getString("IndexedPointArray1"));
+ }
+
+ /**
* Creates the retained mode IndexedPointArrayRetained object that this
* IndexedPointArray object will point to.
*/
@@ -148,22 +176,26 @@ public class IndexedPointArray extends IndexedGeometryArray {
* @deprecated replaced with cloneNodeComponent(boolean forceDuplicate)
*/
public NodeComponent cloneNodeComponent() {
- IndexedPointArrayRetained rt = (IndexedPointArrayRetained) retained;
- int texSetCount = rt.getTexCoordSetCount();
- IndexedPointArray p;
- if (texSetCount == 0) {
- p = new IndexedPointArray(rt.getVertexCount(),
- rt.getVertexFormat(),
- rt.getIndexCount());
- } else {
- int texMap[] = new int[rt.getTexCoordSetMapLength()];
- rt.getTexCoordSetMap(texMap);
- p = new IndexedPointArray(rt.getVertexCount(),
- rt.getVertexFormat(),
- texSetCount,
- texMap,
- rt.getIndexCount());
- }
+ IndexedPointArrayRetained rt = (IndexedPointArrayRetained) retained;
+ int texSetCount = rt.getTexCoordSetCount();
+ int[] texMap = null;
+ int vertexAttrCount = rt.getVertexAttrCount();
+ int[] vertexAttrSizes = null;
+ if (texSetCount > 0) {
+ texMap = new int[rt.getTexCoordSetMapLength()];
+ rt.getTexCoordSetMap(texMap);
+ }
+ if (vertexAttrCount > 0) {
+ vertexAttrSizes = new int[vertexAttrCount];
+ rt.getVertexAttrSizes(vertexAttrSizes);
+ }
+ IndexedPointArray p = new IndexedPointArray(rt.getVertexCount(),
+ rt.getVertexFormat(),
+ texSetCount,
+ texMap,
+ vertexAttrCount,
+ vertexAttrSizes,
+ rt.getIndexCount());
p.duplicateNodeComponent(this);
return p;
}
diff --git a/src/classes/share/javax/media/j3d/IndexedPointArrayRetained.java b/src/classes/share/javax/media/j3d/IndexedPointArrayRetained.java
index 8c63a73..f7289c5 100644
--- a/src/classes/share/javax/media/j3d/IndexedPointArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/IndexedPointArrayRetained.java
@@ -25,10 +25,12 @@ class IndexedPointArrayRetained extends IndexedGeometryArrayRetained {
this.geoType = GEO_TYPE_INDEXED_POINT_SET;
}
- boolean intersect(PickShape pickShape, double dist[], Point3d iPnt) {
- double sdist[] = new double[1];
+ boolean intersect(PickShape pickShape, PickInfo.IntersectionInfo iInfo, int flags, Point3d iPnt) {
+ double sdist[] = new double[1];
double minDist = Double.MAX_VALUE;
double x = 0, y = 0, z = 0;
+ int count = 0;
+ int minICount = 0;
Point3d pnt = new Point3d();
int i = ((vertexFormat & GeometryArray.BY_REFERENCE) == 0 ?
initialVertexIndex : initialCoordIndex);
@@ -39,13 +41,15 @@ class IndexedPointArrayRetained extends IndexedGeometryArrayRetained {
while (i < validVertexCount) {
getVertexData(indexCoord[i++], pnt);
+ count++;
if (intersectPntAndRay(pnt, pickRay.origin,
pickRay.direction, sdist)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = pnt.x;
y = pnt.y;
z = pnt.z;
@@ -62,19 +66,20 @@ class IndexedPointArrayRetained extends IndexedGeometryArrayRetained {
while (i < validVertexCount) {
getVertexData(indexCoord[i++], pnt);
+ count++;
if (intersectPntAndRay(pnt, pickSegment.start,
dir, sdist) &&
(sdist[0] <= 1.0)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = pnt.x;
y = pnt.y;
z = pnt.z;
}
-
}
}
break;
@@ -85,33 +90,35 @@ class IndexedPointArrayRetained extends IndexedGeometryArrayRetained {
while (i < validVertexCount) {
getVertexData(indexCoord[i++], pnt);
+ count++;
if (bounds.intersect(pnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
sdist[0] = pickShape.distance(pnt);
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = pnt.x;
y = pnt.y;
z = pnt.z;
}
}
}
-
break;
case PickShape.PICKCYLINDER:
PickCylinder pickCylinder= (PickCylinder) pickShape;
while (i < validVertexCount) {
getVertexData(indexCoord[i++], pnt);
-
+ count++;
if (intersectCylinder(pnt, pickCylinder, sdist)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = pnt.x;
y = pnt.y;
z = pnt.z;
@@ -124,13 +131,14 @@ class IndexedPointArrayRetained extends IndexedGeometryArrayRetained {
while (i < validVertexCount) {
getVertexData(indexCoord[i++], pnt);
-
+ count++;
if (intersectCone(pnt, pickCone, sdist)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = pnt.x;
y = pnt.y;
z = pnt.z;
@@ -146,7 +154,13 @@ class IndexedPointArrayRetained extends IndexedGeometryArrayRetained {
}
if (minDist < Double.MAX_VALUE) {
- dist[0] = minDist;
+ assert(minICount >=1);
+ int[] vertexIndices = iInfo.getVertexIndices();
+ if (vertexIndices == null) {
+ vertexIndices = new int[1];
+ iInfo.setVertexIndices(vertexIndices);
+ }
+ vertexIndices[0] = minICount - 1;
iPnt.x = x;
iPnt.y = y;
iPnt.z = z;
diff --git a/src/classes/share/javax/media/j3d/IndexedQuadArray.java b/src/classes/share/javax/media/j3d/IndexedQuadArray.java
index 4368340..1c94c4b 100644
--- a/src/classes/share/javax/media/j3d/IndexedQuadArray.java
+++ b/src/classes/share/javax/media/j3d/IndexedQuadArray.java
@@ -27,26 +27,27 @@ public class IndexedQuadArray extends IndexedGeometryArray {
}
/**
- * Constructs an empty IndexedQuadArray object with the specified
- * number of vertices, vertex format, and number of indices.
- * @param vertexCount the number of vertex elements in this object
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.
- * @param indexCount the number of indices in this object. This
- * count is the maximum number of vertices that will be rendered.
+ * Constructs an empty IndexedQuadArray object using the specified
+ * parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param indexCount
+ * see {@link IndexedGeometryArray#IndexedGeometryArray(int,int,int)}
+ * for a description of this parameter.
+ *
* @exception IllegalArgumentException if vertexCount is less than 1,
* or indexCount is less than 4, or indexCount is <i>not</i>
* a multiple of 4
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int)}
+ * for more exceptions that can be thrown
*/
public IndexedQuadArray(int vertexCount, int vertexFormat, int indexCount) {
super(vertexCount,vertexFormat, indexCount);
@@ -59,64 +60,35 @@ public class IndexedQuadArray extends IndexedGeometryArray {
}
/**
- * Constructs an empty IndexedQuadArray object with the specified
- * number of vertices, vertex format, number of texture coordinate
- * sets, texture coordinate mapping array, and number of indices.
- *
- * @param vertexCount the number of vertex elements in this object<p>
- *
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.<p>
- *
- * @param texCoordSetCount the number of texture coordinate sets
- * in this GeometryArray object. If <code>vertexFormat</code>
- * does not include one of <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetCount</code> parameter is not used.<p>
- *
- * @param texCoordSetMap an array that maps texture coordinate
- * sets to texture units. The array is indexed by texture unit
- * number for each texture unit in the associated Appearance
- * object. The values in the array specify the texture coordinate
- * set within this GeometryArray object that maps to the
- * corresponding texture
- * unit. All elements within the array must be less than
- * <code>texCoordSetCount</code>. A negative value specifies that
- * no texture coordinate set maps to the texture unit
- * corresponding to the index. If there are more texture units in
- * any associated Appearance object than elements in the mapping
- * array, the extra elements are assumed to be -1. The same
- * texture coordinate set may be used for more than one texture
- * unit. Each texture unit in every associated Appearance must
- * have a valid source of texture coordinates: either a
- * non-negative texture coordinate set must be specified in the
- * mapping array or texture coordinate generation must be enabled.
- * Texture coordinate generation will take precedence for those
- * texture units for which a texture coordinate set is specified
- * and texture coordinate generation is enabled. If
- * <code>vertexFormat</code> does not include one of
- * <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetMap</code> array is not used.<p>
- *
- * @param indexCount the number of indices in this object. This
- * count is the maximum number of vertices that will be rendered.
+ * Constructs an empty IndexedQuadArray object using the specified
+ * parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param indexCount
+ * see {@link IndexedGeometryArray#IndexedGeometryArray(int,int,int,int[],int)}
+ * for a description of this parameter.
*
* @exception IllegalArgumentException if vertexCount is less than 1,
* or indexCount is less than 4, or indexCount is <i>not</i>
* a multiple of 4
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for more exceptions that can be thrown
*
* @since Java 3D 1.2
*/
@@ -138,6 +110,63 @@ public class IndexedQuadArray extends IndexedGeometryArray {
}
/**
+ * Constructs an empty IndexedQuadArray object using the specified
+ * parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrSizes
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param indexCount
+ * see {@link IndexedGeometryArray#IndexedGeometryArray(int,int,int,int[],int,int[],int)}
+ * for a description of this parameter.
+ *
+ * @exception IllegalArgumentException if vertexCount is less than 1,
+ * or indexCount is less than 4, or indexCount is <i>not</i>
+ * a multiple of 4
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for more exceptions that can be thrown
+ *
+ * @since Java 3D 1.4
+ */
+ public IndexedQuadArray(int vertexCount,
+ int vertexFormat,
+ int texCoordSetCount,
+ int[] texCoordSetMap,
+ int vertexAttrCount,
+ int[] vertexAttrSizes,
+ int indexCount) {
+
+ super(vertexCount, vertexFormat,
+ texCoordSetCount, texCoordSetMap,
+ vertexAttrCount, vertexAttrSizes,
+ indexCount);
+
+ if (vertexCount < 1)
+ throw new IllegalArgumentException(J3dI18N.getString("IndexedQuadArray0"));
+
+ if (indexCount < 4 || ((indexCount%4) != 0))
+ throw new IllegalArgumentException(J3dI18N.getString("IndexedQuadArray1"));
+ }
+
+ /**
* Creates the retained mode IndexedQuadArrayRetained object that this
* IndexedQuadArray object will point to.
*/
@@ -151,23 +180,26 @@ public class IndexedQuadArray extends IndexedGeometryArray {
* @deprecated replaced with cloneNodeComponent(boolean forceDuplicate)
*/
public NodeComponent cloneNodeComponent() {
- IndexedQuadArrayRetained rt = (IndexedQuadArrayRetained) retained;
- int texSetCount = rt.getTexCoordSetCount();
- IndexedQuadArray q;
-
- if (texSetCount == 0) {
- q = new IndexedQuadArray(rt.getVertexCount(),
- rt.getVertexFormat(),
- rt.getIndexCount());
- } else {
- int texMap[] = new int[rt.getTexCoordSetMapLength()];
- rt.getTexCoordSetMap(texMap);
- q = new IndexedQuadArray(rt.getVertexCount(),
- rt.getVertexFormat(),
- texSetCount,
- texMap,
- rt.getIndexCount());
- }
+ IndexedQuadArrayRetained rt = (IndexedQuadArrayRetained) retained;
+ int texSetCount = rt.getTexCoordSetCount();
+ int[] texMap = null;
+ int vertexAttrCount = rt.getVertexAttrCount();
+ int[] vertexAttrSizes = null;
+ if (texSetCount > 0) {
+ texMap = new int[rt.getTexCoordSetMapLength()];
+ rt.getTexCoordSetMap(texMap);
+ }
+ if (vertexAttrCount > 0) {
+ vertexAttrSizes = new int[vertexAttrCount];
+ rt.getVertexAttrSizes(vertexAttrSizes);
+ }
+ IndexedQuadArray q = new IndexedQuadArray(rt.getVertexCount(),
+ rt.getVertexFormat(),
+ texSetCount,
+ texMap,
+ vertexAttrCount,
+ vertexAttrSizes,
+ rt.getIndexCount());
q.duplicateNodeComponent(this);
return q;
}
diff --git a/src/classes/share/javax/media/j3d/IndexedQuadArrayRetained.java b/src/classes/share/javax/media/j3d/IndexedQuadArrayRetained.java
index f06c62d..355f471 100644
--- a/src/classes/share/javax/media/j3d/IndexedQuadArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/IndexedQuadArrayRetained.java
@@ -27,15 +27,15 @@ class IndexedQuadArrayRetained extends IndexedGeometryArrayRetained {
this.geoType = GEO_TYPE_INDEXED_QUAD_SET;
}
-
- boolean intersect(PickShape pickShape, double dist[], Point3d iPnt) {
+ boolean intersect(PickShape pickShape, PickInfo.IntersectionInfo iInfo, int flags, Point3d iPnt) {
Point3d pnts[] = new Point3d[4];
double sdist[] = new double[1];
double minDist = Double.MAX_VALUE;
double x = 0, y = 0, z = 0;
+ int count = 0;
+ int minICount = 0;
int i = ((vertexFormat & GeometryArray.BY_REFERENCE) == 0 ?
- initialVertexIndex : initialCoordIndex);
-
+ initialVertexIndex : initialCoordIndex);
pnts[0] = new Point3d();
pnts[1] = new Point3d();
pnts[2] = new Point3d();
@@ -50,12 +50,14 @@ class IndexedQuadArrayRetained extends IndexedGeometryArrayRetained {
getVertexData(indexCoord[i++], pnts[1]);
getVertexData(indexCoord[i++], pnts[2]);
getVertexData(indexCoord[i++], pnts[3]);
+ count += 4;
if (intersectRay(pnts, pickRay, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -71,18 +73,19 @@ class IndexedQuadArrayRetained extends IndexedGeometryArrayRetained {
getVertexData(indexCoord[i++], pnts[1]);
getVertexData(indexCoord[i++], pnts[2]);
getVertexData(indexCoord[i++], pnts[3]);
+ count += 4;
if (intersectSegment(pnts, pickSegment.start,
pickSegment.end, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
- }
-
+ }
}
}
break;
@@ -94,108 +97,108 @@ class IndexedQuadArrayRetained extends IndexedGeometryArrayRetained {
getVertexData(indexCoord[i++], pnts[1]);
getVertexData(indexCoord[i++], pnts[2]);
getVertexData(indexCoord[i++], pnts[3]);
-
+ count += 4;
if (intersectBoundingBox(pnts, bbox, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
- }
+ }
}
}
-
break;
case PickShape.PICKBOUNDINGSPHERE:
BoundingSphere bsphere = (BoundingSphere)
((PickBounds) pickShape).bounds;
-
while (i < validVertexCount) {
getVertexData(indexCoord[i++], pnts[0]);
getVertexData(indexCoord[i++], pnts[1]);
getVertexData(indexCoord[i++], pnts[2]);
getVertexData(indexCoord[i++], pnts[3]);
-
+ count += 4;
if (intersectBoundingSphere(pnts, bsphere, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
- }
+ }
}
}
break;
case PickShape.PICKBOUNDINGPOLYTOPE:
-
BoundingPolytope bpolytope = (BoundingPolytope)
((PickBounds) pickShape).bounds;
-
while (i < validVertexCount) {
getVertexData(indexCoord[i++], pnts[0]);
getVertexData(indexCoord[i++], pnts[1]);
getVertexData(indexCoord[i++], pnts[2]);
getVertexData(indexCoord[i++], pnts[3]);
-
+ count += 4;
if (intersectBoundingPolytope(pnts, bpolytope, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
- }
+ }
}
}
break;
case PickShape.PICKCYLINDER:
PickCylinder pickCylinder= (PickCylinder) pickShape;
-
while (i < validVertexCount) {
getVertexData(indexCoord[i++], pnts[0]);
getVertexData(indexCoord[i++], pnts[1]);
getVertexData(indexCoord[i++], pnts[2]);
getVertexData(indexCoord[i++], pnts[3]);
-
+ count += 4;
if (intersectCylinder(pnts, pickCylinder, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
- }
+ }
}
}
break;
case PickShape.PICKCONE:
PickCone pickCone= (PickCone) pickShape;
-
while (i < validVertexCount) {
getVertexData(indexCoord[i++], pnts[0]);
getVertexData(indexCoord[i++], pnts[1]);
getVertexData(indexCoord[i++], pnts[2]);
getVertexData(indexCoord[i++], pnts[3]);
+ count += 4;
if (intersectCone(pnts, pickCone, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
- }
+ }
}
}
break;
@@ -207,7 +210,16 @@ class IndexedQuadArrayRetained extends IndexedGeometryArrayRetained {
}
if (minDist < Double.MAX_VALUE) {
- dist[0] = minDist;
+ assert(minICount >= 4);
+ int[] vertexIndices = iInfo.getVertexIndices();
+ if (vertexIndices == null) {
+ vertexIndices = new int[4];
+ iInfo.setVertexIndices(vertexIndices);
+ }
+ vertexIndices[0] = minICount - 4;
+ vertexIndices[1] = minICount - 3;
+ vertexIndices[2] = minICount - 2;
+ vertexIndices[3] = minICount - 1;
iPnt.x = x;
iPnt.y = y;
iPnt.z = z;
@@ -215,8 +227,7 @@ class IndexedQuadArrayRetained extends IndexedGeometryArrayRetained {
}
return false;
- }
-
+ }
// intersect pnts[] with every quad in this object
boolean intersect(Point3d[] pnts) {
diff --git a/src/classes/share/javax/media/j3d/IndexedTriangleArray.java b/src/classes/share/javax/media/j3d/IndexedTriangleArray.java
index 300a812..3f923a4 100644
--- a/src/classes/share/javax/media/j3d/IndexedTriangleArray.java
+++ b/src/classes/share/javax/media/j3d/IndexedTriangleArray.java
@@ -27,32 +27,32 @@ public class IndexedTriangleArray extends IndexedGeometryArray {
}
/**
- * Constructs an empty IndexedTriangleArray object with the specified
- * number of vertices, vertex format, and number of indices.
- * @param vertexCount the number of vertex elements in this object
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.
- * @param indexCount the number of indices in this object. This
- * count is the maximum number of vertices that will be rendered.
+ * Constructs an empty IndexedTriangleArray object using the specified
+ * parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param indexCount
+ * see {@link IndexedGeometryArray#IndexedGeometryArray(int,int,int)}
+ * for a description of this parameter.
+ *
* @exception IllegalArgumentException if vertexCount is less than 1,
* or indexCount is less than 3, or indexCount is <i>not</i>
* a multiple of 3
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int)}
+ * for more exceptions that can be thrown
*/
- public IndexedTriangleArray(int vertexCount, int vertexFormat,
- int indexCount) {
+ public IndexedTriangleArray(int vertexCount, int vertexFormat, int indexCount) {
super(vertexCount,vertexFormat, indexCount);
- if (vertexCount < 1)
+ if (vertexCount < 1)
throw new IllegalArgumentException(J3dI18N.getString("IndexedTriangleArray0"));
if (indexCount < 3 || ((indexCount%3) != 0))
@@ -60,64 +60,35 @@ public class IndexedTriangleArray extends IndexedGeometryArray {
}
/**
- * Constructs an empty IndexedTriangleArray object with the specified
- * number of vertices, vertex format, number of texture coordinate
- * sets, texture coordinate mapping array, and number of indices.
- *
- * @param vertexCount the number of vertex elements in this object<p>
- *
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.<p>
- *
- * @param texCoordSetCount the number of texture coordinate sets
- * in this GeometryArray object. If <code>vertexFormat</code>
- * does not include one of <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetCount</code> parameter is not used.<p>
- *
- * @param texCoordSetMap an array that maps texture coordinate
- * sets to texture units. The array is indexed by texture unit
- * number for each texture unit in the associated Appearance
- * object. The values in the array specify the texture coordinate
- * set within this GeometryArray object that maps to the
- * corresponding texture
- * unit. All elements within the array must be less than
- * <code>texCoordSetCount</code>. A negative value specifies that
- * no texture coordinate set maps to the texture unit
- * corresponding to the index. If there are more texture units in
- * any associated Appearance object than elements in the mapping
- * array, the extra elements are assumed to be -1. The same
- * texture coordinate set may be used for more than one texture
- * unit. Each texture unit in every associated Appearance must
- * have a valid source of texture coordinates: either a
- * non-negative texture coordinate set must be specified in the
- * mapping array or texture coordinate generation must be enabled.
- * Texture coordinate generation will take precedence for those
- * texture units for which a texture coordinate set is specified
- * and texture coordinate generation is enabled. If
- * <code>vertexFormat</code> does not include one of
- * <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetMap</code> array is not used.<p>
- *
- * @param indexCount the number of indices in this object. This
- * count is the maximum number of vertices that will be rendered.
+ * Constructs an empty IndexedTriangleArray object using the specified
+ * parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param indexCount
+ * see {@link IndexedGeometryArray#IndexedGeometryArray(int,int,int,int[],int)}
+ * for a description of this parameter.
*
* @exception IllegalArgumentException if vertexCount is less than 1,
* or indexCount is less than 3, or indexCount is <i>not</i>
* a multiple of 3
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for more exceptions that can be thrown
*
* @since Java 3D 1.2
*/
@@ -131,7 +102,64 @@ public class IndexedTriangleArray extends IndexedGeometryArray {
texCoordSetCount, texCoordSetMap,
indexCount);
- if (vertexCount < 1)
+ if (vertexCount < 1)
+ throw new IllegalArgumentException(J3dI18N.getString("IndexedTriangleArray0"));
+
+ if (indexCount < 3 || ((indexCount%3) != 0))
+ throw new IllegalArgumentException(J3dI18N.getString("IndexedTriangleArray1"));
+ }
+
+ /**
+ * Constructs an empty IndexedTriangleArray object using the specified
+ * parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrSizes
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param indexCount
+ * see {@link IndexedGeometryArray#IndexedGeometryArray(int,int,int,int[],int,int[],int)}
+ * for a description of this parameter.
+ *
+ * @exception IllegalArgumentException if vertexCount is less than 1,
+ * or indexCount is less than 3, or indexCount is <i>not</i>
+ * a multiple of 3
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for more exceptions that can be thrown
+ *
+ * @since Java 3D 1.4
+ */
+ public IndexedTriangleArray(int vertexCount,
+ int vertexFormat,
+ int texCoordSetCount,
+ int[] texCoordSetMap,
+ int vertexAttrCount,
+ int[] vertexAttrSizes,
+ int indexCount) {
+
+ super(vertexCount, vertexFormat,
+ texCoordSetCount, texCoordSetMap,
+ vertexAttrCount, vertexAttrSizes,
+ indexCount);
+
+ if (vertexCount < 1)
throw new IllegalArgumentException(J3dI18N.getString("IndexedTriangleArray0"));
if (indexCount < 3 || ((indexCount%3) != 0))
@@ -152,23 +180,26 @@ public class IndexedTriangleArray extends IndexedGeometryArray {
* @deprecated replaced with cloneNodeComponent(boolean forceDuplicate)
*/
public NodeComponent cloneNodeComponent() {
- IndexedTriangleArrayRetained rt = (IndexedTriangleArrayRetained) retained;
- int texSetCount = rt.getTexCoordSetCount();
- IndexedTriangleArray t;
-
- if (texSetCount == 0) {
- t = new IndexedTriangleArray(rt.getVertexCount(),
- rt.getVertexFormat(),
- rt.getIndexCount());
- } else {
- int texMap[] = new int[rt.getTexCoordSetMapLength()];
- rt.getTexCoordSetMap(texMap);
- t = new IndexedTriangleArray(rt.getVertexCount(),
- rt.getVertexFormat(),
- texSetCount,
- texMap,
- rt.getIndexCount());
- }
+ IndexedTriangleArrayRetained rt = (IndexedTriangleArrayRetained) retained;
+ int texSetCount = rt.getTexCoordSetCount();
+ int[] texMap = null;
+ int vertexAttrCount = rt.getVertexAttrCount();
+ int[] vertexAttrSizes = null;
+ if (texSetCount > 0) {
+ texMap = new int[rt.getTexCoordSetMapLength()];
+ rt.getTexCoordSetMap(texMap);
+ }
+ if (vertexAttrCount > 0) {
+ vertexAttrSizes = new int[vertexAttrCount];
+ rt.getVertexAttrSizes(vertexAttrSizes);
+ }
+ IndexedTriangleArray t = new IndexedTriangleArray(rt.getVertexCount(),
+ rt.getVertexFormat(),
+ texSetCount,
+ texMap,
+ vertexAttrCount,
+ vertexAttrSizes,
+ rt.getIndexCount());
t.duplicateNodeComponent(this);
return t;
}
diff --git a/src/classes/share/javax/media/j3d/IndexedTriangleArrayRetained.java b/src/classes/share/javax/media/j3d/IndexedTriangleArrayRetained.java
index f76dc69..d977894 100644
--- a/src/classes/share/javax/media/j3d/IndexedTriangleArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/IndexedTriangleArrayRetained.java
@@ -27,14 +27,15 @@ class IndexedTriangleArrayRetained extends IndexedGeometryArrayRetained {
this.geoType = GEO_TYPE_INDEXED_TRI_SET;
}
- boolean intersect(PickShape pickShape, double dist[], Point3d iPnt) {
+ boolean intersect(PickShape pickShape, PickInfo.IntersectionInfo iInfo, int flags, Point3d iPnt) {
Point3d pnts[] = new Point3d[3];
double sdist[] = new double[1];
double minDist = Double.MAX_VALUE;
double x = 0, y = 0, z = 0;
+ int count = 0;
+ int minICount = 0;
int i = ((vertexFormat & GeometryArray.BY_REFERENCE) == 0 ?
initialVertexIndex : initialCoordIndex);
-
pnts[0] = new Point3d();
pnts[1] = new Point3d();
pnts[2] = new Point3d();
@@ -47,15 +48,17 @@ class IndexedTriangleArrayRetained extends IndexedGeometryArrayRetained {
getVertexData(indexCoord[i++], pnts[0]);
getVertexData(indexCoord[i++], pnts[1]);
getVertexData(indexCoord[i++], pnts[2]);
+ count += 3;
if (intersectRay(pnts, pickRay, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
}
@@ -66,18 +69,19 @@ class IndexedTriangleArrayRetained extends IndexedGeometryArrayRetained {
getVertexData(indexCoord[i++], pnts[0]);
getVertexData(indexCoord[i++], pnts[1]);
getVertexData(indexCoord[i++], pnts[2]);
- if (intersectSegment(pnts, pickSegment.start,
- pickSegment.end, sdist, iPnt)
- && (sdist[0] <= 1.0)) {
- if (dist == null) {
+ count += 3;
+ if (intersectSegment(pnts, pickSegment.start,
+ pickSegment.end, sdist, iPnt)) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
- }
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
+ }
}
}
break;
@@ -89,15 +93,17 @@ class IndexedTriangleArrayRetained extends IndexedGeometryArrayRetained {
getVertexData(indexCoord[i++], pnts[0]);
getVertexData(indexCoord[i++], pnts[1]);
getVertexData(indexCoord[i++], pnts[2]);
+ count += 3;
if (intersectBoundingBox(pnts, bbox, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
}
@@ -110,15 +116,17 @@ class IndexedTriangleArrayRetained extends IndexedGeometryArrayRetained {
getVertexData(indexCoord[i++], pnts[0]);
getVertexData(indexCoord[i++], pnts[1]);
getVertexData(indexCoord[i++], pnts[2]);
+ count += 3;
if (intersectBoundingSphere(pnts, bsphere, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
}
@@ -131,16 +139,18 @@ class IndexedTriangleArrayRetained extends IndexedGeometryArrayRetained {
getVertexData(indexCoord[i++], pnts[0]);
getVertexData(indexCoord[i++], pnts[1]);
getVertexData(indexCoord[i++], pnts[2]);
- if (intersectBoundingPolytope(pnts, bpolytope,
+ count += 3;
+ if (intersectBoundingPolytope(pnts, bpolytope,
sdist,iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
}
@@ -151,16 +161,18 @@ class IndexedTriangleArrayRetained extends IndexedGeometryArrayRetained {
getVertexData(indexCoord[i++], pnts[0]);
getVertexData(indexCoord[i++], pnts[1]);
getVertexData(indexCoord[i++], pnts[2]);
+ count += 3;
if (intersectCylinder(pnts, pickCylinder, sdist,
iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
}
@@ -172,15 +184,17 @@ class IndexedTriangleArrayRetained extends IndexedGeometryArrayRetained {
getVertexData(indexCoord[i++], pnts[0]);
getVertexData(indexCoord[i++], pnts[1]);
getVertexData(indexCoord[i++], pnts[2]);
+ count += 3;
if (intersectCone(pnts, pickCone, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
}
@@ -194,7 +208,15 @@ class IndexedTriangleArrayRetained extends IndexedGeometryArrayRetained {
if (minDist < Double.MAX_VALUE) {
- dist[0] = minDist;
+ assert(minICount >= 3);
+ int[] vertexIndices = iInfo.getVertexIndices();
+ if (vertexIndices == null) {
+ vertexIndices = new int[3];
+ iInfo.setVertexIndices(vertexIndices);
+ }
+ vertexIndices[0] = minICount - 3;
+ vertexIndices[1] = minICount - 2;
+ vertexIndices[2] = minICount - 1;
iPnt.x = x;
iPnt.y = y;
iPnt.z = z;
@@ -203,7 +225,6 @@ class IndexedTriangleArrayRetained extends IndexedGeometryArrayRetained {
return false;
}
-
// intersect pnts[] with every triangle in this object
boolean intersect(Point3d[] pnts) {
Point3d[] points = new Point3d[3];
diff --git a/src/classes/share/javax/media/j3d/IndexedTriangleFanArray.java b/src/classes/share/javax/media/j3d/IndexedTriangleFanArray.java
index 795de14..d094859 100644
--- a/src/classes/share/javax/media/j3d/IndexedTriangleFanArray.java
+++ b/src/classes/share/javax/media/j3d/IndexedTriangleFanArray.java
@@ -29,39 +29,40 @@ public class IndexedTriangleFanArray extends IndexedGeometryStripArray {
IndexedTriangleFanArray() {}
/**
- * Constructs an empty IndexedTriangleFanArray object with the specified
- * number of vertices, vertex format, number of indices, and
- * array of per-strip index counts.
- * @param vertexCount the number of vertex elements in this object
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.
- * @param indexCount the number of indices in this object. This
- * count is the maximum number of vertices that will be rendered.
- * @param stripIndexCounts array that specifies
- * the count of the number of indices for each separate strip.
- * The length of this array is the number of separate strips.
+ * Constructs an empty IndexedTriangleFanArray object using the
+ * specified parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param indexCount
+ * see {@link IndexedGeometryArray#IndexedGeometryArray(int,int,int)}
+ * for a description of this parameter.
+ *
+ * @param stripIndexCounts
+ * see {@link IndexedGeometryStripArray#IndexedGeometryStripArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
* @exception IllegalArgumentException if vertexCount is less than 1,
* or indexCount is less than 3,
* or any element in the stripIndexCounts array is less than 3
+ * ;<br>
+ * See {@link IndexedGeometryStripArray#IndexedGeometryStripArray(int,int,int,int[])}
+ * for more exceptions that can be thrown
*/
public IndexedTriangleFanArray(int vertexCount,
int vertexFormat,
int indexCount,
- int stripIndexCounts[]) {
+ int[] stripIndexCounts) {
super(vertexCount, vertexFormat, indexCount, stripIndexCounts);
- if (vertexCount < 1)
+ if (vertexCount < 1)
throw new IllegalArgumentException(J3dI18N.getString("IndexedTriangleFanArray0"));
if (indexCount < 3 )
@@ -69,69 +70,39 @@ public class IndexedTriangleFanArray extends IndexedGeometryStripArray {
}
/**
- * Constructs an empty IndexedTriangleFanArray object with the specified
- * number of vertices, vertex format, number of texture coordinate
- * sets, texture coordinate mapping array, number of indices, and
- * array of per-strip index counts.
- *
- * @param vertexCount the number of vertex elements in this object<p>
- *
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.<p>
- *
- * @param texCoordSetCount the number of texture coordinate sets
- * in this GeometryArray object. If <code>vertexFormat</code>
- * does not include one of <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3 or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetCount</code> parameter is not used.<p>
- *
- * @param texCoordSetMap an array that maps texture coordinate
- * sets to texture units. The array is indexed by texture unit
- * number for each texture unit in the associated Appearance
- * object. The values in the array specify the texture coordinate
- * set within this GeometryArray object that maps to the
- * corresponding texture
- * unit. All elements within the array must be less than
- * <code>texCoordSetCount</code>. A negative value specifies that
- * no texture coordinate set maps to the texture unit
- * corresponding to the index. If there are more texture units in
- * any associated Appearance object than elements in the mapping
- * array, the extra elements are assumed to be -1. The same
- * texture coordinate set may be used for more than one texture
- * unit. Each texture unit in every associated Appearance must
- * have a valid source of texture coordinates: either a
- * non-negative texture coordinate set must be specified in the
- * mapping array or texture coordinate generation must be enabled.
- * Texture coordinate generation will take precedence for those
- * texture units for which a texture coordinate set is specified
- * and texture coordinate generation is enabled. If
- * <code>vertexFormat</code> does not include one of
- * <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetMap</code> array is not used.<p>
- *
- * @param indexCount the number of indices in this object. This
- * count is the maximum number of vertices that will be rendered.<p>
- *
- * @param stripIndexCounts array that specifies
- * the count of the number of indices for each separate strip.
- * The length of this array is the number of separate strips.
+ * Constructs an empty IndexedTriangleFanArray object using the
+ * specified parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param indexCount
+ * see {@link IndexedGeometryArray#IndexedGeometryArray(int,int,int,int[],int)}
+ * for a description of this parameter.
+ *
+ * @param stripIndexCounts
+ * see {@link IndexedGeometryStripArray#IndexedGeometryStripArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
*
* @exception IllegalArgumentException if vertexCount is less than 1,
* or indexCount is less than 3,
* or any element in the stripIndexCounts array is less than 3
+ * ;<br>
+ * See {@link IndexedGeometryStripArray#IndexedGeometryStripArray(int,int,int,int[],int,int[])}
+ * for more exceptions that can be thrown
*
* @since Java 3D 1.2
*/
@@ -140,13 +111,75 @@ public class IndexedTriangleFanArray extends IndexedGeometryStripArray {
int texCoordSetCount,
int[] texCoordSetMap,
int indexCount,
- int stripIndexCounts[]) {
+ int[] stripIndexCounts) {
+
+ super(vertexCount, vertexFormat,
+ texCoordSetCount, texCoordSetMap,
+ indexCount, stripIndexCounts);
+
+ if (vertexCount < 1)
+ throw new IllegalArgumentException(J3dI18N.getString("IndexedTriangleFanArray0"));
+
+ if (indexCount < 3 )
+ throw new IllegalArgumentException(J3dI18N.getString("IndexedTriangleFanArray1"));
+ }
+
+ /**
+ * Constructs an empty IndexedTriangleFanArray object using the
+ * specified parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrSizes
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param indexCount
+ * see {@link IndexedGeometryArray#IndexedGeometryArray(int,int,int,int[],int,int[],int)}
+ * for a description of this parameter.
+ *
+ * @param stripIndexCounts
+ * see {@link IndexedGeometryStripArray#IndexedGeometryStripArray(int,int,int,int[],int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @exception IllegalArgumentException if vertexCount is less than 1,
+ * or indexCount is less than 3,
+ * or any element in the stripIndexCounts array is less than 3
+ * ;<br>
+ * See {@link IndexedGeometryStripArray#IndexedGeometryStripArray(int,int,int,int[],int,int[],int,int[])}
+ * for more exceptions that can be thrown
+ *
+ * @since Java 3D 1.4
+ */
+ public IndexedTriangleFanArray(int vertexCount,
+ int vertexFormat,
+ int texCoordSetCount,
+ int[] texCoordSetMap,
+ int vertexAttrCount,
+ int[] vertexAttrSizes,
+ int indexCount,
+ int[] stripIndexCounts) {
super(vertexCount, vertexFormat,
texCoordSetCount, texCoordSetMap,
+ vertexAttrCount, vertexAttrSizes,
indexCount, stripIndexCounts);
- if (vertexCount < 1)
+ if (vertexCount < 1)
throw new IllegalArgumentException(J3dI18N.getString("IndexedTriangleFanArray0"));
if (indexCount < 3 )
@@ -167,29 +200,30 @@ public class IndexedTriangleFanArray extends IndexedGeometryStripArray {
* @deprecated replaced with cloneNodeComponent(boolean forceDuplicate)
*/
public NodeComponent cloneNodeComponent() {
- IndexedTriangleFanArrayRetained rt =
- (IndexedTriangleFanArrayRetained) retained;
- int stripIndexCounts[] = new int[rt.getNumStrips()];
- rt.getStripIndexCounts(stripIndexCounts);
- int texSetCount = rt.getTexCoordSetCount();
- IndexedTriangleFanArray t;
-
- if (texSetCount == 0) {
- t = new IndexedTriangleFanArray(rt.getVertexCount(),
- rt.getVertexFormat(),
- rt.getIndexCount(),
- stripIndexCounts);
- } else {
- int texMap[] = new int[rt.getTexCoordSetMapLength()];
- rt.getTexCoordSetMap(texMap);
- t = new IndexedTriangleFanArray(rt.getVertexCount(),
- rt.getVertexFormat(),
- texSetCount,
- texMap,
- rt.getIndexCount(),
- stripIndexCounts);
- }
-
+ IndexedTriangleFanArrayRetained rt =
+ (IndexedTriangleFanArrayRetained) retained;
+ int stripIndexCounts[] = new int[rt.getNumStrips()];
+ rt.getStripIndexCounts(stripIndexCounts);
+ int texSetCount = rt.getTexCoordSetCount();
+ int[] texMap = null;
+ int vertexAttrCount = rt.getVertexAttrCount();
+ int[] vertexAttrSizes = null;
+ if (texSetCount > 0) {
+ texMap = new int[rt.getTexCoordSetMapLength()];
+ rt.getTexCoordSetMap(texMap);
+ }
+ if (vertexAttrCount > 0) {
+ vertexAttrSizes = new int[vertexAttrCount];
+ rt.getVertexAttrSizes(vertexAttrSizes);
+ }
+ IndexedTriangleFanArray t = new IndexedTriangleFanArray(rt.getVertexCount(),
+ rt.getVertexFormat(),
+ texSetCount,
+ texMap,
+ vertexAttrCount,
+ vertexAttrSizes,
+ rt.getIndexCount(),
+ stripIndexCounts);
t.duplicateNodeComponent(this);
return t;
}
diff --git a/src/classes/share/javax/media/j3d/IndexedTriangleFanArrayRetained.java b/src/classes/share/javax/media/j3d/IndexedTriangleFanArrayRetained.java
index b4f0066..c6e37f7 100644
--- a/src/classes/share/javax/media/j3d/IndexedTriangleFanArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/IndexedTriangleFanArrayRetained.java
@@ -32,15 +32,16 @@ class IndexedTriangleFanArrayRetained extends IndexedGeometryStripArrayRetained
geoType = GEO_TYPE_INDEXED_TRI_FAN_SET;
}
- boolean intersect(PickShape pickShape, double dist[], Point3d iPnt) {
+ boolean intersect(PickShape pickShape, PickInfo.IntersectionInfo iInfo, int flags, Point3d iPnt) {
Point3d pnts[] = new Point3d[3];
double sdist[] = new double[1];
double minDist = Double.MAX_VALUE;
double x = 0, y = 0, z = 0;
int i = 0;
- int j, scount, count = 0;
-
- pnts[0] = new Point3d();
+ int j, scount, count = 0, fSCount;
+ int minICount = 0;
+ int minFSCount = 0;
+ pnts[0] = new Point3d();
pnts[1] = new Point3d();
pnts[2] = new Point3d();
@@ -48,22 +49,25 @@ class IndexedTriangleFanArrayRetained extends IndexedGeometryStripArrayRetained
case PickShape.PICKRAY:
PickRay pickRay= (PickRay) pickShape;
- while (i < stripIndexCounts.length) {
+ while (i < stripIndexCounts.length) {
+ fSCount = count;
getVertexData(indexCoord[count++], pnts[0]);
getVertexData(indexCoord[count++], pnts[1]);
scount = stripIndexCounts[i++];
for (j=2; j < scount; j++) {
- getVertexData(count++, pnts[2]);
+ getVertexData(indexCoord[count++], pnts[2]);
if (intersectRay(pnts, pickRay, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minFSCount = fSCount;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[1].set(pnts[2]);
@@ -74,21 +78,24 @@ class IndexedTriangleFanArrayRetained extends IndexedGeometryStripArrayRetained
PickSegment pickSegment = (PickSegment) pickShape;
while (i < stripIndexCounts.length) {
+ fSCount = count;
getVertexData(indexCoord[count++], pnts[0]);
getVertexData(indexCoord[count++], pnts[1]);
scount = stripIndexCounts[i++];
for (j=2; j < scount; j++) {
- getVertexData(j++, pnts[2]);
+ getVertexData(indexCoord[count++], pnts[2]);
if (intersectSegment(pnts, pickSegment.start,
pickSegment.end, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minFSCount = fSCount;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[1].set(pnts[2]);
@@ -100,20 +107,23 @@ class IndexedTriangleFanArrayRetained extends IndexedGeometryStripArrayRetained
((PickBounds) pickShape).bounds;
while (i < stripIndexCounts.length) {
+ fSCount = count;
getVertexData(indexCoord[count++], pnts[0]);
getVertexData(indexCoord[count++], pnts[1]);
scount = stripIndexCounts[i++];
for (j=2; j < scount; j++) {
- getVertexData(count++, pnts[2]);
+ getVertexData(indexCoord[count++], pnts[2]);
if (intersectBoundingBox(pnts, bbox, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minFSCount = fSCount;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[1].set(pnts[2]);
@@ -125,22 +135,25 @@ class IndexedTriangleFanArrayRetained extends IndexedGeometryStripArrayRetained
((PickBounds) pickShape).bounds;
while (i < stripIndexCounts.length) {
+ fSCount = count;
getVertexData(indexCoord[count++], pnts[0]);
getVertexData(indexCoord[count++], pnts[1]);
scount = stripIndexCounts[i++];
for (j=2; j < scount; j++) {
- getVertexData(count++, pnts[2]);
+ getVertexData(indexCoord[count++], pnts[2]);
if (intersectBoundingSphere(pnts, bsphere, sdist,
iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minFSCount = fSCount;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[1].set(pnts[2]);
@@ -152,22 +165,25 @@ class IndexedTriangleFanArrayRetained extends IndexedGeometryStripArrayRetained
((PickBounds) pickShape).bounds;
while (i < stripIndexCounts.length) {
+ fSCount = count;
getVertexData(indexCoord[count++], pnts[0]);
getVertexData(indexCoord[count++], pnts[1]);
scount = stripIndexCounts[i++];
for (j=2; j < scount; j++) {
- getVertexData(count++, pnts[2]);
+ getVertexData(indexCoord[count++], pnts[2]);
if (intersectBoundingPolytope(pnts, bpolytope,
sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minFSCount = fSCount;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[1].set(pnts[2]);
@@ -178,21 +194,24 @@ class IndexedTriangleFanArrayRetained extends IndexedGeometryStripArrayRetained
PickCylinder pickCylinder= (PickCylinder) pickShape;
while (i < stripIndexCounts.length) {
+ fSCount = count;
getVertexData(indexCoord[count++], pnts[0]);
getVertexData(indexCoord[count++], pnts[1]);
scount = stripIndexCounts[i++];
for (j=2; j < scount; j++) {
- getVertexData(count++, pnts[2]);
+ getVertexData(indexCoord[count++], pnts[2]);
if (intersectCylinder(pnts, pickCylinder, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minFSCount = fSCount;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[1].set(pnts[2]);
@@ -203,21 +222,24 @@ class IndexedTriangleFanArrayRetained extends IndexedGeometryStripArrayRetained
PickCone pickCone= (PickCone) pickShape;
while (i < stripIndexCounts.length) {
+ fSCount = count;
getVertexData(indexCoord[count++], pnts[0]);
getVertexData(indexCoord[count++], pnts[1]);
scount = stripIndexCounts[i++];
for (j=2; j < scount; j++) {
- getVertexData(count++, pnts[2]);
+ getVertexData(indexCoord[count++], pnts[2]);
if (intersectCone(pnts, pickCone, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minFSCount = fSCount;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[1].set(pnts[2]);
@@ -232,14 +254,22 @@ class IndexedTriangleFanArrayRetained extends IndexedGeometryStripArrayRetained
}
if (minDist < Double.MAX_VALUE) {
- dist[0] = minDist;
+ assert(minICount >= 3);
+ int[] vertexIndices = iInfo.getVertexIndices();
+ if (vertexIndices == null) {
+ vertexIndices = new int[3];
+ iInfo.setVertexIndices(vertexIndices);
+ }
+ vertexIndices[0] = minFSCount;
+ vertexIndices[1] = minICount - 2;
+ vertexIndices[2] = minICount - 1;
iPnt.x = x;
iPnt.y = y;
iPnt.z = z;
- return true;
+ return true;
}
return false;
- }
+ }
// intersect pnts[] with every triangle in this object
boolean intersect(Point3d[] pnts) {
diff --git a/src/classes/share/javax/media/j3d/IndexedTriangleStripArray.java b/src/classes/share/javax/media/j3d/IndexedTriangleStripArray.java
index 13970bb..b5395db 100644
--- a/src/classes/share/javax/media/j3d/IndexedTriangleStripArray.java
+++ b/src/classes/share/javax/media/j3d/IndexedTriangleStripArray.java
@@ -31,35 +31,36 @@ public class IndexedTriangleStripArray extends IndexedGeometryStripArray {
}
/**
- * Constructs an empty IndexedTriangleStripArray object with the specified
- * number of vertices, vertex format, number of indices, and
- * array of per-strip index counts.
- * @param vertexCount the number of vertex elements in this object
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.
- * @param indexCount the number of indices in this object. This
- * count is the maximum number of vertices that will be rendered.
- * @param stripIndexCounts array that specifies
- * the count of the number of indices for each separate strip.
- * The length of this array is the number of separate strips.
+ * Constructs an empty IndexedTriangleStripArray object using the
+ * specified parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param indexCount
+ * see {@link IndexedGeometryArray#IndexedGeometryArray(int,int,int)}
+ * for a description of this parameter.
+ *
+ * @param stripIndexCounts
+ * see {@link IndexedGeometryStripArray#IndexedGeometryStripArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
* @exception IllegalArgumentException if vertexCount is less than 1,
* or indexCount is less than 3,
* or any element in the stripIndexCounts array is less than 3
+ * ;<br>
+ * See {@link IndexedGeometryStripArray#IndexedGeometryStripArray(int,int,int,int[])}
+ * for more exceptions that can be thrown
*/
public IndexedTriangleStripArray(int vertexCount,
int vertexFormat,
int indexCount,
- int stripIndexCounts[]) {
+ int[] stripIndexCounts) {
super(vertexCount, vertexFormat, indexCount, stripIndexCounts);
@@ -71,69 +72,39 @@ public class IndexedTriangleStripArray extends IndexedGeometryStripArray {
}
/**
- * Constructs an empty IndexedTriangleStripArray object with the specified
- * number of vertices, vertex format, number of texture coordinate
- * sets, texture coordinate mapping array, number of indices, and
- * array of per-strip index counts.
- *
- * @param vertexCount the number of vertex elements in this object<p>
- *
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.<p>
- *
- * @param texCoordSetCount the number of texture coordinate sets
- * in this GeometryArray object. If <code>vertexFormat</code>
- * does not include one of <code>TEXTURE_COORDINATE_2</code> or
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetCount</code> parameter is not used.<p>
- *
- * @param texCoordSetMap an array that maps texture coordinate
- * sets to texture units. The array is indexed by texture unit
- * number for each texture unit in the associated Appearance
- * object. The values in the array specify the texture coordinate
- * set within this GeometryArray object that maps to the
- * corresponding texture
- * unit. All elements within the array must be less than
- * <code>texCoordSetCount</code>. A negative value specifies that
- * no texture coordinate set maps to the texture unit
- * corresponding to the index. If there are more texture units in
- * any associated Appearance object than elements in the mapping
- * array, the extra elements are assumed to be -1. The same
- * texture coordinate set may be used for more than one texture
- * unit. Each texture unit in every associated Appearance must
- * have a valid source of texture coordinates: either a
- * non-negative texture coordinate set must be specified in the
- * mapping array or texture coordinate generation must be enabled.
- * Texture coordinate generation will take precedence for those
- * texture units for which a texture coordinate set is specified
- * and texture coordinate generation is enabled. If
- * <code>vertexFormat</code> does not include one of
- * <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetMap</code> array is not used.<p>
- *
- * @param indexCount the number of indices in this object. This
- * count is the maximum number of vertices that will be rendered.<p>
- *
- * @param stripIndexCounts array that specifies
- * the count of the number of indices for each separate strip.
- * The length of this array is the number of separate strips.
+ * Constructs an empty IndexedTriangleStripArray object using the
+ * specified parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param indexCount
+ * see {@link IndexedGeometryArray#IndexedGeometryArray(int,int,int,int[],int)}
+ * for a description of this parameter.
+ *
+ * @param stripIndexCounts
+ * see {@link IndexedGeometryStripArray#IndexedGeometryStripArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
*
* @exception IllegalArgumentException if vertexCount is less than 1,
* or indexCount is less than 3,
* or any element in the stripIndexCounts array is less than 3
+ * ;<br>
+ * See {@link IndexedGeometryStripArray#IndexedGeometryStripArray(int,int,int,int[],int,int[])}
+ * for more exceptions that can be thrown
*
* @since Java 3D 1.2
*/
@@ -142,10 +113,72 @@ public class IndexedTriangleStripArray extends IndexedGeometryStripArray {
int texCoordSetCount,
int[] texCoordSetMap,
int indexCount,
- int stripIndexCounts[]) {
+ int[] stripIndexCounts) {
+
+ super(vertexCount, vertexFormat,
+ texCoordSetCount, texCoordSetMap,
+ indexCount, stripIndexCounts);
+
+ if (vertexCount < 1)
+ throw new IllegalArgumentException(J3dI18N.getString("IndexedTriangleStripArray0"));
+
+ if (indexCount < 3 )
+ throw new IllegalArgumentException(J3dI18N.getString("IndexedTriangleStripArray1"));
+ }
+
+ /**
+ * Constructs an empty IndexedTriangleStripArray object using the
+ * specified parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrSizes
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param indexCount
+ * see {@link IndexedGeometryArray#IndexedGeometryArray(int,int,int,int[],int,int[],int)}
+ * for a description of this parameter.
+ *
+ * @param stripIndexCounts
+ * see {@link IndexedGeometryStripArray#IndexedGeometryStripArray(int,int,int,int[],int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @exception IllegalArgumentException if vertexCount is less than 1,
+ * or indexCount is less than 3,
+ * or any element in the stripIndexCounts array is less than 3
+ * ;<br>
+ * See {@link IndexedGeometryStripArray#IndexedGeometryStripArray(int,int,int,int[],int,int[],int,int[])}
+ * for more exceptions that can be thrown
+ *
+ * @since Java 3D 1.4
+ */
+ public IndexedTriangleStripArray(int vertexCount,
+ int vertexFormat,
+ int texCoordSetCount,
+ int[] texCoordSetMap,
+ int vertexAttrCount,
+ int[] vertexAttrSizes,
+ int indexCount,
+ int[] stripIndexCounts) {
super(vertexCount, vertexFormat,
texCoordSetCount, texCoordSetMap,
+ vertexAttrCount, vertexAttrSizes,
indexCount, stripIndexCounts);
if (vertexCount < 1)
@@ -169,28 +202,31 @@ public class IndexedTriangleStripArray extends IndexedGeometryStripArray {
* @deprecated replaced with cloneNodeComponent(boolean forceDuplicate)
*/
public NodeComponent cloneNodeComponent() {
- IndexedTriangleStripArrayRetained rt =
- (IndexedTriangleStripArrayRetained) retained;
+ IndexedTriangleStripArrayRetained rt =
+ (IndexedTriangleStripArrayRetained) retained;
int stripIndexCounts[] = new int[rt.getNumStrips()];
- rt.getStripIndexCounts(stripIndexCounts);
- int texSetCount = rt.getTexCoordSetCount();
- IndexedTriangleStripArray l;
- if (texSetCount == 0) {
- l = new IndexedTriangleStripArray(rt.getVertexCount(),
- rt.getVertexFormat(),
- rt.getIndexCount(),
- stripIndexCounts);
- } else {
- int texMap[] = new int[rt.getTexCoordSetMapLength()];
- rt.getTexCoordSetMap(texMap);
- l = new IndexedTriangleStripArray(rt.getVertexCount(),
- rt.getVertexFormat(),
- texSetCount,
- texMap,
- rt.getIndexCount(),
- stripIndexCounts);
- }
- l.duplicateNodeComponent(this);
- return l;
+ rt.getStripIndexCounts(stripIndexCounts);
+ int texSetCount = rt.getTexCoordSetCount();
+ int[] texMap = null;
+ int vertexAttrCount = rt.getVertexAttrCount();
+ int[] vertexAttrSizes = null;
+ if (texSetCount > 0) {
+ texMap = new int[rt.getTexCoordSetMapLength()];
+ rt.getTexCoordSetMap(texMap);
+ }
+ if (vertexAttrCount > 0) {
+ vertexAttrSizes = new int[vertexAttrCount];
+ rt.getVertexAttrSizes(vertexAttrSizes);
+ }
+ IndexedTriangleStripArray t = new IndexedTriangleStripArray(rt.getVertexCount(),
+ rt.getVertexFormat(),
+ texSetCount,
+ texMap,
+ vertexAttrCount,
+ vertexAttrSizes,
+ rt.getIndexCount(),
+ stripIndexCounts);
+ t.duplicateNodeComponent(this);
+ return t;
}
}
diff --git a/src/classes/share/javax/media/j3d/IndexedTriangleStripArrayRetained.java b/src/classes/share/javax/media/j3d/IndexedTriangleStripArrayRetained.java
index 5e2b017..888b0de 100644
--- a/src/classes/share/javax/media/j3d/IndexedTriangleStripArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/IndexedTriangleStripArrayRetained.java
@@ -31,14 +31,14 @@ class IndexedTriangleStripArrayRetained extends IndexedGeometryStripArrayRetaine
geoType = GEO_TYPE_INDEXED_TRI_STRIP_SET;
}
-
- boolean intersect(PickShape pickShape, double dist[], Point3d iPnt) {
+ boolean intersect(PickShape pickShape, PickInfo.IntersectionInfo iInfo, int flags, Point3d iPnt) {
Point3d pnts[] = new Point3d[3];
double sdist[] = new double[1];
double minDist = Double.MAX_VALUE;
double x = 0, y = 0, z = 0;
int i = 0;
int j, scount, count = 0;
+ int minICount = 0;
pnts[0] = new Point3d();
pnts[1] = new Point3d();
@@ -54,17 +54,18 @@ class IndexedTriangleStripArrayRetained extends IndexedGeometryStripArrayRetaine
scount = stripIndexCounts[i++];
for (j=2; j < scount; j++) {
- getVertexData(count++, pnts[2]);
+ getVertexData(indexCoord[count++], pnts[2]);
if (intersectRay(pnts, pickRay, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
- }
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
+ }
}
pnts[0].set(pnts[1]);
pnts[1].set(pnts[2]);
@@ -79,17 +80,18 @@ class IndexedTriangleStripArrayRetained extends IndexedGeometryStripArrayRetaine
getVertexData(indexCoord[count++], pnts[1]);
scount = stripIndexCounts[i++];
for (j=2; j < scount; j++) {
- getVertexData(j++, pnts[2]);
+ getVertexData(indexCoord[count++], pnts[2]);
if (intersectSegment(pnts, pickSegment.start,
pickSegment.end, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[0].set(pnts[1]);
@@ -106,16 +108,17 @@ class IndexedTriangleStripArrayRetained extends IndexedGeometryStripArrayRetaine
getVertexData(indexCoord[count++], pnts[1]);
scount = stripIndexCounts[i++];
for (j=2; j < scount; j++) {
- getVertexData(count++, pnts[2]);
+ getVertexData(indexCoord[count++], pnts[2]);
if (intersectBoundingBox(pnts, bbox, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[0].set(pnts[1]);
@@ -133,17 +136,18 @@ class IndexedTriangleStripArrayRetained extends IndexedGeometryStripArrayRetaine
scount = stripIndexCounts[i++];
for (j=2; j < scount; j++) {
- getVertexData(count++, pnts[2]);
+ getVertexData(indexCoord[count++], pnts[2]);
if (intersectBoundingSphere(pnts, bsphere, sdist,
iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[0].set(pnts[1]);
@@ -161,17 +165,18 @@ class IndexedTriangleStripArrayRetained extends IndexedGeometryStripArrayRetaine
scount = stripIndexCounts[i++];
for (j=2; j < scount; j++) {
- getVertexData(count++, pnts[2]);
+ getVertexData(indexCoord[count++], pnts[2]);
if (intersectBoundingPolytope(pnts, bpolytope,
sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[0].set(pnts[1]);
@@ -188,16 +193,17 @@ class IndexedTriangleStripArrayRetained extends IndexedGeometryStripArrayRetaine
scount = stripIndexCounts[i++];
for (j=2; j < scount; j++) {
- getVertexData(count++, pnts[2]);
+ getVertexData(indexCoord[count++], pnts[2]);
if (intersectCylinder(pnts, pickCylinder, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[0].set(pnts[1]);
@@ -214,16 +220,17 @@ class IndexedTriangleStripArrayRetained extends IndexedGeometryStripArrayRetaine
scount = stripIndexCounts[i++];
for (j=2; j < scount; j++) {
- getVertexData(count++, pnts[2]);
+ getVertexData(indexCoord[count++], pnts[2]);
if (intersectCone(pnts, pickCone, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[0].set(pnts[1]);
@@ -239,15 +246,23 @@ class IndexedTriangleStripArrayRetained extends IndexedGeometryStripArrayRetaine
}
if (minDist < Double.MAX_VALUE) {
- dist[0] = minDist;
+ assert(minICount >=3);
+ int[] vertexIndices = iInfo.getVertexIndices();
+ if (vertexIndices == null) {
+ vertexIndices = new int[3];
+ iInfo.setVertexIndices(vertexIndices);
+ }
+ vertexIndices[0] = minICount - 3;
+ vertexIndices[1] = minICount - 2;
+ vertexIndices[2] = minICount - 1;
iPnt.x = x;
iPnt.y = y;
iPnt.z = z;
- return true;
+ return true;
}
return false;
}
-
+
// intersect pnts[] with every triangle in this object
boolean intersect(Point3d[] pnts) {
int j, end;
diff --git a/src/classes/share/javax/media/j3d/IndexedUnorderSet.java b/src/classes/share/javax/media/j3d/IndexedUnorderSet.java
index 89d3a4a..54e4b36 100644
--- a/src/classes/share/javax/media/j3d/IndexedUnorderSet.java
+++ b/src/classes/share/javax/media/j3d/IndexedUnorderSet.java
@@ -60,7 +60,7 @@ package javax.media.j3d;
class IndexedUnorderSet implements Cloneable, java.io.Serializable {
- // TODO: set to false when release
+ // XXXX: set to false when release
final static boolean debug = false;
/**
diff --git a/src/classes/share/javax/media/j3d/J3DBuffer.java b/src/classes/share/javax/media/j3d/J3DBuffer.java
index 6422dc1..6cc97cf 100644
--- a/src/classes/share/javax/media/j3d/J3DBuffer.java
+++ b/src/classes/share/javax/media/j3d/J3DBuffer.java
@@ -25,21 +25,11 @@ import com.sun.j3d.internal.ByteOrderWrapper;
* <code>rewind</code> on the read-only view, so that elements 0
* through <code>buffer.limit()-1</code> will be available internally.
*
- * <p>
- * NOTE: Use of this class requires version 1.4 of the
- * Java<sup><font size="-2">TM</font></sup>&nbsp;2 Platform.
- * Any attempt to access this class on an earlier version of the
- * Java&nbsp;2 Platform will fail with a NoClassDefFoundError.
- * Refer to the documentation for version 1.4 of the Java&nbsp;2 SDK
- * for a description of the
- * <code>
- * <a href="http://java.sun.com/j2se/1.4/docs/api/java/nio/package-summary.html">java.nio</a>
- * </code> package.
- *
* @see GeometryArray#setCoordRefBuffer(J3DBuffer)
* @see GeometryArray#setColorRefBuffer(J3DBuffer)
* @see GeometryArray#setNormalRefBuffer(J3DBuffer)
* @see GeometryArray#setTexCoordRefBuffer(int,J3DBuffer)
+ * @see GeometryArray#setVertexAttrRefBuffer(int,J3DBuffer)
* @see GeometryArray#setInterleavedVertexBuffer(J3DBuffer)
* @see CompressedGeometry#CompressedGeometry(CompressedGeometryHeader,J3DBuffer)
*
diff --git a/src/classes/share/javax/media/j3d/J3DGraphics2DImpl.java b/src/classes/share/javax/media/j3d/J3DGraphics2DImpl.java
index 2ed6814..439b0f7 100644
--- a/src/classes/share/javax/media/j3d/J3DGraphics2DImpl.java
+++ b/src/classes/share/javax/media/j3d/J3DGraphics2DImpl.java
@@ -140,7 +140,7 @@ final class J3DGraphics2DImpl extends J3DGraphics2D {
}
}
// Behavior Scheduler or other threads
- // TODO: may not be legal for behaviorScheduler
+ // XXXX: may not be legal for behaviorScheduler
// May cause deadlock if it is in behaviorScheduler
// and we wait for Renderer to finish
boolean renderRun = (Thread.currentThread() !=
@@ -589,13 +589,13 @@ final class J3DGraphics2DImpl extends J3DGraphics2D {
public final void drawArc(int x, int y, int width, int height,
int startAngle, int arcAngle) {
- // TODO: call validate with bounding box of primitive
+ // XXXX: call validate with bounding box of primitive
validate();
offScreenGraphics2D.drawArc(x, y, width, height, startAngle, arcAngle);
}
public final void drawGlyphVector(GlyphVector g, float x, float y) {
- // TODO: call validate with bounding box of primitive
+ // XXXX: call validate with bounding box of primitive
validate();
offScreenGraphics2D.drawGlyphVector(g, x, y);
}
@@ -619,29 +619,29 @@ final class J3DGraphics2DImpl extends J3DGraphics2D {
}
validate(minx, miny, maxx, maxy);
} else {
- // TODO: call validate with bounding box of primitive
- // TODO: Need to consider Stroke width
+ // XXXX: call validate with bounding box of primitive
+ // XXXX: Need to consider Stroke width
validate();
}
offScreenGraphics2D.drawLine(x1, y1, x2, y2);
}
public final void drawOval(int x, int y, int width, int height) {
- // TODO: call validate with bounding box of primitive
+ // XXXX: call validate with bounding box of primitive
validate();
offScreenGraphics2D.drawOval(x, y, width, height);
}
public final void drawPolygon(int xPoints[], int yPoints[],
int nPoints) {
- // TODO: call validate with bounding box of primitive
+ // XXXX: call validate with bounding box of primitive
validate();
offScreenGraphics2D.drawPolygon(xPoints, yPoints, nPoints);
}
public final void drawPolyline(int xPoints[], int yPoints[],
int nPoints) {
- // TODO: call validate with bounding box of primitive
+ // XXXX: call validate with bounding box of primitive
validate();
offScreenGraphics2D.drawPolyline(xPoints, yPoints, nPoints);
}
@@ -661,7 +661,7 @@ final class J3DGraphics2DImpl extends J3DGraphics2D {
public final void drawRoundRect(int x, int y, int width, int height,
int arcWidth, int arcHeight) {
- // TODO: call validate with bounding box of primitive
+ // XXXX: call validate with bounding box of primitive
validate();
offScreenGraphics2D.drawRoundRect(x, y, width, height, arcWidth,
arcHeight);
@@ -669,14 +669,14 @@ final class J3DGraphics2DImpl extends J3DGraphics2D {
public final void drawString(AttributedCharacterIterator iterator,
int x, int y) {
- // TODO: call validate with bounding box of primitive
+ // XXXX: call validate with bounding box of primitive
validate();
offScreenGraphics2D.drawString(iterator, x, y);
}
public final void drawString(AttributedCharacterIterator iterator,
float x, float y) {
- // TODO: call validate with bounding box of primitive
+ // XXXX: call validate with bounding box of primitive
validate();
offScreenGraphics2D.drawString(iterator, x, y);
}
@@ -706,20 +706,20 @@ final class J3DGraphics2DImpl extends J3DGraphics2D {
public final void fillArc(int x, int y, int width, int height,
int startAngle, int arcAngle) {
- // TODO: call validate with bounding box of primitive
+ // XXXX: call validate with bounding box of primitive
validate();
offScreenGraphics2D.fillArc(x, y, width, height, startAngle, arcAngle);
}
public final void fillOval(int x, int y, int width, int height) {
- // TODO: call validate with bounding box of primitive
+ // XXXX: call validate with bounding box of primitive
validate();
offScreenGraphics2D.fillOval(x, y, width, height);
}
public final void fillRoundRect(int x, int y, int width, int height,
int arcWidth, int arcHeight) {
- // TODO: call validate with bounding box of primitive
+ // XXXX: call validate with bounding box of primitive
validate();
offScreenGraphics2D.fillRoundRect(x, y, width, height, arcWidth,
arcHeight);
@@ -810,59 +810,59 @@ final class J3DGraphics2DImpl extends J3DGraphics2D {
public void draw3DRect(int x, int y, int width, int height,
boolean raised) {
- // TODO: call validate with bounding box of primitive
+ // XXXX: call validate with bounding box of primitive
validate();
offScreenGraphics2D.draw3DRect(x, y, width, height, raised);
}
public void drawBytes(byte data[], int offset, int length, int x, int y) {
- // TODO: call validate with bounding box of primitive
+ // XXXX: call validate with bounding box of primitive
validate();
offScreenGraphics2D.drawBytes(data, offset, length, x, y);
}
public void drawChars(char data[], int offset, int length, int x, int y) {
- // TODO: call validate with bounding box of primitive
+ // XXXX: call validate with bounding box of primitive
validate();
offScreenGraphics2D.drawChars(data, offset, length, x, y);
}
public void drawPolygon(Polygon p) {
- // TODO: call validate with bounding box of primitive
+ // XXXX: call validate with bounding box of primitive
validate();
offScreenGraphics2D.drawPolygon(p);
}
public void drawRect(int x, int y, int width, int height) {
- // TODO: call validate with bounding box of primitive
- // TODO: need to consider Stroke width
+ // XXXX: call validate with bounding box of primitive
+ // XXXX: need to consider Stroke width
validate();
offScreenGraphics2D.drawRect(x, y, width, height);
}
public void fill3DRect(int x, int y, int width, int height,
boolean raised) {
- // TODO: call validate with bounding box of primitive
- // TODO: need to consider Stroke width
+ // XXXX: call validate with bounding box of primitive
+ // XXXX: need to consider Stroke width
validate();
offScreenGraphics2D.fill3DRect(x, y, width, height, raised);
}
public void fillPolygon(Polygon p) {
- // TODO: call validate with bounding box of primitive
+ // XXXX: call validate with bounding box of primitive
validate();
offScreenGraphics2D.fillPolygon(p);
}
public final void fillPolygon(int xPoints[], int yPoints[],
int nPoints) {
- // TODO: call validate with bounding box of primitive
+ // XXXX: call validate with bounding box of primitive
validate();
offScreenGraphics2D.fillPolygon(xPoints, yPoints, nPoints);
}
public final void fillRect(int x, int y, int width, int height) {
- // TODO: call validate with bounding box of primitive
+ // XXXX: call validate with bounding box of primitive
validate();
offScreenGraphics2D.fillRect(x, y, width, height);
}
@@ -888,7 +888,7 @@ final class J3DGraphics2DImpl extends J3DGraphics2D {
doDrawAndFlushImage(img, x, y, observer);
} else {
// Behavior Scheduler or other threads
- // TODO: may not be legal for behaviorScheduler
+ // XXXX: may not be legal for behaviorScheduler
// May cause deadlock if it is in behaviorScheduler
// and we wait for Renderer to finish
boolean renderRun = (Thread.currentThread() !=
diff --git a/src/classes/share/javax/media/j3d/J3dMessage.java b/src/classes/share/javax/media/j3d/J3dMessage.java
index 625f2df..d2d073d 100644
--- a/src/classes/share/javax/media/j3d/J3dMessage.java
+++ b/src/classes/share/javax/media/j3d/J3dMessage.java
@@ -84,6 +84,9 @@ class J3dMessage extends Object {
static final int ORDERED_GROUP_TABLE_CHANGED = 59;
static final int BEHAVIOR_REEVALUATE = 60;
static final int CREATE_OFFSCREENBUFFER = 61;
+ static final int SHADER_ATTRIBUTE_CHANGED = 62;
+ static final int SHADER_ATTRIBUTE_SET_CHANGED = 63;
+ static final int SHADER_APPEARANCE_CHANGED = 64;
/**
* This is the time snapshot at which this change occured
diff --git a/src/classes/share/javax/media/j3d/J3dNotification.java b/src/classes/share/javax/media/j3d/J3dNotification.java
new file mode 100644
index 0000000..8560295
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/J3dNotification.java
@@ -0,0 +1,42 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+/**
+ * J3dNotification is used to hold data for asynchronous error notification.
+ */
+
+class J3dNotification extends Object {
+ /**
+ * The various notification types.
+ */
+ static final int INVALID_TYPE = -1;
+ static final int SHADER_ERROR = 0;
+
+ /**
+ * This holds the type of this message
+ */
+ int type = INVALID_TYPE;
+
+ /**
+ * The universe that this message originated from
+ */
+ VirtualUniverse universe;
+
+ /**
+ * The arguements for a message, 6 for now
+ */
+ static final int MAX_ARGS = 6;
+
+ Object[] args = new Object[MAX_ARGS];
+}
diff --git a/src/classes/share/javax/media/j3d/Light.java b/src/classes/share/javax/media/j3d/Light.java
index 2588607..47c479a 100644
--- a/src/classes/share/javax/media/j3d/Light.java
+++ b/src/classes/share/javax/media/j3d/Light.java
@@ -220,6 +220,14 @@ public abstract class Light extends Leaf {
public static final int
ALLOW_SCOPE_WRITE = CapabilityBits.LIGHT_ALLOW_SCOPE_WRITE;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_STATE_READ,
+ ALLOW_COLOR_READ,
+ ALLOW_INFLUENCING_BOUNDS_READ,
+ ALLOW_SCOPE_READ
+ };
+
/**
* Constructs a Light node with default parameters. The default
* values are as follows:
@@ -232,6 +240,8 @@ public abstract class Light extends Leaf {
* </ul>
*/
public Light() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -239,7 +249,10 @@ public abstract class Light extends Leaf {
* @param color the color of the light source
*/
public Light(Color3f color) {
- ((LightRetained)this.retained).initColor(color);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((LightRetained)this.retained).initColor(color);
}
/**
@@ -249,7 +262,10 @@ public abstract class Light extends Leaf {
* @param color the color of the light source
*/
public Light(boolean lightOn, Color3f color) {
- ((LightRetained)this.retained).initEnable(lightOn);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((LightRetained)this.retained).initEnable(lightOn);
((LightRetained)this.retained).initColor(color);
}
diff --git a/src/classes/share/javax/media/j3d/LineArray.java b/src/classes/share/javax/media/j3d/LineArray.java
index f2d0e12..da484d1 100644
--- a/src/classes/share/javax/media/j3d/LineArray.java
+++ b/src/classes/share/javax/media/j3d/LineArray.java
@@ -27,23 +27,22 @@ public class LineArray extends GeometryArray {
}
/**
- * Constructs an empty LineArray object with the specified
- * number of vertices, and vertex format.
- * @param vertexCount the number of vertex elements in this array
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.
+ * Constructs an empty LineArray object using the specified
+ * parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
* @exception IllegalArgumentException if vertexCount is less than 2
* or vertexCount is <i>not</i> a multiple of 2
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int)}
+ * for more exceptions that can be thrown
*/
public LineArray(int vertexCount, int vertexFormat) {
super(vertexCount,vertexFormat);
@@ -53,60 +52,30 @@ public class LineArray extends GeometryArray {
}
/**
- * Constructs an empty LineArray object with the specified
- * number of vertices, and vertex format, number of texture coordinate
- * sets, and texture coordinate mapping array.
- *
- * @param vertexCount the number of vertex elements in this array<p>
- *
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.<p>
- *
- * @param texCoordSetCount the number of texture coordinate sets
- * in this GeometryArray object. If <code>vertexFormat</code>
- * does not include one of <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetCount</code> parameter is not used.<p>
- *
- * @param texCoordSetMap an array that maps texture coordinate
- * sets to texture units. The array is indexed by texture unit
- * number for each texture unit in the associated Appearance
- * object. The values in the array specify the texture coordinate
- * set within this GeometryArray object that maps to the
- * corresponding texture
- * unit. All elements within the array must be less than
- * <code>texCoordSetCount</code>. A negative value specifies that
- * no texture coordinate set maps to the texture unit
- * corresponding to the index. If there are more texture units in
- * any associated Appearance object than elements in the mapping
- * array, the extra elements are assumed to be -1. The same
- * texture coordinate set may be used for more than one texture
- * unit. Each texture unit in every associated Appearance must
- * have a valid source of texture coordinates: either a
- * non-negative texture coordinate set must be specified in the
- * mapping array or texture coordinate generation must be enabled.
- * Texture coordinate generation will take precedence for those
- * texture units for which a texture coordinate set is specified
- * and texture coordinate generation is enabled. If
- * <code>vertexFormat</code> does not include one of
- * <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetMap</code> array is not used.
+ * Constructs an empty LineArray object using the specified
+ * parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
*
* @exception IllegalArgumentException if vertexCount is less than 2
* or vertexCount is <i>not</i> a multiple of 2
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for more exceptions that can be thrown
*
* @since Java 3D 1.2
*/
@@ -123,6 +92,53 @@ public class LineArray extends GeometryArray {
}
/**
+ * Constructs an empty LineArray object using the specified
+ * parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrSizes
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @exception IllegalArgumentException if vertexCount is less than 2
+ * or vertexCount is <i>not</i> a multiple of 3
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for more exceptions that can be thrown
+ *
+ * @since Java 3D 1.4
+ */
+ public LineArray(int vertexCount,
+ int vertexFormat,
+ int texCoordSetCount,
+ int[] texCoordSetMap,
+ int vertexAttrCount,
+ int[] vertexAttrSizes) {
+
+ super(vertexCount, vertexFormat,
+ texCoordSetCount, texCoordSetMap,
+ vertexAttrCount, vertexAttrSizes);
+
+ if (vertexCount < 2 || ((vertexCount%2) != 0))
+ throw new IllegalArgumentException(J3dI18N.getString("LineArray0"));
+ }
+
+ /**
* Creates the retained mode LineArrayRetained object that this
* LineArray object will point to.
*/
@@ -137,23 +153,24 @@ public class LineArray extends GeometryArray {
*/
public NodeComponent cloneNodeComponent() {
LineArrayRetained rt = (LineArrayRetained) retained;
-
-
- int texSetCount = rt.getTexCoordSetCount();
- LineArray l;
- if (texSetCount == 0) {
- l = new LineArray(rt.getVertexCount(),
- rt.getVertexFormat());
- } else {
- int texMap[] = new int[rt.getTexCoordSetMapLength()];
- rt.getTexCoordSetMap(texMap);
- l = new LineArray(rt.getVertexCount(),
- rt.getVertexFormat(),
- texSetCount,
- texMap);
-
- }
-
+ int texSetCount = rt.getTexCoordSetCount();
+ int[] texMap = null;
+ int vertexAttrCount = rt.getVertexAttrCount();
+ int[] vertexAttrSizes = null;
+ if (texSetCount > 0) {
+ texMap = new int[rt.getTexCoordSetMapLength()];
+ rt.getTexCoordSetMap(texMap);
+ }
+ if (vertexAttrCount > 0) {
+ vertexAttrSizes = new int[vertexAttrCount];
+ rt.getVertexAttrSizes(vertexAttrSizes);
+ }
+ LineArray l = new LineArray(rt.getVertexCount(),
+ rt.getVertexFormat(),
+ texSetCount,
+ texMap,
+ vertexAttrCount,
+ vertexAttrSizes);
l.duplicateNodeComponent(this);
return l;
}
diff --git a/src/classes/share/javax/media/j3d/LineArrayRetained.java b/src/classes/share/javax/media/j3d/LineArrayRetained.java
index b29597a..2b07b54 100644
--- a/src/classes/share/javax/media/j3d/LineArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/LineArrayRetained.java
@@ -25,15 +25,16 @@ class LineArrayRetained extends GeometryArrayRetained implements Cloneable {
LineArrayRetained() {
this.geoType = GEO_TYPE_LINE_SET;
}
-
- boolean intersect(PickShape pickShape, double dist[], Point3d iPnt) {
+
+ boolean intersect(PickShape pickShape, PickInfo.IntersectionInfo iInfo, int flags, Point3d iPnt) {
Point3d pnts[] = new Point3d[2];
double sdist[] = new double[1];
double minDist = Double.MAX_VALUE;
double x = 0, y = 0, z = 0;
+ int count = 0;
+ int minICount = 0;
int i = ((vertexFormat & GeometryArray.BY_REFERENCE) == 0 ?
initialVertexIndex : initialCoordIndex);
-
pnts[0] = new Point3d();
pnts[1] = new Point3d();
@@ -44,18 +45,20 @@ class LineArrayRetained extends GeometryArrayRetained implements Cloneable {
while (i < validVertexCount) {
getVertexData(i++, pnts[0]);
getVertexData(i++, pnts[1]);
+ count += 2;
if (intersectLineAndRay(pnts[0], pnts[1], pickRay.origin,
pickRay.direction, sdist,
iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
- }
+ }
}
}
break;
@@ -69,20 +72,21 @@ class LineArrayRetained extends GeometryArrayRetained implements Cloneable {
while (i < validVertexCount) {
getVertexData(i++, pnts[0]);
getVertexData(i++, pnts[1]);
+ count += 2;
if (intersectLineAndRay(pnts[0], pnts[1],
pickSegment.start,
dir, sdist, iPnt) &&
(sdist[0] <= 1.0)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
}
-
}
}
break;
@@ -92,12 +96,14 @@ class LineArrayRetained extends GeometryArrayRetained implements Cloneable {
while (i < validVertexCount) {
getVertexData(i++, pnts[0]);
getVertexData(i++, pnts[1]);
+ count += 2;
if (intersectBoundingBox(pnts, bbox, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -113,12 +119,14 @@ class LineArrayRetained extends GeometryArrayRetained implements Cloneable {
while (i < validVertexCount) {
getVertexData(i++, pnts[0]);
getVertexData(i++, pnts[1]);
+ count += 2;
if (intersectBoundingSphere(pnts, bsphere, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -133,12 +141,14 @@ class LineArrayRetained extends GeometryArrayRetained implements Cloneable {
while (i < validVertexCount) {
getVertexData(i++, pnts[0]);
getVertexData(i++, pnts[1]);
+ count += 2;
if (intersectBoundingPolytope(pnts, bpolytope, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -152,12 +162,14 @@ class LineArrayRetained extends GeometryArrayRetained implements Cloneable {
while (i < validVertexCount) {
getVertexData(i++, pnts[0]);
getVertexData(i++, pnts[1]);
+ count += 2;
if (intersectCylinder(pnts, pickCylinder, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -171,12 +183,14 @@ class LineArrayRetained extends GeometryArrayRetained implements Cloneable {
while (i < validVertexCount) {
getVertexData(i++, pnts[0]);
getVertexData(i++, pnts[1]);
+ count += 2;
if (intersectCone(pnts, pickCone, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -192,7 +206,14 @@ class LineArrayRetained extends GeometryArrayRetained implements Cloneable {
}
if (minDist < Double.MAX_VALUE) {
- dist[0] = minDist;
+ assert(minICount >=2);
+ int[] vertexIndices = iInfo.getVertexIndices();
+ if (vertexIndices == null) {
+ vertexIndices = new int[2];
+ iInfo.setVertexIndices(vertexIndices);
+ }
+ vertexIndices[0] = minICount - 2;
+ vertexIndices[1] = minICount - 1;
iPnt.x = x;
iPnt.y = y;
iPnt.z = z;
@@ -200,8 +221,7 @@ class LineArrayRetained extends GeometryArrayRetained implements Cloneable {
}
return false;
- }
-
+ }
boolean intersect(Point3d[] pnts) {
Point3d[] points = new Point3d[2];
diff --git a/src/classes/share/javax/media/j3d/LineAttributes.java b/src/classes/share/javax/media/j3d/LineAttributes.java
index ca2d569..c60a68c 100644
--- a/src/classes/share/javax/media/j3d/LineAttributes.java
+++ b/src/classes/share/javax/media/j3d/LineAttributes.java
@@ -169,7 +169,13 @@ public class LineAttributes extends NodeComponent {
*/
public static final int PATTERN_USER_DEFINED = 4;
-
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_ANTIALIASING_READ,
+ ALLOW_PATTERN_READ,
+ ALLOW_WIDTH_READ
+ };
+
/**
* Constructs a LineAttributes object with default parameters.
* The default values are as follows:
@@ -182,6 +188,8 @@ public class LineAttributes extends NodeComponent {
* </ul>
*/
public LineAttributes(){
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -197,6 +205,9 @@ public class LineAttributes extends NodeComponent {
if (linePattern < PATTERN_SOLID || linePattern > PATTERN_DASH_DOT)
throw new IllegalArgumentException(J3dI18N.getString("LineAttributes0"));
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((LineAttributesRetained)this.retained).initLineWidth(lineWidth);
((LineAttributesRetained)this.retained).initLinePattern(linePattern);
((LineAttributesRetained)this.retained).initLineAntialiasingEnable(lineAntialiasing);
diff --git a/src/classes/share/javax/media/j3d/LineStripArray.java b/src/classes/share/javax/media/j3d/LineStripArray.java
index ef9ce5a..00581d2 100644
--- a/src/classes/share/javax/media/j3d/LineStripArray.java
+++ b/src/classes/share/javax/media/j3d/LineStripArray.java
@@ -30,28 +30,26 @@ public class LineStripArray extends GeometryStripArray {
}
/**
- * Constructs an empty LineStripArray object with the specified
- * number of vertices, vertex format, and
- * array of per-strip vertex counts.
- * @param vertexCount the number of vertex elements in this array
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.
- * @param stripVertexCounts array that specifies
- * the count of the number of vertices for each separate strip.
- * The length of this array is the number of separate strips.
+ * Constructs an empty LineStripArray object using the
+ * specified parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param stripVertexCounts
+ * see {@link GeometryStripArray#GeometryStripArray(int,int,int[])}
+ * for a description of this parameter.
*
* @exception IllegalArgumentException if vertexCount is less than 2
* or any element in the stripVertexCounts array is less than 2
+ * ;<br>
+ * See {@link GeometryStripArray#GeometryStripArray(int,int,int[])}
+ * for more exceptions that can be thrown
*/
public LineStripArray(int vertexCount,
int vertexFormat,
@@ -64,65 +62,34 @@ public class LineStripArray extends GeometryStripArray {
}
/**
- * Constructs an empty LineStripArray object with the specified
- * number of vertices, vertex format, number of texture coordinate
- * sets, texture coordinate mapping array, and
- * array of per-strip vertex counts.
- *
- * @param vertexCount the number of vertex elements in this array<p>
- *
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.<p>
- *
- * @param texCoordSetCount the number of texture coordinate sets
- * in this GeometryArray object. If <code>vertexFormat</code>
- * does not include one of <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetCount</code> parameter is not used.<p>
- *
- * @param texCoordSetMap an array that maps texture coordinate
- * sets to texture units. The array is indexed by texture unit
- * number for each texture unit in the associated Appearance
- * object. The values in the array specify the texture coordinate
- * set within this GeometryArray object that maps to the
- * corresponding texture
- * unit. All elements within the array must be less than
- * <code>texCoordSetCount</code>. A negative value specifies that
- * no texture coordinate set maps to the texture unit
- * corresponding to the index. If there are more texture units in
- * any associated Appearance object than elements in the mapping
- * array, the extra elements are assumed to be -1. The same
- * texture coordinate set may be used for more than one texture
- * unit. Each texture unit in every associated Appearance must
- * have a valid source of texture coordinates: either a
- * non-negative texture coordinate set must be specified in the
- * mapping array or texture coordinate generation must be enabled.
- * Texture coordinate generation will take precedence for those
- * texture units for which a texture coordinate set is specified
- * and texture coordinate generation is enabled. If
- * <code>vertexFormat</code> does not include one of
- * <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetMap</code> array is not used.<p>
- *
- * @param stripVertexCounts array that specifies
- * the count of the number of vertices for each separate strip.
- * The length of this array is the number of separate strips.
+ * Constructs an empty LineStripArray object using the
+ * specified parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param stripVertexCounts
+ * see {@link GeometryStripArray#GeometryStripArray(int,int,int,int[],int[])}
+ * for a description of this parameter.
*
* @exception IllegalArgumentException if vertexCount is less than 2
* or any element in the stripVertexCounts array is less than 2
+ * ;<br>
+ * See {@link GeometryStripArray#GeometryStripArray(int,int,int,int[],int[])}
+ * for more exceptions that can be thrown
*
* @since Java 3D 1.2
*/
@@ -141,6 +108,59 @@ public class LineStripArray extends GeometryStripArray {
}
/**
+ * Constructs an empty LineStripArray object using the
+ * specified parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrSizes
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param stripVertexCounts
+ * see {@link GeometryStripArray#GeometryStripArray(int,int,int,int[],int,int[],int[])}
+ * for a description of this parameter.
+ *
+ * @exception IllegalArgumentException if vertexCount is less than 2
+ * or any element in the stripVertexCounts array is less than 2
+ * ;<br>
+ * See {@link GeometryStripArray#GeometryStripArray(int,int,int,int[],int,int[],int[])}
+ * for more exceptions that can be thrown
+ *
+ * @since Java 3D 1.4
+ */
+ public LineStripArray(int vertexCount,
+ int vertexFormat,
+ int texCoordSetCount,
+ int[] texCoordSetMap,
+ int vertexAttrCount,
+ int[] vertexAttrSizes,
+ int[] stripVertexCounts) {
+
+ super(vertexCount, vertexFormat,
+ texCoordSetCount, texCoordSetMap,
+ vertexAttrCount, vertexAttrSizes,
+ stripVertexCounts);
+
+ if (vertexCount < 2 )
+ throw new IllegalArgumentException(J3dI18N.getString("LineStripArray0"));
+ }
+
+ /**
* Creates the retained mode LineStripArrayRetained object that this
* LineStripArray object will point to.
*/
@@ -153,24 +173,28 @@ public class LineStripArray extends GeometryStripArray {
* @deprecated replaced with cloneNodeComponent(boolean forceDuplicate)
*/
public NodeComponent cloneNodeComponent() {
- LineStripArrayRetained rt = (LineStripArrayRetained) retained;
+ LineStripArrayRetained rt = (LineStripArrayRetained) retained;
int stripcounts[] = new int[rt.getNumStrips()];
- rt.getStripVertexCounts(stripcounts);
- int texSetCount = rt.getTexCoordSetCount();
- LineStripArray l;
- if (texSetCount == 0) {
- l = new LineStripArray(rt.getVertexCount(),
- rt.getVertexFormat(),
- stripcounts);
- } else {
- int texMap[] = new int[rt.getTexCoordSetMapLength()];
- rt.getTexCoordSetMap(texMap);
- l = new LineStripArray(rt.getVertexCount(),
- rt.getVertexFormat(),
- texSetCount,
- texMap,
- stripcounts);
- }
+ rt.getStripVertexCounts(stripcounts);
+ int texSetCount = rt.getTexCoordSetCount();
+ int[] texMap = null;
+ int vertexAttrCount = rt.getVertexAttrCount();
+ int[] vertexAttrSizes = null;
+ if (texSetCount > 0) {
+ texMap = new int[rt.getTexCoordSetMapLength()];
+ rt.getTexCoordSetMap(texMap);
+ }
+ if (vertexAttrCount > 0) {
+ vertexAttrSizes = new int[vertexAttrCount];
+ rt.getVertexAttrSizes(vertexAttrSizes);
+ }
+ LineStripArray l = new LineStripArray(rt.getVertexCount(),
+ rt.getVertexFormat(),
+ texSetCount,
+ texMap,
+ vertexAttrCount,
+ vertexAttrSizes,
+ stripcounts);
l.duplicateNodeComponent(this);
return l;
}
diff --git a/src/classes/share/javax/media/j3d/LineStripArrayRetained.java b/src/classes/share/javax/media/j3d/LineStripArrayRetained.java
index 4270d74..69fa80b 100644
--- a/src/classes/share/javax/media/j3d/LineStripArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/LineStripArrayRetained.java
@@ -30,14 +30,15 @@ class LineStripArrayRetained extends GeometryStripArrayRetained {
this.geoType = GEO_TYPE_LINE_STRIP_SET;
}
- boolean intersect(PickShape pickShape, double dist[], Point3d iPnt) {
+ boolean intersect(PickShape pickShape, PickInfo.IntersectionInfo iInfo, int flags, Point3d iPnt) {
Point3d pnts[] = new Point3d[2];
double sdist[] = new double[1];
double minDist = Double.MAX_VALUE;
double x = 0, y = 0, z = 0;
int j, end;
int i = 0;
-
+ int count = 0;
+ int minICount = 0;
pnts[0] = new Point3d();
pnts[1] = new Point3d();
@@ -49,20 +50,22 @@ class LineStripArrayRetained extends GeometryStripArrayRetained {
j = stripStartVertexIndices[i];
end = j + stripVertexCounts[i++];
getVertexData(j++, pnts[0]);
+ count++;
while (j < end) {
getVertexData(j++, pnts[1]);
-
+ count++;
if (intersectLineAndRay(pnts[0], pnts[1], pickRay.origin,
pickRay.direction, sdist,
iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[0].set(pnts[1]);
@@ -80,21 +83,23 @@ class LineStripArrayRetained extends GeometryStripArrayRetained {
j = stripStartVertexIndices[i];
end = j + stripVertexCounts[i++];
getVertexData(j++, pnts[0]);
- while (j < end) {
+ count++;
+ while (j < end) {
getVertexData(j++, pnts[1]);
-
+ count++;
if (intersectLineAndRay(pnts[0], pnts[1],
pickSegment.start,
dir, sdist, iPnt) &&
(sdist[0] <= 1.0)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[0].set(pnts[1]);
@@ -109,17 +114,20 @@ class LineStripArrayRetained extends GeometryStripArrayRetained {
j = stripStartVertexIndices[i];
end = j + stripVertexCounts[i++];
getVertexData(j++, pnts[0]);
+ count++;
while (j < end) {
getVertexData(j++, pnts[1]);
+ count++;
if (intersectBoundingBox(pnts, bbox, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[0].set(pnts[1]);
@@ -135,17 +143,20 @@ class LineStripArrayRetained extends GeometryStripArrayRetained {
j = stripStartVertexIndices[i];
end = j + stripVertexCounts[i++];
getVertexData(j++, pnts[0]);
+ count++;
while (j < end) {
getVertexData(j++, pnts[1]);
+ count++;
if (intersectBoundingSphere(pnts, bsphere, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[0].set(pnts[1]);
@@ -160,17 +171,20 @@ class LineStripArrayRetained extends GeometryStripArrayRetained {
j = stripStartVertexIndices[i];
end = j + stripVertexCounts[i++];
getVertexData(j++, pnts[0]);
+ count++;
while (j < end) {
getVertexData(j++, pnts[1]);
+ count++;
if (intersectBoundingPolytope(pnts, bpolytope, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[0].set(pnts[1]);
@@ -184,18 +198,20 @@ class LineStripArrayRetained extends GeometryStripArrayRetained {
j = stripStartVertexIndices[i];
end = j + stripVertexCounts[i++];
getVertexData(j++, pnts[0]);
+ count++;
while (j < end) {
getVertexData(j++, pnts[1]);
-
+ count++;
if (intersectCylinder(pnts, pickCylinder, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[0].set(pnts[1]);
@@ -209,17 +225,20 @@ class LineStripArrayRetained extends GeometryStripArrayRetained {
j = stripStartVertexIndices[i];
end = j + stripVertexCounts[i++];
getVertexData(j++, pnts[0]);
+ count++;
while (j < end) {
getVertexData(j++, pnts[1]);
+ count++;
if (intersectCone(pnts, pickCone, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[0].set(pnts[1]);
@@ -234,14 +253,20 @@ class LineStripArrayRetained extends GeometryStripArrayRetained {
}
if (minDist < Double.MAX_VALUE) {
- dist[0] = minDist;
+ assert(minICount >= 2);
+ int[] vertexIndices = iInfo.getVertexIndices();
+ if (vertexIndices == null) {
+ vertexIndices = new int[2];
+ iInfo.setVertexIndices(vertexIndices);
+ }
+ vertexIndices[0] = minICount - 2;
+ vertexIndices[1] = minICount - 1;
iPnt.x = x;
iPnt.y = y;
iPnt.z = z;
return true;
}
- return false;
-
+ return false;
}
boolean intersect(Point3d[] pnts) {
diff --git a/src/classes/share/javax/media/j3d/LinearFog.java b/src/classes/share/javax/media/j3d/LinearFog.java
index 5232d32..4aa543f 100644
--- a/src/classes/share/javax/media/j3d/LinearFog.java
+++ b/src/classes/share/javax/media/j3d/LinearFog.java
@@ -25,14 +25,16 @@ import javax.vecmath.Color3f;
* the node, but the actual fog equation will ideally take place in eye
* coordinates.
* <P>
- * The linear fog blending factor, f, is computed as follows:
- * <P><UL>
- * f = backDistance - z / backDistance - frontDistance<P>
- * where
- * <ul>z is the distance from the viewpoint.<br>
- * frontDistance is the distance at which fog starts obscuring objects.<br>
- * backDistance is the distance at which fog totally obscurs objects.
- * </ul><P></UL>
+ * The linear fog blending factor, <code>f</code>, is computed as follows:
+ * <ul>
+ * <code>f = (backDistance - z) / (backDistance - frontDistance)</code>
+ * </ul>
+ * where:
+ * <ul>
+ * <code>z</code> is the distance from the viewpoint.<br>
+ * <code>frontDistance</code> is the distance at which fog starts obscuring objects.<br>
+ * <code>backDistance</code> is the distance at which fog totally obscurs objects.
+ * </ul>
*/
public class LinearFog extends Fog {
/**
@@ -49,6 +51,11 @@ public class LinearFog extends Fog {
public static final int
ALLOW_DISTANCE_WRITE = CapabilityBits.LINEAR_FOG_ALLOW_DISTANCE_WRITE;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_DISTANCE_READ
+ };
+
/**
* Constructs a LinearFog node with default parameters.
* The default values are as follows:
@@ -59,6 +66,8 @@ public class LinearFog extends Fog {
*/
public LinearFog() {
// Just use the defaults
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -67,6 +76,9 @@ public class LinearFog extends Fog {
*/
public LinearFog(Color3f color) {
super(color);
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -77,6 +89,10 @@ public class LinearFog extends Fog {
*/
public LinearFog(Color3f color, double frontDistance, double backDistance) {
super(color);
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((LinearFogRetained)this.retained).initFrontDistance(frontDistance);
((LinearFogRetained)this.retained).initBackDistance(backDistance);
}
@@ -89,6 +105,9 @@ public class LinearFog extends Fog {
*/
public LinearFog(float r, float g, float b) {
super(r, g, b);
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -102,6 +121,10 @@ public class LinearFog extends Fog {
public LinearFog(float r, float g, float b,
double frontDistance, double backDistance) {
super(r, g, b);
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((LinearFogRetained)this.retained).initFrontDistance(frontDistance);
((LinearFogRetained)this.retained).initBackDistance(backDistance);
}
diff --git a/src/classes/share/javax/media/j3d/LinearFogRetained.java b/src/classes/share/javax/media/j3d/LinearFogRetained.java
index 4f7b723..4eff1ec 100644
--- a/src/classes/share/javax/media/j3d/LinearFogRetained.java
+++ b/src/classes/share/javax/media/j3d/LinearFogRetained.java
@@ -24,12 +24,10 @@ class LinearFogRetained extends FogRetained {
/**
* Fog front and back distance
*/
- double frontDistance = 0.1;
- double backDistance = 1.0;
- double localToVworldScale = 1.0;
- double frontDistanceInEc;
- double backDistanceInEc;
- double vworldToCoexistenceScale;
+ private double frontDistance = 0.1;
+ private double backDistance = 1.0;
+ private double frontDistanceInEc;
+ private double backDistanceInEc;
// dirty bits for LinearFog
static final int FRONT_DISTANCE_CHANGED = FogRetained.LAST_DEFINED_BIT << 1;
@@ -169,29 +167,21 @@ class LinearFogRetained extends FogRetained {
((LinearFogRetained)mirrorFog).backDistance = ((Double)((Object[])objs[4])[5]).doubleValue();
}
- ((LinearFogRetained)mirrorFog).localToVworldScale =
- getLastLocalToVworld().getDistanceScale();
-
+ ((LinearFogRetained)mirrorFog).setLocalToVworldScale(getLastLocalToVworld().getDistanceScale());
super.updateMirrorObject(objs);
}
/**
* Scale distances from local to eye coordinate
- */
-
- void validateDistancesInEc(double vworldToCoexistenceScale) {
+ */
+ protected void validateDistancesInEc(double vworldToCoexistenceScale) {
// vworldToCoexistenceScale can be used here since
// CoexistenceToEc has a unit scale
- double localToEcScale = localToVworldScale * vworldToCoexistenceScale;
+ double localToEcScale = getLocalToVworldScale() * vworldToCoexistenceScale;
frontDistanceInEc = frontDistance * localToEcScale;
backDistanceInEc = backDistance * localToEcScale;
}
- // Called on mirror object
- void updateTransformChange() {
- super.updateTransformChange();
- localToVworldScale = sgFog.getLastLocalToVworld().getDistanceScale();
- }
}
diff --git a/src/classes/share/javax/media/j3d/Link.java b/src/classes/share/javax/media/j3d/Link.java
index 151952c..549c3aa 100644
--- a/src/classes/share/javax/media/j3d/Link.java
+++ b/src/classes/share/javax/media/j3d/Link.java
@@ -34,11 +34,18 @@ public class Link extends Leaf {
public static final int
ALLOW_SHARED_GROUP_WRITE = CapabilityBits.LINK_ALLOW_SHARED_GROUP_WRITE;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_SHARED_GROUP_READ
+ };
+
/**
* Constructs a Link node object that does not yet point to a
* SharedGroup node.
*/
public Link() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -47,7 +54,10 @@ public class Link extends Leaf {
* @param sharedGroup the SharedGroup node
*/
public Link(SharedGroup sharedGroup) {
- ((LinkRetained)this.retained).setSharedGroup(sharedGroup);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((LinkRetained)this.retained).setSharedGroup(sharedGroup);
}
/**
diff --git a/src/classes/share/javax/media/j3d/LinkRetained.java b/src/classes/share/javax/media/j3d/LinkRetained.java
index f9dafb5..9ba765c 100644
--- a/src/classes/share/javax/media/j3d/LinkRetained.java
+++ b/src/classes/share/javax/media/j3d/LinkRetained.java
@@ -293,7 +293,7 @@ class LinkRetained extends LeafRetained {
super.compile(compState);
- // TODO: for now keep the static transform in the parent tg
+ // XXXX: for now keep the static transform in the parent tg
compState.keepTG = true;
// don't remove this group node
diff --git a/src/classes/share/javax/media/j3d/Locale.java b/src/classes/share/javax/media/j3d/Locale.java
index ecb4c86..157cbde 100644
--- a/src/classes/share/javax/media/j3d/Locale.java
+++ b/src/classes/share/javax/media/j3d/Locale.java
@@ -158,6 +158,7 @@ public class Locale extends Object {
throw new MultipleParentException(J3dI18N.getString("Locale0"));
}
+ universe.notifyStructureChangeListeners(true, this, branchGroup);
universe.resetWaitMCFlag();
synchronized (universe.sceneGraphLock) {
doAddBranchGraph(branchGroup);
@@ -377,6 +378,7 @@ public class Locale extends Object {
universe);
}
universe.setLiveState.reset(null); // cleanup memory
+ universe.notifyStructureChangeListeners(false, this, branchGroup);
}
/**
@@ -408,10 +410,12 @@ public class Locale extends Object {
throw new MultipleParentException(J3dI18N.getString("Locale3"));
}
universe.resetWaitMCFlag();
+ universe.notifyStructureChangeListeners(true, this, newGroup);
synchronized (universe.sceneGraphLock) {
doReplaceBranchGraph(oldGroup, newGroup);
universe.setLiveState.reset(this);
}
+ universe.notifyStructureChangeListeners(false, this, oldGroup);
universe.waitForMC();
}
@@ -494,7 +498,7 @@ public class Locale extends Object {
createMessage.args[4] = universe.setLiveState.ogCIOTableList.toArray();
VirtualUniverse.mc.processMessage(createMessage);
- // TODO: make these two into one message
+ // XXXX: make these two into one message
createMessage = VirtualUniverse.mc.getMessage();
createMessage.threads = universe.setLiveState.notifyThreads;
createMessage.type = J3dMessage.INSERT_NODES;
@@ -525,11 +529,8 @@ public class Locale extends Object {
createMessage.universe = universe;
VirtualUniverse.mc.processMessage(createMessage);
-
// Free up memory.
universe.setLiveState.reset(null);
-
-
}
/**
@@ -553,7 +554,47 @@ public class Locale extends Object {
return branchGroups.elements();
}
+
+ void validateModeFlagAndPickShape(int mode, int flags, PickShape pickShape) {
+
+ if (universe == null) {
+ throw new IllegalStateException(J3dI18N.getString("Locale4"));
+ }
+
+ if((mode != PickInfo.PICK_BOUNDS) && (mode != PickInfo.PICK_GEOMETRY)) {
+
+ throw new IllegalArgumentException(J3dI18N.getString("Locale5"));
+ }
+
+ if((pickShape instanceof PickPoint) && (mode == PickInfo.PICK_GEOMETRY)) {
+ throw new IllegalArgumentException(J3dI18N.getString("Locale6"));
+ }
+
+ if(((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) &&
+ ((flags & PickInfo.ALL_GEOM_INFO) != 0)) {
+ throw new IllegalArgumentException(J3dI18N.getString("Locale7"));
+ }
+
+ if((mode == PickInfo.PICK_BOUNDS) &&
+ (((flags & (PickInfo.CLOSEST_GEOM_INFO |
+ PickInfo.ALL_GEOM_INFO |
+ PickInfo.CLOSEST_DISTANCE |
+ PickInfo.CLOSEST_INTERSECTION_POINT)) != 0))) {
+
+ throw new IllegalArgumentException(J3dI18N.getString("Locale8"));
+ }
+
+ if((pickShape instanceof PickBounds) &&
+ (((flags & (PickInfo.CLOSEST_GEOM_INFO |
+ PickInfo.ALL_GEOM_INFO |
+ PickInfo.CLOSEST_DISTANCE |
+ PickInfo.CLOSEST_INTERSECTION_POINT)) != 0))) {
+
+ throw new IllegalArgumentException(J3dI18N.getString("Locale9"));
+ }
+ }
+
/**
* Returns an array referencing all the items that are pickable below this
* <code>Locale</code> that intersect with PickShape.
@@ -571,12 +612,103 @@ public class Locale extends Object {
throw new IllegalStateException(J3dI18N.getString("Locale4"));
}
- return Picking.pickAll( this, pickShape );
+ PickInfo[] pickInfoArr = pickAll( PickInfo.PICK_BOUNDS,
+ PickInfo.SCENEGRAPHPATH, pickShape);
+
+ if(pickInfoArr == null) {
+ return null;
+ }
+ SceneGraphPath[] sgpArr = new SceneGraphPath[pickInfoArr.length];
+ for( int i=0; i<sgpArr.length; i++) {
+ sgpArr[i] = pickInfoArr[i].getSceneGraphPath();
+ }
+
+ return sgpArr;
+
}
/**
- * Returns a sorted array of references to all the Pickable items
+ * Returns an array unsorted references to all the PickInfo objects that are pickable
+ * below this <code>Locale</code> that intersect with PickShape.
+ * The accuracy of the pick is set by the pick mode. The mode include :
+ * PickInfo.PICK_BOUNDS and PickInfo.PICK_GEOMETRY. The amount of information returned
+ * is specified via a masked variable, flags, indicating which components are
+ * present in each returned PickInfo object.
+ *
+ * @param mode picking mode, one of <code>PickInfo.PICK_BOUNDS</code> or <code>PickInfo.PICK_GEOMETRY</code>.
+ *
+ * @param flags a mask indicating which components are present in each PickInfo object.
+ * This is specified as one or more individual bits that are bitwise "OR"ed together to
+ * describe the PickInfo data. The flags include :
+ * <ul>
+ * <code>PickInfo.SCENEGRAPHPATH</code> - request for computed SceneGraphPath.<br>
+ * <code>PickInfo.NODE</code> - request for computed intersected Node.<br>
+ * <code>PickInfo.LOCAL_TO_VWORLD</code> - request for computed local to virtual world transform.<br>
+ * <code>PickInfo.CLOSEST_INTERSECTION_POINT</code> - request for closest intersection point.<br>
+ * <code>PickInfo.CLOSEST_DISTANCE</code> - request for the distance of closest intersection.<br>
+ * <code>PickInfo.CLOSEST_GEOM_INFO</code> - request for only the closest intersection geometry information.<br>
+ * <code>PickInfo.ALL_GEOM_INFO</code> - request for all intersection geometry information.<br>
+ * </ul>
+ *
+ * @param pickShape the description of this picking volume or area.
+ *
+ * @exception IllegalArgumentException if flags contains both CLOSEST_GEOM_INFO and
+ * ALL_GEOM_INFO.
+ *
+ * @exception IllegalArgumentException if pickShape is a PickPoint and pick mode
+ * is set to PICK_GEOMETRY.
+ *
+ * @exception IllegalArgumentException if pick mode is neither PICK_BOUNDS
+ * nor PICK_GEOMETRY.
+ *
+ * @exception IllegalArgumentException if pick mode is PICK_BOUNDS
+ * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
+ * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
+ *
+ * @exception IllegalArgumentException if pickShape is PickBounds
+ * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
+ * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
+ *
+ * @exception IllegalStateException if this Locale has been
+ * removed from its VirtualUniverse.
+ *
+ * @exception CapabilityNotSetException if the mode is
+ * PICK_GEOMETRY and the Geometry.ALLOW_INTERSECT capability bit
+ * is not set in any Geometry objects referred to by any shape
+ * node whose bounds intersects the PickShape.
+ *
+ * @exception CapabilityNotSetException if flags contains any of
+ * CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE, CLOSEST_GEOM_INFO
+ * or ALL_GEOM_INFO, and the capability bits that control reading of
+ * coordinate data are not set in any GeometryArray object referred
+ * to by any shape node that intersects the PickShape.
+ * The capability bits that must be set to avoid this exception are as follows :
+ * <ul>
+ * <li>By-copy geometry : GeometryArray.ALLOW_COORDINATE_READ</li>
+ * <li>By-reference geometry : GeometryArray.ALLOW_REF_DATA_READ</li>
+ * <li>Indexed geometry : IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ
+ * (in addition to one of the above)</li>
+ * </ul>
+ *
+ * @see BranchGroup#pickAll(int,int,javax.media.j3d.PickShape)
+ * @see PickInfo
+ *
+ * @since Java 3D 1.4
+ *
+ */
+ public PickInfo[] pickAll( int mode, int flags, PickShape pickShape ) {
+
+ validateModeFlagAndPickShape(mode, flags, pickShape);
+
+ GeometryAtom geomAtoms[] = universe.geometryStructure.pickAll(this, pickShape);
+
+ return PickInfo.pick(this, geomAtoms, mode, flags, pickShape, PickInfo.PICK_ALL);
+
+ }
+
+ /**
+ * Returns a sorted array of references to all the pickable items
* that intersect with the pickShape. Element [0] references the
* item closest to <i>origin</i> of PickShape successive array
* elements are further from the <i>origin</i>
@@ -596,9 +728,118 @@ public class Locale extends Object {
throw new IllegalStateException(J3dI18N.getString("Locale4"));
}
- return Picking.pickAllSorted( this, pickShape );
+ PickInfo[] pickInfoArr = pickAllSorted( PickInfo.PICK_BOUNDS,
+ PickInfo.SCENEGRAPHPATH, pickShape);
+
+ if(pickInfoArr == null) {
+ return null;
+ }
+ SceneGraphPath[] sgpArr = new SceneGraphPath[pickInfoArr.length];
+ for( int i=0; i<sgpArr.length; i++) {
+ sgpArr[i] = pickInfoArr[i].getSceneGraphPath();
+ }
+
+ return sgpArr;
+
}
+ /**
+ * Returns a sorted array of PickInfo references to all the pickable
+ * items that intersect with the pickShape. Element [0] references
+ * the item closest to <i>origin</i> of PickShape successive array
+ * elements are further from the <i>origin</i>
+ * The accuracy of the pick is set by the pick mode. The mode include :
+ * PickInfo.PICK_BOUNDS and PickInfo.PICK_GEOMETRY. The amount of information returned
+ * is specified via a masked variable, flags, indicating which components are
+ * present in each returned PickInfo object.
+ *
+ * @param mode picking mode, one of <code>PickInfo.PICK_BOUNDS</code> or <code>PickInfo.PICK_GEOMETRY</code>.
+ *
+ * @param flags a mask indicating which components are present in each PickInfo object.
+ * This is specified as one or more individual bits that are bitwise "OR"ed together to
+ * describe the PickInfo data. The flags include :
+ * <ul>
+ * <code>PickInfo.SCENEGRAPHPATH</code> - request for computed SceneGraphPath.<br>
+ * <code>PickInfo.NODE</code> - request for computed intersected Node.<br>
+ * <code>PickInfo.LOCAL_TO_VWORLD</code> - request for computed local to virtual world transform.<br>
+ * <code>PickInfo.CLOSEST_INTERSECTION_POINT</code> - request for closest intersection point.<br>
+ * <code>PickInfo.CLOSEST_DISTANCE</code> - request for the distance of closest intersection.<br>
+ * <code>PickInfo.CLOSEST_GEOM_INFO</code> - request for only the closest intersection geometry information.<br>
+ * <code>PickInfo.ALL_GEOM_INFO</code> - request for all intersection geometry information.<br>
+ * </ul>
+ *
+ * @param pickShape the description of this picking volume or area.
+ *
+ * @exception IllegalArgumentException if flags contains both CLOSEST_GEOM_INFO and
+ * ALL_GEOM_INFO.
+ *
+ * @exception IllegalArgumentException if pickShape is a PickPoint and pick mode
+ * is set to PICK_GEOMETRY.
+ *
+ * @exception IllegalArgumentException if pick mode is neither PICK_BOUNDS
+ * nor PICK_GEOMETRY.
+ *
+ * @exception IllegalArgumentException if pick mode is PICK_BOUNDS
+ * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
+ * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
+ *
+ * @exception IllegalArgumentException if pickShape is PickBounds
+ * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
+ * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
+ *
+ * @exception IllegalStateException if this Locale has been
+ * removed from its VirtualUniverse.
+ *
+ * @exception CapabilityNotSetException if the mode is
+ * PICK_GEOMETRY and the Geometry.ALLOW_INTERSECT capability bit
+ * is not set in any Geometry objects referred to by any shape
+ * node whose bounds intersects the PickShape.
+ *
+ * @exception CapabilityNotSetException if flags contains any of
+ * CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE, CLOSEST_GEOM_INFO
+ * or ALL_GEOM_INFO, and the capability bits that control reading of
+ * coordinate data are not set in any GeometryArray object referred
+ * to by any shape node that intersects the PickShape.
+ * The capability bits that must be set to avoid this exception are as follows :
+ * <ul>
+ * <li>By-copy geometry : GeometryArray.ALLOW_COORDINATE_READ</li>
+ * <li>By-reference geometry : GeometryArray.ALLOW_REF_DATA_READ</li>
+ * <li>Indexed geometry : IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ
+ * (in addition to one of the above)</li>
+ * </ul>
+ *
+ * @see BranchGroup#pickAllSorted(int,int,javax.media.j3d.PickShape)
+ * @see PickInfo
+ *
+ * @since Java 3D 1.4
+ *
+ */
+ public PickInfo[] pickAllSorted( int mode, int flags, PickShape pickShape ) {
+
+ validateModeFlagAndPickShape(mode, flags, pickShape);
+ GeometryAtom geomAtoms[] = universe.geometryStructure.pickAll(this, pickShape);
+
+ if ((geomAtoms == null) || (geomAtoms.length == 0)) {
+ return null;
+ }
+
+ PickInfo[] pickInfoArr = null;
+
+ if (mode == PickInfo.PICK_GEOMETRY) {
+ // Need to have closestDistance set
+ flags |= PickInfo.CLOSEST_DISTANCE;
+ pickInfoArr= PickInfo.pick(this, geomAtoms, mode, flags, pickShape, PickInfo.PICK_ALL);
+ if (pickInfoArr != null) {
+ PickInfo.sortPickInfoArray(pickInfoArr);
+ }
+ }
+ else {
+ PickInfo.sortGeomAtoms(geomAtoms, pickShape);
+ pickInfoArr= PickInfo.pick(this, geomAtoms, mode, flags, pickShape, PickInfo.PICK_ALL);
+ }
+
+ return pickInfoArr;
+ }
/**
* Returns a SceneGraphPath which references the pickable item
@@ -615,13 +856,101 @@ public class Locale extends Object {
* @see BranchGroup#pickClosest
*/
public SceneGraphPath pickClosest( PickShape pickShape ) {
- if (universe == null) {
- throw new IllegalStateException(J3dI18N.getString("Locale4"));
- }
+ if (universe == null) {
+ throw new IllegalStateException(J3dI18N.getString("Locale4"));
+ }
- return Picking.pickClosest( this, pickShape );
+ PickInfo pickInfo = pickClosest( PickInfo.PICK_BOUNDS,
+ PickInfo.SCENEGRAPHPATH, pickShape);
+
+ if(pickInfo == null) {
+ return null;
+ }
+ return pickInfo.getSceneGraphPath();
}
+ /**
+ * Returns a PickInfo which references the pickable item
+ * which is closest to the origin of <code>pickShape</code>.
+ * The accuracy of the pick is set by the pick mode. The mode include :
+ * PickInfo.PICK_BOUNDS and PickInfo.PICK_GEOMETRY. The amount of information returned
+ * is specified via a masked variable, flags, indicating which components are
+ * present in each returned PickInfo object.
+ *
+ * @param mode picking mode, one of <code>PickInfo.PICK_BOUNDS</code> or <code>PickInfo.PICK_GEOMETRY</code>.
+ *
+ * @param flags a mask indicating which components are present in each PickInfo object.
+ * This is specified as one or more individual bits that are bitwise "OR"ed together to
+ * describe the PickInfo data. The flags include :
+ * <ul>
+ * <code>PickInfo.SCENEGRAPHPATH</code> - request for computed SceneGraphPath.<br>
+ * <code>PickInfo.NODE</code> - request for computed intersected Node.<br>
+ * <code>PickInfo.LOCAL_TO_VWORLD</code> - request for computed local to virtual world transform.<br>
+ * <code>PickInfo.CLOSEST_INTERSECTION_POINT</code> - request for closest intersection point.<br>
+ * <code>PickInfo.CLOSEST_DISTANCE</code> - request for the distance of closest intersection.<br>
+ * <code>PickInfo.CLOSEST_GEOM_INFO</code> - request for only the closest intersection geometry information.<br>
+ * <code>PickInfo.ALL_GEOM_INFO</code> - request for all intersection geometry information.<br>
+ * </ul>
+ *
+ * @param pickShape the description of this picking volume or area.
+ *
+ * @exception IllegalArgumentException if flags contains both CLOSEST_GEOM_INFO and
+ * ALL_GEOM_INFO.
+ *
+ * @exception IllegalArgumentException if pickShape is a PickPoint and pick mode
+ * is set to PICK_GEOMETRY.
+ *
+ * @exception IllegalArgumentException if pick mode is neither PICK_BOUNDS
+ * nor PICK_GEOMETRY.
+ *
+ * @exception IllegalArgumentException if pick mode is PICK_BOUNDS
+ * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
+ * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
+ *
+ * @exception IllegalArgumentException if pickShape is PickBounds
+ * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
+ * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
+ *
+ * @exception IllegalStateException if this Locale has been
+ * removed from its VirtualUniverse.
+ *
+ * @exception CapabilityNotSetException if the mode is
+ * PICK_GEOMETRY and the Geometry.ALLOW_INTERSECT capability bit
+ * is not set in any Geometry objects referred to by any shape
+ * node whose bounds intersects the PickShape.
+ *
+ * @exception CapabilityNotSetException if flags contains any of
+ * CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE, CLOSEST_GEOM_INFO
+ * or ALL_GEOM_INFO, and the capability bits that control reading of
+ * coordinate data are not set in any GeometryArray object referred
+ * to by any shape node that intersects the PickShape.
+ * The capability bits that must be set to avoid this exception are as follows :
+ * <ul>
+ * <li>By-copy geometry : GeometryArray.ALLOW_COORDINATE_READ</li>
+ * <li>By-reference geometry : GeometryArray.ALLOW_REF_DATA_READ</li>
+ * <li>Indexed geometry : IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ
+ * (in addition to one of the above)</li>
+ * </ul>
+ *
+ * @see BranchGroup#pickClosest(int,int,javax.media.j3d.PickShape)
+ * @see PickInfo
+ *
+ * @since Java 3D 1.4
+ *
+ */
+ public PickInfo pickClosest( int mode, int flags, PickShape pickShape ) {
+
+ PickInfo[] pickInfoArr = null;
+
+ pickInfoArr = pickAllSorted( mode, flags, pickShape );
+
+ if(pickInfoArr == null) {
+ return null;
+ }
+
+ return pickInfoArr[0];
+
+ }
/**
* Returns a reference to any item that is Pickable below this
@@ -638,10 +967,100 @@ public class Locale extends Object {
if (universe == null) {
throw new IllegalStateException(J3dI18N.getString("Locale4"));
}
-
- return Picking.pickAny( this, pickShape );
+
+ PickInfo pickInfo = pickAny( PickInfo.PICK_BOUNDS,
+ PickInfo.SCENEGRAPHPATH, pickShape);
+
+ if(pickInfo == null) {
+ return null;
+ }
+ return pickInfo.getSceneGraphPath();
+
}
+ /**
+ * Returns a PickInfo which references the pickable item below this
+ * Locale which intersects with <code>pickShape</code>.
+ * The accuracy of the pick is set by the pick mode. The mode include :
+ * PickInfo.PICK_BOUNDS and PickInfo.PICK_GEOMETRY. The amount of information returned
+ * is specified via a masked variable, flags, indicating which components are
+ * present in each returned PickInfo object.
+ *
+ * @param mode picking mode, one of <code>PickInfo.PICK_BOUNDS</code> or <code>PickInfo.PICK_GEOMETRY</code>.
+ *
+ * @param flags a mask indicating which components are present in each PickInfo object.
+ * This is specified as one or more individual bits that are bitwise "OR"ed together to
+ * describe the PickInfo data. The flags include :
+ * <ul>
+ * <code>PickInfo.SCENEGRAPHPATH</code> - request for computed SceneGraphPath.<br>
+ * <code>PickInfo.NODE</code> - request for computed intersected Node.<br>
+ * <code>PickInfo.LOCAL_TO_VWORLD</code> - request for computed local to virtual world transform.<br>
+ * <code>PickInfo.CLOSEST_INTERSECTION_POINT</code> - request for closest intersection point.<br>
+ * <code>PickInfo.CLOSEST_DISTANCE</code> - request for the distance of closest intersection.<br>
+ * <code>PickInfo.CLOSEST_GEOM_INFO</code> - request for only the closest intersection geometry information.<br>
+ * <code>PickInfo.ALL_GEOM_INFO</code> - request for all intersection geometry information.<br>
+ * </ul>
+ *
+ * @param pickShape the description of this picking volume or area.
+ *
+ * @exception IllegalArgumentException if flags contains both CLOSEST_GEOM_INFO and
+ * ALL_GEOM_INFO.
+ *
+ * @exception IllegalArgumentException if pickShape is a PickPoint and pick mode
+ * is set to PICK_GEOMETRY.
+ *
+ * @exception IllegalArgumentException if pick mode is neither PICK_BOUNDS
+ * nor PICK_GEOMETRY.
+ *
+ * @exception IllegalArgumentException if pick mode is PICK_BOUNDS
+ * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
+ * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
+ *
+ * @exception IllegalArgumentException if pickShape is PickBounds
+ * and flags includes any of CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE,
+ * CLOSEST_GEOM_INFO or ALL_GEOM_INFO.
+ *
+ * @exception IllegalStateException if this Locale has been
+ * removed from its VirtualUniverse.
+ *
+ * @exception CapabilityNotSetException if the mode is
+ * PICK_GEOMETRY and the Geometry.ALLOW_INTERSECT capability bit
+ * is not set in any Geometry objects referred to by any shape
+ * node whose bounds intersects the PickShape.
+ *
+ * @exception CapabilityNotSetException if flags contains any of
+ * CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE, CLOSEST_GEOM_INFO
+ * or ALL_GEOM_INFO, and the capability bits that control reading of
+ * coordinate data are not set in any GeometryArray object referred
+ * to by any shape node that intersects the PickShape.
+ * The capability bits that must be set to avoid this exception are as follows :
+ * <ul>
+ * <li>By-copy geometry : GeometryArray.ALLOW_COORDINATE_READ</li>
+ * <li>By-reference geometry : GeometryArray.ALLOW_REF_DATA_READ</li>
+ * <li>Indexed geometry : IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ
+ * (in addition to one of the above)</li>
+ * </ul>
+ *
+ * @see BranchGroup#pickAny(int,int,javax.media.j3d.PickShape)
+ * @see PickInfo
+ *
+ * @since Java 3D 1.4
+ *
+ */
+ public PickInfo pickAny( int mode, int flags, PickShape pickShape ) {
+
+ validateModeFlagAndPickShape(mode, flags, pickShape);
+ GeometryAtom geomAtoms[] = universe.geometryStructure.pickAll(this, pickShape);
+
+ PickInfo[] pickInfoArr = PickInfo.pick(this, geomAtoms, mode, flags, pickShape, PickInfo.PICK_ANY);
+
+ if(pickInfoArr == null) {
+ return null;
+ }
+
+ return pickInfoArr[0];
+
+ }
/**
* Cleans up resources associated with this Locale
diff --git a/src/classes/share/javax/media/j3d/MasterControl.java b/src/classes/share/javax/media/j3d/MasterControl.java
index c70b268..8e15f3f 100644
--- a/src/classes/share/javax/media/j3d/MasterControl.java
+++ b/src/classes/share/javax/media/j3d/MasterControl.java
@@ -20,6 +20,8 @@ package javax.media.j3d;
import java.util.*;
import java.awt.*;
+import java.io.File;
+
class MasterControl {
@@ -77,6 +79,8 @@ class MasterControl {
static final Integer SET_QUERYPROPERTIES = new Integer(20);
static final Integer SET_VIEW = new Integer(21);
+ private static boolean librariesLoaded = false;
+
/**
* reference to MasterControl thread
*/
@@ -197,6 +201,9 @@ class MasterControl {
// Only one Timer thread in the system.
TimerThread timerThread;
+ // Only one Notification thread in the system.
+ private NotificationThread notificationThread;
+
/**
* This flag indicates that MC is running
*/
@@ -305,9 +312,11 @@ class MasterControl {
// This is a time stamp used when context is created
private long contextTimeStamp = 0;
-
- // This is a counter for canvas bit
- private int canvasBitCount = 0;
+
+ // This is an array of canvasIds in used
+ private boolean[] canvasIds = null;
+ private int canvasFreeIndex = 0;
+ private Object canvasIdLock = new Object();
// This is a counter for rendererBit
private int rendererCount = 0;
@@ -335,15 +344,28 @@ class MasterControl {
// Flag that indicates whether separate specular color is disabled or not
boolean disableSeparateSpecularColor = false;
- // Maximum number of texture units
- int textureUnitMax = 100;
-
// Flag that indicates whether DisplayList is used or not
boolean isDisplayList = true;
// If this flag is set, then by-ref geometry will not be
// put in display list
boolean buildDisplayListIfPossible = false;
+
+ // If this flag is set, then geometry arrays with vertex attributes can
+ // be in display list.
+ boolean vertexAttrsInDisplayList = false;
+
+ // The global shading language being used. Using a ShaderProgram
+ // with a shading language other than the one specified by
+ // globalShadingLanguage will cause a ShaderError to be generated,
+ static int globalShadingLanguage = Shader.SHADING_LANGUAGE_GLSL;
+
+ // Flags indicating whether the Cg or GLSL libraries are available; we still need
+ // to check for the actual extension support when the Canvas3D with its associated context
+ // is created. Note that these are qualifed by the above globalShadingLanguage, so at
+ // most one of these two flags will be true;
+ static boolean cgLibraryAvailable = false;
+ static boolean glslLibraryAvailable = false;
// REQUESTCLEANUP messages argument
@@ -390,6 +412,9 @@ class MasterControl {
// False to disable rescale normal if OGL support
boolean isForceNormalized = false;
+ // True to allow simulated (multi-pass) multi-texture
+ boolean allowSimulatedMultiTexture = false;
+
// Hashtable that maps a GraphicsDevice to its associated
// Screen3D--this is only used for on-screen Canvas3Ds
Hashtable deviceScreenMap = new Hashtable();
@@ -417,6 +442,13 @@ class MasterControl {
private ArrayList timestampUpdateList = new ArrayList(3);
private UnorderList freeMessageList = new UnorderList(8);
+
+ // System properties containing the native library search PATH
+ // The order listed is the order in which they will be searched
+ private static final String[] systemPathProps = {
+ "sun.boot.library.path",
+ "java.library.path"
+ };
long awt;
native long getAWT();
@@ -424,6 +456,9 @@ class MasterControl {
// Method to initialize the native J3D library
private native boolean initializeJ3D(boolean disableXinerama);
+ // Method to verify whether the native Cg library is available
+ private static native boolean loadNativeCgLibrary(String[] libpath);
+
// Method to get number of procesor
private native int getNumberOfProcessor();
@@ -464,7 +499,8 @@ class MasterControl {
* VirtualUniverse.
*/
MasterControl() {
-
+ assert librariesLoaded;
+
// Get AWT handle
awt = getAWT();
@@ -522,23 +558,6 @@ class MasterControl {
System.err.println("Java 3D: separate specular color disabled if possible");
}
- // Get the maximum number of texture units
- final int defaultTextureUnitMax = textureUnitMax;
- Integer textureUnitLimit =
- (Integer) java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction() {
- public Object run() {
- return Integer.getInteger("j3d.textureUnitMax",
- defaultTextureUnitMax);
- }
- });
-
- textureUnitMax = textureUnitLimit.intValue();
- if (textureUnitMax != defaultTextureUnitMax) {
- System.err.println("Java 3D: maximum number of texture units = " +
- textureUnitMax);
- }
-
isDisplayList = getBooleanProperty("j3d.displaylist", isDisplayList,
"display list");
@@ -553,24 +572,41 @@ class MasterControl {
"compiled vertex array");
isForceNormalized =
- getBooleanProperty("j3d.forceNormalized", isForceNormalized,
+ getBooleanProperty("j3d.forceNormalized",
+ isForceNormalized,
"force normalized");
+ allowSimulatedMultiTexture =
+ getBooleanProperty("j3d.simulatedMultiTexture",
+ allowSimulatedMultiTexture,
+ "simulated multi-texture");
+
+ if (allowSimulatedMultiTexture) {
+ System.err.println("************************************************************************");
+ System.err.println(J3dI18N.getString("MasterControl2"));
+ System.err.println(J3dI18N.getString("MasterControl3"));
+ System.err.println("************************************************************************");
+ }
- boolean j3dOptimizeSpace =
+ boolean j3dOptimizeSpace =
getBooleanProperty("j3d.optimizeForSpace", true,
"optimize for space");
- // Build Display list for by-ref geometry and infrequently changing geometry
- // ONLY IF (isDisplayList is true and optimizeForSpace if False)
- if (isDisplayList && !j3dOptimizeSpace) {
- buildDisplayListIfPossible = true;
- }
- else {
- buildDisplayListIfPossible = false;
- }
+ if (isDisplayList) {
+ // Build Display list for by-ref geometry
+ // ONLY IF optimizeForSpace is false
+ if (!j3dOptimizeSpace) {
+ buildDisplayListIfPossible = true;
+ }
+
+ // Build display lists for geometry with vertex attributes
+ // ONLY if we are in GLSL mode and GLSL shaders are available
+ if (glslLibraryAvailable) {
+ vertexAttrsInDisplayList = true;
+ }
+ }
- // Check to see whether Renderer can run without DSI lock
+ // Check to see whether Renderer can run without DSI lock
doDsiRenderLock = getBooleanProperty("j3d.renderLock",
doDsiRenderLock,
"render lock");
@@ -682,6 +718,16 @@ class MasterControl {
// create the freelists
FreeListManager.createFreeLists();
+
+ // create an array canvas use registers
+ // The 32 limit can be lifted once the
+ // resourceXXXMasks in other classes
+ // are change not to use integer.
+ canvasIds = new boolean[32];
+ for(int i=0; i<canvasIds.length; i++) {
+ canvasIds[i] = false;
+ }
+ canvasFreeIndex = 0;
}
private static String getProperty(final String prop) {
@@ -728,7 +774,9 @@ class MasterControl {
* the MasterControl object is created.
*/
static void loadLibraries() {
- // This works around a native load library bug
+ assert !librariesLoaded;
+
+ // This works around a native load library bug
try {
java.awt.Toolkit toolkit = java.awt.Toolkit.getDefaultToolkit();
toolkit = null; // just making sure GC collects this
@@ -745,37 +793,113 @@ class MasterControl {
});
// Load the native J3D library
- java.security.AccessController.doPrivileged(new
+ final String oglLibraryName = "j3dcore-ogl";
+ final String d3dLibraryName = "j3dcore-d3d";
+ final String libraryName = (String)
+ java.security.AccessController.doPrivileged(new
java.security.PrivilegedAction() {
public Object run() {
-
+ String libName = oglLibraryName;
+
+ // If it is a Windows OS, we want to support dynamic native library selection (ogl, d3d)
String osName = System.getProperty("os.name");
- // System.err.println(" os.name is " + osName );
- // If it is a Windows OS, we want to support
- // dynamic native library selection (ogl, d3d)
- if((osName.length() > 8) &&
- ((osName.substring(0,7)).equals("Windows"))){
-
- // TODO : Will support a more flexible dynamic
- // selection scheme via the use of Preferences API.
+ if (osName != null && osName.startsWith("Windows")) {
+ // XXXX : Should eventually support a more flexible dynamic
+ // selection scheme via an API call.
String str = System.getProperty("j3d.rend");
- if ((str == null) || (!str.equals("d3d"))) {
- // System.err.println("(1) ogl case : j3d.rend is " + str );
- System.loadLibrary("j3dcore-ogl");
-
- }
- else {
- // System.err.println("(2) d3d case : j3d.rend is " + str);
- System.loadLibrary("j3dcore-d3d");
+ if (str != null && str.equals("d3d")) {
+ libName = d3dLibraryName;
}
}
- else {
- // System.err.println("(3) ogl case");
- System.loadLibrary("j3dcore-ogl");
- }
- return null;
+
+ System.loadLibrary(libName);
+ return libName;
}
});
+
+ // Get the global j3d.shadingLanguage property
+ final String slStr = getProperty("j3d.shadingLanguage");
+ if (slStr != null) {
+ boolean found = false;
+ if (slStr.equals("GLSL")) {
+ globalShadingLanguage = Shader.SHADING_LANGUAGE_GLSL;
+ found = true;
+ }
+ else if (slStr.equals("Cg")) {
+ globalShadingLanguage = Shader.SHADING_LANGUAGE_CG;
+ found = true;
+ }
+
+ if (found) {
+ System.err.println("Java 3D: Setting global shading language to " + slStr);
+ }
+ else {
+ System.err.println("Java 3D: Unrecognized shading language: " + slStr);
+ }
+ }
+
+ // Check whether the Cg library is available
+ if (globalShadingLanguage == Shader.SHADING_LANGUAGE_CG) {
+ String cgLibraryName = libraryName + "-cg";
+ String[] libpath = setupLibPath(systemPathProps, cgLibraryName);
+ if (loadNativeCgLibrary(libpath)) {
+ cgLibraryAvailable = true;
+ }
+ }
+
+ // Check whether the GLSL library is available
+ if (globalShadingLanguage == Shader.SHADING_LANGUAGE_GLSL) {
+ if (libraryName == oglLibraryName) {
+ // No need to verify that GLSL is available, since GLSL is part
+ // of OpenGL as an extension (or part of core in 2.0)
+ glslLibraryAvailable = true;
+ }
+ }
+
+ assert !(glslLibraryAvailable && cgLibraryAvailable) :
+ "ERROR: cannot support both GLSL and CG at the same time";
+
+ librariesLoaded = true;
+ }
+
+
+ /**
+ * Parse the specified System properties containing a PATH and return an
+ * array of Strings, where each element is an absolute filename consisting of
+ * the individual component of the path concatenated with the (relative)
+ * library file name. Only those absolute filenames that exist are included.
+ * If no absolute filename is found, we will try the relative library name.
+ */
+ private static String[] setupLibPath(String[] props, String libName) {
+ ArrayList pathList = new ArrayList();
+
+ String filename = System.mapLibraryName(libName);
+ for (int n = 0; n < props.length; n++) {
+ String pathString = getProperty(props[n]);
+ boolean done = false;
+ int posStart = 0;
+ while (!done) {
+ int posEnd = pathString.indexOf(File.pathSeparator, posStart);
+ if (posEnd == -1) {
+ posEnd = pathString.length();
+ done = true;
+ }
+ String pathDir = pathString.substring(posStart, posEnd);
+ File pathFile = new File(pathDir, filename);
+ if (pathFile.exists()) {
+ pathList.add(pathFile.getAbsolutePath());
+ }
+
+ posStart = posEnd + 1;
+ }
+ }
+
+ // If no absolute path names exist, add in the relative library name
+ if (pathList.size() == 0) {
+ pathList.add(filename);
+ }
+
+ return (String[])pathList.toArray(new String[0]);
}
@@ -837,6 +961,14 @@ class MasterControl {
return (1 << rendererCount++);
}
+
+ /**
+ * This returns the a unused renderer bit
+ */
+ int getRendererId() {
+ return rendererCount++;
+ }
+
/**
* This returns a context creation time stamp
* Note: this has to be called under the contextCreationLock
@@ -900,28 +1032,39 @@ class MasterControl {
FreeListManager.freeObject(FreeListManager.TEXTURE3D, new Integer(id));
}
- int getCanvasBit() {
- // Master control need to keep count itself
- MemoryFreeList cbId =
- FreeListManager.getFreeList(FreeListManager.CANVASBIT);
- if (cbId.size() > 0) {
- return ((Integer)FreeListManager.
- getObject(FreeListManager.CANVASBIT)).intValue();
- }
- else {
- if (canvasBitCount > 31) {
+ int getCanvasId() {
+ int i;
+
+ synchronized(canvasIdLock) {
+ // Master control need to keep count itself
+ for(i=canvasFreeIndex; i<canvasIds.length; i++) {
+ if(canvasIds[i] == false)
+ break;
+ }
+
+ if ( canvasFreeIndex >= canvasIds.length) {
throw new RuntimeException("Cannot render to more than 32 Canvas3Ds");
}
- return (1 << canvasBitCount++);
+
+ canvasIds[i] = true;
+ canvasFreeIndex = i + 1;
}
+
+ return i;
+
}
+ void freeCanvasId(int canvasId) {
+ // Valid range is [0, 31]
+ synchronized(canvasIdLock) {
- void freeCanvasBit(int canvasBit) {
- FreeListManager.freeObject(FreeListManager.CANVASBIT,
- new Integer(canvasBit));
+ canvasIds[canvasId] = false;
+ if(canvasFreeIndex > canvasId) {
+ canvasFreeIndex = canvasId;
+ }
+ }
}
-
+
Transform3D getTransform3D(Transform3D val) {
Transform3D t;
t = (Transform3D)
@@ -1096,6 +1239,10 @@ class MasterControl {
timerThread.finish();
timerThread = null;
}
+ if (notificationThread != null) {
+ notificationThread.finish();
+ notificationThread = null;
+ }
requestObjList.clear();
requestTypeList.clear();
return true;
@@ -1210,7 +1357,14 @@ class MasterControl {
}
setWork();
}
-
+
+ /**
+ * This takes the specified notification message and sends it to the
+ * notification thread for processing.
+ */
+ void sendNotification(J3dNotification notification) {
+ notificationThread.addNotification(notification);
+ }
/**
* Create and start the MasterControl Thread.
@@ -2050,6 +2204,19 @@ class MasterControl {
}
});
timerThread.start();
+
+ // Create notification thread
+ java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction() {
+ public Object run() {
+ synchronized (rootThreadGroup) {
+ notificationThread = new NotificationThread(rootThreadGroup);
+ notificationThread.setPriority(threadPriority);
+ }
+ return null;
+ }
+ });
+ notificationThread.start();
}
/**
@@ -2099,6 +2266,10 @@ class MasterControl {
timerThread.finish();
timerThread = null;
}
+ if (notificationThread != null) {
+ notificationThread.finish();
+ notificationThread = null;
+ }
// shouldn't all of these be synchronized ???
synchronized (VirtualUniverse.mc.deviceScreenMap) {
@@ -2112,8 +2283,11 @@ class MasterControl {
// list here because other structure may release them
// later
- FreeListManager.clearList(FreeListManager.CANVASBIT);
- canvasBitCount = 0;
+ for(int i=0; i<canvasIds.length; i++) {
+ canvasIds[i] = false;
+ }
+ canvasFreeIndex = 0;
+
renderOnceList.clear();
timestampUpdateList.clear();
@@ -3441,7 +3615,7 @@ class MasterControl {
static {
/*
// Determine whether the JVM is version JDK1.5 or later.
- // TODO: replace this with code that checks for the existence
+ // XXXX: replace this with code that checks for the existence
// of a class or method that is defined in 1.5, but not in 1.4
String versionString =
(String) java.security.AccessController.doPrivileged(
diff --git a/src/classes/share/javax/media/j3d/Material.java b/src/classes/share/javax/media/j3d/Material.java
index d35c1d5..deacac9 100644
--- a/src/classes/share/javax/media/j3d/Material.java
+++ b/src/classes/share/javax/media/j3d/Material.java
@@ -103,7 +103,11 @@ public class Material extends NodeComponent {
*/
public static final int AMBIENT_AND_DIFFUSE = 4;
-
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_COMPONENT_READ
+ };
+
/**
* Constructs and initializes a Material object using default parameters.
* The default values are as follows:
@@ -119,6 +123,8 @@ public class Material extends NodeComponent {
*/
public Material() {
// Just use the defaults
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -139,7 +145,10 @@ public class Material extends NodeComponent {
Color3f diffuseColor,
Color3f specularColor,
float shininess) {
- ((MaterialRetained)this.retained).createMaterial(ambientColor,
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((MaterialRetained)this.retained).createMaterial(ambientColor,
emissiveColor, diffuseColor, specularColor,
shininess);
}
@@ -602,7 +611,8 @@ public class Material extends NodeComponent {
* Capability read bit set will be displayed.
*/
public String toString() {
- StringBuffer str=new StringBuffer("Material Object:");
+ StringBuffer str = new StringBuffer(getNamePrefix());
+ str.append("javax.media.j3d.Material: ");
Color3f color=new Color3f();
try {
getAmbientColor(color);
diff --git a/src/classes/share/javax/media/j3d/MediaContainer.java b/src/classes/share/javax/media/j3d/MediaContainer.java
index 10e1502..e2c6e39 100644
--- a/src/classes/share/javax/media/j3d/MediaContainer.java
+++ b/src/classes/share/javax/media/j3d/MediaContainer.java
@@ -60,6 +60,12 @@ public class MediaContainer extends NodeComponent {
public static final int
ALLOW_URL_WRITE = CapabilityBits.MEDIA_CONTAINER_ALLOW_URL_WRITE;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_CACHE_READ,
+ ALLOW_URL_READ
+ };
+
/**
* Constructs a MediaContainer object with default parameters.
* The default values are as follows:
@@ -72,6 +78,8 @@ public class MediaContainer extends NodeComponent {
*/
public MediaContainer() {
// Just use default values
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -81,6 +89,9 @@ public class MediaContainer extends NodeComponent {
* @exception SoundException if the URL is not valid or cannot be opened
*/
public MediaContainer(String path) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((MediaContainerRetained)this.retained).setURLString(path);
}
@@ -91,6 +102,9 @@ public class MediaContainer extends NodeComponent {
* @exception SoundException if the URL is not valid or cannot be opened
*/
public MediaContainer(URL url) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((MediaContainerRetained)this.retained).setURLObject(url);
}
@@ -102,6 +116,9 @@ public class MediaContainer extends NodeComponent {
* @since Java 3D 1.2
*/
public MediaContainer(InputStream stream) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((MediaContainerRetained)this.retained).setInputStream(stream);
}
diff --git a/src/classes/share/javax/media/j3d/MediaContainerRetained.java b/src/classes/share/javax/media/j3d/MediaContainerRetained.java
index 19f2547..f120902 100644
--- a/src/classes/share/javax/media/j3d/MediaContainerRetained.java
+++ b/src/classes/share/javax/media/j3d/MediaContainerRetained.java
@@ -141,7 +141,7 @@ class MediaContainerRetained extends NodeComponentRetained {
* @param stream InputStream that references the sound data
*/
void setInputStream(InputStream stream, boolean forceLoad) {
- // %%% TODO AudioDevice not intellegent enough to process InputStreams yet
+ // XXXX: AudioDevice not intellegent enough to process InputStreams yet
// can NOT set stream field unless the other related fields are null
if (stream != null) {
if (url != null || urlString != null)
diff --git a/src/classes/share/javax/media/j3d/ModelClip.java b/src/classes/share/javax/media/j3d/ModelClip.java
index 308af79..6895c2d 100644
--- a/src/classes/share/javax/media/j3d/ModelClip.java
+++ b/src/classes/share/javax/media/j3d/ModelClip.java
@@ -109,7 +109,14 @@ public class ModelClip extends Leaf {
public static final int ALLOW_SCOPE_WRITE =
CapabilityBits.MODEL_CLIP_ALLOW_SCOPE_WRITE;
-
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_SCOPE_READ,
+ ALLOW_ENABLE_READ,
+ ALLOW_INFLUENCING_BOUNDS_READ,
+ ALLOW_PLANE_READ
+ };
+
/**
* Constructs a ModelClip node with default parameters. The default
* values are as follows:
@@ -128,6 +135,9 @@ public class ModelClip extends Leaf {
*/
public ModelClip() {
// Just use the defaults
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
}
@@ -137,7 +147,10 @@ public class ModelClip extends Leaf {
* @param planes an array of 6 model clipping planes
*/
public ModelClip(Vector4d[] planes) {
- ((ModelClipRetained)this.retained).initPlanes(planes);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((ModelClipRetained)this.retained).initPlanes(planes);
}
@@ -149,6 +162,9 @@ public class ModelClip extends Leaf {
* @param enables an array of 6 enable flags
*/
public ModelClip(Vector4d[] planes, boolean[] enables) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((ModelClipRetained)this.retained).initPlanes(planes);
((ModelClipRetained)this.retained).initEnables(enables);
}
diff --git a/src/classes/share/javax/media/j3d/Morph.java b/src/classes/share/javax/media/j3d/Morph.java
index 9cabaa8..a03edec 100644
--- a/src/classes/share/javax/media/j3d/Morph.java
+++ b/src/classes/share/javax/media/j3d/Morph.java
@@ -77,6 +77,8 @@ import javax.vecmath.*;
* <i>before</i> the indexes are applied. Only the indexes in the
* first geometry array (geometry[0]) are used when rendering the
* geometry.
+ *
+ * @deprecated As of Java 3D version 1.4.
*/
public class Morph extends Leaf {
@@ -149,9 +151,19 @@ public class Morph extends Leaf {
public static final int ALLOW_APPEARANCE_OVERRIDE_WRITE =
CapabilityBits.MORPH_ALLOW_APPEARANCE_OVERRIDE_WRITE;
-
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_GEOMETRY_ARRAY_READ,
+ ALLOW_APPEARANCE_READ,
+ ALLOW_WEIGHTS_READ,
+ ALLOW_COLLISION_BOUNDS_READ,
+ ALLOW_APPEARANCE_OVERRIDE_READ
+ };
+
// non public default constructor
Morph() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -171,6 +183,7 @@ public class Morph extends Leaf {
* a null or zero-length array of GeometryArray objects is
* permitted, and specifies that no geometry is drawn. In this case,
* the array of weights is initialized to a zero-length array.
+ *
* @exception IllegalArgumentException if any of the specified
* geometry array objects differ from each other in any of the
* following ways:
@@ -187,19 +200,28 @@ public class Morph extends Leaf {
* (coord, color, normal, texcoord),
* for indexed geometry by-reference</li>
* </ul>
+ *
+ * @exception UnsupportedOperationException if the specified
+ * geometry arrays contain vertex attributes (that is, if their
+ * vertexFormat includes the <code>VERTEX_ATTRIBUTES</code> flag).
*/
public Morph(GeometryArray geometryArrays[]) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((MorphRetained)retained).setGeometryArrays(geometryArrays);
}
/**
* Constructs and initializes a Morph node with the specified array
* of GeometryArray objects and the specified appearance object.
+ *
* @param geometryArrays the geometry components of the Morph node
* a null or zero-length array of GeometryArray objects is
* permitted, and specifies that no geometry is drawn. In this case,
* the array of weights is initialized to a zero-length array.
* @param appearance the appearance component of the Morph node
+ *
* @exception IllegalArgumentException if any of the specified
* geometry array objects differ from each other in any of the
* following ways:
@@ -216,9 +238,16 @@ public class Morph extends Leaf {
* (coord, color, normal, texcoord),
* for indexed geometry by-reference</li>
* </ul>
+ *
+ * @exception UnsupportedOperationException if the specified
+ * geometry arrays contain vertex attributes (that is, if their
+ * vertexFormat includes the <code>VERTEX_ATTRIBUTES</code> flag).
*/
public Morph(GeometryArray geometryArrays[], Appearance appearance) {
- ((MorphRetained)retained).setGeometryArrays(geometryArrays);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((MorphRetained)retained).setGeometryArrays(geometryArrays);
((MorphRetained)this.retained).setAppearance(appearance);
}
@@ -303,6 +332,10 @@ public class Morph extends Leaf {
* (coord, color, normal, texcoord),
* for indexed geometry by-reference</li>
* </ul>
+ *
+ * @exception UnsupportedOperationException if the specified
+ * geometry arrays contain vertex attributes (that is, if their
+ * vertexFormat includes the <code>VERTEX_ATTRIBUTES</code> flag).
*/
public void setGeometryArrays(GeometryArray geometryArrays[]) {
@@ -642,7 +675,8 @@ public class Morph extends Leaf {
// have the bit set.
private void checkForAllowIntersect() {
MorphRetained morphR = ((MorphRetained)this.retained);
- for (int i = 0; i < morphR.numGeometryArrays; i++) {
+ int numGeometryArrays = morphR.getNumGeometryArrays();
+ for (int i = 0; i < numGeometryArrays; i++) {
if (!morphR.geometryArrays[i].source.
getCapability(Geometry.ALLOW_INTERSECT)) {
diff --git a/src/classes/share/javax/media/j3d/MorphRetained.java b/src/classes/share/javax/media/j3d/MorphRetained.java
index 34633f7..351122f 100644
--- a/src/classes/share/javax/media/j3d/MorphRetained.java
+++ b/src/classes/share/javax/media/j3d/MorphRetained.java
@@ -56,7 +56,7 @@ class MorphRetained extends LeafRetained implements GeometryUpdater {
*/
GeometryArrayRetained geometryArrays[];
- int numGeometryArrays = 0;
+ private int numGeometryArrays = 0;
/**
* The weight vector the morph node.
@@ -200,6 +200,13 @@ class MorphRetained extends LeafRetained implements GeometryUpdater {
}
doErrorCheck(prevGeo, geo);
}
+
+ // Check the first one for vertex attributes
+ geo = (GeometryArrayRetained)geometryArrays[0].retained;
+ if ((geo.vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
+ throw new UnsupportedOperationException(J3dI18N.getString("MorphRetained9"));
+ }
+
// Check if the first one is in Immediate context
if (geometryArrays[0] != null) {
geo = (GeometryArrayRetained)geometryArrays[0].retained;
@@ -452,8 +459,58 @@ class MorphRetained extends LeafRetained implements GeometryUpdater {
boolean getAppearanceOverrideEnable() {
return appearanceOverrideEnable;
}
+
+ boolean intersect(PickInfo pickInfo, PickShape pickShape, int flags ) {
+
+ Transform3D localToVworld = pickInfo.getLocalToVWorldRef();
+
+ Transform3D vworldToLocal = new Transform3D();
+ vworldToLocal.invert(localToVworld);
+ PickShape newPS = pickShape.transform(vworldToLocal);
+ GeometryRetained geo = (GeometryRetained) (morphedGeometryArray.retained);
+ if (geo.mirrorGeometry != null) {
+ geo = geo.mirrorGeometry;
+ }
+
+ if (((flags & PickInfo.CLOSEST_INTERSECTION_POINT) == 0) &&
+ ((flags & PickInfo.CLOSEST_DISTANCE) == 0) &&
+ ((flags & PickInfo.CLOSEST_GEOM_INFO) == 0) &&
+ ((flags & PickInfo.ALL_GEOM_INFO) == 0)) {
+ return geo.intersect(newPS, null, 0, null);
+ } else {
+ Point3d closestIPnt = new Point3d();
+ Point3d iPnt = new Point3d();
+ Point3d iPntVW = new Point3d();
+ PickInfo.IntersectionInfo intersectionInfo
+ = pickInfo.createIntersectionInfo();
+
+ if (geo.intersect(newPS, intersectionInfo, flags, iPnt)) {
+
+ iPntVW.set(iPnt);
+ localToVworld.transform(iPntVW);
+ double distance = pickShape.distance(iPntVW);
+ if ((flags & PickInfo.CLOSEST_DISTANCE) != 0) {
+ pickInfo.setClosestDistance(distance);
+ }
+ if((flags & PickInfo.CLOSEST_INTERSECTION_POINT) != 0) {
+ pickInfo.setClosestIntersectionPoint(iPnt);
+ } else if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
+ intersectionInfo.setGeometry((Geometry) geo.source);
+ intersectionInfo.setGeometryIndex(0);
+ intersectionInfo.setIntersectionPoint(iPnt);
+ intersectionInfo.setDistance(distance);
+ // VertexIndices has been computed in intersect method.
+ pickInfo.insertIntersectionInfo(intersectionInfo);
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+
/**
* Check if the geometry component of this shape node under path
* intersects with the pickShape.
@@ -461,48 +518,38 @@ class MorphRetained extends LeafRetained implements GeometryUpdater {
* contains the closest distance of intersection if it is not
* equal to null.
*/
- boolean intersect(SceneGraphPath path, PickShape pickShape,
- double[] dist) {
-
+ boolean intersect(SceneGraphPath path,
+ PickShape pickShape, double[] dist) {
+
// This method will not do bound intersect check, as it assume caller
// has already done that. ( For performance and code simplification
// reasons. )
- Transform3D localToVworld = path.getTransform();
-
+ int flags;
+ PickInfo pickInfo = new PickInfo();
+
+ Transform3D localToVworld = path.getTransform();
if (localToVworld == null) {
throw new RuntimeException(J3dI18N.getString("MorphRetained5"));
}
- Transform3D vworldToLocal = VirtualUniverse.mc.getTransform3D(null);
- vworldToLocal.invert(localToVworld);
- PickShape newPS = pickShape.transform(vworldToLocal);
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D, vworldToLocal);
-
- Point3d iPnt = Shape3DRetained.getPoint3d();
-
- GeometryRetained geo = (GeometryRetained) (morphedGeometryArray.retained);
-
- if (geo.mirrorGeometry != null) {
- geo = geo.mirrorGeometry;
- }
-
- boolean isIntersect;
- if (dist != null) {
- isIntersect = geo.intersect(newPS, dist, iPnt);
- if (isIntersect) {
- // compute the real distance since the dist return
- // above distance may scaled (non-uniform) by transform3d
- localToVworld.transform(iPnt);
- dist[0] = pickShape.distance(iPnt);
- }
- } else {
- isIntersect = geo.intersect(newPS, null, iPnt);
- }
- Shape3DRetained.freePoint3d(iPnt);
- return isIntersect;
- }
-
+ pickInfo.setLocalToVWorldRef( localToVworld);
+ //System.out.println("MorphRetained.intersect() : ");
+ if (dist == null) {
+ //System.out.println(" no dist request ....");
+ return intersect(pickInfo, pickShape, 0);
+ }
+
+ flags = PickInfo.CLOSEST_DISTANCE;
+ if (intersect(pickInfo, pickShape, flags)) {
+ dist[0] = pickInfo.getClosestDistance();
+ return true;
+ }
+
+ return false;
+
+ }
+
/**
* Sets the Morph node's weight vector
* @param wieghts the new vector of weights for the morph node
@@ -571,8 +618,8 @@ class MorphRetained extends LeafRetained implements GeometryUpdater {
} else {
return super.getBounds();
}
- }
-
+ }
+
Bounds getEffectiveBounds() {
if(boundsAutoCompute) {
return getBounds();
@@ -604,6 +651,11 @@ class MorphRetained extends LeafRetained implements GeometryUpdater {
}
}
+ // Return the number of geometry arrays in this MorphRetained object.
+ int getNumGeometryArrays() {
+ return numGeometryArrays;
+ }
+
// If the geometry of a morph changes, make sure that the
// validVertexCount has not changed
void updateMorphedGeometryArray(GeometryArrayRetained geo, boolean coordinatesChanged) {
@@ -1767,8 +1819,8 @@ class MorphRetained extends LeafRetained implements GeometryUpdater {
}
if ((vFormat & GeometryArray.TEXTURE_COORDINATE) != 0) {
for (k = 0; k < texCoordSetCount; k++) {
- morphedGeo.setTextureCoordinateIndices(k, 0,
- (int[]) igeo.indexTexCoord[k]);
+ morphedGeo.setTextureCoordinateIndices(k, 0,
+ igeo.indexTexCoord[k]);
}
}
}
@@ -1797,7 +1849,7 @@ class MorphRetained extends LeafRetained implements GeometryUpdater {
super.compile(compState);
- // TODO: for now keep the static transform in the parent tg
+ // XXXX: for now keep the static transform in the parent tg
compState.keepTG = true;
if (J3dDebug.devPhase && J3dDebug.debug) {
diff --git a/src/classes/share/javax/media/j3d/Node.java b/src/classes/share/javax/media/j3d/Node.java
index 9be9ab3..3853a63 100644
--- a/src/classes/share/javax/media/j3d/Node.java
+++ b/src/classes/share/javax/media/j3d/Node.java
@@ -109,7 +109,34 @@ public abstract class Node extends SceneGraphObject {
*/
public static final int
ALLOW_LOCAL_TO_VWORLD_READ = CapabilityBits.NODE_ALLOW_LOCAL_TO_VWORLD_READ;
-
+
+ /**
+ * Specifies that this Node allows read access to its parent Group node.
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int
+ ALLOW_PARENT_READ = CapabilityBits.NODE_ALLOW_PARENT_READ;
+
+ /**
+ * Specifies that this Node allows read access to its Locale.
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int
+ ALLOW_LOCALE_READ = CapabilityBits.NODE_ALLOW_LOCALE_READ;
+
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_BOUNDS_READ,
+ ALLOW_PICKABLE_READ,
+ ALLOW_COLLIDABLE_READ,
+ ALLOW_AUTO_COMPUTE_BOUNDS_READ,
+ ALLOW_LOCAL_TO_VWORLD_READ,
+ ALLOW_PARENT_READ,
+ ALLOW_LOCALE_READ
+ };
+
// for checking for cycles
private boolean visited = false;
@@ -125,18 +152,22 @@ public abstract class Node extends SceneGraphObject {
* </ul>
*/
public Node() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
- * Retrieves the parent of this Node. This method is only valid
- * during the construction of the scene graph.
+
* @return the parent of this node, or null if this node has no parent
- * @exception RestrictedAccessException if this object is part of live
- * or compiled scene graph
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
*/
public Node getParent() {
- if (isLiveOrCompiled())
- throw new RestrictedAccessException(J3dI18N.getString("Node0"));
+ if (isLiveOrCompiled()) {
+ if(!this.getCapability(ALLOW_PARENT_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("Node0"));
+ }
+ }
NodeRetained nr = ((NodeRetained)this.retained).getParent();
return (nr == null ? null : (Node) nr.getSource());
@@ -245,24 +276,36 @@ public abstract class Node extends SceneGraphObject {
* of all transforms in the scene graph from the root down to
* <code>this</code> node. It is only valid
* for nodes that are part of a live scene graph.
+ * If the node is not part of a live scene graph then the coordinates are
+ * calculated as if the graph was attached at the origin of a locale.
* @param t the object that will receive the local coordinates to
* Vworld coordinates transform.
- * @exception RestrictedAccessException if the node is <em>not</em>
+ * @exception RestrictedAccessException if the node is compiled but not
* part of a live scene graph
* @exception CapabilityNotSetException if appropriate capability is
- * not set and this node is part of live scene graph
+ * not set and this node is part of live or compiled scene graph
* @exception IllegalSharingException if the node is a descendant
* of a SharedGroup node.
*/
public void getLocalToVworld(Transform3D t) {
- if (!isLive())
- throw new RestrictedAccessException(J3dI18N.getString("Node7"));
-
- if(!this.getCapability(ALLOW_LOCAL_TO_VWORLD_READ))
- throw new CapabilityNotSetException(J3dI18N.getString("Node8"));
-
- ((NodeRetained)this.retained).getLocalToVworld(t);
+ if (isLiveOrCompiled()) {
+ if(!this.getCapability(ALLOW_LOCAL_TO_VWORLD_READ))
+ throw new CapabilityNotSetException(J3dI18N.getString("Node8"));
+ }
+
+ if (!isLive()) {
+ // TODO Support compiled graphs
+ if (isCompiled())
+ throw new RestrictedAccessException(J3dI18N.getString("Node7"));
+
+ // In 1.4 we support getLocalToVworld for non live nodes
+ ((NodeRetained)this.retained).computeNonLiveLocalToVworld(t, this);
+ //throw new RestrictedAccessException(J3dI18N.getString("Node7"));
+ } else {
+ ((NodeRetained)this.retained).getLocalToVworld(t);
+ }
}
+
/**
* Retrieves the local coordinates to virtual world coordinates
@@ -281,15 +324,44 @@ public abstract class Node extends SceneGraphObject {
* @exception IllegalArgumentException if the specified path does
* not contain a valid Locale, or if the last node in the path is
* different from this node
+ * @exception IllegalSharingException if the node is not a descendant
+ * of a SharedGroup node.
*/
public void getLocalToVworld(SceneGraphPath path, Transform3D t) {
- if (!isLive())
+ if (!isLive()) {
throw new RestrictedAccessException(J3dI18N.getString("Node7"));
-
- if(!this.getCapability(ALLOW_LOCAL_TO_VWORLD_READ))
- throw new CapabilityNotSetException(J3dI18N.getString("Node8"));
+ }
+
+ if(!this.getCapability(ALLOW_LOCAL_TO_VWORLD_READ))
+ throw new CapabilityNotSetException(J3dI18N.getString("Node8"));
((NodeRetained)this.retained).getLocalToVworld(path,t);
+
+ }
+
+ /**
+ * Retrieves the locale to which this node is attached. If the
+ * node is not part of a live scene graph, null is returned.
+ *
+ * @return the locale to which this node is attached.
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this node is part of live scene graph
+ * @exception IllegalSharingException if the node is a descendant
+ * of a SharedGroup node.
+ *
+ * @since Java 3D 1.4
+ */
+ public Locale getLocale() {
+ if (!isLive()) {
+ return null;
+ }
+
+ if(!this.getCapability(ALLOW_LOCALE_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("Node17"));
+ }
+
+ return ((NodeRetained)this.retained).getLocale();
}
/**
diff --git a/src/classes/share/javax/media/j3d/NodeData.java b/src/classes/share/javax/media/j3d/NodeData.java
index 90505e2..5c927c6 100644
--- a/src/classes/share/javax/media/j3d/NodeData.java
+++ b/src/classes/share/javax/media/j3d/NodeData.java
@@ -15,7 +15,7 @@ package javax.media.j3d;
class NodeData {
// per path node data
- // TODO: replace per path mirror objects with node data
- // TODO: move other basic node's data here
+ // XXXX: replace per path mirror objects with node data
+ // XXXX: move other basic node's data here
SwitchState switchState = null;
}
diff --git a/src/classes/share/javax/media/j3d/NodeRetained.java b/src/classes/share/javax/media/j3d/NodeRetained.java
index de91ce4..a8d9467 100644
--- a/src/classes/share/javax/media/j3d/NodeRetained.java
+++ b/src/classes/share/javax/media/j3d/NodeRetained.java
@@ -374,7 +374,26 @@ abstract class NodeRetained extends SceneGraphObjectRetained implements NnuId {
return;
}
-
+ /**
+ * Compute the LocalToVworld of this node even though it is not live. We
+ * assume the graph is attached at the origin of a locale
+ */
+ void computeNonLiveLocalToVworld(Transform3D t, Node caller) {
+ NodeRetained n = getParent();
+
+ if (n==null)
+ t.setIdentity();
+ else
+ n.computeNonLiveLocalToVworld(t, caller);
+
+ if (this instanceof TransformGroupRetained && this.source!=caller) {
+ Transform3D trans = new Transform3D();
+ ((TransformGroupRetained)this).getTransform(trans);
+ t.mul(trans);
+ }
+
+ }
+
/**
* Get the localToVworld transform for a node.
*/
@@ -413,7 +432,19 @@ abstract class NodeRetained extends SceneGraphObjectRetained implements NnuId {
HashKey newKey = new HashKey(key);
computeLocalToVworld(this, this, newKey, t);
}
-
+
+
+ /**
+ * Get the Locale to which the node is attached
+ */
+ Locale getLocale() {
+ if (inSharedGroup) {
+ throw new IllegalSharingException(J3dI18N.getString("NodeRetained0"));
+ }
+
+ return locale;
+ }
+
/**
* Get the current localToVworld transform for a node
@@ -868,6 +899,7 @@ abstract class NodeRetained extends SceneGraphObjectRetained implements NnuId {
boolean isStatic() {
if (source.getCapability(Node.ALLOW_LOCAL_TO_VWORLD_READ) ||
+ source.getCapability(Node.ALLOW_PARENT_READ) ||
source.getCapability(Node.ENABLE_PICK_REPORTING) ||
source.getCapability(Node.ENABLE_COLLISION_REPORTING) ||
source.getCapability(Node.ALLOW_BOUNDS_READ) ||
diff --git a/src/classes/share/javax/media/j3d/NotificationThread.java b/src/classes/share/javax/media/j3d/NotificationThread.java
new file mode 100644
index 0000000..1d7a44f
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/NotificationThread.java
@@ -0,0 +1,120 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import java.util.LinkedList;
+
+/**
+ * The NotificationThread class is used for asynchronous error notification,
+ * such as notifying ShaderError listeners.
+ */
+class NotificationThread extends Thread {
+ // action flag for runMonitor
+ private static final int WAIT = 0;
+ private static final int NOTIFY = 1;
+ private static final int STOP = 2;
+
+ private volatile boolean running = true;
+ private boolean waiting = false;
+ private boolean ready = false;
+
+ private LinkedList notificationQueue = new LinkedList();
+
+ /**
+ * Creates a new instance of NotificationThread
+ */
+ NotificationThread(ThreadGroup t) {
+ // Only one notification thread for the entire system
+ super(t, "J3D-NotificationThread");
+ }
+
+ /**
+ * Adds a notification message to the queue
+ */
+ synchronized void addNotification(J3dNotification n) {
+ notificationQueue.add(n);
+ runMonitor(NOTIFY);
+ }
+
+ /**
+ * Gets the list of queued notification messages
+ */
+ private synchronized J3dNotification[] getNotifications() {
+ J3dNotification[] notifications = (J3dNotification[])notificationQueue.toArray(new J3dNotification[0]);
+ notificationQueue.clear();
+ return notifications;
+ }
+
+ /**
+ * Processes all pending notification messages
+ */
+ private void processNotifications() {
+ J3dNotification[] notifications = getNotifications();
+
+ for (int i = 0; i < notifications.length; i++) {
+ J3dNotification n = notifications[i];
+ switch (n.type) {
+ case J3dNotification.SHADER_ERROR:
+ n.universe.notifyShaderErrorListeners((ShaderError)n.args[0]);
+ break;
+ default:
+ System.err.println("J3dNotification.processNotifications: unrecognized type = " + n.type);
+ }
+ }
+ }
+
+ // Called from MasterControlThread
+ void finish() {
+ runMonitor(STOP);
+ }
+
+ public void run() {
+ while (running) {
+ runMonitor(WAIT);
+
+ processNotifications();
+ }
+// System.err.println("Notification thread finished");
+ }
+
+
+ private synchronized void runMonitor(int action) {
+ switch (action) {
+ case WAIT:
+ while (running && !ready) {
+ waiting = true;
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ }
+ waiting = false;
+ }
+ ready = false;
+ break;
+ case NOTIFY:
+ ready = true;
+ if (waiting) {
+ notify();
+ }
+ break;
+ case STOP:
+ running = false;
+ notify();
+ break;
+ default:
+ // Should never get here...
+ assert(false);
+ }
+ }
+
+}
diff --git a/src/classes/share/javax/media/j3d/OrderedGroup.java b/src/classes/share/javax/media/j3d/OrderedGroup.java
index e3d4e87..1ffdd93 100644
--- a/src/classes/share/javax/media/j3d/OrderedGroup.java
+++ b/src/classes/share/javax/media/j3d/OrderedGroup.java
@@ -72,6 +72,10 @@ public class OrderedGroup extends Group {
public static final int ALLOW_CHILD_INDEX_ORDER_WRITE =
CapabilityBits.ORDERED_GROUP_ALLOW_CHILD_INDEX_ORDER_WRITE;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_CHILD_INDEX_ORDER_READ
+ };
/**
* Constructs and initializes a new OrderedGroup node object.
@@ -79,6 +83,8 @@ public class OrderedGroup extends Group {
* that its children are rendered in increasing index order.
*/
public OrderedGroup() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
diff --git a/src/classes/share/javax/media/j3d/OrientedShape3D.java b/src/classes/share/javax/media/j3d/OrientedShape3D.java
index bea85dd..478eb71 100644
--- a/src/classes/share/javax/media/j3d/OrientedShape3D.java
+++ b/src/classes/share/javax/media/j3d/OrientedShape3D.java
@@ -144,6 +144,14 @@ public class OrientedShape3D extends Shape3D {
CapabilityBits.ORIENTED_SHAPE3D_ALLOW_SCALE_WRITE;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_MODE_READ,
+ ALLOW_AXIS_READ,
+ ALLOW_POINT_READ,
+ ALLOW_SCALE_READ
+ };
+
/**
* Constructs an OrientedShape3D node with default parameters.
* The default values are as follows:
@@ -157,6 +165,8 @@ public class OrientedShape3D extends Shape3D {
*/
public OrientedShape3D() {
super();
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
@@ -182,6 +192,10 @@ public class OrientedShape3D extends Shape3D {
Vector3f axis) {
super(geometry, appearance);
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((OrientedShape3DRetained)retained).initAlignmentMode(mode);
((OrientedShape3DRetained)retained).initAlignmentAxis(axis);
}
@@ -203,6 +217,10 @@ public class OrientedShape3D extends Shape3D {
Point3f point) {
super(geometry, appearance);
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((OrientedShape3DRetained)retained).initAlignmentMode(mode);
((OrientedShape3DRetained)retained).initRotationPoint(point);
@@ -240,6 +258,9 @@ public class OrientedShape3D extends Shape3D {
super(geometry, appearance);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((OrientedShape3DRetained)retained).initAlignmentMode(mode);
((OrientedShape3DRetained)retained).initAlignmentAxis(axis);
((OrientedShape3DRetained)retained).
@@ -272,6 +293,9 @@ public class OrientedShape3D extends Shape3D {
super(geometry, appearance);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((OrientedShape3DRetained)retained).initAlignmentMode(mode);
((OrientedShape3DRetained)retained).initRotationPoint(point);
((OrientedShape3DRetained)retained).
diff --git a/src/classes/share/javax/media/j3d/PhysicalBody.java b/src/classes/share/javax/media/j3d/PhysicalBody.java
index 442e44f..40de532 100644
--- a/src/classes/share/javax/media/j3d/PhysicalBody.java
+++ b/src/classes/share/javax/media/j3d/PhysicalBody.java
@@ -128,7 +128,7 @@ public class PhysicalBody extends Object {
synchronized void notifyUsers() {
for (int i=users.size()-1; i>=0; i--) {
View view = (View)users.get(i);
- // TODO: notifyUsers should have a parameter denoting field changed
+ // XXXX: notifyUsers should have a parameter denoting field changed
if (view.soundScheduler != null) {
view.soundScheduler.setListenerFlag(
SoundScheduler.EAR_POSITIONS_CHANGED |
diff --git a/src/classes/share/javax/media/j3d/PickConeRay.java b/src/classes/share/javax/media/j3d/PickConeRay.java
index ebc2d6a..7821e1e 100644
--- a/src/classes/share/javax/media/j3d/PickConeRay.java
+++ b/src/classes/share/javax/media/j3d/PickConeRay.java
@@ -204,7 +204,7 @@ public final class PickConeRay extends PickCone {
double distToEdge;
for (i=0;i<ptope.nVerts;i++) {
for (j=i;i<ptope.nVerts;i++) {
- // TODO: make BoundingPolytope.pointInPolytope available to package
+ // XXXX: make BoundingPolytope.pointInPolytope available to package
// scope
midpt.x = (ptope.verts[i].x + ptope.verts[j].x) * 0.5;
midpt.y = (ptope.verts[i].y + ptope.verts[j].y) * 0.5;
diff --git a/src/classes/share/javax/media/j3d/PickConeSegment.java b/src/classes/share/javax/media/j3d/PickConeSegment.java
index fe2c45b..11adb80 100644
--- a/src/classes/share/javax/media/j3d/PickConeSegment.java
+++ b/src/classes/share/javax/media/j3d/PickConeSegment.java
@@ -233,7 +233,7 @@ public final class PickConeSegment extends PickCone {
double distToEdge;
for (i=0;i<ptope.nVerts;i++) {
for (j=i;i<ptope.nVerts;i++) {
- // TODO: make BoundingPolytope.pointInPolytope available to package
+ // XXXX: make BoundingPolytope.pointInPolytope available to package
// scope
midpt.x = (ptope.verts[i].x + ptope.verts[j].x) * 0.5;
midpt.y = (ptope.verts[i].y + ptope.verts[j].y) * 0.5;
diff --git a/src/classes/share/javax/media/j3d/PickCylinder.java b/src/classes/share/javax/media/j3d/PickCylinder.java
index 9d805eb..1a624f9 100644
--- a/src/classes/share/javax/media/j3d/PickCylinder.java
+++ b/src/classes/share/javax/media/j3d/PickCylinder.java
@@ -71,7 +71,7 @@ public abstract class PickCylinder extends PickShape {
// This is a duplicate of the same method, declared private inside of
// BoundingPolytope
- // TODO: remove this once the original method is available (public) in
+ // XXXX: remove this once the original method is available (public) in
// BoundingPolytope
static boolean pointInPolytope(BoundingPolytope ptope,
double x, double y, double z ){
diff --git a/src/classes/share/javax/media/j3d/PickCylinderRay.java b/src/classes/share/javax/media/j3d/PickCylinderRay.java
index 2fb33b1..6b5266f 100644
--- a/src/classes/share/javax/media/j3d/PickCylinderRay.java
+++ b/src/classes/share/javax/media/j3d/PickCylinderRay.java
@@ -185,7 +185,7 @@ public final class PickCylinderRay extends PickCylinder {
double distToEdge;
for (i=0;i<ptope.nVerts;i++) {
for (j=i;i<ptope.nVerts;i++) {
- // TODO: make BoundingPolytope.pointInPolytope available to package
+ // XXXX: make BoundingPolytope.pointInPolytope available to package
// scope
midpt.x = (ptope.verts[i].x + ptope.verts[j].x) * 0.5;
midpt.y = (ptope.verts[i].y + ptope.verts[j].y) * 0.5;
diff --git a/src/classes/share/javax/media/j3d/PickCylinderSegment.java b/src/classes/share/javax/media/j3d/PickCylinderSegment.java
index 37bb1a7..6f03cd0 100644
--- a/src/classes/share/javax/media/j3d/PickCylinderSegment.java
+++ b/src/classes/share/javax/media/j3d/PickCylinderSegment.java
@@ -205,7 +205,7 @@ public final class PickCylinderSegment extends PickCylinder {
double distToEdge;
for (i=0;i<ptope.nVerts;i++) {
for (j=i;i<ptope.nVerts;i++) {
- // TODO: make BoundingPolytope.pointInPolytope available to package
+ // XXXX: make BoundingPolytope.pointInPolytope available to package
// scope
midpt.x = (ptope.verts[i].x + ptope.verts[j].x) * 0.5;
midpt.y = (ptope.verts[i].y + ptope.verts[j].y) * 0.5;
diff --git a/src/classes/share/javax/media/j3d/PickInfo.java b/src/classes/share/javax/media/j3d/PickInfo.java
new file mode 100644
index 0000000..64a6392
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/PickInfo.java
@@ -0,0 +1,1056 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import javax.vecmath.*;
+import java.util.*;
+
+/**
+ * The PickInfo object contains the computed information about a pick hit.
+ * The detailed information about each intersection of the PickShape
+ * with the picked Node can be inquired. The PickInfo object is constructed with
+ * basic information and more detailed information can be generated by setting the
+ * appropriate mask to the flag argument in the pick methods of BranchGroup and
+ * Locale.
+ * <p>
+ *
+ * @see Locale
+ * @see BranchGroup
+ *
+ * @since Java 3D 1.4
+ */
+
+
+public class PickInfo extends Object {
+
+ static final int PICK_ALL = 1;
+
+ static final int PICK_ANY = 2;
+
+ /* The SceneGraphPath of the intersected pickable item */
+ private SceneGraphPath sgp;
+
+ /* The intersected pickable node object */
+ private Node node;
+
+ /* A copy of LocalToVworld transform of the pickable node */
+ private Transform3D l2vw;
+
+ /* The closest intersection point */
+ private Point3d closestIntersectionPoint;
+
+ /* Distance between start point of pickShape and closest intersection point */
+ private double closestDistance;
+
+ /* An array to store intersection results */
+ private IntersectionInfo[] intersectionInfoArr;
+
+ /* The following references are for internal geometry computation use only */
+ private ArrayList intersectionInfoList = new ArrayList();
+ private boolean intersectionInfoListSorted = false;
+ private Transform3D l2vwRef;
+ private Node nodeRef;
+
+ /**
+ * Specifies a Pick using the bounds of the pickable nodes.
+ */
+ public static final int PICK_BOUNDS = 1;
+
+ /**
+ * Specifies a Pick using the geometry of the pickable nodes.
+ */
+ public static final int PICK_GEOMETRY = 2;
+
+ /**
+ * Specifies that this PickInfo returns the computed SceneGraphPath object.
+ */
+ public static final int SCENEGRAPHPATH = 0x01;
+
+ /**
+ * Specifies that this PickInfo returns the computed intersected Node object.
+ */
+ public static final int NODE = 0x02;
+
+ /**
+ * Specifies that this PickInfo returns the computed local to vworld transform.
+ */
+ public static final int LOCAL_TO_VWORLD = 0x04;
+
+ /**
+ * Specifies that this PickInfo returns the closest intersection point.
+ */
+ public static final int CLOSEST_INTERSECTION_POINT = 0x08;
+
+ /**
+ * Specifies that this PickInfo returns the closest intersection distance.
+ */
+ public static final int CLOSEST_DISTANCE = 0x10;
+
+ /**
+ * Specifies that this PickInfo returns only the closest intersection
+ * geometry information.
+ */
+ public static final int CLOSEST_GEOM_INFO = 0x20;
+
+ /**
+ * Specifies that this PickInfo returns all the closest intersection
+ * geometry informations.
+ */
+ public static final int ALL_GEOM_INFO = 0x40;
+
+
+ /** PickInfo Constructor */
+ PickInfo() {
+
+ }
+
+ void setSceneGraphPath(SceneGraphPath sgp) {
+ this.sgp = sgp;
+ }
+
+ void setNode(Node node) {
+ this.node = node;
+ }
+
+ void setLocalToVWorld(Transform3D l2vw) {
+ this.l2vw = l2vw;
+ }
+
+ void setClosestIntersectionPoint(Point3d cIPt) {
+ this.closestIntersectionPoint = cIPt;
+ }
+
+ void setClosestDistance(double cDist) {
+ this.closestDistance = cDist;
+ }
+
+ void setLocalToVWorldRef(Transform3D l2vwRef) {
+ this.l2vwRef = l2vwRef;
+ }
+
+ void setNodeRef(Node nodeRef) {
+ this.nodeRef = nodeRef;
+ }
+
+ IntersectionInfo createIntersectionInfo() {
+ return new IntersectionInfo();
+ }
+
+ void insertIntersectionInfo(IntersectionInfo iInfo) {
+ intersectionInfoList.add(iInfo);
+ intersectionInfoListSorted = false;
+ }
+
+ void sortIntersectionInfoArray(IntersectionInfo[] iInfoArr) {
+
+ class Sort {
+
+ IntersectionInfo iInfoArr[];
+
+ Sort(IntersectionInfo[] iInfoArr) {
+ // System.out.println("Sort IntersectionInfo ...");
+ this.iInfoArr = iInfoArr;
+ }
+
+ void sorting() {
+ if (iInfoArr.length < 7) {
+ // System.out.println(" -- insertSort.");
+ insertSort();
+ } else {
+ // System.out.println(" -- quicksort.");
+ quicksort(0, iInfoArr.length-1);
+ }
+ }
+
+ // Insertion sort on smallest arrays
+ final void insertSort() {
+ for (int i=0; i<iInfoArr.length; i++) {
+ for (int j=i; j>0 &&
+ (iInfoArr[j-1].distance > iInfoArr[j].distance); j--) {
+ IntersectionInfo iInfo = iInfoArr[j];
+ iInfoArr[j] = iInfoArr[j-1];
+ iInfoArr[j-1] = iInfo;
+ }
+ }
+ }
+
+ final void quicksort( int l, int r ) {
+ int i = l;
+ int j = r;
+ double k = iInfoArr[(l+r) / 2].distance;
+
+ do {
+ while (iInfoArr[i].distance<k) i++;
+ while (k<iInfoArr[j].distance) j--;
+ if (i<=j) {
+ IntersectionInfo iInfo = iInfoArr[i];
+ iInfoArr[i] = iInfoArr[j];
+ iInfoArr[j] = iInfo;
+ i++;
+ j--;
+ }
+ } while (i<=j);
+
+ if (l<j) quicksort(l,j);
+ if (l<r) quicksort(i,r);
+ }
+ }
+
+ (new Sort(iInfoArr)).sorting();
+ intersectionInfoListSorted = true;
+ }
+
+ static void sortPickInfoArray(PickInfo[] pickInfoArr) {
+
+ class Sort {
+
+ PickInfo pIArr[];
+
+ Sort(PickInfo[] pIArr) {
+ // System.out.println("Sort PickInfo ...");
+ this.pIArr = pIArr;
+ }
+
+ void sorting() {
+ if (pIArr.length < 7) {
+ // System.out.println(" -- insertSort.");
+ insertSort();
+ } else {
+ // System.out.println(" -- quicksort.");
+ quicksort(0, pIArr.length-1);
+ }
+ }
+
+ // Insertion sort on smallest arrays
+ final void insertSort() {
+ for (int i=0; i<pIArr.length; i++) {
+ for (int j=i; j>0 &&
+ (pIArr[j-1].closestDistance > pIArr[j].closestDistance); j--) {
+ PickInfo pI = pIArr[j];
+ pIArr[j] = pIArr[j-1];
+ pIArr[j-1] = pI;
+ }
+ }
+ }
+
+ final void quicksort( int l, int r ) {
+ int i = l;
+ int j = r;
+ double k = pIArr[(l+r) / 2].closestDistance;
+
+ do {
+ while (pIArr[i].closestDistance<k) i++;
+ while (k<pIArr[j].closestDistance) j--;
+ if (i<=j) {
+ PickInfo pI = pIArr[i];
+ pIArr[i] = pIArr[j];
+ pIArr[j] = pI;
+ i++;
+ j--;
+ }
+ } while (i<=j);
+
+ if (l<j) quicksort(l,j);
+ if (l<r) quicksort(i,r);
+ }
+ }
+
+ (new Sort(pickInfoArr)).sorting();
+
+ }
+
+
+ /**
+ * Retrieves the reference to the SceneGraphPath in this PickInfo object.
+ * @return the SceneGraphPath object, or null if flag is not set with SCENEGRAPHPATH.
+ * @see Locale
+ * @see BranchGroup
+ */
+ public SceneGraphPath getSceneGraphPath() {
+ return sgp;
+ }
+
+ /**
+ * Retrieves the reference to the picked node, either a Shape3D or a Morph, in this PickInfo object.
+ * @return the picked leaf node object, or null if flag is not set with NODE.
+ * @see Locale
+ * @see BranchGroup
+ */
+ public Node getNode() {
+ return node;
+ }
+
+ /**
+ * Retrieves the reference to the LocalToVworld transform of the picked node in this PickInfo object.
+ * @return the local to vworld transform, or null if flag is not set with LOCAL_TO_VWORLD.
+ * @see Locale
+ * @see BranchGroup
+ */
+ public Transform3D getLocalToVWorld() {
+ return l2vw;
+ }
+
+ /**
+ * Retrieves the reference to the closest intersection point in this PickInfo object.
+ * @return the closest intersection point, or null if flag is not set with CLOSEST_INTERSECTION_POINT.
+ * @see Locale
+ * @see BranchGroup
+ */
+ public Point3d getClosestIntersectionPoint() {
+ return closestIntersectionPoint;
+ }
+
+ /**
+ * Retrieves the distance between the start point of the pickShape and the closest intersection point.
+ * @return the closest distance in double, or NaN if flag is not set with CLOSEST_INTERSECTION_POINT.
+ * Note : If this PickInfo object is returned by either pickClosest or pickAllSorted method, the return
+ * value is the closest distance in double even if flag is not set with CLOSET_INTERSECTION_POINT.
+ * @see Locale
+ * @see BranchGroup
+ */
+ public double getClosestDistance() {
+ return closestDistance;
+ }
+
+ Transform3D getLocalToVWorldRef() {
+ return l2vwRef;
+ }
+
+ Node getNodeRef() {
+ return nodeRef;
+ }
+
+ /**
+ * Retrieves the reference to the array of intersection results in this PickInfo object.
+ * @return an array of 1 IntersectionInfo object if flag is to set CLOSEST_GEOM_INFO,
+ * or an array of <i>N</i> IntersectionInfo objects containing all intersections of
+ * the picked node in sorted order if flag is to set ALL_GEOM_INFO, or null if neither
+ * bit is set.
+ * @see Locale
+ * @see BranchGroup
+ */
+ public IntersectionInfo[] getIntersectionInfos() {
+ if (intersectionInfoListSorted == false) {
+ intersectionInfoArr = new IntersectionInfo[intersectionInfoList.size()];
+ intersectionInfoArr =
+ (IntersectionInfo []) intersectionInfoList.toArray(intersectionInfoArr);
+
+ sortIntersectionInfoArray(intersectionInfoArr);
+ }
+
+ return intersectionInfoArr;
+ }
+
+ /**
+ * Search the path from nodeR up to Locale.
+ * Return the search path as ArrayList if found.
+ * Note that the locale will not insert into path.
+ */
+ static ArrayList initSceneGraphPath(NodeRetained nodeR) {
+ ArrayList path = new ArrayList(5);
+
+ do {
+ if (nodeR.source.getCapability(Node.ENABLE_PICK_REPORTING)){
+ path.add(nodeR);
+ }
+ nodeR = nodeR.parent;
+ } while (nodeR != null); // reach Locale
+
+ return path;
+ }
+
+ static private Node[] createPath(NodeRetained srcNode,
+ BranchGroupRetained bgRetained,
+ GeometryAtom geomAtom,
+ ArrayList initpath) {
+
+ ArrayList path = retrievePath(srcNode, bgRetained,
+ geomAtom.source.key);
+ assert(path != null);
+
+ return mergePath(path, initpath);
+
+ }
+
+
+ /**
+ * Return true if bg is inside cachedBG or bg is null
+ */
+ static private boolean inside(BranchGroupRetained bgArr[],
+ BranchGroupRetained bg) {
+
+ if ((bg == null) || (bgArr == null)) {
+ return true;
+ }
+
+ for (int i=0; i < bgArr.length; i++) {
+ if (bgArr[i] == bg) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * search the full path from the bottom of the scene graph -
+ * startNode, up to the Locale if endNode is null.
+ * If endNode is not null, the path is found up to, but not
+ * including, endNode or return null if endNode not hit
+ * during the search.
+ */
+ static private ArrayList retrievePath(NodeRetained startNode,
+ NodeRetained endNode,
+ HashKey key) {
+
+ ArrayList path = new ArrayList(5);
+ NodeRetained nodeR = startNode;
+
+ if (nodeR.inSharedGroup) {
+ // getlastNodeId() will destroy this key
+ key = new HashKey(key);
+ }
+
+ do {
+ if (nodeR == endNode) { // we found it !
+ return path;
+ }
+
+ if (nodeR.source.getCapability(Node.ENABLE_PICK_REPORTING)) {
+ path.add(nodeR);
+ }
+
+ if (nodeR instanceof SharedGroupRetained) {
+ // retrieve the last node ID
+ String nodeId = key.getLastNodeId();
+ Vector parents = ((SharedGroupRetained) nodeR).parents;
+ int sz = parents.size();
+ NodeRetained prevNodeR = nodeR;
+ for(int i=0; i< sz; i++) {
+ NodeRetained linkR = (NodeRetained) parents.elementAt(i);
+ if (linkR.nodeId.equals(nodeId)) {
+ nodeR = linkR;
+ // Need to add Link to the path report
+ path.add(nodeR);
+ // since !(endNode instanceof Link), we
+ // can skip the check (nodeR == endNode) and
+ // proceed to parent of link below
+ break;
+ }
+ }
+ if (nodeR == prevNodeR) {
+ // branch is already detach
+ return null;
+ }
+ }
+ nodeR = nodeR.parent;
+ } while (nodeR != null); // reach Locale
+
+ if (endNode == null) {
+ // user call pickxxx(Locale locale, PickShape shape)
+ return path;
+ }
+
+ // user call pickxxx(BranchGroup endNode, PickShape shape)
+ // if locale is reached and endNode not hit, this is not
+ // the path user want to select
+ return null;
+ }
+
+ /**
+ * copy p1, (follow by) p2 into a new array, p2 can be null
+ * The path is then reverse before return.
+ */
+ static private Node[] mergePath(ArrayList p1, ArrayList p2) {
+ int s = p1.size();
+ int len;
+ int i;
+ int l;
+ if (p2 == null) {
+ len = s;
+ } else {
+ len = s + p2.size();
+ }
+
+ Node nodes[] = new Node[len];
+ l = len-1;
+ for (i=0; i < s; i++) {
+ nodes[l-i] = (Node) ((NodeRetained) p1.get(i)).source;
+ }
+ for (int j=0; i< len; i++, j++) {
+ nodes[l-i] = (Node) ((NodeRetained) p2.get(j)).source;
+ }
+ return nodes;
+ }
+
+ /**
+ * Sort the GeometryAtoms distance from shape in ascending order
+ * geomAtoms.length must be >= 1
+ */
+ static void sortGeomAtoms(GeometryAtom geomAtoms[],
+ PickShape shape) {
+
+ final double distance[] = new double[geomAtoms.length];
+ Point4d pickPos = new Point4d();
+
+ for (int i=0; i < geomAtoms.length; i++) {
+ shape.intersect(geomAtoms[i].source.vwcBounds, pickPos);
+ distance[i] = pickPos.w;
+ }
+
+ class Sort {
+
+ GeometryAtom atoms[];
+
+ Sort(GeometryAtom[] atoms) {
+ this.atoms = atoms;
+ }
+
+ void sorting() {
+ if (atoms.length < 7) {
+ insertSort();
+ } else {
+ quicksort(0, atoms.length-1);
+ }
+ }
+
+ // Insertion sort on smallest arrays
+ final void insertSort() {
+ for (int i=0; i<atoms.length; i++) {
+ for (int j=i; j>0 &&
+ (distance[j-1] > distance[j]); j--) {
+ double t = distance[j];
+ distance[j] = distance[j-1];
+ distance[j-1] = t;
+ GeometryAtom p = atoms[j];
+ atoms[j] = atoms[j-1];
+ atoms[j-1] = p;
+ }
+ }
+ }
+
+ final void quicksort( int l, int r ) {
+ int i = l;
+ int j = r;
+ double k = distance[(l+r) / 2];
+
+ do {
+ while (distance[i]<k) i++;
+ while (k<distance[j]) j--;
+ if (i<=j) {
+ double tmp = distance[i];
+ distance[i] =distance[j];
+ distance[j] = tmp;
+
+ GeometryAtom p=atoms[i];
+ atoms[i]=atoms[j];
+ atoms[j]=p;
+ i++;
+ j--;
+ }
+ } while (i<=j);
+
+ if (l<j) quicksort(l,j);
+ if (l<r) quicksort(i,r);
+ }
+ }
+
+ (new Sort(geomAtoms)).sorting();
+ }
+
+
+ /**
+ * return all PickInfo[] of the geomAtoms.
+ * If initpath is null, the path is search from
+ * geomAtom Shape3D/Morph Node up to Locale
+ * (assume the same locale).
+ * Otherwise, the path is search up to node or
+ * null is return if it is not hit.
+ */
+ static ArrayList getPickInfos(ArrayList initpath,
+ BranchGroupRetained bgRetained,
+ GeometryAtom geomAtoms[],
+ Locale locale, int flags, int pickType) {
+
+ ArrayList pickInfoList = new ArrayList(5);
+ NodeRetained srcNode;
+ ArrayList text3dList = null;
+
+ if ((geomAtoms == null) || (geomAtoms.length == 0)) {
+ return null;
+ }
+
+ for (int i=0; i < geomAtoms.length; i++) {
+ assert((geomAtoms[i] != null) &&
+ (geomAtoms[i].source != null));
+
+ PickInfo pickInfo = null;
+ Shape3DRetained shape = geomAtoms[i].source;
+ srcNode = shape.sourceNode;
+
+ if (srcNode == null) {
+ // The node is just detach from branch so sourceNode = null
+ continue;
+ }
+
+ // Special case, for Text3DRetained, it is possible
+ // for different geomAtoms pointing to the same
+ // source Text3DRetained. So we need to combine
+ // those cases and report only once.
+ if (srcNode instanceof Shape3DRetained) {
+ Shape3DRetained s3dR = (Shape3DRetained) srcNode;
+ GeometryRetained geomR = null;
+ for(int cnt=0; cnt<s3dR.geometryList.size(); cnt++) {
+ geomR = (GeometryRetained) s3dR.geometryList.get(cnt);
+ if(geomR != null)
+ break;
+ }
+
+ if (geomR == null)
+ continue;
+
+ if (geomR instanceof Text3DRetained) {
+ // assume this case is not frequent, we allocate
+ // ArrayList only when necessary and we use ArrayList
+ // instead of HashMap since the case of when large
+ // number of distingish Text3DRetained node hit is
+ // rare.
+ if (text3dList == null) {
+ text3dList = new ArrayList(3);
+ } else {
+ int size = text3dList.size();
+ boolean found = false;
+ for (int j=0; j < size; j++) {
+ if (text3dList.get(j) == srcNode) {
+ found = true;
+ break;
+ }
+ }
+ if (found) {
+ continue; // try next geomAtom
+ }
+ }
+ text3dList.add(srcNode);
+ }
+ }
+
+ // If srcNode is instance of compile retained, then loop thru
+ // the entire source list and add it to the scene graph path
+ if (srcNode instanceof Shape3DCompileRetained) {
+
+ Shape3DCompileRetained s3dCR = (Shape3DCompileRetained)srcNode;
+
+ Node[] mpath = null;
+ boolean first = true;
+
+ for (int n = 0; n < s3dCR.srcList.length; n++) {
+
+ pickInfo = null;
+
+ // PickInfo.SCENEGRAPHPATH - request for computed SceneGraphPath.
+ if (((flags & SCENEGRAPHPATH) != 0) &&
+ (inside(shape.branchGroupPath,bgRetained))){
+
+ if(first) {
+ mpath = createPath(srcNode, bgRetained, geomAtoms[i], initpath);
+ first = false;
+ }
+
+ if(mpath != null) {
+ SceneGraphPath sgpath = new SceneGraphPath(locale,
+ mpath, (Node) s3dCR.srcList[n]);
+ sgpath.setTransform(shape.getCurrentLocalToVworld(0));
+ if(pickInfo == null)
+ pickInfo = new PickInfo();
+ pickInfo.setSceneGraphPath(sgpath);
+ }
+ }
+
+ // PickInfo.NODE - request for computed intersected Node.
+ if ((flags & NODE) != 0) {
+ if(pickInfo == null)
+ pickInfo = new PickInfo();
+ pickInfo.setNode((Node) s3dCR.srcList[n]);
+ }
+
+ // PickInfo.LOCAL_TO_VWORLD
+ // - request for computed local to virtual world transform.
+ if ((flags & LOCAL_TO_VWORLD) != 0) {
+ Transform3D l2vw = geomAtoms[i].source.getCurrentLocalToVworld();
+ if(pickInfo == null)
+ pickInfo = new PickInfo();
+ pickInfo.setLocalToVWorld( new Transform3D(l2vw));
+ }
+
+ // NOTE : Piggy bag for geometry computation by caller.
+ if (((flags & CLOSEST_DISTANCE) != 0) ||
+ ((flags & CLOSEST_GEOM_INFO) != 0) ||
+ ((flags & CLOSEST_INTERSECTION_POINT) != 0) ||
+ ((flags & ALL_GEOM_INFO) != 0)) {
+
+ pickInfo.setNodeRef((Node) s3dCR.srcList[n]);
+ Transform3D l2vw = geomAtoms[i].source.getCurrentLocalToVworld();
+ if(pickInfo == null)
+ pickInfo = new PickInfo();
+ pickInfo.setLocalToVWorldRef(l2vw);
+ }
+
+ if(pickInfo != null)
+ pickInfoList.add(pickInfo);
+ if(pickType == PICK_ANY) {
+ return pickInfoList;
+ }
+ }
+ }
+ else {
+ Node[] mpath = null;
+
+ // PickInfo.SCENEGRAPHPATH - request for computed SceneGraphPath.
+ if (((flags & SCENEGRAPHPATH) != 0) &&
+ (inside(shape.branchGroupPath,bgRetained))) {
+
+ mpath = createPath(srcNode, bgRetained, geomAtoms[i], initpath);
+
+ if(mpath != null) {
+ SceneGraphPath sgpath = new SceneGraphPath(locale, mpath,
+ (Node) srcNode.source);
+ sgpath.setTransform(shape.getCurrentLocalToVworld(0));
+ if(pickInfo == null)
+ pickInfo = new PickInfo();
+ pickInfo.setSceneGraphPath(sgpath);
+ }
+ }
+
+ // PickInfo.NODE - request for computed intersected Node.
+ if ((flags & NODE) != 0) {
+ if(pickInfo == null)
+ pickInfo = new PickInfo();
+ pickInfo.setNode((Node) srcNode.source);
+ }
+
+ // PickInfo.LOCAL_TO_VWORLD
+ // - request for computed local to virtual world transform.
+ if ((flags & LOCAL_TO_VWORLD) != 0) {
+ Transform3D l2vw = geomAtoms[i].source.getCurrentLocalToVworld();
+ if(pickInfo == null)
+ pickInfo = new PickInfo();
+ pickInfo.setLocalToVWorld( new Transform3D(l2vw));
+ }
+
+ // NOTE : Piggy bag for geometry computation by caller.
+ if (((flags & CLOSEST_DISTANCE) != 0) ||
+ ((flags & CLOSEST_GEOM_INFO) != 0) ||
+ ((flags & CLOSEST_INTERSECTION_POINT) != 0) ||
+ ((flags & ALL_GEOM_INFO) != 0)) {
+
+ pickInfo.setNodeRef((Node) srcNode.source);
+ Transform3D l2vw = geomAtoms[i].source.getCurrentLocalToVworld();
+ if(pickInfo == null)
+ pickInfo = new PickInfo();
+ pickInfo.setLocalToVWorldRef(l2vw);
+ }
+
+ if(pickInfo != null)
+ pickInfoList.add(pickInfo);
+ if(pickType == PICK_ANY) {
+ return pickInfoList;
+ }
+ }
+ }
+
+ return pickInfoList;
+ }
+
+ static PickInfo[] pick(Object node, GeometryAtom[] geomAtoms,
+ int mode, int flags, PickShape pickShape, int pickType) {
+
+ int pickInfoListSize;
+ PickInfo[] pickInfoArr = null;
+ Locale locale = null;
+ BranchGroupRetained bgRetained = null;
+ ArrayList initPath = null;
+ ArrayList pickInfoList = null;
+
+ if (node instanceof Locale) {
+ locale = (Locale) node;
+ }
+ else if ( node instanceof BranchGroupRetained) {
+ bgRetained = (BranchGroupRetained) node;
+ locale = bgRetained.locale;
+ }
+ synchronized (locale.universe.sceneGraphLock) {
+ if ( bgRetained != null) {
+ initPath = initSceneGraphPath(bgRetained);
+ }
+ pickInfoList = getPickInfos(initPath, bgRetained, geomAtoms,
+ locale, flags, pickType);
+ }
+
+ // We're done with PICK_BOUNDS case, but there is still more work for PICK_GEOMETRY case.
+ if((mode == PICK_GEOMETRY) && ((pickInfoListSize = pickInfoList.size()) > 0)) {
+
+ //System.out.println("PickInfo.pick() - In geometry case : pickInfoList.size() is " + pickInfoListSize);
+ PickInfo pickInfo = null;
+ Node pickNode = null;
+
+ // Order is impt. Need to do in reverse order.
+ for(int i = pickInfoListSize - 1; i >= 0; i--) {
+ pickInfo = (PickInfo) pickInfoList.get(i);
+ pickNode = pickInfo.getNode();
+
+ if (pickNode instanceof Shape3D) {
+
+ /*
+ * @exception CapabilityNotSetException if the mode is
+ * PICK_GEOMETRY and the Geometry.ALLOW_INTERSECT capability bit
+ * is not set in any Geometry objects referred to by any shape
+ * node whose bounds intersects the PickShape.
+ *
+ * @exception CapabilityNotSetException if flags contains any of
+ * CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE, CLOSEST_GEOM_INFO
+ * or ALL_GEOM_INFO, and the capability bits that control reading of
+ * coordinate data are not set in any GeometryArray object referred
+ * to by any shape node that intersects the PickShape.
+ * The capability bits that must be set to avoid this exception are
+ * as follows :
+ *
+ * By-copy geometry : GeometryArray.ALLOW_COORDINATE_READ
+ * By-reference geometry : GeometryArray.ALLOW_REF_DATA_READ
+ * Indexed geometry : IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ
+ * (in addition to one of the above)
+ *
+ */
+
+ if (!pickNode.getCapability(Shape3D.ALLOW_GEOMETRY_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("PickInfo0"));
+ }
+
+ for (int j = 0; j < ((Shape3D)pickNode).numGeometries(); j++) {
+ Geometry geo = ((Shape3D)pickNode).getGeometry(j);
+
+ if(!geo.getCapability(Geometry.ALLOW_INTERSECT)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("PickInfo1"));
+ }
+
+ if (geo instanceof GeometryArray) {
+ if(!geo.getCapability(GeometryArray.ALLOW_COORDINATE_READ))
+ throw new CapabilityNotSetException(J3dI18N.getString("PickInfo2"));
+ if(!geo.getCapability(GeometryArray.ALLOW_COUNT_READ))
+ throw new CapabilityNotSetException(J3dI18N.getString("PickInfo3"));
+ if(!geo.getCapability(GeometryArray.ALLOW_FORMAT_READ))
+ throw new CapabilityNotSetException(J3dI18N.getString("PickInfo4"));
+ if (geo instanceof IndexedGeometryArray) {
+ if(!geo.getCapability(IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ))
+ throw new CapabilityNotSetException(J3dI18N.getString("PickInfo5"));
+ }
+ } else if (geo instanceof CompressedGeometry) {
+ if(!geo.getCapability(CompressedGeometry.ALLOW_GEOMETRY_READ))
+ throw new CapabilityNotSetException(J3dI18N.getString("PickInfo0"));
+ }
+ }
+
+ if (((Shape3DRetained)(pickNode.retained)).intersect(pickInfo, pickShape, flags) == false) {
+ // System.out.println(" ---- geom " + i + " not intersected");
+
+ pickInfoList.remove(i);
+
+ }
+ else if(pickType == PICK_ANY) {
+ pickInfoArr = new PickInfo[1];
+ pickInfoArr[0] = pickInfo;
+ return pickInfoArr;
+ }
+ } else if (pickNode instanceof Morph) {
+
+ /*
+ * @exception CapabilityNotSetException if the mode is
+ * PICK_GEOMETRY and the Geometry.ALLOW_INTERSECT capability bit
+ * is not set in any Geometry objects referred to by any shape
+ * node whose bounds intersects the PickShape.
+ *
+ * @exception CapabilityNotSetException if flags contains any of
+ * CLOSEST_INTERSECTION_POINT, CLOSEST_DISTANCE, CLOSEST_GEOM_INFO
+ * or ALL_GEOM_INFO, and the capability bits that control reading of
+ * coordinate data are not set in any GeometryArray object referred
+ * to by any shape node that intersects the PickShape.
+ * The capability bits that must be set to avoid this exception are
+ * as follows :
+ *
+ * By-copy geometry : GeometryArray.ALLOW_COORDINATE_READ
+ * By-reference geometry : GeometryArray.ALLOW_REF_DATA_READ
+ * Indexed geometry : IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ
+ * (in addition to one of the above)
+ *
+ */
+
+ if (!pickNode.getCapability(Morph.ALLOW_GEOMETRY_ARRAY_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("PickInfo6"));
+ }
+
+ int numGeo = ((MorphRetained)(pickNode.retained)).getNumGeometryArrays();
+ for (int j = 0; j < numGeo; j++) {
+ GeometryArray geo = ((Morph)pickNode).getGeometryArray(j);
+
+ if(!geo.getCapability(Geometry.ALLOW_INTERSECT)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("PickInfo1"));
+ }
+
+ if(!geo.getCapability(GeometryArray.ALLOW_COORDINATE_READ))
+ throw new CapabilityNotSetException(J3dI18N.getString("PickInfo2"));
+ if(!geo.getCapability(GeometryArray.ALLOW_COUNT_READ))
+ throw new CapabilityNotSetException(J3dI18N.getString("PickInfo3"));
+ if(!geo.getCapability(GeometryArray.ALLOW_FORMAT_READ))
+ throw new CapabilityNotSetException(J3dI18N.getString("PickInfo4"));
+
+ if (geo instanceof IndexedGeometryArray) {
+ if(!geo.getCapability(IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ))
+ throw new CapabilityNotSetException(J3dI18N.getString("PickInfo5"));
+ }
+ }
+
+ if (((MorphRetained)(pickNode.retained)).intersect(pickInfo, pickShape, flags) == false) {
+ pickInfoList.remove(i);
+ }
+ else if(pickType == PICK_ANY) {
+ pickInfoArr = new PickInfo[1];
+ pickInfoArr[0] = pickInfo;
+ return pickInfoArr;
+ }
+ }
+ }
+ }
+
+ // System.out.println("PickInfo : pickInfoList " + pickInfoList);
+
+ if ((pickInfoList != null) && (pickInfoList.size() > 0)) {
+ // System.out.println(" --- : pickInfoList.size() " + pickInfoList.size());
+ // System.out.println(" --- : pickInfoList's sgp " +
+ // ((PickInfo)(pickInfoList.get(0))).getSceneGraphPath());
+ pickInfoArr = new PickInfo[pickInfoList.size()];
+ return (PickInfo []) pickInfoList.toArray(pickInfoArr);
+ }
+
+ return null;
+
+ }
+
+ /**
+ * The IntersectionInfo object holds extra information about an intersection
+ * of a PickShape with a Node as part of a PickInfo. Information such as
+ * the intersected geometry, the intersected point, and the vertex indices
+ * can be inquired.
+ * The local coordinates, normal, color and texture coordiantes of at the
+ * intersection can be computed, if they are present and readable, using the
+ * interpolation weights and vertex indices.
+ * <p>
+ * If the Shape3D being picked has multiple geometry arrays, the possible arrays
+ * of IntersectionInfo are stored in the PickInfo and referred to by a geometry
+ * index. If the picked geometry is of type, Text3D or CompressGeometry,
+ * getVertexIndices is invalid. If the picked Node is an Morph
+ * object, the geometry used in pick computation is alway at index 0.
+ * <p>
+ *
+ * @since Java 3D 1.4
+ */
+
+ public class IntersectionInfo extends Object {
+
+ /* The index to the intersected geometry in the pickable node */
+ private int geomIndex;
+
+ /* The reference to the intersected geometry in the pickable object */
+ private Geometry geom;
+
+ /* The intersection point */
+ private Point3d intersectionPoint;
+
+ /* Distance between start point of pickShape and intersection point */
+ private double distance;
+
+ /* The vertex indices of the intersected primitive in the geometry */
+ private int[] vertexIndices;
+
+ /* The interpolation weights for each of the verticies of the primitive */
+ // private float[] weights; Not supported. Should be done in util. package
+
+ /** IntersectionInfo Constructor */
+ IntersectionInfo() {
+
+ }
+
+ void setGeometryIndex(int geomIndex) {
+ this.geomIndex = geomIndex;
+ }
+
+ void setGeometry(Geometry geom) {
+ this.geom = geom;
+ }
+
+ void setIntersectionPoint(Point3d intersectionPoint) {
+ this.intersectionPoint = intersectionPoint;
+ }
+
+ void setDistance(double distance) {
+ this.distance = distance;
+ }
+
+ void setVertexIndices(int[] vertexIndices) {
+ this.vertexIndices = vertexIndices;
+ }
+
+
+ /**
+ * Retrieves the index to the intersected geometry in the picked node, either a Shape3D or Morph.
+ * @return the index of the intersected geometry in the pickable node.
+ */
+ public int getGeometryIndex() {
+ return geomIndex;
+ }
+
+ /**
+ * Retrieves the reference to the intersected geometry in the picked object, either a Shape3D or Morph.
+ * @return the intersected geometry in the pickable node.
+ */
+ public Geometry getGeometry() {
+ return geom;
+ }
+
+ /**
+ * Retrieves the reference to the intersection point in the pickable node.
+ * @return the intersected point in the pickable node.
+ */
+ public Point3d getIntersectionPoint() {
+ return intersectionPoint;
+ }
+
+ /**
+ * Retrieves the distance between the start point of the pickShape and the
+ * intersection point.
+ * @return distance between the start point of the pickShape and the
+ * intersection point.
+ */
+ public double getDistance() {
+ return distance;
+ }
+
+ /**
+ * Retrieves the vertex indices of the intersected primitive in the geometry.
+ * @return the vertex indices of the intersected primitive.
+ */
+ public int[] getVertexIndices() {
+ return vertexIndices;
+ }
+
+ }
+}
+
+
diff --git a/src/classes/share/javax/media/j3d/PickPoint.java b/src/classes/share/javax/media/j3d/PickPoint.java
index 3001af1..22ec12b 100644
--- a/src/classes/share/javax/media/j3d/PickPoint.java
+++ b/src/classes/share/javax/media/j3d/PickPoint.java
@@ -20,6 +20,10 @@ import javax.vecmath.*;
*
* @see BranchGroup#pickAll
* @see Locale#pickAll
+ * @see PickBounds
+ *
+ * @deprecated As of Java 3D version 1.4, use PickBounds with a
+ * BoundingSphere that has a small radius.
*/
public final class PickPoint extends PickShape {
diff --git a/src/classes/share/javax/media/j3d/Picking.java b/src/classes/share/javax/media/j3d/Picking.java
deleted file mode 100644
index 952248d..0000000
--- a/src/classes/share/javax/media/j3d/Picking.java
+++ /dev/null
@@ -1,660 +0,0 @@
-/*
- * $RCSfile$
- *
- * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
- *
- * Use is subject to license terms.
- *
- * $Revision$
- * $Date$
- * $State$
- */
-
-package javax.media.j3d;
-
-import javax.vecmath.*;
-import java.util.*;
-
-
-/**
- * Internal class that implements picking functionality.
- */
-
-class Picking {
-
- static SceneGraphPath[] pickAll(Locale locale, PickShape shape) {
- if(locale == null) {
- return null;
- }
-
- GeometryAtom geomAtoms[] =
- locale.universe.geometryStructure.pickAll(locale, shape);
- if ((geomAtoms == null) || (geomAtoms.length == 0)) {
- // although getSceneGraphPath() also return null, we
- // save time for synchronization
- return null;
- }
- synchronized (locale.universe.sceneGraphLock) {
- return getSceneGraphPath(null, null, geomAtoms, locale);
- }
- }
-
-
-
- static SceneGraphPath[] pickAll(BranchGroup node,
- PickShape shape) {
- if (node == null) {
- return null;
- }
-
- BranchGroupRetained nodeR = (BranchGroupRetained) node.retained;
-
- if (nodeR.inSharedGroup) {
- throw new RestrictedAccessException(J3dI18N.getString("Picking0"));
- }
-
- Locale locale = nodeR.locale;
-
- GeometryAtom geomAtoms[] =
- locale.universe.geometryStructure.pickAll(locale, shape);
-
- if ((geomAtoms == null) || (geomAtoms.length == 0)) {
- return null;
- }
-
- synchronized (nodeR.universe.sceneGraphLock) {
- return getSceneGraphPath(initSceneGraphPath(nodeR),
- nodeR, geomAtoms, locale);
- }
- }
-
-
- static SceneGraphPath[] pickAllSorted(Locale locale,
- PickShape shape) {
- if(locale == null) {
- return null;
- }
-
- GeometryAtom geomAtoms[] =
- locale.universe.geometryStructure.pickAll(locale, shape);
-
- if ((geomAtoms == null) || (geomAtoms.length == 0)) {
- return null;
- }
-
- sortGeomAtoms(geomAtoms, shape);
-
- synchronized (locale.universe.sceneGraphLock) {
- return getSceneGraphPath(null, null, geomAtoms, locale);
- }
- }
-
-
- static SceneGraphPath[] pickAllSorted(BranchGroup node,
- PickShape shape) {
- if (node == null) {
- return null;
- }
-
- BranchGroupRetained nodeR = (BranchGroupRetained) node.retained;
-
- if (nodeR.inSharedGroup) {
- throw new RestrictedAccessException(J3dI18N.getString("Picking0"));
- }
-
- Locale locale = nodeR.locale;
-
- GeometryAtom geomAtoms[] =
- locale.universe.geometryStructure.pickAll(locale, shape);
-
- if ((geomAtoms == null) || (geomAtoms.length == 0)) {
- return null;
- }
-
- // we have to sort first before eliminate duplicate Text3D
- // since we want the closest geometry atoms of Text3D
- sortGeomAtoms(geomAtoms, shape);
-
- synchronized (nodeR.universe.sceneGraphLock) {
- return getSceneGraphPath(initSceneGraphPath(nodeR),
- nodeR, geomAtoms, locale);
- }
- }
-
-
- static SceneGraphPath pickClosest(Locale locale,
- PickShape shape) {
-
- if(locale == null) {
- return null;
- }
-
- GeometryAtom geomAtoms[] =
- locale.universe.geometryStructure.pickAll(locale, shape);
-
-
- if ((geomAtoms == null) || (geomAtoms.length == 0)) {
- return null;
- }
-
-
- GeometryAtom geomAtom = selectClosest(geomAtoms, shape);
-
-
- synchronized (locale.universe.sceneGraphLock) {
- return getSceneGraphPath(null, null, geomAtom, locale);
- }
- }
-
-
- static SceneGraphPath pickClosest(BranchGroup node,
- PickShape shape) {
- if (node == null) {
- return null;
- }
-
- BranchGroupRetained nodeR = (BranchGroupRetained) node.retained;
-
- if (nodeR.inSharedGroup) {
- throw new RestrictedAccessException(J3dI18N.getString("Picking0"));
- }
-
- Locale locale = nodeR.locale;
-
- GeometryAtom geomAtoms[] =
- locale.universe.geometryStructure.pickAll(locale, shape);
-
-
-
- if ((geomAtoms == null) || (geomAtoms.length == 0)) {
- return null;
- }
-
-
- // We must sort all since the closest one in geomAtoms may not
- // under the BranchGroup node
- sortGeomAtoms(geomAtoms, shape);
-
- synchronized (nodeR.universe.sceneGraphLock) {
- return getFirstSceneGraphPath(initSceneGraphPath(nodeR),
- nodeR, geomAtoms, locale);
-
- }
- }
-
-
- static SceneGraphPath pickAny(Locale locale, PickShape shape) {
-
- if(locale == null) {
- return null;
- }
-
- GeometryAtom geomAtom =
- locale.universe.geometryStructure.pickAny(locale, shape);
-
- if (geomAtom == null) {
- return null;
- }
-
-
- synchronized (locale.universe.sceneGraphLock) {
- return getSceneGraphPath(null, null, geomAtom, locale);
- }
- }
-
- static SceneGraphPath pickAny(BranchGroup node, PickShape shape) {
-
- if (node == null) {
- return null;
- }
-
- BranchGroupRetained nodeR = (BranchGroupRetained) node.retained;
-
- if (nodeR.inSharedGroup) {
- throw new RestrictedAccessException(J3dI18N.getString("Picking0"));
- }
-
- Locale locale = nodeR.locale;
-
- // since PickAny return from geometry may not lie under
- // BranchGroup node, we have to use pickAll
-
- GeometryAtom geomAtoms[] =
- locale.universe.geometryStructure.pickAll(locale, shape);
-
- if ((geomAtoms == null) || (geomAtoms.length == 0)) {
- return null;
- }
-
- synchronized (nodeR.universe.sceneGraphLock) {
- return getFirstSceneGraphPath(initSceneGraphPath(nodeR),
- nodeR, geomAtoms, locale);
- }
- }
-
-
- /**
- * Search the path from nodeR up to Locale.
- * Return the search path as ArrayList if found.
- * Note that the locale will not insert into path.
- */
- static private ArrayList initSceneGraphPath(NodeRetained nodeR) {
- ArrayList path = new ArrayList(5);
-
- do {
- if (nodeR.source.getCapability(Node.ENABLE_PICK_REPORTING)){
- path.add(nodeR);
- }
- nodeR = nodeR.parent;
- } while (nodeR != null); // reach Locale
-
- return path;
- }
-
- /**
- * return all SceneGraphPath[] of the geomAtoms.
- * If initpath is null, the path is search from
- * geomAtom Shape3D/Morph Node up to Locale
- * (assume the same locale).
- * Otherwise, the path is search up to node or
- * null is return if it is not hit.
- */
- static private SceneGraphPath[] getSceneGraphPath(ArrayList initpath,
- BranchGroupRetained node,
- GeometryAtom geomAtoms[],
- Locale locale) {
-
- ArrayList paths = new ArrayList(5);
- GeometryAtom geomAtom;
- NodeRetained target;
- ArrayList texts = null;
-
- if (geomAtoms == null) {
- return null;
- }
-
-
- for (int i=0; i < geomAtoms.length; i++) {
- geomAtom = (GeometryAtom) geomAtoms[i];
- Shape3DRetained shape = geomAtom.source;
-
- // isPickable and currentSwitchOn has been check in BHTree
-
- if (!inside(shape.branchGroupPath, node)) {
- continue;
- }
-
- target = shape.sourceNode;
-
- if (target == null) {
- // The node is just detach from branch so sourceNode = null
- continue;
- }
-
- // Special case, for Text3DRetained, it is possible
- // for different geomAtoms pointing to the same
- // source Text3DRetained. So we need to combine
- // those cases and report only once.
- if (target instanceof Shape3DRetained) {
- Shape3DRetained s3dR = (Shape3DRetained) target;
- GeometryRetained geomR = null;
- for(int cnt=0; cnt<s3dR.geometryList.size(); cnt++) {
- geomR = (GeometryRetained) s3dR.geometryList.get(cnt);
- if(geomR != null)
- break;
- }
-
- if (geomR == null)
- continue;
-
- if (geomR instanceof Text3DRetained) {
- // assume this case is not frequent, we allocate
- // ArrayList only when necessary and we use ArrayList
- // instead of HashMap since the case of when large
- // number of distingish Text3DRetained node hit is
- // rare.
- if (texts == null) {
- texts = new ArrayList(3);
- } else {
- int size = texts.size();
- boolean found = false;
- for (int j=0; j < size; j++) {
- if (texts.get(j) == target) {
- found = true;
- break;
- }
- }
- if (found) {
- continue; // try next geomAtom
- }
- }
- texts.add(target);
- }
- }
-
- ArrayList path = retrievePath(target, node,
- geomAtom.source.key);
-
- if (path == null) {
- continue;
- }
-
- // If target is instance of compile retained, then loop thru
- // the entire source list and add it to the scene graph path
- if (target instanceof Shape3DCompileRetained) {
- Shape3DCompileRetained s3dCR = (Shape3DCompileRetained)target;
- Node[] mpath = mergePath(path, initpath);
- for (int n = 0; n < s3dCR.srcList.length; n++) {
- SceneGraphPath sgpath = new SceneGraphPath(locale,
- mpath,
- (Node) s3dCR.srcList[n]);
- sgpath.setTransform(shape.getCurrentLocalToVworld(0));
- paths.add(sgpath);
- }
-
- }
- else {
- SceneGraphPath sgpath = new SceneGraphPath(locale,
- mergePath(path, initpath),
- (Node) target.source);
- sgpath.setTransform(shape.getCurrentLocalToVworld(0));
- paths.add(sgpath);
- }
-
-
- }
- SceneGraphPath pathArray[] = new SceneGraphPath[paths.size()];
- return (SceneGraphPath []) paths.toArray(pathArray);
- }
-
- /**
- * return the SceneGraphPath of the geomAtom.
- * If initpath is null, the path is search from
- * geomAtom Shape3D/Morph Node up to Locale
- * (assume the same locale).
- * Otherwise, the path is search up to node or
- * null is return if it is not hit.
- */
- static private SceneGraphPath getSceneGraphPath(ArrayList initpath,
- BranchGroupRetained node,
- GeometryAtom geomAtom,
- Locale locale) {
- if (geomAtom == null) {
- return null;
- }
-
- Shape3DRetained shape = geomAtom.source;
- NodeRetained target = shape.sourceNode;
-
- if (target == null) {
- // The node is just detach from branch so sourceNode = null
- return null;
- }
-
- if (!inside(shape.branchGroupPath, node)) {
- return null;
- }
-
- ArrayList path = retrievePath(target, node, shape.key);
-
- if (path == null) {
- return null;
- }
-
- SceneGraphPath sgpath = new SceneGraphPath(locale,
- mergePath(path, initpath),
- (Node)
- target.source);
- sgpath.setTransform(shape.getCurrentLocalToVworld(0));
- return sgpath;
- }
-
- /**
- * Return true if bg is inside cachedBG or bg is null
- */
- static private boolean inside(BranchGroupRetained bgArr[],
- BranchGroupRetained bg) {
-
- if ((bg == null) || (bgArr == null)) {
- return true;
- }
-
- for (int i=0; i < bgArr.length; i++) {
- if (bgArr[i] == bg) {
- return true;
- }
- }
- return false;
- }
-
-
- /**
- * return the first SceneGraphPath of the geomAtom.
- * If initpath is null, the path is search from
- * geomAtom Shape3D/Morph Node up to Locale
- * (assume the same locale).
- * Otherwise, the path is search up to node or
- * null is return if it is not hit.
- */
- static private SceneGraphPath getFirstSceneGraphPath(ArrayList initpath,
- BranchGroupRetained node,
- GeometryAtom geomAtoms[],
- Locale locale) {
- if (geomAtoms == null) {
- return null;
- }
-
- for (int i=0; i < geomAtoms.length; i++) {
- Shape3DRetained shape = geomAtoms[i].source;
- NodeRetained target = shape.sourceNode;
-
- if (target == null) {
- // The node is just detach from branch so sourceNode = null
- continue;
- }
- if (!inside(shape.branchGroupPath, node)) {
- continue;
- }
- ArrayList path = retrievePath(target, node, geomAtoms[i].source.key);
-
- if (path == null) {
- continue;
- }
- SceneGraphPath sgpath = new SceneGraphPath(locale,
- mergePath(path, initpath),
- (Node) target.source);
- sgpath.setTransform(shape.getCurrentLocalToVworld(0));
- return sgpath;
- }
- return null;
- }
-
-
- /**
- * search the full path from the botton of the scene graph -
- * startNode, up to the Locale if endNode is null.
- * If endNode is not null, the path is found up to, but not
- * including, endNode or return null if endNode not hit
- * during the search.
- */
- static private ArrayList retrievePath(NodeRetained startNode,
- NodeRetained endNode,
- HashKey key) {
-
- ArrayList path = new ArrayList(5);
- NodeRetained nodeR = startNode;
-
- if (nodeR.inSharedGroup) {
- // getlastNodeId() will destroy this key
- key = new HashKey(key);
- }
-
- do {
- if (nodeR == endNode) { // we found it !
- return path;
- }
-
- if (nodeR.source.getCapability(Node.ENABLE_PICK_REPORTING)) {
- path.add(nodeR);
- }
-
- if (nodeR instanceof SharedGroupRetained) {
- // retrieve the last node ID
- String nodeId = key.getLastNodeId();
- Vector parents = ((SharedGroupRetained) nodeR).parents;
- int sz = parents.size();
- NodeRetained prevNodeR = nodeR;
- for(int i=0; i< sz; i++) {
- NodeRetained linkR = (NodeRetained) parents.elementAt(i);
- if (linkR.nodeId.equals(nodeId)) {
- nodeR = linkR;
- // Need to add Link to the path report
- path.add(nodeR);
- // since !(endNode instanceof Link), we
- // can skip the check (nodeR == endNode) and
- // proceed to parent of link below
- break;
- }
- }
- if (nodeR == prevNodeR) {
- // branch is already detach
- return null;
- }
- }
- nodeR = nodeR.parent;
- } while (nodeR != null); // reach Locale
-
- if (endNode == null) {
- // user call pickxxx(Locale locale, PickShape shape)
- return path;
- }
-
- // user call pickxxx(BranchGroup endNode, PickShape shape)
- // if locale is reached and endNode not hit, this is not
- // the path user want to select
- return null;
- }
-
- /**
- * copy p1, (follow by) p2 into a new array, p2 can be null
- * The path is then reverse before return.
- */
- static private Node[] mergePath(ArrayList p1, ArrayList p2) {
- int s = p1.size();
- int len;
- int i;
- int l;
- if (p2 == null) {
- len = s;
- } else {
- len = s + p2.size();
- }
-
- Node nodes[] = new Node[len];
- l = len-1;
- for (i=0; i < s; i++) {
- nodes[l-i] = (Node) ((NodeRetained) p1.get(i)).source;
- }
- for (int j=0; i< len; i++, j++) {
- nodes[l-i] = (Node) ((NodeRetained) p2.get(j)).source;
- }
- return nodes;
- }
-
- /**
- * Select the closest geomAtoms from shape
- * geomAtoms.length must be >= 1
- */
- static private GeometryAtom selectClosest(GeometryAtom geomAtoms[],
- PickShape shape) {
- Point4d pickPos = new Point4d();
- GeometryAtom closestAtom = geomAtoms[0];
- shape.intersect(closestAtom.source.vwcBounds, pickPos);
- double distance = pickPos.w;
-
- for (int i=1; i < geomAtoms.length; i++) {
- shape.intersect(geomAtoms[i].source.vwcBounds, pickPos);
- if (pickPos.w < distance) {
- distance = pickPos.w;
- closestAtom = geomAtoms[i];
- }
- }
- return closestAtom;
- }
-
- /**
- * Sort the GeometryAtoms distance from shape in ascending order
- * geomAtoms.length must be >= 1
- */
- static private void sortGeomAtoms(GeometryAtom geomAtoms[],
- PickShape shape) {
-
- final double distance[] = new double[geomAtoms.length];
- Point4d pickPos = new Point4d();
-
- for (int i=0; i < geomAtoms.length; i++) {
- shape.intersect(geomAtoms[i].source.vwcBounds, pickPos);
- distance[i] = pickPos.w;
- }
-
- class Sort {
-
- GeometryAtom atoms[];
-
- Sort(GeometryAtom[] atoms) {
- this.atoms = atoms;
- }
-
- void sorting() {
- if (atoms.length < 7) {
- insertSort();
- } else {
- quicksort(0, atoms.length-1);
- }
- }
-
- // Insertion sort on smallest arrays
- final void insertSort() {
- for (int i=0; i<atoms.length; i++) {
- for (int j=i; j>0 &&
- (distance[j-1] > distance[j]); j--) {
- double t = distance[j];
- distance[j] = distance[j-1];
- distance[j-1] = t;
- GeometryAtom p = atoms[j];
- atoms[j] = atoms[j-1];
- atoms[j-1] = p;
- }
- }
- }
-
- final void quicksort( int l, int r ) {
- int i = l;
- int j = r;
- double k = distance[(l+r) / 2];
-
- do {
- while (distance[i]<k) i++;
- while (k<distance[j]) j--;
- if (i<=j) {
- double tmp = distance[i];
- distance[i] =distance[j];
- distance[j] = tmp;
-
- GeometryAtom p=atoms[i];
- atoms[i]=atoms[j];
- atoms[j]=p;
- i++;
- j--;
- }
- } while (i<=j);
-
- if (l<j) quicksort(l,j);
- if (l<r) quicksort(i,r);
- }
- }
-
- (new Sort(geomAtoms)).sorting();
- }
-
-}
diff --git a/src/classes/share/javax/media/j3d/PointArray.java b/src/classes/share/javax/media/j3d/PointArray.java
index 412f4d5..421960d 100644
--- a/src/classes/share/javax/media/j3d/PointArray.java
+++ b/src/classes/share/javax/media/j3d/PointArray.java
@@ -23,22 +23,21 @@ public class PointArray extends GeometryArray {
PointArray() {}
/**
- * Constructs an empty PointArray object with the specified
- * number of vertices, and vertex format.
- * @param vertexCount the number of vertex elements in this array
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.
+ * Constructs an empty PointArray object using the specified
+ * parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
* @exception IllegalArgumentException if vertexCount is less than 1
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int)}
+ * for more exceptions that can be thrown
*/
public PointArray(int vertexCount, int vertexFormat) {
super(vertexCount,vertexFormat);
@@ -48,59 +47,29 @@ public class PointArray extends GeometryArray {
}
/**
- * Constructs an empty PointArray object with the specified
- * number of vertices, and vertex format, number of texture coordinate
- * sets, and texture coordinate mapping array.
- *
- * @param vertexCount the number of vertex elements in this array<p>
- *
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.<p>
- *
- * @param texCoordSetCount the number of texture coordinate sets
- * in this GeometryArray object. If <code>vertexFormat</code>
- * does not include one of <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetCount</code> parameter is not used.<p>
- *
- * @param texCoordSetMap an array that maps texture coordinate
- * sets to texture units. The array is indexed by texture unit
- * number for each texture unit in the associated Appearance
- * object. The values in the array specify the texture coordinate
- * set within this GeometryArray object that maps to the
- * corresponding texture
- * unit. All elements within the array must be less than
- * <code>texCoordSetCount</code>. A negative value specifies that
- * no texture coordinate set maps to the texture unit
- * corresponding to the index. If there are more texture units in
- * any associated Appearance object than elements in the mapping
- * array, the extra elements are assumed to be -1. The same
- * texture coordinate set may be used for more than one texture
- * unit. Each texture unit in every associated Appearance must
- * have a valid source of texture coordinates: either a
- * non-negative texture coordinate set must be specified in the
- * mapping array or texture coordinate generation must be enabled.
- * Texture coordinate generation will take precedence for those
- * texture units for which a texture coordinate set is specified
- * and texture coordinate generation is enabled. If
- * <code>vertexFormat</code> does not include one of
- * <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetMap</code> array is not used.
+ * Constructs an empty PointArray object using the specified
+ * parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
*
* @exception IllegalArgumentException if vertexCount is less than 1
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for more exceptions that can be thrown
*
* @since Java 3D 1.2
*/
@@ -117,6 +86,52 @@ public class PointArray extends GeometryArray {
}
/**
+ * Constructs an empty PointArray object using the specified
+ * parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrSizes
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @exception IllegalArgumentException if vertexCount is less than 1
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for more exceptions that can be thrown
+ *
+ * @since Java 3D 1.4
+ */
+ public PointArray(int vertexCount,
+ int vertexFormat,
+ int texCoordSetCount,
+ int[] texCoordSetMap,
+ int vertexAttrCount,
+ int[] vertexAttrSizes) {
+
+ super(vertexCount, vertexFormat,
+ texCoordSetCount, texCoordSetMap,
+ vertexAttrCount, vertexAttrSizes);
+
+ if (vertexCount < 1 )
+ throw new IllegalArgumentException(J3dI18N.getString("PointArray0"));
+ }
+
+ /**
* Creates the retained mode PointArrayRetained object that this
* PointArray object will point to.
*/
@@ -130,21 +145,26 @@ public class PointArray extends GeometryArray {
* @deprecated replaced with cloneNodeComponent(boolean forceDuplicate)
*/
public NodeComponent cloneNodeComponent() {
- PointArrayRetained rt = (PointArrayRetained) retained;
- int texSetCount = rt.getTexCoordSetCount();
- PointArray p;
- if (texSetCount == 0) {
- p = new PointArray(rt.getVertexCount(),
- rt.getVertexFormat());
- } else {
- int texMap[] = new int[rt.getTexCoordSetMapLength()];
- rt.getTexCoordSetMap(texMap);
- p = new PointArray(rt.getVertexCount(),
- rt.getVertexFormat(),
- texSetCount,
- texMap);
- }
- p.duplicateNodeComponent(this);
+ PointArrayRetained rt = (PointArrayRetained) retained;
+ int texSetCount = rt.getTexCoordSetCount();
+ int[] texMap = null;
+ int vertexAttrCount = rt.getVertexAttrCount();
+ int[] vertexAttrSizes = null;
+ if (texSetCount > 0) {
+ texMap = new int[rt.getTexCoordSetMapLength()];
+ rt.getTexCoordSetMap(texMap);
+ }
+ if (vertexAttrCount > 0) {
+ vertexAttrSizes = new int[vertexAttrCount];
+ rt.getVertexAttrSizes(vertexAttrSizes);
+ }
+ PointArray p = new PointArray(rt.getVertexCount(),
+ rt.getVertexFormat(),
+ texSetCount,
+ texMap,
+ vertexAttrCount,
+ vertexAttrSizes);
+ p.duplicateNodeComponent(this);
return p;
}
}
diff --git a/src/classes/share/javax/media/j3d/PointArrayRetained.java b/src/classes/share/javax/media/j3d/PointArrayRetained.java
index b06e410..319a643 100644
--- a/src/classes/share/javax/media/j3d/PointArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/PointArrayRetained.java
@@ -25,13 +25,15 @@ class PointArrayRetained extends GeometryArrayRetained {
this.geoType = GEO_TYPE_POINT_SET;
}
- boolean intersect(PickShape pickShape, double dist[], Point3d iPnt) {
+ boolean intersect(PickShape pickShape, PickInfo.IntersectionInfo iInfo, int flags, Point3d iPnt) {
double sdist[] = new double[1];
double minDist = Double.MAX_VALUE;
double x = 0, y = 0, z = 0;
- Point3d pnt = new Point3d();
+ int count = 0;
+ int minICount = 0;
int i = ((vertexFormat & GeometryArray.BY_REFERENCE) == 0 ?
initialVertexIndex : initialCoordIndex);
+ Point3d pnt = new Point3d();
switch (pickShape.getPickType()) {
case PickShape.PICKRAY:
@@ -39,13 +41,15 @@ class PointArrayRetained extends GeometryArrayRetained {
while (i < validVertexCount) {
getVertexData(i++, pnt);
- if (intersectPntAndRay(pnt, pickRay.origin,
+ count++;
+ if (intersectPntAndRay(pnt, pickRay.origin,
pickRay.direction, sdist)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = pnt.x;
y = pnt.y;
z = pnt.z;
@@ -61,14 +65,16 @@ class PointArrayRetained extends GeometryArrayRetained {
pickSegment.end.z - pickSegment.start.z);
while (i < validVertexCount) {
getVertexData(i++, pnt);
+ count++;
if (intersectPntAndRay(pnt, pickSegment.start,
dir, sdist) &&
(sdist[0] <= 1.0)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = pnt.x;
y = pnt.y;
z = pnt.z;
@@ -84,13 +90,15 @@ class PointArrayRetained extends GeometryArrayRetained {
while (i < validVertexCount) {
getVertexData(i++, pnt);
+ count++;
if (bounds.intersect(pnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
sdist[0] = pickShape.distance(pnt);
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = pnt.x;
y = pnt.y;
z = pnt.z;
@@ -104,13 +112,14 @@ class PointArrayRetained extends GeometryArrayRetained {
while (i < validVertexCount) {
getVertexData(i++, pnt);
-
+ count++;
if (intersectCylinder(pnt, pickCylinder, sdist)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = pnt.x;
y = pnt.y;
z = pnt.z;
@@ -123,13 +132,14 @@ class PointArrayRetained extends GeometryArrayRetained {
while (i < validVertexCount) {
getVertexData(i++, pnt);
-
+ count++;
if (intersectCone(pnt, pickCone, sdist)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = pnt.x;
y = pnt.y;
z = pnt.z;
@@ -145,14 +155,19 @@ class PointArrayRetained extends GeometryArrayRetained {
}
if (minDist < Double.MAX_VALUE) {
- dist[0] = minDist;
+ assert(minICount >=1);
+ int[] vertexIndices = iInfo.getVertexIndices();
+ if (vertexIndices == null) {
+ vertexIndices = new int[1];
+ iInfo.setVertexIndices(vertexIndices);
+ }
+ vertexIndices[0] = minICount - 1;
iPnt.x = x;
iPnt.y = y;
iPnt.z = z;
return true;
}
return false;
-
}
boolean intersect(Point3d[] pnts) {
diff --git a/src/classes/share/javax/media/j3d/PointAttributes.java b/src/classes/share/javax/media/j3d/PointAttributes.java
index 29b9e92..66c4e39 100644
--- a/src/classes/share/javax/media/j3d/PointAttributes.java
+++ b/src/classes/share/javax/media/j3d/PointAttributes.java
@@ -65,6 +65,12 @@ public class PointAttributes extends NodeComponent {
public static final int
ALLOW_ANTIALIASING_WRITE = CapabilityBits.POINT_ATTRIBUTES_ALLOW_ANTIALIASING_WRITE;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_SIZE_READ,
+ ALLOW_ANTIALIASING_READ
+ };
+
/**
* Constructs a PointAttributes object with default parameters.
* The default values are as follows:
@@ -74,6 +80,8 @@ public class PointAttributes extends NodeComponent {
* </ul>
*/
public PointAttributes(){
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -82,8 +90,10 @@ public class PointAttributes extends NodeComponent {
* @param pointAntialiasing flag to set point antialising ON or OFF
*/
public PointAttributes(float pointSize, boolean pointAntialiasing){
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
- ((PointAttributesRetained)this.retained).initPointSize(pointSize);
+ ((PointAttributesRetained)this.retained).initPointSize(pointSize);
((PointAttributesRetained)this.retained).initPointAntialiasingEnable(pointAntialiasing);
}
diff --git a/src/classes/share/javax/media/j3d/PointLight.java b/src/classes/share/javax/media/j3d/PointLight.java
index 3e87f84..147c186 100644
--- a/src/classes/share/javax/media/j3d/PointLight.java
+++ b/src/classes/share/javax/media/j3d/PointLight.java
@@ -80,6 +80,12 @@ public class PointLight extends Light {
public static final int
ALLOW_ATTENUATION_WRITE = CapabilityBits.POINT_LIGHT_ALLOW_ATTENUATION_WRITE;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_POSITION_READ,
+ ALLOW_ATTENUATION_READ
+ };
+
/**
* Constructs a PointLight node with default parameters.
* The default values are as follows:
@@ -89,6 +95,8 @@ public class PointLight extends Light {
* </ul>
*/
public PointLight() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -101,6 +109,10 @@ public class PointLight extends Light {
Point3f position,
Point3f attenuation) {
super(color);
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((PointLightRetained)this.retained).initPosition(position);
((PointLightRetained)this.retained).initAttenuation(attenuation);
}
@@ -117,6 +129,10 @@ public class PointLight extends Light {
Point3f position,
Point3f attenuation) {
super(lightOn, color);
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((PointLightRetained)this.retained).initPosition(position);
((PointLightRetained)this.retained).initAttenuation(attenuation);
}
diff --git a/src/classes/share/javax/media/j3d/PointSound.java b/src/classes/share/javax/media/j3d/PointSound.java
index 1f005eb..4af92dd 100644
--- a/src/classes/share/javax/media/j3d/PointSound.java
+++ b/src/classes/share/javax/media/j3d/PointSound.java
@@ -99,6 +99,13 @@ public class PointSound extends Sound {
public static final int
ALLOW_DISTANCE_GAIN_WRITE = CapabilityBits.POINT_SOUND_ALLOW_DISTANCE_GAIN_WRITE;
+
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_POSITION_READ,
+ ALLOW_DISTANCE_GAIN_READ
+ };
+
/**
* Constructs and initializes a new PointSound node using default
* parameters. The following default values are used:
@@ -111,6 +118,9 @@ public class PointSound extends Sound {
public PointSound() {
// Uses default values defined for Sound and PointSound nodes
super();
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
}
/**
@@ -126,6 +136,10 @@ public class PointSound extends Sound {
float initialGain,
Point3f position) {
super(soundData, initialGain);
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((PointSoundRetained)this.retained).setPosition(position);
}
@@ -144,6 +158,10 @@ public class PointSound extends Sound {
float initialGain,
float posX, float posY, float posZ ) {
super(soundData, initialGain);
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((PointSoundRetained)this.retained).setPosition(posX,posY,posZ);
}
@@ -180,6 +198,10 @@ public class PointSound extends Sound {
super(soundData, initialGain, loopCount, release, continuous,
enable, region, priority );
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((PointSoundRetained)this.retained).setPosition(position);
((PointSoundRetained)this.retained).setDistanceGain(distanceGain);
}
@@ -215,6 +237,10 @@ public class PointSound extends Sound {
super(soundData, initialGain, loopCount, release,
continuous, enable, region, priority );
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((PointSoundRetained)this.retained).setPosition(posX,posY,posZ);
((PointSoundRetained)this.retained).setDistanceGain(distanceGain);
}
@@ -249,6 +275,10 @@ public class PointSound extends Sound {
super(soundData, initialGain, loopCount, release, continuous,
enable, region, priority );
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((PointSoundRetained)this.retained).setPosition(position);
((PointSoundRetained)this.retained).setDistanceGain(
attenuationDistance, attenuationGain);
@@ -286,6 +316,10 @@ public class PointSound extends Sound {
super(soundData, initialGain, loopCount, release,
continuous, enable, region, priority );
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((PointSoundRetained)this.retained).setPosition(posX,posY,posZ);
((PointSoundRetained)this.retained).setDistanceGain(
attenuationDistance, attenuationGain);
diff --git a/src/classes/share/javax/media/j3d/PolygonAttributes.java b/src/classes/share/javax/media/j3d/PolygonAttributes.java
index 25b1269..ec676e2 100644
--- a/src/classes/share/javax/media/j3d/PolygonAttributes.java
+++ b/src/classes/share/javax/media/j3d/PolygonAttributes.java
@@ -146,6 +146,14 @@ public class PolygonAttributes extends NodeComponent {
*/
public static final int CULL_FRONT = 2;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_CULL_FACE_READ,
+ ALLOW_MODE_READ,
+ ALLOW_NORMAL_FLIP_READ,
+ ALLOW_OFFSET_READ
+ };
+
/**
* Constructs a PolygonAttributes object with default parameters.
* The default values are as follows:
@@ -159,6 +167,8 @@ public class PolygonAttributes extends NodeComponent {
*/
public PolygonAttributes() {
// Just use defaults for all attributes
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -216,6 +226,9 @@ public class PolygonAttributes extends NodeComponent {
if (cullFace < CULL_NONE || cullFace > CULL_FRONT)
throw new IllegalArgumentException(J3dI18N.getString("PolygonAttributes12"));
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((PolygonAttributesRetained)this.retained).initPolygonMode(polygonMode);
((PolygonAttributesRetained)this.retained).initCullFace(cullFace);
((PolygonAttributesRetained)this.retained).initPolygonOffset(polygonOffset);
diff --git a/src/classes/share/javax/media/j3d/QuadArray.java b/src/classes/share/javax/media/j3d/QuadArray.java
index 79818d3..ee7ab2f 100644
--- a/src/classes/share/javax/media/j3d/QuadArray.java
+++ b/src/classes/share/javax/media/j3d/QuadArray.java
@@ -25,23 +25,22 @@ public class QuadArray extends GeometryArray {
QuadArray() {}
/**
- * Constructs an empty QuadArray object with the specified
- * number of vertices, and vertex format.
- * @param vertexCount the number of vertex elements in this array
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.
+ * Constructs an empty QuadArray object using the specified
+ * parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
* @exception IllegalArgumentException if vertexCount is less than 4
* or vertexCount is <i>not</i> a multiple of 4
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int)}
+ * for more exceptions that can be thrown
*/
public QuadArray(int vertexCount, int vertexFormat) {
super(vertexCount,vertexFormat);
@@ -51,60 +50,30 @@ public class QuadArray extends GeometryArray {
}
/**
- * Constructs an empty QuadArray object with the specified
- * number of vertices, and vertex format, number of texture coordinate
- * sets, and texture coordinate mapping array.
- *
- * @param vertexCount the number of vertex elements in this array<p>
- *
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.<p>
- *
- * @param texCoordSetCount the number of texture coordinate sets
- * in this GeometryArray object. If <code>vertexFormat</code>
- * does not include one of <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3 or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetCount</code> parameter is not used.<p>
- *
- * @param texCoordSetMap an array that maps texture coordinate
- * sets to texture units. The array is indexed by texture unit
- * number for each texture unit in the associated Appearance
- * object. The values in the array specify the texture coordinate
- * set within this GeometryArray object that maps to the
- * corresponding texture
- * unit. All elements within the array must be less than
- * <code>texCoordSetCount</code>. A negative value specifies that
- * no texture coordinate set maps to the texture unit
- * corresponding to the index. If there are more texture units in
- * any associated Appearance object than elements in the mapping
- * array, the extra elements are assumed to be -1. The same
- * texture coordinate set may be used for more than one texture
- * unit. Each texture unit in every associated Appearance must
- * have a valid source of texture coordinates: either a
- * non-negative texture coordinate set must be specified in the
- * mapping array or texture coordinate generation must be enabled.
- * Texture coordinate generation will take precedence for those
- * texture units for which a texture coordinate set is specified
- * and texture coordinate generation is enabled. If
- * <code>vertexFormat</code> does not include one of
- * <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetMap</code> array is not used.
+ * Constructs an empty QuadArray object using the specified
+ * parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
*
* @exception IllegalArgumentException if vertexCount is less than 4
* or vertexCount is <i>not</i> a multiple of 4
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for more exceptions that can be thrown
*
* @since Java 3D 1.2
*/
@@ -121,6 +90,53 @@ public class QuadArray extends GeometryArray {
}
/**
+ * Constructs an empty QuadArray object using the specified
+ * parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrSizes
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @exception IllegalArgumentException if vertexCount is less than 4
+ * or vertexCount is <i>not</i> a multiple of 4
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for more exceptions that can be thrown
+ *
+ * @since Java 3D 1.4
+ */
+ public QuadArray(int vertexCount,
+ int vertexFormat,
+ int texCoordSetCount,
+ int[] texCoordSetMap,
+ int vertexAttrCount,
+ int[] vertexAttrSizes) {
+
+ super(vertexCount, vertexFormat,
+ texCoordSetCount, texCoordSetMap,
+ vertexAttrCount, vertexAttrSizes);
+
+ if (vertexCount < 4 || ((vertexCount%4) != 0))
+ throw new IllegalArgumentException(J3dI18N.getString("QuadArray0"));
+ }
+
+ /**
* Creates the retained mode QuadArrayRetained object that this
* QuadArray object will point to.
*/
@@ -134,21 +150,26 @@ public class QuadArray extends GeometryArray {
* @deprecated replaced with cloneNodeComponent(boolean forceDuplicate)
*/
public NodeComponent cloneNodeComponent() {
- QuadArrayRetained rt = (QuadArrayRetained) retained;
- int texSetCount = rt.getTexCoordSetCount();
- QuadArray q;
- if (texSetCount == 0) {
- q = new QuadArray(rt.getVertexCount(),
- rt.getVertexFormat());
- } else {
- int texMap[] = new int[rt.getTexCoordSetMapLength()];
- rt.getTexCoordSetMap(texMap);
- q = new QuadArray(rt.getVertexCount(),
- rt.getVertexFormat(),
- texSetCount,
- texMap);
- }
- q.duplicateNodeComponent(this);
+ QuadArrayRetained rt = (QuadArrayRetained) retained;
+ int texSetCount = rt.getTexCoordSetCount();
+ int[] texMap = null;
+ int vertexAttrCount = rt.getVertexAttrCount();
+ int[] vertexAttrSizes = null;
+ if (texSetCount > 0) {
+ texMap = new int[rt.getTexCoordSetMapLength()];
+ rt.getTexCoordSetMap(texMap);
+ }
+ if (vertexAttrCount > 0) {
+ vertexAttrSizes = new int[vertexAttrCount];
+ rt.getVertexAttrSizes(vertexAttrSizes);
+ }
+ QuadArray q = new QuadArray(rt.getVertexCount(),
+ rt.getVertexFormat(),
+ texSetCount,
+ texMap,
+ vertexAttrCount,
+ vertexAttrSizes);
+ q.duplicateNodeComponent(this);
return q;
}
diff --git a/src/classes/share/javax/media/j3d/QuadArrayRetained.java b/src/classes/share/javax/media/j3d/QuadArrayRetained.java
index b33f605..5e95b76 100644
--- a/src/classes/share/javax/media/j3d/QuadArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/QuadArrayRetained.java
@@ -27,14 +27,15 @@ class QuadArrayRetained extends GeometryArrayRetained {
this.geoType = GEO_TYPE_QUAD_SET;
}
- boolean intersect(PickShape pickShape, double dist[], Point3d iPnt) {
+ boolean intersect(PickShape pickShape, PickInfo.IntersectionInfo iInfo, int flags, Point3d iPnt) {
Point3d pnts[] = new Point3d[4];
double sdist[] = new double[1];
double minDist = Double.MAX_VALUE;
double x = 0, y = 0, z = 0;
+ int count = 0;
+ int minICount = 0;
int i = ((vertexFormat & GeometryArray.BY_REFERENCE) == 0 ?
initialVertexIndex : initialCoordIndex);
-
pnts[0] = new Point3d();
pnts[1] = new Point3d();
pnts[2] = new Point3d();
@@ -49,12 +50,14 @@ class QuadArrayRetained extends GeometryArrayRetained {
getVertexData(i++, pnts[1]);
getVertexData(i++, pnts[2]);
getVertexData(i++, pnts[3]);
+ count += 4;
if (intersectRay(pnts, pickRay, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -70,18 +73,19 @@ class QuadArrayRetained extends GeometryArrayRetained {
getVertexData(i++, pnts[1]);
getVertexData(i++, pnts[2]);
getVertexData(i++, pnts[3]);
+ count += 4;
if (intersectSegment(pnts, pickSegment.start,
pickSegment.end, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
}
-
}
}
break;
@@ -93,20 +97,20 @@ class QuadArrayRetained extends GeometryArrayRetained {
getVertexData(i++, pnts[1]);
getVertexData(i++, pnts[2]);
getVertexData(i++, pnts[3]);
-
+ count += 4;
if (intersectBoundingBox(pnts, bbox, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
}
}
}
-
break;
case PickShape.PICKBOUNDINGSPHERE:
BoundingSphere bsphere = (BoundingSphere)
@@ -117,13 +121,14 @@ class QuadArrayRetained extends GeometryArrayRetained {
getVertexData(i++, pnts[1]);
getVertexData(i++, pnts[2]);
getVertexData(i++, pnts[3]);
-
+ count += 4;
if (intersectBoundingSphere(pnts, bsphere, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -141,13 +146,14 @@ class QuadArrayRetained extends GeometryArrayRetained {
getVertexData(i++, pnts[1]);
getVertexData(i++, pnts[2]);
getVertexData(i++, pnts[3]);
-
+ count += 4;
if (intersectBoundingPolytope(pnts, bpolytope, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -163,13 +169,14 @@ class QuadArrayRetained extends GeometryArrayRetained {
getVertexData(i++, pnts[1]);
getVertexData(i++, pnts[2]);
getVertexData(i++, pnts[3]);
-
+ count += 4;
if (intersectCylinder(pnts, pickCylinder, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -185,12 +192,14 @@ class QuadArrayRetained extends GeometryArrayRetained {
getVertexData(i++, pnts[1]);
getVertexData(i++, pnts[2]);
getVertexData(i++, pnts[3]);
+ count += 4;
if (intersectCone(pnts, pickCone, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -206,7 +215,16 @@ class QuadArrayRetained extends GeometryArrayRetained {
}
if (minDist < Double.MAX_VALUE) {
- dist[0] = minDist;
+ assert(minICount >= 4);
+ int[] vertexIndices = iInfo.getVertexIndices();
+ if (vertexIndices == null) {
+ vertexIndices = new int[4];
+ iInfo.setVertexIndices(vertexIndices);
+ }
+ vertexIndices[0] = minICount - 4;
+ vertexIndices[1] = minICount - 3;
+ vertexIndices[2] = minICount - 2;
+ vertexIndices[3] = minICount - 1;
iPnt.x = x;
iPnt.y = y;
iPnt.z = z;
@@ -215,7 +233,7 @@ class QuadArrayRetained extends GeometryArrayRetained {
return false;
}
-
+
// intersect pnts[] with every quad in this object
boolean intersect(Point3d[] pnts) {
Point3d[] points = new Point3d[4];
diff --git a/src/classes/share/javax/media/j3d/Raster.java b/src/classes/share/javax/media/j3d/Raster.java
index d14eaf7..d95fee7 100644
--- a/src/classes/share/javax/media/j3d/Raster.java
+++ b/src/classes/share/javax/media/j3d/Raster.java
@@ -180,6 +180,17 @@ public class Raster extends Geometry {
ALLOW_CLIP_MODE_WRITE = CapabilityBits.RASTER_ALLOW_CLIP_MODE_WRITE;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_POSITION_READ,
+ ALLOW_OFFSET_READ,
+ ALLOW_IMAGE_READ,
+ ALLOW_DEPTH_COMPONENT_READ,
+ ALLOW_SIZE_READ,
+ ALLOW_TYPE_READ,
+ ALLOW_CLIP_MODE_READ
+ };
+
/**
* Constructs a Raster object with default parameters.
* The default values are as follows:
@@ -195,6 +206,8 @@ public class Raster extends Geometry {
* </ul>
*/
public Raster() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -223,6 +236,9 @@ public class Raster extends Geometry {
ImageComponent2D image,
DepthComponent depthComponent) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((RasterRetained)this.retained).setPosition(pos);
((RasterRetained)this.retained).setType(type);
((RasterRetained)this.retained).setSrcOffset(xSrcOffset, ySrcOffset);
@@ -252,6 +268,9 @@ public class Raster extends Geometry {
ImageComponent2D image,
DepthComponent depthComponent) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((RasterRetained)this.retained).setPosition(pos);
((RasterRetained)this.retained).setType(type);
((RasterRetained)this.retained).setSrcOffset(srcOffset.x, srcOffset.y);
@@ -289,6 +308,9 @@ public class Raster extends Geometry {
ImageComponent2D image,
DepthComponent depthComponent) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((RasterRetained)this.retained).setPosition(pos);
((RasterRetained)this.retained).setType(type);
((RasterRetained)this.retained).setClipMode(clipMode);
diff --git a/src/classes/share/javax/media/j3d/RasterRetained.java b/src/classes/share/javax/media/j3d/RasterRetained.java
index d580cd7..bd591b9 100644
--- a/src/classes/share/javax/media/j3d/RasterRetained.java
+++ b/src/classes/share/javax/media/j3d/RasterRetained.java
@@ -687,9 +687,10 @@ class RasterRetained extends GeometryRetained {
ImageComponentUpdateInfo value) {
}
- boolean intersect(PickShape pickShape, double dist[], Point3d iPnt) {
+ boolean intersect(PickShape pickShape, PickInfo.IntersectionInfo iInfo, int flags, Point3d iPnt) {
return false;
}
+
boolean intersect(Bounds targetBound) {
return false;
}
diff --git a/src/classes/share/javax/media/j3d/RenderBin.java b/src/classes/share/javax/media/j3d/RenderBin.java
index e252bef..23ba119 100644
--- a/src/classes/share/javax/media/j3d/RenderBin.java
+++ b/src/classes/share/javax/media/j3d/RenderBin.java
@@ -46,6 +46,12 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
ArrayList aBinUpdateList = new ArrayList();
/**
+ * List of ShaderBin that are soleUser that
+ * needs to have its components updated @updateObject time
+ */
+ ArrayList sBinUpdateList = new ArrayList();
+
+ /**
* List of TextureBin that are soleUser that
* needs to have its components updated @updateObject time
*/
@@ -95,6 +101,7 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
ArrayList lightBinFreelist = new ArrayList(5);
ArrayList envSetFreelist = new ArrayList(5);
ArrayList attrBinFreelist = new ArrayList(5);
+ ArrayList shaderBinFreelist = new ArrayList(5);
ArrayList textureBinFreelist = new ArrayList(5);
ArrayList renderMoleculeFreelist = new ArrayList(5);
ArrayList transparentInfoFreeList = new ArrayList(5);
@@ -167,6 +174,8 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
*/
View view = null;
+ private Comparator transparencySortComparator = null;
+
ArrayList toBeAddedTextureResourceFreeList = new ArrayList(5);
ArrayList displayListResourceFreeList = new ArrayList(5);
boolean resourceToFree = false;
@@ -526,10 +535,15 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
for (i = 0; i < size; i++) {
AttributeBin abin = (AttributeBin)aBinUpdateList.get(i);
abin.updateNodeComponent();
-
}
}
+ if ((size = sBinUpdateList.size()) > 0) {
+ for (i = 0; i < size; i++) {
+ ShaderBin sbin = (ShaderBin)sBinUpdateList.get(i);
+ sbin.updateNodeComponent();
+ }
+ }
// Update the sole user TextureBins.
if (tbUpdateList.size() > 0) {
@@ -544,12 +558,12 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
// texture in the first texture unit state
for (i = 0; i < size; i++) {
tb = (TextureBin) tbUpdateList.get(i);
- // Bug Id : 4701430 - Have to be sure tb.attributeBin is
+ // Bug Id : 4701430 - Have to be sure tb.shaderBin is
// not equal to null. This is a temporary fix for j3d1.3.
if (((tb.tbFlag & TextureBin.RESORT) != 0) &&
- (tb.attributeBin != null)) {
+ (tb.shaderBin != null)) {
- tb.attributeBin.reInsertTextureBin(tb);
+ tb.shaderBin.reInsertTextureBin(tb);
tb.tbFlag &= ~TextureBin.RESORT;
}
}
@@ -823,7 +837,7 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
continue;
zVal = renderAtom.geometryAtom.centroid[k].distanceSquared(eyeInVworld);
renderAtom.parentTInfo[k].zVal = zVal;
-
+ renderAtom.parentTInfo[k].geometryAtom = renderAtom.geometryAtom;
}
}
@@ -923,7 +937,7 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
}
// lock list of dlist
- // TODO: Instead of copying could we keep 2 arrays
+ // XXXX: Instead of copying could we keep 2 arrays
// and just toggle?
size = dirtyRenderMoleculeList.size();
for (i = 0; i < size; i++) {
@@ -964,7 +978,7 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
RenderAtomListInfo arr[];
RenderAtomListInfo ra;
- // TODO: there is a possible problem in the case of multiple
+ // XXXX: there is a possible problem in the case of multiple
// renderers (i.e., multiple screens). Unless the
// MasterControl sends us a separate message for each
// renderer, we won't create a new display list for renderers
@@ -1125,6 +1139,7 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
rmUpdateList.clear();
ogCIOList.clear();
aBinUpdateList.clear();
+ sBinUpdateList.clear();
tbUpdateList.clear();
removeRenderAtomInRMList.clear();
addOpaqueBin = null;
@@ -1334,6 +1349,10 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
}
}
texIdObj = new Integer(id);
+ // XXXX: The following code seems wrong -- why add it to
+ // the list if it is already there? Maybe one is for the
+ // texture and the other (idential value) is for the
+ // detail texture?
if (cv.textureIdResourceFreeList.contains(texIdObj)) {
cv.textureIdResourceFreeList.add(texIdObj);
dtex.resourceCreationMask[tex.format] &= ~cv.canvasBit;
@@ -1616,8 +1635,13 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
// Texture is always in a sole user position
processTextureChanged((NodeComponentRetained) m.args[0],
(GeometryAtom[])m.args[3],
- m.args);
-
+ m.args);
+ m.decRefcount();
+ break;
+ case J3dMessage.SHADER_APPEARANCE_CHANGED:
+ case J3dMessage.SHADER_ATTRIBUTE_SET_CHANGED:
+ case J3dMessage.SHADER_ATTRIBUTE_CHANGED:
+ processShaderComponentChanged(m.args);
m.decRefcount();
break;
case J3dMessage.RENDERINGATTRIBUTES_CHANGED:
@@ -1695,7 +1719,7 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
updateViewPlatform((ViewPlatformRetained)vp.retained,
((Float)m.args[1]).floatValue());
visQuery = true;
- // TODO : Handle view.visibilityPolicy changed.
+ // XXXX : Handle view.visibilityPolicy changed.
if(((View.VISIBILITY_POLICY_DIRTY != 0) &&
(View.VISIBILITY_DRAW_ALL != view.viewCache.visibilityPolicy)) ||
locale != ((ViewPlatformRetained) (vp.retained)).locale) {
@@ -2050,7 +2074,7 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
RenderAtom ra = null;
TextureBin tb;
- AttributeBin ab;
+ ShaderBin sb;
boolean reInsertNeeded = false;
if (nc.mirror.changedFrequent == 0) {
@@ -2101,9 +2125,9 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
tb.soleUserCompDirty |= TextureBin.SOLE_USER_DIRTY_TA;
} else {
- ab= ra.renderMolecule.textureBin.attributeBin;
+ sb= ra.renderMolecule.textureBin.shaderBin;
ra.renderMolecule.removeRenderAtom(ra);
- reInsertTextureBin(ab, ra);
+ reInsertTextureBin(sb, ra);
}
}
}
@@ -2113,7 +2137,7 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
RenderAtom ra = null;
TextureBin tb;
- AttributeBin ab;
+ ShaderBin sb;
boolean reInsertNeeded = false;
if (nc.mirror.changedFrequent == 0) {
@@ -2164,9 +2188,9 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
tb.soleUserCompDirty |= TextureBin.SOLE_USER_DIRTY_TC;
} else {
- ab= ra.renderMolecule.textureBin.attributeBin;
+ sb= ra.renderMolecule.textureBin.shaderBin;
ra.renderMolecule.removeRenderAtom(ra);
- reInsertTextureBin(ab, ra);
+ reInsertTextureBin(sb, ra);
}
}
}
@@ -2178,7 +2202,7 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
RenderAtom ra = null;
TextureBin tb;
- AttributeBin ab;
+ ShaderBin sb;
boolean reInsertNeeded = false;
int command = ((Integer)args[1]).intValue();
@@ -2275,7 +2299,7 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
GeometryAtom[] gaArr) {
RenderAtom ra = null;
TextureBin tb;
- AttributeBin ab;
+ ShaderBin sb;
boolean mirrorSet = false;
boolean firstTextureBin = true;
@@ -2313,9 +2337,9 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
tb.soleUserCompDirty |= TextureBin.SOLE_USER_DIRTY_TUS;
} else {
- ab= ra.renderMolecule.textureBin.attributeBin;
+ sb = ra.renderMolecule.textureBin.shaderBin;
ra.renderMolecule.removeRenderAtom(ra);
- reInsertTextureBin(ab, ra);
+ reInsertTextureBin(sb, ra);
}
}
}
@@ -2359,7 +2383,7 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
if (ra== null || !ra.inRenderBin())
continue;
if (restructure && !ra.renderMolecule.textureBin.attributeBin.soleUser) {
- EnvironmentSet e= ra.renderMolecule.textureBin.attributeBin.environmentSet;
+ EnvironmentSet e= ra.renderMolecule.textureBin.environmentSet;
ra.renderMolecule.removeRenderAtom(ra);
reInsertAttributeBin(e, ra);
/*
@@ -2400,6 +2424,131 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
}
}
+ /**
+ * This processes a shader component change.
+ */
+ void processShaderComponentChanged(Object[] args) {
+
+ // System.out.println("RenderBin : processShaderComponentChanged");
+
+ int component = ((Integer)args[1]).intValue();
+ int i;
+ GeometryAtom[] gaArr = (GeometryAtom[] )args[3];
+ GeometryAtom ga;
+ RenderAtom ra = null;
+ /* TODO : JADA - Sole user logic is incomplete. Will disable for JavaOne */
+ // Note : args[0] may be a ShaderAppearanceRetained or ShaderAttributeSetRetained
+ //ShaderAppearanceRetained sApp = (ShaderAppearanceRetained) args[0];
+ int start = -1;
+
+
+ // Get the first ra that is visible
+ for (i = 0; (i < gaArr.length && (start < 0)); i++) {
+ ra = gaArr[i].getRenderAtom(view);
+ if (ra== null || !ra.inRenderBin()) {
+ continue;
+ }
+ else {
+ start = i;
+ }
+ }
+ if (start >= 0) {
+
+
+
+ boolean spUpdate =
+ ((component & ShaderAppearanceRetained.SHADER_PROGRAM) != 0);
+ boolean sasUpdate =
+ (((component & ShaderAppearanceRetained.SHADER_ATTRIBUTE_SET) != 0) ||
+ ((component & ShaderAttributeSetRetained.ATTRIBUTE_SET_PUT) != 0) ||
+ ((component & ShaderAttributeSetRetained.ATTRIBUTE_SET_REMOVE) != 0) ||
+ ((component & ShaderAttributeSetRetained.ATTRIBUTE_SET_CLEAR) != 0) ||
+ ((component & ShaderAttributeRetained.SHADER_ATTRIBUTE_VALUE_UPDATE) != 0));
+
+ if (spUpdate) {
+ /* TODO : JADA - Sole user logic is incomplete. Will disable for JavaOne */
+ //if (false && (sApp.mirror.changedFrequent & component) != 0) {
+ if(false) {
+ /*
+ System.out.println("RenderBin : Shader sole user (SHADER_PROGRAM)" +
+ ra.renderMolecule.textureBin.shaderBin);
+ */
+
+ ShaderBin sBin;
+
+ for (i = start; i < gaArr.length; i++) {
+ ra = gaArr[i].getRenderAtom(view);
+ if (ra== null || !ra.inRenderBin())
+ continue;
+
+ sBin = ra.renderMolecule.textureBin.shaderBin;
+
+ if (sBin.componentDirty == 0) {
+ sBinUpdateList.add(sBin);
+ sBin.componentDirty |= ShaderBin.SHADER_PROGRAM_DIRTY;
+ }
+ }
+ } else {
+ /*
+ System.out.println("RenderBin : not soleUser (SHADER_PROGRAM)" +
+ ra.renderMolecule.textureBin.shaderBin);
+ */
+
+ for (i = 0; i < gaArr.length; i++) {
+ ra = gaArr[i].getRenderAtom(view);
+ if (ra== null || !ra.inRenderBin())
+ continue;
+
+ AttributeBin attrBin = ra.renderMolecule.textureBin.attributeBin;
+ ra.renderMolecule.removeRenderAtom(ra);
+ reInsertShaderBin(attrBin, ra);
+ }
+ }
+ } else if (sasUpdate) {
+ /* TODO : JADA - Sole user logic is incomplete. Will disable for JavaOne */
+ //if (false && (sApp.mirror.changedFrequent & component) != 0) {
+ if(false) {
+ /*
+ System.out.println("RenderBin : sole user (SHADER_ATTRIBUTE_SET)" +
+ ra.renderMolecule.textureBin.shaderBin);
+ */
+
+ ShaderBin sBin;
+
+ for (i = 0; i < gaArr.length; i++) {
+ ra = gaArr[i].getRenderAtom(view);
+ if (ra== null || !ra.inRenderBin())
+ continue;
+
+
+ sBin = ra.renderMolecule.textureBin.shaderBin;
+
+ if (sBin.componentDirty == 0) {
+ sBinUpdateList.add(sBin);
+ sBin.componentDirty |= ShaderBin.SHADER_ATTRIBUTE_SET_DIRTY;
+ }
+ }
+ } else {
+ /*
+ System.out.println("RenderBin :not soleUser (SHADER_ATTRIBUTE_SET) " +
+ ra.renderMolecule.textureBin.shaderBin);
+ */
+
+ for (i = 0; i < gaArr.length; i++) {
+ ra = gaArr[i].getRenderAtom(view);
+ if (ra== null || !ra.inRenderBin())
+ continue;
+
+ AttributeBin attrBin = ra.renderMolecule.textureBin.attributeBin;
+ ra.renderMolecule.removeRenderAtom(ra);
+ reInsertShaderBin(attrBin, ra);
+ }
+ }
+ }
+ }
+
+ }
+
void processFogChanged(Object[] args) {
FogRetained fog = (FogRetained)args[0];
@@ -2464,7 +2613,7 @@ class RenderBin extends J3dStructure implements ObjectUpdate {
if ((component & TEXTURE_STATE_CHANGED) != 0) {
- if (((app.changedFrequent & TEXTURE_STATE_CHANGED) != 0) &&
+ if (((app.mirror.changedFrequent & TEXTURE_STATE_CHANGED) != 0) &&
((ra.renderMolecule.textureBin.tbFlag &
TextureBin.SOLE_USER) != 0)) {
@@ -2501,8 +2650,8 @@ System.out.println("renderbin. texture state changed tb not sole user " +
System.out.println("......tb.soleUser= " +
((ra.renderMolecule.textureBin.tbFlag & TextureBin.SOLE_USER) != 0) +
- " app.changedFrequent= " +
- ((app.changedFrequent & TEXTURE_STATE_CHANGED) != 0));
+ " app.mirror.changedFrequent= " +
+ ((app.mirror.changedFrequent & TEXTURE_STATE_CHANGED) != 0));
*/
@@ -2510,9 +2659,9 @@ System.out.println("......tb.soleUser= " +
ra = gaArr[i].getRenderAtom(view);
if (ra== null || !ra.inRenderBin())
continue;
- AttributeBin ab = ra.renderMolecule.textureBin.attributeBin;
+ ShaderBin sb = ra.renderMolecule.textureBin.shaderBin;
ra.renderMolecule.removeRenderAtom(ra);
- reInsertTextureBin(ab, ra);
+ reInsertTextureBin(sb, ra);
}
}
} else if ((component & AppearanceRetained.RENDERING) != 0) {
@@ -2551,7 +2700,7 @@ System.out.println("......tb.soleUser= " +
ra = gaArr[i].getRenderAtom(view);
if (ra== null || !ra.inRenderBin())
continue;
- EnvironmentSet e = ra.renderMolecule.textureBin.attributeBin.environmentSet;
+ EnvironmentSet e = ra.renderMolecule.textureBin.environmentSet;
ra.renderMolecule.removeRenderAtom(ra);
reInsertAttributeBin(e, ra);
}
@@ -2656,7 +2805,7 @@ System.out.println("......tb.soleUser= " +
Object[] users = (Object[])(args[3]);
int i;
- // TODO: Handle other object affected by bounding leaf changes
+ // XXXX: Handle other object affected by bounding leaf changes
for (i = 0; i < users.length; i++) {
LeafRetained leaf = (LeafRetained)users[i];
switch(leaf.nodeType) {
@@ -2725,7 +2874,7 @@ System.out.println("......tb.soleUser= " +
continue;
}
ra.app = ra.geometryAtom.source.appearance;
- e = ra.renderMolecule.textureBin.attributeBin.environmentSet;
+ e = ra.renderMolecule.textureBin.environmentSet;
ra.renderMolecule.removeRenderAtom(ra);
reInsertAttributeBin(e, ra);
}
@@ -2740,7 +2889,7 @@ System.out.println("......tb.soleUser= " +
if (ra.app == ra.geometryAtom.source.otherAppearance)
continue;
ra.app = ra.geometryAtom.source.appearance;
- e = ra.renderMolecule.textureBin.attributeBin.environmentSet;
+ e = ra.renderMolecule.textureBin.environmentSet;
ra.renderMolecule.removeRenderAtom(ra);
reInsertAttributeBin(e, ra);
}
@@ -2793,7 +2942,7 @@ System.out.println("......tb.soleUser= " +
app = saveApp;
}
ra.app = app;
- e = ra.renderMolecule.textureBin.attributeBin.environmentSet;
+ e = ra.renderMolecule.textureBin.environmentSet;
ra.renderMolecule.removeRenderAtom(ra);
reInsertAttributeBin(e, ra);
}
@@ -2860,7 +3009,7 @@ System.out.println("......tb.soleUser= " +
continue;
}
ra.app = ra.geometryAtom.source.appearance;
- e = ra.renderMolecule.textureBin.attributeBin.environmentSet;
+ e = ra.renderMolecule.textureBin.environmentSet;
ra.renderMolecule.removeRenderAtom(ra);
reInsertAttributeBin(e, ra);
}
@@ -2875,7 +3024,7 @@ System.out.println("......tb.soleUser= " +
if (ra.app == ra.geometryAtom.source.otherAppearance)
continue;
ra.app = ra.geometryAtom.source.appearance;
- e = ra.renderMolecule.textureBin.attributeBin.environmentSet;
+ e = ra.renderMolecule.textureBin.environmentSet;
ra.renderMolecule.removeRenderAtom(ra);
reInsertAttributeBin(e, ra);
}
@@ -2926,7 +3075,7 @@ System.out.println("......tb.soleUser= " +
app = saveApp;
}
ra.app = app;
- e = ra.renderMolecule.textureBin.attributeBin.environmentSet;
+ e = ra.renderMolecule.textureBin.environmentSet;
ra.renderMolecule.removeRenderAtom(ra);
reInsertAttributeBin(e, ra);
}
@@ -3243,7 +3392,7 @@ System.out.println("......tb.soleUser= " +
}
}
- void processText3DTransformChanged(Object[] list,
+ private void processText3DTransformChanged(Object[] list,
Object[] transforms,
long referenceTime) {
int i, j, numShapes;
@@ -3290,7 +3439,7 @@ System.out.println("......tb.soleUser= " +
}
- void processOrderedGroupRemoved(J3dMessage m) {
+ private void processOrderedGroupRemoved(J3dMessage m) {
int i, n;
Object[] ogList = (Object[])m.args[0];
Object[] ogChildIdList = (Object[])m.args[1];
@@ -3329,7 +3478,7 @@ System.out.println("......tb.soleUser= " +
}
- void processOrderedGroupInserted(J3dMessage m) {
+ private void processOrderedGroupInserted(J3dMessage m) {
Object[] ogList = (Object[])m.args[0];
Object[] ogChildIdList = (Object[])m.args[1];
Object[] ogOrderedIdList = (Object[])m.args[2];
@@ -3368,7 +3517,7 @@ System.out.println("......tb.soleUser= " +
}
}
- void processTransformChanged(long referenceTime) {
+ private void processTransformChanged(long referenceTime) {
int i, j, k, numRenderMolecules, n;
Shape3DRetained s;
RenderMolecule rm;
@@ -3435,8 +3584,7 @@ System.out.println("......tb.soleUser= " +
else {
app = ra.geometryAtom.source.appearance;
}
- // TODO: Should we do a more extensive equals
- // app?
+ // XXXX: Should we do a more extensive equals app?
if (ra.envSet.equals(ra, lights, fog, modelClip) &&
app == ra.app) {
@@ -3614,7 +3762,7 @@ System.out.println("......tb.soleUser= " +
/**
* This processes a LIGHT change.
*/
- void processLightChanged() {
+ private void processLightChanged() {
int i, j, k, l, n;
LightRetained lt;
EnvironmentSet e;
@@ -3785,7 +3933,7 @@ System.out.println("......tb.soleUser= " +
- void processBgGeometryAtoms(GeometryAtom[] nodes, long referenceTime) {
+ private void processBgGeometryAtoms(GeometryAtom[] nodes, long referenceTime) {
int i;
GeometryAtom ga;
RenderAtom renderAtom;
@@ -3826,7 +3974,7 @@ System.out.println("......tb.soleUser= " +
* This method looks through the list of RenderAtoms to see if
* compaction is needed.
*/
- void checkForCompaction() {
+ private void checkForCompaction() {
int i, numRas;
int numDead = 0;
int numAlive = 0;
@@ -3879,7 +4027,7 @@ System.out.println("......tb.soleUser= " +
}
- void reEvaluateAlternateAppearance() {
+ private void reEvaluateAlternateAppearance() {
AppearanceRetained app;
EnvironmentSet e;
Object[] retVal;
@@ -3924,7 +4072,7 @@ System.out.println("......tb.soleUser= " +
}
- void reEvaluateAllRenderAtoms(boolean altAppDirty) {
+ private void reEvaluateAllRenderAtoms(boolean altAppDirty) {
int sz = renderAtoms.size();
@@ -3966,7 +4114,7 @@ System.out.println("......tb.soleUser= " +
// If the lights/fog/model_clip of the render atom is the same
// as the old set of lights/fog/model_clip, then move on to the
// next renderAtom
- // TODO: Should app test for equivalent?
+ // XXXX: Should app test for equivalent?
if (ra.envSet.equals(ra, lights, newfog, newModelClip) &&
app == ra.app)
continue;
@@ -3996,7 +4144,7 @@ System.out.println("......tb.soleUser= " +
- void getNewEnvironment(RenderAtom ra, LightRetained[] lights,
+ private void getNewEnvironment(RenderAtom ra, LightRetained[] lights,
FogRetained fog, ModelClipRetained modelClip,
AppearanceRetained app) {
@@ -4176,28 +4324,36 @@ System.out.println("......tb.soleUser= " +
reInsertAttributeBin(eNew, ra);
}
- void reInsertAttributeBin(EnvironmentSet e, RenderAtom ra) {
+
+ private void reInsertAttributeBin(EnvironmentSet e, RenderAtom ra) {
AttributeBin ab;
// Just go up to the environment and re-insert
ab = findAttributeBin(e, ra);
- reInsertTextureBin(ab, ra);
+ reInsertShaderBin(ab, ra);
}
+ private void reInsertShaderBin(AttributeBin ab, RenderAtom ra) {
+ ShaderBin sb;
+
+ // System.out.println("RenderBin.reInsertShaderBin() ra= " + ra);
+ sb = findShaderBin(ab, ra);
+ reInsertTextureBin(sb, ra);
+ }
- void reInsertTextureBin(AttributeBin ab, RenderAtom ra) {
+ private void reInsertTextureBin(ShaderBin sb, RenderAtom ra) {
TextureBin tb;
- tb = findTextureBin(ab, ra);
+ tb = findTextureBin(sb, ra);
reInsertRenderAtom(tb, ra);
}
- void reInsertRenderAtom(TextureBin tb, RenderAtom ra) {
+ private void reInsertRenderAtom(TextureBin tb, RenderAtom ra) {
RenderMolecule newRm;
// Just go up to the texture bin and re-insert
newRm = findRenderMolecule(tb, ra);
}
- void computeViewFrustumBBox(BoundingBox viewFrustumBBox) {
+ private void computeViewFrustumBBox(BoundingBox viewFrustumBBox) {
//Initial view frustumBBox BBox
viewFrustumBBox.lower.x = Float.POSITIVE_INFINITY;
viewFrustumBBox.lower.y = Float.POSITIVE_INFINITY;
@@ -4241,10 +4397,11 @@ System.out.println("......tb.soleUser= " +
/**
* This inserts a RenderAtom into the appropriate bin.
*/
- RenderMolecule insertRenderAtom(RenderAtom ra) {
+ private RenderMolecule insertRenderAtom(RenderAtom ra) {
LightBin lightBin;
EnvironmentSet environmentSet;
AttributeBin attributeBin;
+ ShaderBin shaderBin;
TextureBin textureBin;
RenderMolecule renderMolecule;
OrderedCollection oc;
@@ -4301,7 +4458,11 @@ System.out.println("......tb.soleUser= " +
// determined
environmentSet = findEnvironmentSet(ra);
attributeBin = findAttributeBin(environmentSet, ra);
- textureBin = findTextureBin(attributeBin, ra);
+
+ // System.out.println("RenderBin : findShaderBin()");
+ shaderBin = findShaderBin(attributeBin, ra);
+
+ textureBin = findTextureBin(shaderBin, ra);
renderMolecule = findRenderMolecule(textureBin, ra);
ra.setRenderBin(true);
renderAtoms.add(ra);
@@ -4347,7 +4508,7 @@ System.out.println("......tb.soleUser= " +
return (renderMolecule);
}
- OrderedCollection findOrderedCollection(GeometryAtom ga,
+ private OrderedCollection findOrderedCollection(GeometryAtom ga,
boolean doBackground) {
int i, n;
int oi; // an id which identifies a children of the orderedGroup
@@ -4509,7 +4670,7 @@ System.out.println("......tb.soleUser= " +
return (oc);
}
- void removeOrderedHeadLightBin(LightBin lightBin) {
+ private void removeOrderedHeadLightBin(LightBin lightBin) {
int i, k;
int oi; // an id which identifies a children of the orderedGroup
int ci; // child index of the ordered group
@@ -4541,7 +4702,7 @@ System.out.println("......tb.soleUser= " +
* This gets a new EnviornmentSet. It creates one if there are none
* on the freelist.
*/
- EnvironmentSet getEnvironmentSet(RenderAtom ra, LightRetained[] lights,
+ private EnvironmentSet getEnvironmentSet(RenderAtom ra, LightRetained[] lights,
FogRetained fog, ModelClipRetained modelClip) {
EnvironmentSet envSet;
@@ -4554,10 +4715,11 @@ System.out.println("......tb.soleUser= " +
}
return (envSet);
}
+
/**
* This finds or creates an AttributeBin for a given RenderAtom.
*/
- AttributeBin findAttributeBin(EnvironmentSet envSet, RenderAtom ra) {
+ private AttributeBin findAttributeBin(EnvironmentSet envSet, RenderAtom ra) {
int i;
AttributeBin currentBin;
RenderingAttributesRetained renderingAttributes;
@@ -4566,7 +4728,6 @@ System.out.println("......tb.soleUser= " +
} else {
renderingAttributes = ra.app.renderingAttributes;
}
-
currentBin = envSet.attributeBinList;
while (currentBin != null) {
@@ -4575,7 +4736,6 @@ System.out.println("......tb.soleUser= " +
}
currentBin = currentBin.next;
}
-
// Check the "to-be-added" list of attributeBins for a match
for (i = 0; i < envSet.addAttributeBins.size(); i++) {
currentBin = (AttributeBin)envSet.addAttributeBins.get(i);
@@ -4583,59 +4743,88 @@ System.out.println("......tb.soleUser= " +
return(currentBin);
}
}
-
currentBin = getAttributeBin(ra.app, renderingAttributes);
envSet.addAttributeBin(currentBin, this);
return(currentBin);
}
/**
- * This finds or creates a TextureBin for a given RenderAtom.
+ * This finds or creates an ShaderBin for a given RenderAtom.
*/
- TextureBin findTextureBin(AttributeBin attributeBin, RenderAtom ra) {
+ private ShaderBin findShaderBin(AttributeBin attributeBin, RenderAtom ra) {
+ int i, size;
+ ShaderBin currentBin;
+ ShaderAppearanceRetained sApp;
+ if((ra != null) && (ra.app instanceof ShaderAppearanceRetained))
+ sApp = (ShaderAppearanceRetained)ra.app;
+ else
+ sApp = null;
- int i;
+ currentBin = attributeBin.shaderBinList;
+ while (currentBin != null) {
+ if (currentBin.equals(sApp)) {
+ return currentBin;
+ }
+ currentBin = currentBin.next;
+ }
+
+ // Check the "to-be-added" list of shaderBins for a match
+ size = attributeBin.addShaderBins.size();
+ for (i = 0; i < size; i++) {
+ currentBin = (ShaderBin)attributeBin.addShaderBins.get(i);
+ if (currentBin.equals(sApp)) {
+ return currentBin;
+ }
+ }
+
+ currentBin = getShaderBin(sApp);
+ attributeBin.addShaderBin(currentBin, this, sApp);
+ return currentBin;
+ }
+
+ /**
+ * This finds or creates a TextureBin for a given RenderAtom.
+ */
+ private TextureBin findTextureBin(ShaderBin shaderBin, RenderAtom ra) {
+ int i, size;
TextureBin currentBin;
TextureRetained texture;
TextureUnitStateRetained texUnitState[];
- RenderingAttributesRetained rAttrs =
- (ra.geometryAtom.source.appearance == null)? null:
- ra.geometryAtom.source.appearance.renderingAttributes;
-
if (ra.app == null) {
texUnitState = null;
} else {
texUnitState = ra.app.texUnitState;
}
- currentBin = attributeBin.textureBinList;
+ currentBin = shaderBin.textureBinList;
while (currentBin != null) {
if (currentBin.equals(texUnitState, ra)) {
- //System.out.println("1: Equal");
+ //System.out.println("1: Equal");
return(currentBin);
}
currentBin = currentBin.next;
}
// Check the "to-be-added" list of TextureBins for a match
- for (i = 0; i < attributeBin.addTBs.size(); i++) {
- currentBin = (TextureBin)attributeBin.addTBs.get(i);
+ size = shaderBin.addTextureBins.size();
+ for (i = 0; i < size; i++) {
+ currentBin = (TextureBin)shaderBin.addTextureBins.get(i);
if (currentBin.equals(texUnitState, ra)) {
- //System.out.println("2: Equal");
+ //System.out.println("2: Equal");
return(currentBin);
}
}
// get a new texture bin for this texture unit state
currentBin = getTextureBin(texUnitState, ra.app);
- attributeBin.addTextureBin(currentBin, this, ra);
+ shaderBin.addTextureBin(currentBin, this, ra);
return(currentBin);
}
/**
* This finds or creates a RenderMolecule for a given RenderAtom.
*/
- RenderMolecule findRenderMolecule(TextureBin textureBin,
+ private RenderMolecule findRenderMolecule(TextureBin textureBin,
RenderAtom ra) {
RenderMolecule currentBin;
@@ -4691,7 +4880,7 @@ System.out.println("......tb.soleUser= " +
ra.geometryAtom.source.localToVworld[0])) {
currentBin.addRenderAtom(ra, this);
- ra.envSet = ra.renderMolecule.textureBin.attributeBin.environmentSet;
+ ra.envSet = ra.renderMolecule.textureBin.environmentSet;
// If the locale has changed for an existing renderMolecule
// handle the RmlocaleToVworld
return(currentBin);
@@ -4731,12 +4920,26 @@ System.out.println("......tb.soleUser= " +
return(currentBin);
}
+ /**
+ * This gets a new ShaderBin. It creates one if there are none
+ * on the freelist.
+ */
+ private ShaderBin getShaderBin(ShaderAppearanceRetained sApp) {
+ ShaderBin shaderBin;
+ if (shaderBinFreelist.size() > 0) {
+ shaderBin = (ShaderBin)shaderBinFreelist.remove(shaderBinFreelist.size()-1);
+ shaderBin.reset(sApp, this);
+ } else {
+ shaderBin = new ShaderBin( sApp, this);
+ }
+ return (shaderBin);
+ }
/**
* This gets a new AttributeBin. It creates one if there are none
* on the freelist.
*/
- AttributeBin getAttributeBin(AppearanceRetained app, RenderingAttributesRetained ra) {
+ private AttributeBin getAttributeBin(AppearanceRetained app, RenderingAttributesRetained ra) {
AttributeBin attrBin;
if (attrBinFreelist.size() > 0) {
attrBin = (AttributeBin)attrBinFreelist.remove(
@@ -4754,7 +4957,7 @@ System.out.println("......tb.soleUser= " +
* This gets a new LightBin. It creates one if there are none
* on the freelist.
*/
- LightBin getLightBin(int maxLights, BackgroundRetained bg, boolean inOpaque) {
+ private LightBin getLightBin(int maxLights, BackgroundRetained bg, boolean inOpaque) {
LightBin lightBin;
if (lightBinFreelist.size() > 0) {
@@ -4772,7 +4975,7 @@ System.out.println("......tb.soleUser= " +
* This gets a new TextureBin. It creates one if there are none
* on the freelist.
*/
- TextureBin getTextureBin(TextureUnitStateRetained texUnitState[],
+ private TextureBin getTextureBin(TextureUnitStateRetained texUnitState[],
AppearanceRetained app) {
TextureBin textureBin;
@@ -4791,7 +4994,7 @@ System.out.println("......tb.soleUser= " +
* This gets a new RenderMolecule. It creates one if there are none
* on the freelist.
*/
- RenderMolecule getRenderMolecule(GeometryAtom ga,
+ private RenderMolecule getRenderMolecule(GeometryAtom ga,
PolygonAttributesRetained polya,
LineAttributesRetained linea,
PointAttributesRetained pointa,
@@ -4823,7 +5026,7 @@ System.out.println("......tb.soleUser= " +
* This finds or creates an EnviornmentSet for a given RenderAtom.
* This also deals with empty LightBin lists.
*/
- EnvironmentSet findEnvironmentSet(RenderAtom ra) {
+ private EnvironmentSet findEnvironmentSet(RenderAtom ra) {
LightBin currentBin, lightBin ;
EnvironmentSet currentEnvSet, newBin;
int i;
@@ -5040,9 +5243,9 @@ System.out.println("......tb.soleUser= " +
*/
void renderOpaque(Canvas3D cv) {
LightBin currentBin = opaqueBin;
- // System.out.println("========> renderOpaque");
+ //System.out.println("========> renderOpaque");
while (currentBin != null) {
- // System.out.println("====> rendering Opaque Bin ");
+ //System.out.println("====> rendering Opaque Bin ");
currentBin.render(cv);
currentBin = currentBin.next;
}
@@ -5055,9 +5258,10 @@ System.out.println("......tb.soleUser= " +
void renderTransparent(Canvas3D cv) {
boolean savedDepthBufferWriteEnable = true;
+ //System.out.println("====> renderTransparent");
TransparentRenderingInfo tinfo = transparentInfo;
if (tinfo != null) {
- // System.out.println("====> rendering transparent Bin");
+ //System.out.println("====> rendering transparent Bin");
if (cv.view.depthBufferFreezeTransparent) {
cv.setDepthBufferWriteEnableOverride(true);
@@ -5110,9 +5314,7 @@ System.out.println("......tb.soleUser= " +
OrderedCollection oc;
boolean depthBufferEnable = true;
OrderedGroupRetained og = orderedBin.source;
- boolean isDecal = (og instanceof DecalGroupRetained) &&
- ((cv.extensionsSupported & Canvas3D.STENCIL_BUFFER) != 0);
-
+ boolean isDecal = (og instanceof DecalGroupRetained) && cv.systemStencilAvailable;
int size = orderedBin.orderedCollections.size();
// System.out.println("RB : orderedBin.orderedCollections.size() " + size);
@@ -5198,9 +5400,14 @@ System.out.println("......tb.soleUser= " +
Canvas3D canvases[] = view.getCanvases();
for (int i=0; i< canvases.length; i++) {
Canvas3D canvas = canvases[i];
- if(cvDirty)
- canvas.cvDirtyMask |= Canvas3D.BACKGROUND_DIRTY;
- canvas.cvDirtyMask |= Canvas3D.BACKGROUND_IMAGE_DIRTY;
+ synchronized (canvas.dirtyMaskLock) {
+ if(cvDirty) {
+ canvas.cvDirtyMask[0] |= Canvas3D.BACKGROUND_DIRTY;
+ canvas.cvDirtyMask[1] |= Canvas3D.BACKGROUND_DIRTY;
+ }
+ canvas.cvDirtyMask[0] |= Canvas3D.BACKGROUND_IMAGE_DIRTY;
+ canvas.cvDirtyMask[1] |= Canvas3D.BACKGROUND_IMAGE_DIRTY;
+ }
}
}
@@ -5801,6 +6008,7 @@ System.out.println("......tb.soleUser= " +
lightBinFreelist.clear();
envSetFreelist.clear();
attrBinFreelist.clear();
+ shaderBinFreelist.clear();
textureBinFreelist.clear();
renderMoleculeFreelist.clear();
@@ -5848,22 +6056,26 @@ System.out.println("......tb.soleUser= " +
AttributeBin abin = envSet.attributeBinList;
while (abin != null) {
System.out.println(" ABin = "+abin);
- TextureBin tbin = abin.textureBinList;
- while (tbin != null) {
- System.out.println(" Tbin = "+tbin);
- RenderMolecule rm = tbin.opaqueRMList;
- System.out.println("===> Begin Dumping OpaqueBin");
- dumpRM(rm);
- System.out.println("===> End Dumping OpaqueBin");
- rm = tbin.transparentRMList;
- System.out.println("===> Begin Dumping transparentBin");
- dumpRM(rm);
- System.out.println("===> End Dumping transparentBin");
- tbin = tbin.next;
+ ShaderBin sbin = abin.shaderBinList;
+ while (sbin != null) {
+ System.out.println(" SBin = "+sbin);
+ TextureBin tbin = sbin.textureBinList;
+ while (tbin != null) {
+ System.out.println(" Tbin = "+tbin);
+ RenderMolecule rm = tbin.opaqueRMList;
+ System.out.println("===> Begin Dumping OpaqueBin");
+ dumpRM(rm);
+ System.out.println("===> End Dumping OpaqueBin");
+ rm = tbin.transparentRMList;
+ System.out.println("===> Begin Dumping transparentBin");
+ dumpRM(rm);
+ System.out.println("===> End Dumping transparentBin");
+ tbin = tbin.next;
+ }
+ sbin = sbin.next;
}
abin = abin.next;
}
-
envSet = envSet.next;
}
obin = obin.next;
@@ -5914,7 +6126,7 @@ System.out.println("......tb.soleUser= " +
// System.out.println("&&&&&&&&&&&&removeTransparentObject r = "+obj);
if (obj instanceof TextureBin) {
TextureBin tb = (TextureBin) obj;
- if (tb.attributeBin.environmentSet.lightBin.geometryBackground != null) {
+ if (tb.environmentSet.lightBin.geometryBackground != null) {
TransparentRenderingInfo t = tb.parentTInfo;
// Remove the element from the transparentInfo struct
@@ -6018,7 +6230,7 @@ System.out.println("......tb.soleUser= " +
if (obj instanceof TextureBin) {
TextureBin tb = (TextureBin) obj;
// Background geometry
- if (tb.attributeBin.environmentSet.lightBin.geometryBackground != null) {
+ if (tb.environmentSet.lightBin.geometryBackground != null) {
bgTransparentInfo = computeDirtyAcrossTransparentBins(tb, bgTransparentInfo);
}
else {
@@ -6063,8 +6275,8 @@ System.out.println("......tb.soleUser= " +
TransparentRenderingInfo computeDirtyAcrossTransparentBins(TextureBin tb, TransparentRenderingInfo startinfo) {
TransparentRenderingInfo tinfo = getTransparentInfo();
/*
- tinfo.lightBin = tb.attributeBin.environmentSet.lightBin;
- tinfo.envSet = tb.attributeBin.environmentSet;
+ tinfo.lightBin = tb.environmentSet.lightBin;
+ tinfo.envSet = tb.environmentSet;
tinfo.aBin = tb.attributeBin;
*/
tinfo.rm = tb.transparentRMList;
@@ -6257,7 +6469,16 @@ System.out.println("......tb.soleUser= " +
zval1 = input1.zVal;
zval2 = input2.zVal;
// Put the newList before the current one
- if (zval2 > zval1) {
+
+// System.out.print("Code path 1 ");
+// if (transparencySortComparator!=null)
+// if (zval2 > zval1 && (transparencySortComparator.compare(input2, input1)>0))
+// System.out.println("PASS");
+// else
+// System.out.println("FAIL");
+
+ if ((transparencySortComparator==null && zval2 > zval1) ||
+ (transparencySortComparator!=null && (transparencySortComparator.compare(input2, input1)>0))){
// System.out.println("===> path1");
if (input1.prev == null) {
input1.prev = input2;
@@ -6293,38 +6514,48 @@ System.out.println("......tb.soleUser= " +
return oldList;
}
- void insertDepthSort(RenderAtom r) {
- TransparentRenderingInfo tinfo = null;
- // System.out.println("&&&&&&&&insertDepthSort");
- for (int i = 0; i < r.rListInfo.length; i++) {
- if (r.parentTInfo[i] == null)
- continue;
-
- if (transparentInfo == null) {
- transparentInfo = r.parentTInfo[i];
- transparentInfo.prev = null;
- transparentInfo.next = null;
- }
- else {
- tinfo = transparentInfo;
- TransparentRenderingInfo prevInfo = transparentInfo;
- while (tinfo != null&& r.parentTInfo[i].zVal < tinfo.zVal) {
- prevInfo = tinfo;
- tinfo = tinfo.next;
- }
- r.parentTInfo[i].prev = prevInfo;
- if (prevInfo.next != null) {
- prevInfo.next.prev = r.parentTInfo[i];
- }
- r.parentTInfo[i].next = prevInfo.next;
- prevInfo.next = r.parentTInfo[i];
-
- }
-
- }
- }
-
-
+// void insertDepthSort(RenderAtom r) {
+// TransparentRenderingInfo tinfo = null;
+// // System.out.println("&&&&&&&&insertDepthSort");
+// for (int i = 0; i < r.rListInfo.length; i++) {
+// if (r.parentTInfo[i] == null)
+// continue;
+//
+// if (transparentInfo == null) {
+// transparentInfo = r.parentTInfo[i];
+// transparentInfo.prev = null;
+// transparentInfo.next = null;
+// }
+// else {
+// tinfo = transparentInfo;
+// TransparentRenderingInfo prevInfo = transparentInfo;
+// if (transparencySortComparator==null)
+// while (tinfo != null && r.parentTInfo[i].zVal < tinfo.zVal) {
+// prevInfo = tinfo;
+// tinfo = tinfo.next;
+// }
+// else {
+// System.out.println("Code Path 2 ");
+// if (tinfo!=null && (transparencySortComparator.compare(r.parentTInfo[i], tinfo)<0)==r.parentTInfo[i].zVal < tinfo.zVal)
+// System.out.println("PASS");
+// else
+// System.out.println("FAIL");
+// while (tinfo != null && transparencySortComparator.compare(r.parentTInfo[i], tinfo)<0) {
+// prevInfo = tinfo;
+// tinfo = tinfo.next;
+// }
+// }
+// r.parentTInfo[i].prev = prevInfo;
+// if (prevInfo.next != null) {
+// prevInfo.next.prev = r.parentTInfo[i];
+// }
+// r.parentTInfo[i].next = prevInfo.next;
+// prevInfo.next = r.parentTInfo[i];
+//
+// }
+//
+// }
+// }
TransparentRenderingInfo collectDirtyTRInfo( TransparentRenderingInfo dirtyList,
RenderAtom r) {
@@ -6371,6 +6602,7 @@ System.out.println("......tb.soleUser= " +
TransparentRenderingInfo depthSortAll(TransparentRenderingInfo startinfo) {
+ transparencySortComparator = com.sun.j3d.utils.scenegraph.transparency.TransparencySortController.getComparator(view);
TransparentRenderingInfo tinfo, previnfo, nextinfo;
double curZ;
// System.out.println("&&&&&&&&&&&depthSortAll");
@@ -6390,10 +6622,21 @@ System.out.println("......tb.soleUser= " +
previnfo = tinfo.prev;
// Find the correct location for tinfo
- while (previnfo != null && previnfo.zVal < curZ) {
- previnfo = previnfo.prev;
-
- }
+ if (transparencySortComparator==null) {
+ while (previnfo != null && previnfo.zVal < curZ) {
+ previnfo = previnfo.prev;
+ }
+ } else {
+// System.out.println("Code Path 3 ");
+// if (tinfo!=null && (transparencySortComparator.compare(previnfo, tinfo)<0)==previnfo.zVal < curZ)
+// System.out.println("PASS");
+// else
+// System.out.println("FAIL");
+ while (previnfo != null && transparencySortComparator.compare(previnfo,tinfo)<0) {
+ previnfo = previnfo.prev;
+ }
+ }
+
if (tinfo.prev != previnfo) {
if (previnfo == null) {
if (tinfo.next != null) {
@@ -6764,7 +7007,7 @@ System.out.println("......tb.soleUser= " +
// context creation bits for this canvas, but don't do anything
// with the geo's user list.
if (geo.dlistId > 0) {
- // TODO: for the shared ctx case, we really should
+ // XXXX: for the shared ctx case, we really should
// only free the display lists if this is the last
// Canvas in the renderer. However, since the
// display lists will be recreated, it doesn't
@@ -6936,14 +7179,14 @@ System.out.println("......tb.soleUser= " +
if (ra== null || !ra.inRenderBin())
continue;
- EnvironmentSet e= ra.renderMolecule.textureBin.attributeBin.environmentSet;
+ EnvironmentSet e= ra.renderMolecule.textureBin.environmentSet;
ra.renderMolecule.removeRenderAtom(ra);
reInsertAttributeBin(e, ra);
}
}
else {
- // TODO: handle texture
+ // XXXX: handle texture
}
diff --git a/src/classes/share/javax/media/j3d/RenderMolecule.java b/src/classes/share/javax/media/j3d/RenderMolecule.java
index d52cd93..61672cf 100644
--- a/src/classes/share/javax/media/j3d/RenderMolecule.java
+++ b/src/classes/share/javax/media/j3d/RenderMolecule.java
@@ -45,7 +45,7 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
AppearanceRetained.TRANSPARENCY|
AppearanceRetained.COLOR);
- // TODO: use definingMaterial etc. instead of these
+ // XXXX: use definingMaterial etc. instead of these
// when sole user is completely implement
PolygonAttributesRetained polygonAttributes = null;
LineAttributesRetained lineAttributes = null;
@@ -740,7 +740,7 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
k++;
}
- // TODO: Add tags
+ // XXXX: Add tags
switch (ga.geoType) {
case GeometryRetained.GEO_TYPE_POINT_SET:
case GeometryRetained.GEO_TYPE_INDEXED_POINT_SET:
@@ -788,7 +788,7 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
return (false);
}
/*
- // TODO : Check this
+ // XXXX : Check this
if (useDisplayList &&
(ga.geometry.isEditable ||
ga.geometry.refCount > 1 ||
@@ -811,7 +811,7 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
return (false);
}
- // TODO: Its is necessary to have same vformat for dl,
+ // XXXX: Its is necessary to have same vformat for dl,
// Howabout iteration, should we have 2 vformats in rm?
if (geo instanceof GeometryArrayRetained) {
GeometryArrayRetained gr = (GeometryArrayRetained)geo;
@@ -845,7 +845,7 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
return (false);
}
} else {
- //TODO: compare isEditable
+ //XXXX: compare isEditable
if (this.vertexFormat != -1) {
return (false);
}
@@ -1143,7 +1143,7 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
renderBin.orientedRAs.remove(renderBin.orientedRAs.indexOf(r));
}
- if ((textureBin.attributeBin.environmentSet.lightBin.geometryBackground == null) &&
+ if ((textureBin.environmentSet.lightBin.geometryBackground == null) &&
!isOpaqueOrInOG && renderBin.transpSortMode == View.TRANSPARENCY_SORT_GEOMETRY) {
renderBin.removeTransparentObject(r);
}
@@ -1318,7 +1318,7 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
}
// If transparent and not in bg geometry and is depth sorted transparency
- if (!isOpaqueOrInOG && (textureBin.attributeBin.environmentSet.lightBin.geometryBackground == null)&&
+ if (!isOpaqueOrInOG && (textureBin.environmentSet.lightBin.geometryBackground == null)&&
(renderBin.transpSortMode == View.TRANSPARENCY_SORT_GEOMETRY)) {
GeometryRetained geo = null;
int k = 0;
@@ -1401,36 +1401,11 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
}
boolean canBeInDisplayList(GeometryRetained geo, GeometryAtom ga) {
- boolean inDL = false;
- inDL = geo.canBeInDisplayList(ga.alphaEditable);
- // If can not in DL, then check if all the attrs affecting
- // it are infrequently changing, if yes then put it
- // Exclude Morph and indexed-by-ref-use-index-coord only for now
- // in displayList if OptimizeForSpace if false
-
- // System.out.println("inDL = "+inDL);
- // System.out.println("geo.cachedChangedFrequent = "+geo.cachedChangedFrequent);
- // System.out.println("inDL = "+inDL);
- // System.out.println("COLOR = "+((((GeometryArrayRetained)geo).vertexFormat&
- // GeometryArray.COLOR) != 0));
- // System.out.println("Before: inDL = "+inDL);
- // System.out.println("VirtualUniverse.mc.buildDisplayListIfPossible = "+VirtualUniverse.mc.buildDisplayListIfPossible);
- if (VirtualUniverse.mc.buildDisplayListIfPossible &&
- !inDL &&
- !(ga.source.sourceNode instanceof MorphRetained ||
- (geo instanceof GeometryArrayRetained &&
- ((((GeometryArrayRetained)geo).vertexFormat & (GeometryArray.USE_NIO_BUFFER|GeometryArray.INTERLEAVED)) ==(GeometryArray.USE_NIO_BUFFER|GeometryArray.INTERLEAVED))) ||
- (geo instanceof IndexedGeometryArrayRetained &&
- ((((IndexedGeometryArrayRetained)geo).vertexFormat & (GeometryArray.BY_REFERENCE|GeometryArray.USE_COORD_INDEX_ONLY)) == (GeometryArray.BY_REFERENCE|GeometryArray.USE_COORD_INDEX_ONLY))))) {
- // Check if geometry is frequentlyEditable
- boolean alphaFreqEditable = ga.source.isAlphaFrequentlyEditable(geo);
- inDL = !((geo.cachedChangedFrequent != 0) ||
- ((!(geo instanceof GeometryArrayRetained) && alphaFreqEditable)||
- (alphaFreqEditable && ((((GeometryArrayRetained)geo).vertexFormat&
- GeometryArray.COLOR) != 0))));
- }
- // System.out.println("After: inDL = "+inDL);
- return inDL;
+ if (ga.source.sourceNode instanceof MorphRetained) {
+ return false;
+ }
+
+ return geo.canBeInDisplayList(ga.alphaEditable);
}
// If dlist will be altered due to alpha or ignoreVertexColors, then don't
@@ -1498,7 +1473,7 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
RenderAtomListInfo r;
int index;
- renderAtom.envSet = textureBin.attributeBin.environmentSet;
+ renderAtom.envSet = textureBin.environmentSet;
renderAtom.renderMolecule = this;
renderAtom.dirtyMask &= ~RenderAtom.NEED_SEPARATE_LOCALE_VWC_BOUNDS;
@@ -1732,8 +1707,6 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
void evalAlphaUsage(RenderingAttributesRetained renderAttrs,
TextureUnitStateRetained[] texUnits) {
- RenderingAttributesRetained ra;
- TextureAttributesRetained ta;
boolean alphaBlend, alphaTest, textureBlend = false;
alphaBlend =
@@ -1847,7 +1820,7 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
// we'll have to punt to vertex array as well.
if ((pass != TextureBin.USE_DISPLAYLIST) ||
- (texCoordSetMapLen > cv.numTexCoordSupported) ||
+ (texCoordSetMapLen > cv.maxTexCoordSets) ||
(VirtualUniverse.mc.isD3D() &&
(((definingPolygonAttributes != null) &&
((isQuadGeometryArray &&
@@ -1862,7 +1835,7 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
/*
System.out.println("texCoord " + texCoordSetMapLen + " " +
- cv.numTexCoordSupported + " " + modeSupportDL);
+ cv.maxTexCoordSets + " " + modeSupportDL);
System.out.println("primaryMoleculeType = "+primaryMoleculeType+" primaryRenderAtomList ="+primaryRenderAtomList+" separateDlistRenderAtomList ="+separateDlistRenderAtomList+" vertexArrayRenderAtomList ="+vertexArrayRenderAtomList);
*/
@@ -1934,7 +1907,7 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
}
- // TODO: In the case of independent primitives such as quads,
+ // XXXX: In the case of independent primitives such as quads,
// it would still be better to call multi draw arrays
if (vertexArrayRenderAtomList != null) {
if (pass == TextureBin.USE_DISPLAYLIST) {
@@ -2171,7 +2144,7 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
// instead.
if ((pass != TextureBin.USE_DISPLAYLIST) ||
- (texCoordSetMapLen > cv.numTexCoordSupported) ||
+ (texCoordSetMapLen > cv.maxTexCoordSets) ||
(VirtualUniverse.mc.isD3D() &&
(((definingPolygonAttributes != null) &&
((isQuadGeometryArray &&
@@ -2188,7 +2161,7 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
// System.out.println("r.isOpaque = "+isOpaque+" rinfo = "+tinfo.rInfo+" groupType = "+tinfo.rInfo.groupType);
// Only support individual dlist or varray
// If this rInfo is a part of a bigger dlist, render as VA
- // TODO: What to do with Text3D, Raster, CG?
+ // XXXX: What to do with Text3D, Raster, CG?
if ((tinfo.rInfo.groupType & RenderAtom.SEPARATE_DLIST_PER_RINFO) != 0) {
RenderAtomListInfo save= tinfo.rInfo.next;
// Render only one geometry
@@ -2353,7 +2326,7 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
void checkEquivalenceWithLeftNeighbor(RenderMolecule rm, int dirtyBits) {
boolean reload_color = reloadColor(rm);
- // TODO : For now ignore the dirtyBits being sent in
+ // XXXX : For now ignore the dirtyBits being sent in
dirtyAttrsAcrossRms = ALL_DIRTY_BITS ;
@@ -2703,6 +2676,30 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
}
+ // Issue 129: method to add or remove all rendering atoms in this
+ // RenderMolecule to or from the transparent info list when we are
+ // in depth sorted transparency mode and the RenderMolecule
+ // changes from opaque to transparent or vice versa.
+ void addRemoveTransparentObject(RenderBin renderBin, boolean add) {
+ addRemoveTransparentObject(renderBin, add, primaryRenderAtomList);
+ addRemoveTransparentObject(renderBin, add, separateDlistRenderAtomList);
+ addRemoveTransparentObject(renderBin, add, vertexArrayRenderAtomList);
+ }
+
+ private void addRemoveTransparentObject(RenderBin renderBin,
+ boolean add,
+ RenderAtomListInfo rinfo) {
+ while (rinfo != null) {
+ if (add) {
+ renderBin.addTransparentObject(rinfo.renderAtom);
+ }
+ else {
+ renderBin.removeTransparentObject(rinfo.renderAtom);
+ }
+ rinfo = rinfo.next;
+ }
+ }
+
void evalMaterialCachedState() {
if (definingMaterial == null) {
enableLighting = false;;
@@ -3118,7 +3115,3 @@ class RenderMolecule extends IndexedObject implements ObjectUpdate, NodeComponen
}
}
}
-
-
-
-
diff --git a/src/classes/share/javax/media/j3d/Renderer.java b/src/classes/share/javax/media/j3d/Renderer.java
index 4f52a06..bb61822 100644
--- a/src/classes/share/javax/media/j3d/Renderer.java
+++ b/src/classes/share/javax/media/j3d/Renderer.java
@@ -96,6 +96,8 @@ class Renderer extends J3dThread {
// an unique bit to identify this renderer
int rendererBit = 0;
+ // an unique number to identify this renderer : ( rendererBit = 1 << rendererId)
+ int rendererId = 0;
// List of renderMolecules that are dirty due to additions
// or removal of renderAtoms from their display list set
@@ -117,10 +119,6 @@ class Renderer extends J3dThread {
ArrayList textureReloadList = new ArrayList();
- // This is a local copy of canvas view cache. It is used as a data storage for the
- // renderer. Note: This isn't the "real" canvasViewCache references by the Canvas.
- CanvasViewCache copyOfCvCache = new CanvasViewCache(null, null, null);
-
J3dMessage[] renderMessage;
// The screen for this Renderer. Note that this renderer may share
@@ -178,7 +176,8 @@ class Renderer extends J3dThread {
setName("J3D-Renderer-" + getInstanceNum());
type = J3dThread.RENDER_THREAD;
- rendererBit = VirtualUniverse.mc.getRendererBit();
+ rendererId = VirtualUniverse.mc.getRendererId();
+ rendererBit = (1 << rendererId);
renderMessage = new J3dMessage[1];
}
@@ -391,7 +390,25 @@ class Renderer extends J3dThread {
c.doubleBufferAvailable = nct.hasDoubleBuffer(c);
c.stereoAvailable = nct.hasStereo(c);
}
- c.sceneAntialiasingMultiSamplesAvailable =
+
+ // Setup stencil related variables.
+ c.actualStencilSize = nct.getStencilSize(c);
+ boolean userOwnsStencil = c.requestedStencilSize > 0;
+
+ c.userStencilAvailable =
+ (userOwnsStencil && (c.actualStencilSize > 0));
+ c.systemStencilAvailable =
+ (!userOwnsStencil && (c.actualStencilSize > 0));
+
+ /*
+ System.out.println("Renderer :check for nct configuration");
+ System.out.println("-- userStencilAvailable " +
+ c.userStencilAvailable);
+ System.out.println("-- systemStencilAvailable " +
+ c.systemStencilAvailable);
+ */
+
+ c.sceneAntialiasingMultiSamplesAvailable =
nct.hasSceneAntialiasingMultisample(c);
if (c.sceneAntialiasingMultiSamplesAvailable) {
@@ -667,13 +684,7 @@ class Renderer extends J3dThread {
}
synchronized (VirtualUniverse.mc.contextCreationLock) {
- sharedCtx =
- canvas.createNewContext(canvas.screen.display,
- canvas.window,
- canvas.vid,
- canvas.fbConfig,
- 0, true,
- canvas.offScreen);
+ sharedCtx = canvas.createNewContext(0, true);
if (sharedCtx == 0) {
canvas.drawingSurfaceObject.unLock();
if ((offBufRetained != null) &&
@@ -706,15 +717,9 @@ class Renderer extends J3dThread {
}
synchronized (VirtualUniverse.mc.contextCreationLock) {
- canvas.ctx =
- canvas.createNewContext(canvas.screen.display,
- canvas.window, canvas.vid,
- canvas.fbConfig, sharedCtx,
- false, canvas.offScreen);
-
-
+ canvas.ctx = canvas.createNewContext(sharedCtx, false);
- if (canvas.ctx == 0) {
+ if (canvas.ctx == 0) {
canvas.drawingSurfaceObject.unLock();
if ((offBufRetained != null) &&
offBufRetained.isByReference()) {
@@ -737,56 +742,29 @@ class Renderer extends J3dThread {
NodeComponentRetained nc = (NodeComponentRetained)renderBin.nodeComponentList.get(i);
nc.evaluateExtensions(canvas.extensionsSupported);
}
- }
-
-
- // query for the number of texture units supported
- if (canvas.multiTexAccelerated) {
- canvas.numTexUnitSupported =
- canvas.getTextureUnitCount(canvas.ctx);
- if (VirtualUniverse.mc.textureUnitMax < canvas.numTexUnitSupported) {
- canvas.numTexUnitSupported = VirtualUniverse.mc.textureUnitMax;
- }
- }
+ }
- // enable separate specular color
+ // enable separate specular color
canvas.enableSeparateSpecularColor();
-
}
+ // create the cache texture state in canvas
+ // for state download checking purpose
+ if (canvas.texUnitState == null) {
+ canvas.createTexUnitState();
+ }
- // create the cache texture state in canvas
- // for state download checking purpose
-
- if (canvas.texUnitState == null) {
- canvas.texUnitState =
- new TextureUnitStateRetained[
- canvas.numTexCoordSupported];
- for (int t = 0; t < canvas.numTexCoordSupported;
- t++) {
- canvas.texUnitState[t] =
- new TextureUnitStateRetained();
- canvas.texUnitState[t].texture = null;
- canvas.texUnitState[t].mirror = null;
- }
- }
-
+ // Create the texture unit state map
+ if (canvas.texUnitStateMap == null) {
+ canvas.createTexUnitStateMap();
+ }
- // also create the texture unit state map
- // which is a mapping from texture unit state to
- // the actual underlying texture unit
+ canvas.resetImmediateRendering(Canvas3D.NOCHANGE);
+ canvas.drawingSurfaceObject.contextValidated();
- if (canvas.texUnitStateMap == null) {
- canvas.texUnitStateMap =
- new int[canvas.numTexCoordSupported];
- }
-
- canvas.resetImmediateRendering(Canvas3D.NOCHANGE);
- canvas.drawingSurfaceObject.contextValidated();
-
- if (!canvas.useSharedCtx) {
- canvas.needToRebuildDisplayList = true;
- }
+ if (!canvas.useSharedCtx) {
+ canvas.needToRebuildDisplayList = true;
+ }
canvas.drawingSurfaceObject.unLock();
} else {
@@ -819,30 +797,22 @@ class Renderer extends J3dThread {
// save the BACKGROUND_IMAGE_DIRTY before canvas.updateViewCache
// clean it
- background_image_update =
- ((canvas.cvDirtyMask & Canvas3D.BACKGROUND_IMAGE_DIRTY) != 0);
-
- // copyOfcvCache is a copy of canvas view
- // cache. It is used as a data storage for the
- // renderer. Note: This isn't the "real"
- // canvasViewCache references by the Canvas.
- //
- // Note : For performance reason, copyOfcvCache
- // doesn't contain are valid canvasViewCache info.,
- // only data needed by the renderer are stored.
- //
- // The valid data are : useStereo, canvasWidth,
- // canvasHeight, leftProjection, rightProjection,
- // leftVpcToEc, rightVpcToEc, leftFrustumPlanes,
- // rightFrustumPlanes, vpcToVworld and vworldToVpc.
+ synchronized (canvas.dirtyMaskLock) {
+ background_image_update =
+ ((canvas.cvDirtyMask[Canvas3D.RENDERER_DIRTY_IDX] & Canvas3D.BACKGROUND_IMAGE_DIRTY) != 0);
+ }
if (VirtualUniverse.mc.doDsiRenderLock) {
canvas.drawingSurfaceObject.unLock();
}
+ // Issue 109 : removed copyOfCvCache now that we have
+ // a separate canvasViewCache for computing view frustum
+ CanvasViewCache cvCache = canvas.canvasViewCache;
+
// Deadlock if we include updateViewCache in
// drawingSurfaceObject sync.
- canvas.updateViewCache(false, copyOfCvCache, null,
+ canvas.updateViewCache(false, null, null,
renderBin.geometryBackground != null);
if ((VirtualUniverse.mc.doDsiRenderLock) &&
@@ -856,8 +826,8 @@ class Renderer extends J3dThread {
// setup viewport
canvas.setViewport(canvas.ctx, 0, 0,
- copyOfCvCache.getCanvasWidth(),
- copyOfCvCache.getCanvasHeight());
+ cvCache.getCanvasWidth(),
+ cvCache.getCanvasHeight());
@@ -915,7 +885,7 @@ class Renderer extends J3dThread {
// stereo setup
- boolean useStereo = copyOfCvCache.getUseStereo();
+ boolean useStereo = cvCache.getUseStereo();
if (useStereo) {
num_stereo_passes = 2;
stereo_mode = Canvas3D.FIELD_LEFT;
@@ -942,7 +912,7 @@ class Renderer extends J3dThread {
num_accum_passes = NUM_ACCUMULATION_SAMPLES;
System.arraycopy(
- copyOfCvCache.getLeftProjection().mat,
+ cvCache.getLeftProjection().mat,
0, accumLeftProjMat, 0, 16);
@@ -960,7 +930,7 @@ class Renderer extends J3dThread {
if (useStereo) {
System.arraycopy(
- copyOfCvCache.getRightProjection().mat,
+ cvCache.getRightProjection().mat,
0, accumRightProjMat, 0, 16);
accumRightX = accumRightProjMat[3];
accumRightY = accumRightProjMat[7];
@@ -968,13 +938,13 @@ class Renderer extends J3dThread {
if (renderBin.geometryBackground != null) {
System.arraycopy(
- copyOfCvCache.getInfLeftProjection().mat,
+ cvCache.getInfLeftProjection().mat,
0, accumInfLeftProjMat, 0, 16);
accumInfLeftX = accumInfLeftProjMat[3];
accumInfLeftY = accumInfLeftProjMat[7];
if (useStereo) {
System.arraycopy(
- copyOfCvCache.getInfRightProjection().mat,
+ cvCache.getInfRightProjection().mat,
0, accumInfRightProjMat, 0, 16);
accumInfRightX = accumInfRightProjMat[3];
accumInfRightY = accumInfRightProjMat[7];
@@ -1044,8 +1014,8 @@ class Renderer extends J3dThread {
canvas.beginScene();
// this is if the background image resizes with the canvas
- int winWidth = copyOfCvCache.getCanvasWidth();
- int winHeight = copyOfCvCache.getCanvasHeight();
+ int winWidth = cvCache.getCanvasWidth();
+ int winHeight = cvCache.getCanvasHeight();
// clear background if not full screen antialiasing
@@ -1217,7 +1187,7 @@ class Renderer extends J3dThread {
// setup rendering matrices
if (pass == 0) {
canvas.vpcToEc =
- copyOfCvCache.getInfLeftVpcToEc();
+ cvCache.getInfLeftVpcToEc();
if (doAccum) {
canvas.setProjectionMatrix(
canvas.ctx,
@@ -1225,11 +1195,11 @@ class Renderer extends J3dThread {
} else {
canvas.setProjectionMatrix(
canvas.ctx,
- copyOfCvCache.getInfLeftProjection().mat);
+ cvCache.getInfLeftProjection().mat);
}
} else {
canvas.vpcToEc =
- copyOfCvCache.getInfRightVpcToEc();
+ cvCache.getInfRightVpcToEc();
if (doAccum) {
canvas.setProjectionMatrix(
canvas.ctx,
@@ -1237,11 +1207,11 @@ class Renderer extends J3dThread {
} else {
canvas.setProjectionMatrix(
canvas.ctx,
- copyOfCvCache.getInfRightProjection().mat);
+ cvCache.getInfRightProjection().mat);
}
}
canvas.vworldToEc.mul(canvas.vpcToEc,
- copyOfCvCache.getInfVworldToVpc());
+ cvCache.getInfVworldToVpc());
// render background geometry
renderBin.renderBackground(canvas);
@@ -1249,33 +1219,33 @@ class Renderer extends J3dThread {
// setup rendering matrices
if (pass == 0) {
- canvas.vpcToEc = copyOfCvCache.getLeftVpcToEc();
+ canvas.vpcToEc = cvCache.getLeftVpcToEc();
if (doAccum) {
canvas.setProjectionMatrix(
canvas.ctx, accumLeftProjMat);
} else {
canvas.setProjectionMatrix(canvas.ctx,
- copyOfCvCache.getLeftProjection().mat);
+ cvCache.getLeftProjection().mat);
}
} else {
- canvas.vpcToEc = copyOfCvCache.getRightVpcToEc();
+ canvas.vpcToEc = cvCache.getRightVpcToEc();
if (doAccum) {
canvas.setProjectionMatrix(
canvas.ctx, accumRightProjMat);
} else {
canvas.setProjectionMatrix(canvas.ctx,
- copyOfCvCache.getRightProjection().mat);
+ cvCache.getRightProjection().mat);
}
}
canvas.vworldToEc.mul(canvas.vpcToEc,
- copyOfCvCache.getVworldToVpc());
+ cvCache.getVworldToVpc());
- synchronized (copyOfCvCache) {
+ synchronized (cvCache) {
if (pass == 0) {
- canvas.setFrustumPlanes(copyOfCvCache.getLeftFrustumPlanesInVworld());
+ canvas.setFrustumPlanes(cvCache.getLeftFrustumPlanesInVworld());
} else {
- canvas.setFrustumPlanes(copyOfCvCache.getRightFrustumPlanesInVworld());
+ canvas.setFrustumPlanes(cvCache.getRightFrustumPlanesInVworld());
}
}
@@ -1464,7 +1434,6 @@ class Renderer extends J3dThread {
dirtyDlistPerRinfoList.clear();
textureIdResourceFreeList.clear();
displayListResourceFreeList.clear();
- copyOfCvCache = new CanvasViewCache(null, null, null);
onScreen = null;
offScreen = null;
m = null;
@@ -1630,12 +1599,15 @@ class Renderer extends J3dThread {
// restore current context
currentCanvas.makeCtxCurrent();
}
- if (texture.equals("2D")){
- VirtualUniverse.mc.freeTexture2DId(texId);
- }
- else if(texture.equals("3D")){
- VirtualUniverse.mc.freeTexture3DId(texId);
- }
+ // Issue 162: TEMPORARY FIX -- don't free the texture ID, since it will
+ // be freed once per canvas / screen and will subsequently cause the ID
+ // to be used for multiple textures.
+// if (texture.equals("2D")){
+// VirtualUniverse.mc.freeTexture2DId(texId);
+// }
+// else if(texture.equals("3D")){
+// VirtualUniverse.mc.freeTexture3DId(texId);
+// }
}
diff --git a/src/classes/share/javax/media/j3d/RenderingAttributes.java b/src/classes/share/javax/media/j3d/RenderingAttributes.java
index d3cb2be..d4c444a 100644
--- a/src/classes/share/javax/media/j3d/RenderingAttributes.java
+++ b/src/classes/share/javax/media/j3d/RenderingAttributes.java
@@ -16,38 +16,72 @@ package javax.media.j3d;
* The RenderingAttributes object defines common rendering attributes
* for all primitive types. The rendering attributes are:<p>
* <ul>
- * <li>Alpha test function - used to compare the alpha test value with
- * each per-pixel alpha value. If the test passes, the pixel is
+ * <li>Depth test function - used to compare the incoming (source) depth of
+ * each pixel with depth of the pixel stored in frame buffer. If the test
+ * passes, the pixel is written, otherwise the pixel is not written. The depth test
+ * function is set with the <code>setDepthTestFunction</code>
+ * method. By default, LESS_OR_EQUAL is the function used. The depth test
+ * function is one of the following:</li><p>
+ * <ul>
+ * <li>ALWAYS - pixels are always drawn, irrespective of the depth
+ * value. This effectively disables depth testing.</li><p>
+ *
+ * <li>NEVER - pixels are never drawn, irrespective of the depth
+ * value.</li><p>
+ *
+ * <li>EQUAL - pixels are drawn if the incoming pixel depth is equal
+ * to the stored pixel depth in the frame buffer.</li><p>
+ *
+ * <li>NOT_EQUAL - pixels are drawn if the incoming pixel depth is
+ * not equal to the stored pixel depth in the frame buffer.</li><p>
+ *
+ * <li>LESS - pixels are drawn if the incoming pixel depth is less
+ * than the stored pixel depth in the frame buffer.</li><p>
+ *
+ * <li>LESS_OR_EQUAL - pixels are drawn if the incoming pixel depth
+ * is less than or equal to the stored pixel depth in the frame buffer.
+ * This is the default setting.</li><p>
+ *
+ * <li>GREATER - pixels are drawn if the incoming pixel depth is greater
+ * than the stored pixel depth in the frame buffer.</li><p>
+ *
+ * <li>GREATER_OR_EQUAL - pixels are drawn if the incoming pixel depth
+ * is greater than or equal to the stored pixel depth in the frame buffer.</li><p>
+ * </ul>
+ *
+ * <li>Alpha test function - used to compare the incoming (source) alpha value
+ * of each pixel with the alpha test value. If the test passes, the pixel is
* written, otherwise the pixel is not written. The alpha test
* function is set with the <code>setAlphaTestFunction</code>
* method. The alpha test
* function is one of the following:</li><p>
* <ul>
* <li>ALWAYS - pixels are always drawn, irrespective of the alpha
- * value. This effectively disables alpha testing. This is
- * the default setting.</li><p>
+ * value. This effectively disables alpha testing.
+ * This is the default setting.</li><p>
*
* <li>NEVER - pixels are never drawn, irrespective of the alpha
* value.</li><p>
*
- * <li>EQUAL - pixels are drawn if the pixel alpha value is equal
+ * <li>EQUAL - pixels are drawn if the incoming pixel alpha value is equal
* to the alpha test value.</li><p>
*
- * <li>NOT_EQUAL - pixels are drawn if the pixel alpha value is
+ * <li>NOT_EQUAL - pixels are drawn if the incoming pixel alpha value is
* not equal to the alpha test value.</li><p>
*
- * <li>LESS - pixels are drawn if the pixel alpha value is less
+ * <li>LESS - pixels are drawn if the incoming pixel alpha value is less
* than the alpha test value.</li><p>
*
- * <li>LESS_OR_EQUAL - pixels are drawn if the pixel alpha value
+ * <li>LESS_OR_EQUAL - pixels are drawn if the incoming pixel alpha value
* is less than or equal to the alpha test value.</li><p>
*
- * <li>GREATER - pixels are drawn if the pixel alpha value is greater
+ * <li>GREATER - pixels are drawn if the incoming pixel alpha value is greater
* than the alpha test value.</li><p>
*
- * <li>GREATER_OR_EQUAL - pixels are drawn if the pixel alpha
+ * <li>GREATER_OR_EQUAL - pixels are drawn if the incoming pixel alpha
* value is greater than or equal to the alpha test value.</li><p>
* </ul>
+ *
* <li>Alpha test value - the test value used by the alpha test function.
* This value is compared to the alpha value of each rendered pixel.
* The alpha test value is set with the <code>setAlphaTestValue</code>
@@ -59,8 +93,22 @@ package javax.media.j3d;
* is enabled or disabled with the <code>setRasterOpEnable</code>
* method. The raster operation is one of the following:</li><p>
* <ul>
+ * <li>ROP_CLEAR - DST = 0.</li>
+ * <li>ROP_AND DST = SRC & DST.</li>
+ * <li>ROP_AND_REVERSE DST = SRC & ~DST.</li>
* <li>ROP_COPY - DST = SRC. This is the default operation.</li>
- * <li>ROP_XOR - DST = SRC ^ DST.</li><p>
+ * <li>ROP_AND_INVERTED - DST = ~SRC & DST.</li>
+ * <li>ROP_NOOP - DST = DST.</li>
+ * <li>ROP_XOR - DST = SRC ^ DST.</li>
+ * <li>ROP_OR - DST = DST | SRC.</li>
+ * <li>ROP_NOR - DST = ~( DST | SRC .)</li>
+ * <li>ROP_EQUIV - DST = ~( DST ^ SRC .)</li>
+ * <li>ROP_INVERT - DST = ~DST.</li>
+ * <li>ROP_OR_REVERSE - DST = src | ~DST.</li>
+ * <li>ROP_COPY_INVERTED - DST = ~SRC.</li>
+ * <li>ROP_OR_INVERTED - DST = ~SRC | DST.</li>
+ * <li>ROP_NAND - DST = ~(SRC & DST.)</li>
+ * <li>ROP_SET - DST = 1.</li><p>
* </ul>
* <li>Vertex colors - vertex colors can be ignored for this
* RenderingAttributes object. This capability is set with the
@@ -93,12 +141,79 @@ package javax.media.j3d;
* include opaque objects or primitives rendered with
* SCREEN_DOOR transparency. By default, the depth buffer
* is enabled and the depth buffer write is enabled.</li><p>
+ *
+ * <li>Stencil buffer - can be enabled or disabled for this RenderingAttributes
+ * component object using the <code>setStencilEnable</code> method. If the
+ * stencil buffer is disabled, the stencil operation and function are ignored.
+ * If a scene graph is rendered on a Canvas3D that does not have a stencil
+ * buffer, the stencil buffer will be implicitly disabled for that
+ * canvas.</li><p>
+ *
+ * <li>Stencil write mask - mask that controls which bits of the stencil
+ * buffer are written when the stencil buffer is enabled. The default value is
+ * <code>~0</code> (all ones).</li><p>
+ *
+ * <li>Stencil operation - a set of three stencil operations performed
+ * when: 1)&nbsp;the stencil test fails; 2)&nbsp;the stencil test passes, but
+ * the depth test fails; or 3)&nbsp;both the stencil test and depth test pass.
+ * The stencil operations are set with the <code>setStencilOp</code>
+ * method. The stencil operation is one of the following:</li><p>
+ * <ul>
+ * <li>STENCIL_KEEP - keeps the current value (no operation performed).
+ * This is the default setting.</li>
+ * <li>STENCIL_ZERO - Sets the stencil buffer value to 0.</li>
+ * <li>STENCIL_REPLACE - Sets the stencil buffer value to
+ * <code>refValue</code>, as specified by <code>setStencilFunction</code>.</li>
+ * <li>STENCIL_INCR - Increments the current stencil buffer value.</li>
+ * <li>STENCIL_DECR - Decrements the current stencil buffer value.</li>
+ * <li>STENCIL_INVERT - Bitwise inverts the current stencil buffer value.</li><p>
* </ul>
*
- * @see Appearance
+ * <li>Stencil test function - used to compare the stencil reference value with
+ * the per-pixel stencil value stored in the frame buffer. If the test passes,
+ * the pixel is written, otherwise the pixel is not written. The stencil
+ * test function, reference value, and comparison mask are set with the
+ * <code>setStencilFunction</code> method. The stencil comparison mask is
+ * bitwise-ANDed with both the stencil reference value and the stored stencil
+ * value prior to doing the comparison. The default value for the reference value
+ * is 0. The default value for the comparison mask is <code>~0</code> (all ones).
+ * The stencil test function is one of the following:</li><p>
+ * <ul>
+ * <li>ALWAYS - pixels are always drawn, irrespective of the stencil
+ * value. This effectively disables stencil testing.
+ * This is the default setting.</li><p>
+ *
+ * <li>NEVER - pixels are never drawn, irrespective of the stencil
+ * value.</li><p>
+ *
+ * <li>EQUAL - pixels are drawn if the stencil reference value is equal
+ * to the stored stencil value in the frame buffer.</li><p>
+ *
+ * <li>NOT_EQUAL - pixels are drawn if the stencil reference value is
+ * not equal to the stored stencil value in the frame buffer.</li><p>
+ *
+ * <li>LESS - pixels are drawn if the stencil reference value is less
+ * than the stored stencil value in the frame buffer.</li><p>
*
+ * <li>LESS_OR_EQUAL - pixels are drawn if the stencil reference value
+ * is less than or equal to the stored stencil value in the frame buffer.</li><p>
+ *
+ * <li>GREATER - pixels are drawn if the stencil reference value is greater
+ * than the stored stencil value in the frame buffer.</li><p>
+ *
+ * <li>GREATER_OR_EQUAL - pixels are drawn if the stencil reference value
+ * is greater than or equal to the stored stencil value in the frame buffer.</li><p>
+ * </ul>
+ *
+ * </ul>
+ *
+ * <p>Note: the alpha test, depth test, and stencil functions all use
+ * the same enums.</p>
+ *
+ * @see Appearance
*/
public class RenderingAttributes extends NodeComponent {
+
/**
* Specifies that this RenderingAttributes object
* allows reading its alpha test value component information.
@@ -127,6 +242,24 @@ public class RenderingAttributes extends NodeComponent {
public static final int
ALLOW_ALPHA_TEST_FUNCTION_WRITE = CapabilityBits.RENDERING_ATTRIBUTES_ALLOW_ALPHA_TEST_FUNCTION_WRITE;
+ /**
+ * Specifies that this RenderingAttributes object
+ * allows reading its depth test function component information.
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int
+ ALLOW_DEPTH_TEST_FUNCTION_READ = CapabilityBits.RENDERING_ATTRIBUTES_ALLOW_DEPTH_TEST_FUNCTION_READ;
+
+ /**
+ * Specifies that this RenderingAttributes object
+ * allows writing its depth test function component information.
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int
+ ALLOW_DEPTH_TEST_FUNCTION_WRITE = CapabilityBits.RENDERING_ATTRIBUTES_ALLOW_DEPTH_TEST_FUNCTION_WRITE;
+
/**
* Specifies that this RenderingAttributes object
* allows reading its depth buffer enable and depth buffer write enable
@@ -200,84 +333,322 @@ public class RenderingAttributes extends NodeComponent {
CapabilityBits.RENDERING_ATTRIBUTES_ALLOW_RASTER_OP_WRITE;
/**
- * Indicates pixels are always drawn irrespective of alpha value.
- * This effectively disables alpha testing.
+ * Specifies that this RenderingAttributes object allows reading
+ * its stencil enable, stencil op, stencil function, and
+ * stencil write mask information.
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int ALLOW_STENCIL_ATTRIBUTES_READ =
+ CapabilityBits.RENDERING_ATTRIBUTES_ALLOW_STENCIL_ATTRIBUTES_READ;
+
+ /**
+ * Specifies that this RenderingAttributes object allows writing
+ * its stencil enable, stencil op, stencil function, and
+ * stencil write mask information.
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int ALLOW_STENCIL_ATTRIBUTES_WRITE =
+ CapabilityBits.RENDERING_ATTRIBUTES_ALLOW_STENCIL_ATTRIBUTES_WRITE;
+
+
+ //
+ // Enums for alpha test, depth test, and stencil test
+ //
+
+ /**
+ * Specifies that pixels are always drawn irrespective of the
+ * values being tested.
+ * Can be used to specify the alpha test function, the depth test function,
+ * or the stencil function.
+ * This setting effectively disables alpha, depth, or stencil testing.
+ *
+ * @see #setAlphaTestFunction
+ * @see #setDepthTestFunction
+ * @see #setStencilFunction(int,int,int)
*/
public static final int ALWAYS = 0;
/**
- * Indicates pixels are never drawn irrespective of alpha value.
+ * Specifies that pixels are never drawn irrespective of the
+ * values being tested.
+ * Can be used to specify the alpha test function, the depth test function,
+ * or the stencil function.
+ *
+ * @see #setAlphaTestFunction
+ * @see #setDepthTestFunction
+ * @see #setStencilFunction(int,int,int)
*/
public static final int NEVER = 1;
/**
- * Indicates pixels are drawn if pixel alpha value is equal
- * to alpha test value.
+ * Specifies that pixels are drawn if the two values being tested are equal.
+ * Can be used to specify the alpha test function, the depth test function,
+ * or the stencil function.
+ *
+ * @see #setAlphaTestFunction
+ * @see #setDepthTestFunction
+ * @see #setStencilFunction(int,int,int)
*/
public static final int EQUAL = 2;
/**
- * Indicates pixels are drawn if pixel alpha value is not equal
- * to alpha test value.
+ * Specifies that pixels are drawn if the two values being tested are not equal.
+ * Can be used to specify the alpha test function, the depth test function,
+ * or the stencil function.
+ *
+ * @see #setAlphaTestFunction
+ * @see #setDepthTestFunction
+ * @see #setStencilFunction(int,int,int)
*/
public static final int NOT_EQUAL = 3;
/**
- * Indicates pixels are drawn if pixel alpha value is less
- * than alpha test value.
+ * Specifies that pixels are drawn if the source/reference value is less
+ * than the destination/test value.
+ * Can be used to specify the alpha test function, the depth test function,
+ * or the stencil function.
+ *
+ * @see #setAlphaTestFunction
+ * @see #setDepthTestFunction
+ * @see #setStencilFunction(int,int,int)
*/
public static final int LESS = 4;
/**
- * Indicates pixels are drawn if pixel alpha value is less
- * than or equal to alpha test value.
+ * Specifies that pixels are drawn if the source/reference value is less
+ * than or equal to the destination/test value.
+ * Can be used to specify the alpha test function, the depth test function,
+ * or the stencil function.
+ *
+ * @see #setAlphaTestFunction
+ * @see #setDepthTestFunction
+ * @see #setStencilFunction(int,int,int)
*/
public static final int LESS_OR_EQUAL = 5;
/**
- * Indicates pixels are drawn if pixel alpha value is greater
- * than alpha test value.
+ * Specifies that pixels are drawn if the source/reference value is greater
+ * than the destination/test value.
+ * Can be used to specify the alpha test function, the depth test function,
+ * or the stencil function.
+ *
+ * @see #setAlphaTestFunction
+ * @see #setDepthTestFunction
+ * @see #setStencilFunction(int,int,int)
*/
public static final int GREATER = 6;
/**
- * Indicates pixels are drawn if pixel alpha value is greater
- * than or equal to alpha test value.
+ * Specifies that pixels are drawn if the source/reference value is greater
+ * than or equal to the destination/test value.
+ * Can be used to specify the alpha test function, the depth test function,
+ * or the stencil function.
+ *
+ * @see #setAlphaTestFunction
+ * @see #setDepthTestFunction
+ * @see #setStencilFunction(int,int,int)
*/
public static final int GREATER_OR_EQUAL = 7;
-// public static final int ROP_CLEAR = 0x0;
-// public static final int ROP_AND = 0x1;
-// public static final int ROP_AND_REVERSE = 0x2;
+ //
+ // Raster op enums
+ //
+
+ /**
+ * Raster operation: <code>DST = 0</code>.
+ * @see #setRasterOp
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int ROP_CLEAR = 0x0;
+
+ /**
+ * Raster operation: <code>DST = SRC & DST</code>.
+ * @see #setRasterOp
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int ROP_AND = 0x1;
+
+ /**
+ * Raster operation: <code>DST = SRC & ~DST</code>.
+ * @see #setRasterOp
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int ROP_AND_REVERSE = 0x2;
/**
* Raster operation: <code>DST = SRC</code>.
* @see #setRasterOp
+ *
* @since Java 3D 1.2
*/
public static final int ROP_COPY = 0x3;
-// public static final int ROP_AND_INVERTED = 0x4;
-// public static final int ROP_NOOP = 0x5;
+ /**
+ * Raster operation: <code>DST = ~SRC & DST</code>.
+ * @see #setRasterOp
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int ROP_AND_INVERTED = 0x4;
+
+ /**
+ * Raster operation: <code>DST = DST</code>.
+ * @see #setRasterOp
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int ROP_NOOP = 0x5;
/**
* Raster operation: <code>DST = SRC ^ DST</code>.
* @see #setRasterOp
+ *
* @since Java 3D 1.2
*/
public static final int ROP_XOR = 0x6;
-// public static final int ROP_OR = 0x7;
-// public static final int ROP_NOR = 0x8;
-// public static final int ROP_EQUIV = 0x9;
-// public static final int ROP_INVERT = 0xA;
-// public static final int ROP_OR_REVERSE = 0xB;
-// public static final int ROP_COPY_INVERTED = 0xC;
-// public static final int ROP_OR_INVERTED = 0xD;
-// public static final int ROP_NAND = 0xE;
-// public static final int ROP_SET = 0xF;
+ /**
+ * Raster operation: <code>DST = DST | SRC</code>.
+ * @see #setRasterOp
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int ROP_OR = 0x7;
+
+ /**
+ * Raster operation: <code>DST = ~( DST | SRC )</code>.
+ * @see #setRasterOp
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int ROP_NOR = 0x8;
+
+ /**
+ * Raster operation: <code>DST = ~( DST ^ SRC )</code>.
+ * @see #setRasterOp
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int ROP_EQUIV = 0x9;
+
+ /**
+ * Raster operation: <code>DST = ~DST</code>.
+ * @see #setRasterOp
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int ROP_INVERT = 0xA;
+
+ /**
+ * Raster operation: <code>DST = src | ~DST</code>.
+ * @see #setRasterOp
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int ROP_OR_REVERSE = 0xB;
+ /**
+ * Raster operation: <code>DST = ~SRC</code>.
+ * @see #setRasterOp
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int ROP_COPY_INVERTED = 0xC;
+
+ /**
+ * Raster operation: <code>DST = ~SRC | DST</code>.
+ * @see #setRasterOp
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int ROP_OR_INVERTED = 0xD;
+
+ /**
+ * Raster operation: <code>DST = ~(SRC & DST)</code>.
+ * @see #setRasterOp
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int ROP_NAND = 0xE;
+
+ /**
+ * Raster operation: <code>DST = 1</code>.
+ * @see #setRasterOp
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int ROP_SET = 0xF;
+
+
+ //
+ // Stencil op enums
+ //
+
+ /**
+ * Stencil operation: <code>DST = DST</code>
+ * @see #setStencilOp(int,int,int)
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int STENCIL_KEEP = 1;
+
+ /**
+ * Stencil operation: <code>DST = 0</code>
+ * @see #setStencilOp(int,int,int)
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int STENCIL_ZERO = 2;
+
+ /**
+ * Stencil operation: <code>DST = REF</code>
+ * @see #setStencilOp(int,int,int)
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int STENCIL_REPLACE = 3;
+
+ /**
+ * Stencil operation: <code>DST = DST + 1</code>
+ * @see #setStencilOp(int,int,int)
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int STENCIL_INCR = 4;
+
+ /**
+ * Stencil operation: <code>DST = DST - 1</code>
+ * @see #setStencilOp(int,int,int)
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int STENCIL_DECR = 5;
+
+ /**
+ * Stencil operation: <code>DST = ~DST</code>
+ * @see #setStencilOp(int,int,int)
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int STENCIL_INVERT = 6;
+
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_ALPHA_TEST_FUNCTION_READ,
+ ALLOW_ALPHA_TEST_VALUE_READ,
+ ALLOW_DEPTH_ENABLE_READ,
+ ALLOW_DEPTH_TEST_FUNCTION_READ,
+ ALLOW_IGNORE_VERTEX_COLORS_READ,
+ ALLOW_RASTER_OP_READ,
+ ALLOW_STENCIL_ATTRIBUTES_READ,
+ ALLOW_VISIBLE_READ
+ };
/**
* Constructs a RenderingAttributes object with default parameters.
@@ -286,15 +657,26 @@ public class RenderingAttributes extends NodeComponent {
* depth buffer enable : true<br>
* depth buffer write enable : true<br>
* alpha test function : ALWAYS<br>
- * alpha test value : 0.0<br>
+ * alpha test value : 0.0f<br>
* visible : true<br>
* ignore vertex colors : false<br>
* raster operation enable : false<br>
* raster operation : ROP_COPY<br>
+ * depth test: LESS_OR_EQUAL<br>
+ * stencil enable : false<br>
+ * stencil write mask : ~0 (all ones)<br>
+ * stencil op - failOp : STENCIL_KEEP<br>
+ * stencil op - zFailOp : STENCIL_KEEP<br>
+ * stencil op - zPassOp : STENCIL_KEEP<br>
+ * stencil function : ALWAYS<br>
+ * stencil reference value : 0<br>
+ * stencil comparison mask : ~0 (all ones)
* </ul>
*/
public RenderingAttributes() {
// Just use default attributes
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -327,8 +709,10 @@ public class RenderingAttributes extends NodeComponent {
* @param rasterOpEnable a flag that specifies whether logical
* raster operations are enabled for this RenderingAttributes object.
* This disables all alpha blending operations.
- * @param rasterOp the logical raster operation, one of ROP_COPY or
- * ROP_XOR.
+ * @param rasterOp the logical raster operation, one of:
+ * ROP_CLEAR, ROP_AND, ROP_AND_REVERSE, ROP_COPY, ROP_AND_INVERTED,
+ * ROP_NOOP, ROP_XOR, ROP_OR, ROP_NOR, ROP_EQUIV, ROP_INVERT,
+ * ROP_OR_REVERSE, ROP_COPY_INVERTED, ROP_OR_INVERTED, ROP_NAND or ROP_SET
*
* @since Java 3D 1.2
*/
@@ -340,6 +724,8 @@ public class RenderingAttributes extends NodeComponent {
boolean ignoreVertexColors,
boolean rasterOpEnable,
int rasterOp) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
((RenderingAttributesRetained)this.retained).initDepthBufferEnable(depthBufferEnable);
((RenderingAttributesRetained)this.retained).initDepthBufferWriteEnable(depthBufferWriteEnable);
@@ -356,9 +742,13 @@ public class RenderingAttributes extends NodeComponent {
/**
* Enables or disables depth buffer mode for this RenderingAttributes
* component object.
+ *
* @param state true or false to enable or disable depth buffer mode
+ *
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
+ *
+ * @see GraphicsConfigTemplate3D#setDepthSize
*/
public void setDepthBufferEnable(boolean state){
if (isLiveOrCompiled())
@@ -401,7 +791,6 @@ public class RenderingAttributes extends NodeComponent {
if (isLiveOrCompiled())
if (!this.getCapability(ALLOW_DEPTH_ENABLE_WRITE))
throw new CapabilityNotSetException(J3dI18N.getString("RenderingAttributes2"));
-
if (isLive())
((RenderingAttributesRetained)this.retained).setDepthBufferWriteEnable(state);
else
@@ -456,9 +845,9 @@ public class RenderingAttributes extends NodeComponent {
}
/**
- * Set alpha test function. This function is used to compare the
- * alpha test value with each per-pixel alpha value. If the test
- * passes, the pixel is written otherwise the pixel is not
+ * Set alpha test function. This function is used to compare
+ * each incoming (source) per-pixel alpha value with the alpha test value.
+ * If the test passes, the pixel is written otherwise the pixel is not
* written.
* @param function the new alpha test function. One of
* ALWAYS, NEVER, EQUAL, NOT_EQUAL, LESS, LESS_OR_EQUAL, GREATER,
@@ -639,8 +1028,10 @@ public class RenderingAttributes extends NodeComponent {
* Sets the raster operation function for this RenderingAttributes
* component object.
*
- * @param rasterOp the logical raster operation, one of ROP_COPY or
- * ROP_XOR
+ * @param rasterOp the logical raster operation, one of:
+ * ROP_CLEAR, ROP_AND, ROP_AND_REVERSE, ROP_COPY, ROP_AND_INVERTED,
+ * ROP_NOOP, ROP_XOR, ROP_OR, ROP_NOR, ROP_EQUIV, ROP_INVERT,
+ * ROP_OR_REVERSE, ROP_COPY_INVERTED, ROP_OR_INVERTED, ROP_NAND or ROP_SET.
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
@@ -660,7 +1051,10 @@ public class RenderingAttributes extends NodeComponent {
/**
* Retrieves the current raster operation for this RenderingAttributes
* object.
- * @return one of ROP_COPY or ROP_XOR.
+ * @return one of:
+ * ROP_CLEAR, ROP_AND, ROP_AND_REVERSE, ROP_COPY, ROP_AND_INVERTED,
+ * ROP_NOOP, ROP_XOR, ROP_OR, ROP_NOR, ROP_EQUIV, ROP_INVERT,
+ * ROP_OR_REVERSE, ROP_COPY_INVERTED, ROP_OR_INVERTED, ROP_NAND or ROP_SET
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
@@ -723,13 +1117,368 @@ public class RenderingAttributes extends NodeComponent {
rt.initDepthBufferEnable(attr.getDepthBufferEnable());
rt.initDepthBufferWriteEnable(attr.getDepthBufferWriteEnable());
+ rt.initDepthTestFunction(attr.getDepthTestFunction());
rt.initAlphaTestValue(attr.getAlphaTestValue());
rt.initAlphaTestFunction(attr.getAlphaTestFunction());
rt.initVisible(attr.getVisible());
rt.initIgnoreVertexColors(attr.getIgnoreVertexColors());
rt.initRasterOpEnable(attr.getRasterOpEnable());
rt.initRasterOp(attr.getRasterOp());
+ rt.initStencilEnable(attr.getStencilEnable());
+ int[] ops = new int[3];
+ attr.getStencilOp(ops);
+ rt.initStencilOp(ops[0], ops[1], ops[2]);
+ attr.getStencilFunction(ops);
+ rt.initStencilFunction(ops[0], ops[1], ops[2]);
+ rt.initStencilWriteMask(attr.getStencilWriteMask());
+
+ }
+
+ /**
+ * Set depth test function. This function is used to compare each
+ * incoming (source) per-pixel depth test value with the stored per-pixel
+ * depth value in the frame buffer. If the test
+ * passes, the pixel is written, otherwise the pixel is not
+ * written.
+ * @param function the new depth test function. One of
+ * ALWAYS, NEVER, EQUAL, NOT_EQUAL, LESS, LESS_OR_EQUAL, GREATER,
+ * or GREATER_OR_EQUAL.
+ * The default value is LESS_OR_EQUAL.
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @since Java 3D 1.4
+ */
+ public void setDepthTestFunction(int function){
+ if (isLiveOrCompiled())
+ if (!this.getCapability(ALLOW_DEPTH_TEST_FUNCTION_WRITE))
+ throw new CapabilityNotSetException(J3dI18N.getString("RenderingAttributes14"));
+ if (isLive())
+ ((RenderingAttributesRetained)this.retained).setDepthTestFunction(function);
+ else
+ ((RenderingAttributesRetained)this.retained).initDepthTestFunction(function);
+ }
+
+ /**
+ * Retrieves current depth test function.
+ * @return the current depth test function
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @since Java 3D 1.4
+ */
+ public int getDepthTestFunction(){
+ if (isLiveOrCompiled())
+ if (!this.getCapability(ALLOW_DEPTH_TEST_FUNCTION_READ))
+ throw new CapabilityNotSetException(J3dI18N.getString("RenderingAttributes15"));
+
+ return ((RenderingAttributesRetained)this.retained).getDepthTestFunction();
+ }
+
+ /**
+ * Enables or disables the stencil buffer for this RenderingAttributes
+ * component object. If the stencil buffer is disabled, the
+ * stencil operation and function are ignored. If a scene graph
+ * is rendered on a Canvas3D that does not have a stencil buffer,
+ * the stencil buffer will be implicitly disabled for that canvas.
+ *
+ * @param state true or false to enable or disable stencil buffer
+ * operations.
+ * If this is set to false, the stencilOp and stencilFunction parameters
+ * are not used.
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @see GraphicsConfigTemplate3D#setStencilSize
+ *
+ * @since Java 3D 1.4
+ */
+ public void setStencilEnable(boolean state) {
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_STENCIL_ATTRIBUTES_WRITE)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("RenderingAttributes16"));
+ }
+ }
+
+ if (isLive())
+ ((RenderingAttributesRetained)this.retained).setStencilEnable(state);
+ else
+ ((RenderingAttributesRetained)this.retained).initStencilEnable(state);
+
+ }
+
+ /**
+ * Retrieves the stencil buffer enable flag for this RenderingAttributes
+ * object.
+ *
+ * @return true if stencil buffer operations are enabled; false
+ * if stencil buffer operations are disabled.
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @since Java 3D 1.4
+ */
+ public boolean getStencilEnable() {
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_STENCIL_ATTRIBUTES_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("RenderingAttributes17"));
+ }
+ }
+
+ return ((RenderingAttributesRetained)this.retained).getStencilEnable();
+ }
+
+ /**
+ * Sets the stencil operations for this RenderingAttributes object to the
+ * specified parameters.
+ *
+ * @param failOp operation performed when the stencil test fails, one of:
+ * STENCIL_KEEP, STENCIL_ZERO, STENCIL_REPLACE, STENCIL_INCR, STENCIL_DECR,
+ * or STENCIL_INVERT.
+ *
+ * @param zFailOp operation performed when the stencil test passes and the
+ * depth test fails, one of:
+ * STENCIL_KEEP, STENCIL_ZERO, STENCIL_REPLACE, STENCIL_INCR, STENCIL_DECR,
+ * or STENCIL_INVERT.
+ *
+ * @param zPassOp operation performed when both the stencil test and the
+ * depth test pass, one of:
+ * STENCIL_KEEP, STENCIL_ZERO, STENCIL_REPLACE, STENCIL_INCR, STENCIL_DECR,
+ * or STENCIL_INVERT.
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @since Java 3D 1.4
+ */
+ public void setStencilOp(int failOp, int zFailOp, int zPassOp) {
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_STENCIL_ATTRIBUTES_WRITE)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("RenderingAttributes16"));
+ }
+ }
+
+ if (isLive())
+ ((RenderingAttributesRetained)this.retained).setStencilOp(failOp,
+ zFailOp,
+ zPassOp);
+ else
+ ((RenderingAttributesRetained)this.retained).initStencilOp(failOp,
+ zFailOp,
+ zPassOp);
+
+ }
+
+ /**
+ * Sets the stencil operations for this RenderingAttributes object to the
+ * specified parameters.
+ *
+ * @param stencilOps an array of three integers that specifies the new
+ * set of stencil operations. Element 0 of the array specifies the
+ * <code>failOp</code> parameter, element 1 specifies the
+ * <code>zFailOp</code> parameter, and element 2 specifies the
+ * <code>zPassOp</code> parameter.
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @see #setStencilOp(int,int,int)
+ *
+ * @since Java 3D 1.4
+ */
+ public void setStencilOp(int[] stencilOps) {
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_STENCIL_ATTRIBUTES_WRITE)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("RenderingAttributes16"));
+ }
+ }
+
+ if (isLive())
+ ((RenderingAttributesRetained)this.retained).setStencilOp(stencilOps[0],
+ stencilOps[1],
+ stencilOps[2]);
+ else
+ ((RenderingAttributesRetained)this.retained).initStencilOp(stencilOps[0],
+ stencilOps[1],
+ stencilOps[2]);
+ }
+
+ /**
+ * Retrieves the current set of stencil operations, and copies them
+ * into the specified array. The caller must ensure that this array
+ * has been allocated with enough space to hold the results.
+ *
+ * @param stencilOps array that will receive the current set of
+ * three stencil operations. The <code>failOp</code> parameter is copied
+ * into element 0 of the array, the <code>zFailOp</code> parameter is copied
+ * into element 1, and the <code>zPassOp</code> parameter is copied
+ * into element 2.
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @since Java 3D 1.4
+ */
+ public void getStencilOp(int[] stencilOps) {
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_STENCIL_ATTRIBUTES_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("RenderingAttributes17"));
+ }
+ }
+
+ ((RenderingAttributesRetained)this.retained).getStencilOp(stencilOps);
+ }
+
+ /**
+ * Sets the stencil function, reference value, and comparison mask
+ * for this RenderingAttributes object to the specified parameters.
+ *
+ * @param function the stencil test function, used to compare the
+ * stencil reference value with the stored per-pixel
+ * stencil value in the frame buffer. If the test
+ * passes, the pixel is written, otherwise the pixel is not
+ * written. The stencil function is one of:
+ * ALWAYS, NEVER, EQUAL, NOT_EQUAL, LESS, LESS_OR_EQUAL, GREATER,
+ * or GREATER_OR_EQUAL.
+ *
+ * @param refValue the stencil reference value that is tested against
+ * the stored per-pixel stencil value
+ *
+ * @param compareMask a mask that limits which bits are compared; it is
+ * bitwise-ANDed with both the stencil reference value and the stored
+ * per-pixel stencil value before doing the comparison.
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @since Java 3D 1.4
+ */
+ public void setStencilFunction(int function, int refValue, int compareMask) {
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_STENCIL_ATTRIBUTES_WRITE)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("RenderingAttributes16"));
+ }
+ }
+ if (isLive())
+ ((RenderingAttributesRetained)this.retained).setStencilFunction(function,
+ refValue,
+ compareMask);
+ else
+ ((RenderingAttributesRetained)this.retained).initStencilFunction(function,
+ refValue,
+ compareMask);
+ }
+
+ /**
+ * Sets the stencil function, reference value, and comparison mask
+ * for this RenderingAttributes object to the specified parameters.
+ *
+ * @param params an array of three integers that specifies the new
+ * stencil function, reference value, and comparison mask.
+ * Element 0 of the array specifies the
+ * stencil function, element 1 specifies the
+ * reference value, and element 2 specifies the
+ * comparison mask.
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @see #setStencilFunction(int,int,int)
+ *
+ * @since Java 3D 1.4
+ */
+ public void setStencilFunction(int[] params) {
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_STENCIL_ATTRIBUTES_WRITE)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("RenderingAttributes16"));
+ }
+ }
+
+ if (isLive())
+ ((RenderingAttributesRetained)this.retained).setStencilFunction(params[0],
+ params[1],
+ params[2]);
+ else
+ ((RenderingAttributesRetained)this.retained).initStencilFunction(params[0],
+ params[1],
+ params[2]);
+
+ }
+
+ /**
+ * Retrieves the stencil function, reference value, and comparison mask,
+ * and copies them into the specified array. The caller must ensure
+ * that this array has been allocated with enough space to hold the results.
+ *
+ * @param params array that will receive the current stencil function,
+ * reference value, and comparison mask. The stencil function is copied
+ * into element 0 of the array, the reference value is copied
+ * into element 1, and the comparison mask is copied
+ * into element 2.
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @since Java 3D 1.4
+ */
+ public void getStencilFunction(int[] params) {
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_STENCIL_ATTRIBUTES_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("RenderingAttributes17"));
+ }
+ }
+
+ ((RenderingAttributesRetained)this.retained).getStencilFunction(params);
+ }
+
+ /**
+ * Sets the stencil write mask for this RenderingAttributes
+ * object. This mask controls which bits of the
+ * stencil buffer are written.
+ * The default value is <code>~0</code> (all ones).
+ *
+ * @param mask the new stencil write mask.
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @since Java 3D 1.4
+ */
+ public void setStencilWriteMask(int mask) {
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_STENCIL_ATTRIBUTES_WRITE)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("RenderingAttributes16"));
+ }
+ }
+
+ if (isLive())
+ ((RenderingAttributesRetained)this.retained).setStencilWriteMask(mask);
+ else
+ ((RenderingAttributesRetained)this.retained).initStencilWriteMask(mask);
+ }
+
+ /**
+ * Retrieves the current stencil write mask for this RenderingAttributes
+ * object.
+ *
+ * @return the stencil write mask.
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @since Java 3D 1.4
+ */
+ public int getStencilWriteMask() {
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_STENCIL_ATTRIBUTES_READ)) {
+ throw new CapabilityNotSetException(J3dI18N.getString("RenderingAttributes17"));
+ }
+ }
+
+ return ((RenderingAttributesRetained)this.retained).getStencilWriteMask();
}
}
diff --git a/src/classes/share/javax/media/j3d/RenderingAttributesRetained.java b/src/classes/share/javax/media/j3d/RenderingAttributesRetained.java
index 1847fdf..44afe88 100644
--- a/src/classes/share/javax/media/j3d/RenderingAttributesRetained.java
+++ b/src/classes/share/javax/media/j3d/RenderingAttributesRetained.java
@@ -37,6 +37,15 @@ class RenderingAttributesRetained extends NodeComponentRetained {
static final int RASTER_OP_VALUE = 0x80;
+ static final int DEPTH_TEST_FUNC = 0x100;
+
+ static final int STENCIL_ENABLE = 0x200;
+
+ static final int STENCIL_OP_VALUES = 0x400;
+
+ static final int STENCIL_FUNC = 0x800;
+
+ static final int STENCIL_WRITE_MASK = 0x1000;
// depth buffer Enable for hidden surface removal
boolean depthBufferEnable = true;
@@ -47,6 +56,8 @@ class RenderingAttributesRetained extends NodeComponentRetained {
int alphaTestFunction = RenderingAttributes.ALWAYS;
+ int depthTestFunction = RenderingAttributes.LESS_OR_EQUAL;
+
boolean visible = true;
boolean ignoreVertexColors = false;
@@ -54,8 +65,19 @@ class RenderingAttributesRetained extends NodeComponentRetained {
// raster operation
boolean rasterOpEnable = false;
int rasterOp = RenderingAttributes.ROP_COPY;
-
+
+ // stencil operation
+ boolean stencilEnable = false;
+ int stencilFailOp = RenderingAttributes.STENCIL_KEEP;
+ int stencilZFailOp = RenderingAttributes.STENCIL_KEEP;
+ int stencilZPassOp = RenderingAttributes.STENCIL_KEEP;
+ int stencilFunction = RenderingAttributes.ALWAYS;
+ int stencilReferenceValue = 0;
+ int stencilCompareMask = ~0;
+ int stencilWriteMask = ~0;
+
// depth buffer comparison function. Used by multi-texturing only
+ //[PEPE] NOTE: they are both unused. Candidates for removal.
static final int LESS = 0;
static final int LEQUAL = 1;
@@ -113,16 +135,33 @@ class RenderingAttributesRetained extends NodeComponentRetained {
return visible;
}
- final void initIgnoreVertexColors(boolean state) {
+
+ /**
+ * Enables or disables vertex colors for this RenderAttributes
+ * component object.
+ * @param state true or false to enable or disable vertex colors
+ */
+ final void initIgnoreVertexColors(boolean state) {
ignoreVertexColors = state;
}
+ /**
+ * Enables or disables vertex colors for this RenderAttributes
+ * component object and sends a
+ * message notifying the interested structures of the change.
+ * @param state true or false to enable or disable depth vertex colors
+ */
final void setIgnoreVertexColors(boolean state) {
initIgnoreVertexColors(state);
sendMessage(IGNORE_VCOLOR,
(state ? Boolean.TRUE: Boolean.FALSE));
}
+ /**
+ * Retrieves the state of vertex color Enable flag
+ * @return true if vertex colors are enabled, false
+ * if vertex colors are disabled
+ */
final boolean getIgnoreVertexColors() {
return ignoreVertexColors;
}
@@ -260,6 +299,47 @@ class RenderingAttributesRetained extends NodeComponentRetained {
return alphaTestFunction;
}
+ /**
+ * Set depth test function. This function is used to compare the
+ * depth test value with each per-pixel alpha value. If the test
+ * passes, then the pixel is written otherwise the pixel is not
+ * written.
+ * @param function the new depth test function. One of:
+ * ALWAYS, NEVER, EQUAL, NOT_EQUAL, LESS, LESS_OR_EQUAL, GREATER,
+ * GREATER_OR_EQUAL.
+ * Default value is LESS_OR_EQUAL
+ * @since Java 3D 1.4
+ */
+ final void initDepthTestFunction(int function){
+ depthTestFunction = function;
+ }
+
+ /**
+ * Set depth test function. This function is used to compare the
+ * depth test value with each per-pixel depth value. If the test
+ * passes, the pixel is written otherwise the pixel is not
+ * written.
+ * @param function the new depth test function. One of
+ * ALWAYS, NEVER, EQUAL, NOT_EQUAL, LESS, LESS_OR_EQUAL, GREATER,
+ * GREATER_OR_EQUAL
+ * Default value is LESS_OR_EQUAL
+ * @since Java 3D 1.4
+ */
+ final void setDepthTestFunction(int function){
+ initDepthTestFunction(function);
+ sendMessage(DEPTH_TEST_FUNC, new Integer(function));
+ }
+
+ /**
+ * Retrieves current depth test function.
+ * @return the current depth test function
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ * @since Java 3D 1.4
+ */
+ final int getDepthTestFunction(){
+ return depthTestFunction;
+ }
/**
* Initialize the raster op enable flag
@@ -306,30 +386,149 @@ class RenderingAttributesRetained extends NodeComponentRetained {
}
+ // Stencil operations
+ /**
+ * Initialize the stencil enable state
+ */
+ final void initStencilEnable(boolean state) {
+ stencilEnable = state;
+ }
+
+ /**
+ * Set the stencil enable state
+ */
+ final void setStencilEnable(boolean state) {
+ initStencilEnable(state);
+ sendMessage(STENCIL_ENABLE, new Boolean(state));
+ }
+
+ /**
+ * Retrieves the current stencil enable state.
+ */
+ final boolean getStencilEnable() {
+ return stencilEnable;
+ }
+
+ /**
+ * Initialize the stencil op. value
+ */
+ final void initStencilOp(int failOp, int zFailOp, int zPassOp) {
+ stencilFailOp = failOp;
+ stencilZFailOp = zFailOp;
+ stencilZPassOp = zPassOp;
+ }
+
+ /**
+ * Set the stencil op. value
+ */
+ final void setStencilOp(int failOp, int zFailOp, int zPassOp) {
+ initStencilOp(failOp, zFailOp, zPassOp);
+
+ ArrayList arrList = new ArrayList(3);
+ arrList.add(new Integer(failOp));
+ arrList.add(new Integer(zFailOp));
+ arrList.add(new Integer(zPassOp));
+ sendMessage(STENCIL_OP_VALUES, arrList);
+ }
+
+ /**
+ * Retrieves the current stencil op. value
+ */
+ final void getStencilOp(int[] stencilOps) {
+ stencilOps[0] = stencilFailOp;
+ stencilOps[1] = stencilZFailOp;
+ stencilOps[2] = stencilZPassOp;
+ }
+
+
+ /**
+ * Initialize the stencil function value
+ */
+ final void initStencilFunction(int function, int refValue, int compareMask) {
+ stencilFunction = function;
+ stencilReferenceValue = refValue;
+ stencilCompareMask = compareMask;
+ }
+
+ /**
+ * Set the stencil function value
+ */
+ final void setStencilFunction(int function, int refValue, int compareMask) {
+ initStencilOp(function, refValue, compareMask);
+
+ ArrayList arrList = new ArrayList(3);
+ arrList.add(new Integer(function));
+ arrList.add(new Integer(refValue));
+ arrList.add(new Integer(compareMask));
+ sendMessage(STENCIL_FUNC, arrList);
+ }
+
+ /**
+ * Retrieves the current stencil op. value
+ */
+ final void getStencilFunction(int[] params) {
+ params[0] = stencilFunction;
+ params[1] = stencilReferenceValue;
+ params[2] = stencilCompareMask;
+ }
+
+
+ /**
+ * Initialize the stencil write mask
+ */
+ final void initStencilWriteMask(int mask) {
+ stencilWriteMask = mask;
+ }
+
+ /**
+ * Set the stencil write mask
+ */
+ final void setStencilWriteMask(int mask) {
+ initStencilWriteMask(mask);
+ sendMessage(STENCIL_WRITE_MASK, new Integer(mask));
+ }
+
+ /**
+ * Retrieves the current stencil write mask
+ */
+ final int getStencilWriteMask() {
+ return stencilWriteMask;
+ }
+
/**
* Updates the native context.
*/
+
+ // TODO : Need to handle stencil operation on the native side -- Chien
native void updateNative(long ctx,
boolean depthBufferWriteEnableOverride,
boolean depthBufferEnableOverride,
boolean depthBufferEnable,
boolean depthBufferWriteEnable,
+ int depthTestFunction,
float alphaTestValue, int alphaTestFunction,
boolean ignoreVertexColors,
- boolean rasterOpEnable, int rasterOp);
+ boolean rasterOpEnable, int rasterOp,
+ boolean userStencilAvailable, boolean stencilEnable,
+ int stencilFailOp, int stencilZFailOp, int stencilZPassOp,
+ int stencilFunction, int stencilReferenceValue,
+ int stencilCompareMask, int stencilWriteMask );
/**
* Updates the native context.
*/
- void updateNative(long ctx,
+ void updateNative(Canvas3D c3d,
boolean depthBufferWriteEnableOverride,
boolean depthBufferEnableOverride) {
- updateNative(ctx,
+ updateNative(c3d.ctx,
depthBufferWriteEnableOverride, depthBufferEnableOverride,
- depthBufferEnable, depthBufferWriteEnable, alphaTestValue,
- alphaTestFunction, ignoreVertexColors,
- rasterOpEnable, rasterOp);
+ depthBufferEnable, depthBufferWriteEnable, depthTestFunction,
+ alphaTestValue, alphaTestFunction, ignoreVertexColors,
+ rasterOpEnable, rasterOp, c3d.userStencilAvailable, stencilEnable,
+ stencilFailOp, stencilZFailOp, stencilZPassOp,
+ stencilFunction, stencilReferenceValue, stencilCompareMask,
+ stencilWriteMask );
}
/**
@@ -368,14 +567,17 @@ class RenderingAttributesRetained extends NodeComponentRetained {
* given "value"
*/
synchronized void updateMirrorObject(int component, Object value) {
- RenderingAttributesRetained mirrorRa = (RenderingAttributesRetained)mirror;
-
+ RenderingAttributesRetained mirrorRa = (RenderingAttributesRetained)mirror;
+
if ((component & DEPTH_ENABLE) != 0) {
mirrorRa.depthBufferEnable = ((Boolean)value).booleanValue();
}
else if ((component & DEPTH_WRITE_ENABLE) != 0) {
mirrorRa.depthBufferWriteEnable = ((Boolean)value).booleanValue();
}
+ else if ((component & DEPTH_TEST_FUNC) != 0) {
+ mirrorRa.depthTestFunction = ((Integer)value).intValue();
+ }
else if ((component & ALPHA_TEST_VALUE) != 0) {
mirrorRa.alphaTestValue = ((Float)value).floatValue();
}
@@ -393,7 +595,25 @@ class RenderingAttributesRetained extends NodeComponentRetained {
}
else if ((component & RASTER_OP_VALUE) != 0) {
mirrorRa.rasterOp = (((Integer)value).intValue());
- }
+ }
+ else if ((component & STENCIL_ENABLE) != 0) {
+ mirrorRa.stencilEnable = (((Boolean)value).booleanValue());
+ }
+ else if ((component & STENCIL_OP_VALUES) != 0) {
+ ArrayList arrlist = (ArrayList) value;
+ mirrorRa.stencilFailOp = (((Integer)arrlist.get(0)).intValue());
+ mirrorRa.stencilZFailOp = (((Integer)arrlist.get(1)).intValue());
+ mirrorRa.stencilZPassOp = (((Integer)arrlist.get(2)).intValue());
+ }
+ else if ((component & STENCIL_FUNC) != 0) {
+ ArrayList arrlist = (ArrayList) value;
+ mirrorRa.stencilFunction = (((Integer)arrlist.get(0)).intValue());
+ mirrorRa.stencilReferenceValue = (((Integer)arrlist.get(1)).intValue());
+ mirrorRa.stencilCompareMask = (((Integer)arrlist.get(2)).intValue());
+ }
+ else if ((component & STENCIL_WRITE_MASK) != 0) {
+ mirrorRa.stencilWriteMask = (((Integer)value).intValue());
+ }
}
boolean equivalent(RenderingAttributesRetained rr) {
@@ -406,7 +626,16 @@ class RenderingAttributesRetained extends NodeComponentRetained {
(rr.visible == visible) &&
(rr.ignoreVertexColors == ignoreVertexColors) &&
(rr.rasterOpEnable == rasterOpEnable) &&
- (rr.rasterOp == rasterOp));
+ (rr.rasterOp == rasterOp) &&
+ (rr.depthTestFunction == depthTestFunction) &&
+ (rr.stencilEnable == stencilEnable) &&
+ (rr.stencilFailOp == stencilFailOp) &&
+ (rr.stencilZFailOp == stencilZFailOp) &&
+ (rr.stencilZPassOp == stencilZPassOp) &&
+ (rr.stencilFunction == stencilFunction) &&
+ (rr.stencilReferenceValue == stencilReferenceValue) &&
+ (rr.stencilCompareMask == stencilCompareMask) &&
+ (rr.stencilWriteMask == stencilWriteMask));
}
protected void set(RenderingAttributesRetained ra) {
@@ -415,10 +644,20 @@ class RenderingAttributesRetained extends NodeComponentRetained {
depthBufferWriteEnable = ra.depthBufferWriteEnable;
alphaTestValue = ra.alphaTestValue;
alphaTestFunction = ra.alphaTestFunction;
+ depthTestFunction = ra.depthTestFunction;
visible = ra.visible;
ignoreVertexColors = ra.ignoreVertexColors;
rasterOpEnable = ra.rasterOpEnable;
rasterOp = ra.rasterOp;
+ stencilEnable = ra.stencilEnable;
+ stencilFailOp = ra.stencilFailOp;
+ stencilZFailOp = ra.stencilZFailOp;
+ stencilZPassOp = ra.stencilZPassOp;
+ stencilFunction = ra.stencilFunction;
+ stencilReferenceValue = ra.stencilReferenceValue;
+ stencilCompareMask = ra.stencilCompareMask;
+ stencilWriteMask = ra.stencilWriteMask;
+
}
final void sendMessage(int attrMask, Object attr) {
@@ -462,7 +701,7 @@ class RenderingAttributesRetained extends NodeComponentRetained {
}
-
+ // TODO : Need to handle stencil operation -- Chien
void handleFrequencyChange(int bit) {
int mask = 0;
@@ -478,6 +717,16 @@ class RenderingAttributesRetained extends NodeComponentRetained {
mask = RASTER_OP_ENABLE;
if(bit == RenderingAttributes.ALLOW_DEPTH_ENABLE_WRITE)
mask = DEPTH_WRITE_ENABLE;
+ if( bit == RenderingAttributes.ALLOW_DEPTH_TEST_FUNCTION_WRITE)
+ mask = DEPTH_TEST_FUNC;
+
+ if( bit == RenderingAttributes.ALLOW_STENCIL_ATTRIBUTES_WRITE)
+ mask = DEPTH_TEST_FUNC;
+
+ if( bit == RenderingAttributes.ALLOW_DEPTH_TEST_FUNCTION_WRITE)
+ mask = STENCIL_ENABLE | STENCIL_OP_VALUES | STENCIL_FUNC |
+ STENCIL_WRITE_MASK;
+
if (mask != 0)
setFrequencyChangeMask(bit, mask);
// System.out.println("changedFreqent2 = "+changedFrequent);
diff --git a/src/classes/share/javax/media/j3d/RenderingAttributesStructure.java b/src/classes/share/javax/media/j3d/RenderingAttributesStructure.java
index d81a58a..abe2180 100644
--- a/src/classes/share/javax/media/j3d/RenderingAttributesStructure.java
+++ b/src/classes/share/javax/media/j3d/RenderingAttributesStructure.java
@@ -42,11 +42,13 @@ class RenderingAttributesStructure extends J3dStructure implements ObjectUpdate
for (int i=0; i < nMsg; i++) {
m = messages[i];
switch (m.type) {
- // Apperance is always updated immediately, since rBin needs
+ // Appearance is always updated immediately, since rBin needs
// the most up-to-date values for restructuring
case J3dMessage.APPEARANCE_CHANGED:
- case J3dMessage.TEXTURE_UNIT_STATE_CHANGED: // TODO: Is this correct?
+ case J3dMessage.SHADER_APPEARANCE_CHANGED:
+ case J3dMessage.TEXTURE_UNIT_STATE_CHANGED:
{
+ // System.out.println("1 RAS : J3dMessage type : " + m.type);
int component = ((Integer)m.args[1]).intValue();
NodeComponentRetained nc = (NodeComponentRetained)m.args[0];
nc.mirror.changedFrequent = ((Integer)m.args[3]).intValue();
@@ -69,7 +71,11 @@ class RenderingAttributesStructure extends J3dStructure implements ObjectUpdate
case J3dMessage.TRANSPARENCYATTRIBUTES_CHANGED:
case J3dMessage.MATERIAL_CHANGED:
case J3dMessage.TEXCOORDGENERATION_CHANGED:
+ case J3dMessage.SHADER_ATTRIBUTE_CHANGED:
+ case J3dMessage.SHADER_ATTRIBUTE_SET_CHANGED:
{
+ // System.out.println("2 RAS : J3dMessage type : " + m.type);
+
NodeComponentRetained nc = (NodeComponentRetained)m.args[0];
nc.mirror.changedFrequent = ((Integer)m.args[3]).intValue();
if (nc.mirror.changedFrequent != 0) {
@@ -105,8 +111,6 @@ class RenderingAttributesStructure extends J3dStructure implements ObjectUpdate
NodeComponentRetained nc = (NodeComponentRetained)m.args[0];
nc.mirror.changedFrequent = ((Integer)m.args[4]).intValue();
-
-
if (nc.mirror.changedFrequent != 0) {
objList.add(m);
addMirrorObj = true;
@@ -118,11 +122,9 @@ class RenderingAttributesStructure extends J3dStructure implements ObjectUpdate
}
}
break;
-
case J3dMessage.TEXTURE_CHANGED:
{
NodeComponentRetained nc = (NodeComponentRetained)m.args[0];
- int attrMask = ((Integer)m.args[1]).intValue();
nc.mirror.changedFrequent = ((Integer)m.args[3]).intValue();
objList.add(m);
@@ -190,6 +192,7 @@ class RenderingAttributesStructure extends J3dStructure implements ObjectUpdate
updateTextureAttributes((Object[])m.args);
}
else if (m.type == J3dMessage.APPEARANCE_CHANGED ||
+ m.type == J3dMessage.SHADER_APPEARANCE_CHANGED ||
m.type == J3dMessage.TEXTURE_UNIT_STATE_CHANGED){
NodeComponentRetained nc = (NodeComponentRetained)m.args[0];
nc.mirror.compChanged = 0;
@@ -206,12 +209,13 @@ class RenderingAttributesStructure extends J3dStructure implements ObjectUpdate
}
- void updateNodeComponent(Object[] args) {
- NodeComponentRetained n = (NodeComponentRetained)args[0];
- n.updateMirrorObject(((Integer)args[1]).intValue(), args[2]);
+ private void updateNodeComponent(Object[] args) {
+ // System.out.println("RAS : updateNodeComponent : " + this);
+ NodeComponentRetained n = (NodeComponentRetained)args[0];
+ n.updateMirrorObject(((Integer)args[1]).intValue(), args[2]);
}
- void updateTextureAttributes(Object[] args) {
+ private void updateTextureAttributes(Object[] args) {
TextureAttributesRetained n = (TextureAttributesRetained)args[0];
n.updateMirrorObject(((Integer)args[1]).intValue(), args[2], args[3]);
}
diff --git a/src/classes/share/javax/media/j3d/SceneGraphObject.java b/src/classes/share/javax/media/j3d/SceneGraphObject.java
index bfae7f3..32c52b8 100644
--- a/src/classes/share/javax/media/j3d/SceneGraphObject.java
+++ b/src/classes/share/javax/media/j3d/SceneGraphObject.java
@@ -15,9 +15,37 @@ package javax.media.j3d;
import java.util.Hashtable;
/**
- * SceneGraphObject is a common superclass for
- * all scene graph component objects. This includes Node,
- * Geometry, Appearance, etc.
+ * SceneGraphObject is the common superclass for all scene graph
+ * objects. Scene graph objects are classified into two main types:
+ * nodes and node components. The Node object is the common superclass
+ * of all nodes, which includes TransformGroup, Shape3D, etc.
+ * The NodeComponent object is the common superclass of all node
+ * components, which includes Geometry, Appearance, etc.
+ *
+ * <p>
+ * All scene graph objects have a name, a user data object, a set of
+ * capability bits, and a set of capabilityIsFrequent bits.
+ *
+ * <p>
+ * Capability bits control whether a particular attribute in a node or
+ * node component is readable or writable. For live or compiled scene
+ * graphs, only those attributes whose capabilities are set before the
+ * scene graph is compiled or made live may be read or written. The
+ * default value for all <i>read</i> capability bits is true, meaning
+ * that all attributes may be read by default. The default value for
+ * all <i>write</i> capability bits is false, meaning that no
+ * attributes may be written by default. Read capability bits are
+ * defined as those capability bits of the form <code>ALLOW_*_READ</code>,
+ * plus the <code>ALLOW_INTERSECT</code> capability bit. Write
+ * capability bits are defined as those capability bits of the form
+ * <code>ALLOW_*_WRITE</code>, plus the <code>ALLOW_CHILDREN_EXTEND</code>
+ * and <code>ALLOW_DETACH</code> capability bits.
+ *
+ * <p>
+ * NOTE that the <code>ENABLE_COLLISION_REPORTING</code> and
+ * <code>ENABLE_PICK_REPORTING</code> bits are not really capability bits,
+ * although they are set with the setCapability method. The default value
+ * for each of the <code>ENABLE_*_REPORTING bits</code> is false.
*/
public abstract class SceneGraphObject extends Object {
// Any global flags? (e.g., execution cullable, collideable)
@@ -43,6 +71,9 @@ public abstract class SceneGraphObject extends Object {
// A reference to user data
private Object userData = null;
+ // Optional name for object.
+ private String objectName = null;
+
// use for cloneTree/cloneNode only, set to null after the operation
Hashtable nodeHashtable = null;
@@ -52,10 +83,13 @@ public abstract class SceneGraphObject extends Object {
* Constructs a SceneGraphObject with default parameters. The default
* values are as follows:
* <ul>
- * capability bits : clear (all bits)<br>
+ * all <i>read</i> capability bits : set (true)<br>
+ * all <i>write</i> capability bits : clear (false)<br>
+ * all capabilityIsFrequent bits : set (true)<br>
* isLive : false<br>
* isCompiled : false<br>
* user data : null<br>
+ * name : null<br>
* </ul>
*/
public SceneGraphObject() {
@@ -76,7 +110,18 @@ public abstract class SceneGraphObject extends Object {
// this.retained = new <ClassName>Retained();
// this.retained.setSource(this);
}
-
+
+ /**
+ * Method to set default read capability bits to true
+ */
+ void setDefaultReadCapabilities(int[] bits) {
+ if (true /*VirtualUniverse.mc.defaultReadCapability*/) {
+ for (int i=0; i < bits.length; i++) {
+ setCapability(bits[i]);
+ }
+ }
+ }
+
/**
* Retrieves the specified capability bit. Note that only one capability
* bit may be retrieved per method invocation--capability bits cannot
@@ -331,6 +376,28 @@ public abstract class SceneGraphObject extends Object {
public void updateNodeReferences(NodeReferenceTable referenceTable) {
}
+ /**
+ * Sets the name of this object. Object names are for information
+ * only.
+ *
+ * @param name the new name of this object
+ *
+ * @since Java 3D 1.4
+ */
+ public void setName( String name ) {
+ objectName = name;
+ }
+
+ /**
+ * Returns the name of this object.
+ *
+ * @return the name of this object
+ *
+ * @since Java 3D 1.4
+ */
+ public String getName() {
+ return objectName;
+ }
/**
* Copies all SceneGraphObject information from
@@ -353,6 +420,7 @@ public abstract class SceneGraphObject extends Object {
// Duplicate any class specific data here.
capabilityBits = originalNode.capabilityBits;
userData = originalNode.userData;
+ objectName = originalNode.objectName;
}
@@ -402,4 +470,25 @@ public abstract class SceneGraphObject extends Object {
return originalNodeComponent;
}
}
+
+ // Internal method to make a prefix out of the name of this object
+ String getNamePrefix() {
+ String name = getName();
+
+ if (name != null) {
+ return "[" + name + "] ";
+ }
+
+ return "";
+ }
+
+ /**
+ * Returns a String representation of this SceneGraphObject.
+ * If its name is non-null, then it is concatenated with
+ * super.toString().
+ */
+ public String toString() {
+ return getNamePrefix() + super.toString();
+ }
+
}
diff --git a/src/classes/share/javax/media/j3d/ScreenViewCache.java b/src/classes/share/javax/media/j3d/ScreenViewCache.java
index a3802d4..397367a 100644
--- a/src/classes/share/javax/media/j3d/ScreenViewCache.java
+++ b/src/classes/share/javax/media/j3d/ScreenViewCache.java
@@ -37,7 +37,12 @@ class ScreenViewCache extends Object {
// Mask that indicates Screen3D view dependence info. has changed,
// and CanvasViewCache may need to recompute the final view matries.
- int scrvcDirtyMask = 0;
+ // Issue 163: Array of dirty bits is used because the Renderer and
+ // RenderBin run asynchronously. Now that they each have a separate
+ // instance of CanvasViewCache (due to the fix for Issue 109), they
+ // need separate dirty bits. Array element 0 is used for the Renderer and
+ // element 1 is used for the RenderBin.
+ int[] scrvcDirtyMask = new int[2];
//
// Tracker-base coordinate system to image-plate coordinate
@@ -72,17 +77,20 @@ class ScreenViewCache extends Object {
* Take snapshot of all per-screen API parameters.
*/
synchronized void snapshot() {
-
- // accumulate the dirty bits for offscreen because
- // the dirty bits will not be processed until renderOffScreen
- // or triggered by RenderBin at some little time
- if (screen.offScreen)
- scrvcDirtyMask |= screen.scrDirtyMask;
- else
- scrvcDirtyMask = screen.scrDirtyMask;
-
- screen.scrDirtyMask = 0;
- physicalScreenWidth = screen.physicalScreenWidth;
+
+ // accumulate the dirty bits for offscreen because
+ // the dirty bits will not be processed until renderOffScreen
+ // or triggered by RenderBin at some little time
+ if (screen.offScreen) {
+ scrvcDirtyMask[0] |= screen.scrDirtyMask;
+ scrvcDirtyMask[1] |= screen.scrDirtyMask;
+ } else {
+ scrvcDirtyMask[0] = screen.scrDirtyMask;
+ scrvcDirtyMask[1] = screen.scrDirtyMask;
+ }
+ screen.scrDirtyMask = 0;
+
+ physicalScreenWidth = screen.physicalScreenWidth;
physicalScreenHeight = screen.physicalScreenHeight;
screenWidth = screen.screenSize.width;
screenHeight = screen.screenSize.height;
diff --git a/src/classes/share/javax/media/j3d/Sensor.java b/src/classes/share/javax/media/j3d/Sensor.java
index ef44ac6..05df43a 100644
--- a/src/classes/share/javax/media/j3d/Sensor.java
+++ b/src/classes/share/javax/media/j3d/Sensor.java
@@ -59,29 +59,35 @@ public class Sensor {
/**
* Set predictor type to do no prediction; this is the default.
+ *
+ * @deprecated As of Java 3D version 1.4, prediction is not a
+ * supported feature.
*/
public static final int PREDICT_NONE = 1;
/**
- * Set predictor type to generate the SensorRead to correspond with
- * the next frame time.
+ * @deprecated As of Java 3D version 1.4, prediction is not a
+ * supported feature.
*/
public static final int PREDICT_NEXT_FRAME_TIME = 2;
/**
* Use no prediction policy; this is the default.
+ *
+ * @deprecated As of Java 3D version 1.4, prediction is not a
+ * supported feature.
*/
public static final int NO_PREDICTOR = 16;
/**
- * Set the predictor policy to assume the sensor is predicting head
- * position/orientation.
+ * @deprecated As of Java 3D version 1.4, prediction is not a
+ * supported feature.
*/
public static final int HEAD_PREDICTOR = 32;
/**
- * Set the predictor policy to assume the sensor is predicting hand
- * position/orientation.
+ * @deprecated As of Java 3D version 1.4, prediction is not a
+ * supported feature.
*/
public static final int HAND_PREDICTOR = 64;
@@ -110,11 +116,11 @@ public class Sensor {
// size of the sensor read buffer
int sensorReadCount;
- // Default prediction policy: don't predict
- int predictionPolicy = NO_PREDICTOR;
+ // Prediction policy -- unused
+ private int predictionPolicy = NO_PREDICTOR;
- // Default Predictor none
- int predictorType = PREDICT_NONE;
+ // Predictor type -- unused
+ private int predictorType = PREDICT_NONE;
// This sensor's associated device
InputDevice device;
@@ -135,12 +141,6 @@ public class Sensor {
Matrix3d temp_rot = new Matrix3d();
Matrix3d local_svd = new Matrix3d();
- // Prediction workspace -- these may go away when the readings array
- // is used.
- static int MAX_PREDICTION_LENGTH = 20;
- Transform3D[] previousReads = new Transform3D[MAX_PREDICTION_LENGTH];
- long[] times = new long[MAX_PREDICTION_LENGTH];
-
/**
* Constructs a Sensor object for the specified input device using
@@ -149,8 +149,8 @@ public class Sensor {
* sensor read count : 30<br>
* sensor button count : 0<br>
* hot spot : (0,0,0)<br>
- * predictor : PREDICT_NONE<br>
- * prediction policy : NO_PREDICTOR<br>
+ * predictor : PREDICT_NONE &mdash; <i>this attribute is unused</i><br>
+ * prediction policy : NO_PREDICTOR &mdash; <i>this attribute is unused</i><br>
* </ul>
* @param device the Sensor's associated device.
*/
@@ -237,11 +237,6 @@ public class Sensor {
}
currentIndex = 0;
this.hotspot = new Point3d(hotspot);
-
- // prediction initialization
- for(int i=0 ; i<MAX_PREDICTION_LENGTH ; i++) {
- previousReads[i] = new Transform3D();
- }
}
// argument of 0 is last reading (ie, currentIndex), argument
@@ -252,11 +247,16 @@ public class Sensor {
}
/**
- * This function sets the type of predictor to use with this sensor.
+ * Sets the type of predictor to use with this sensor.
+ * Since prediction is not implemented (and never has been), this
+ * attribute has no effect.
* @param predictor predictor type one of PREDICT_NONE or
* PREDICT_NEXT_FRAME_TIME
* @exception IllegalArgumentException if an invalid predictor type
* is specified.
+ *
+ * @deprecated As of Java 3D version 1.4, prediction is not a
+ * supported feature.
*/
public void setPredictor(int predictor){
if (predictor != PREDICT_NONE && predictor != PREDICT_NEXT_FRAME_TIME) {
@@ -267,20 +267,27 @@ public class Sensor {
}
/**
- * This function returns the type of predictor used by this sensor.
- * @return returns the predictor type. One of PREDICT_NONE or
- * PREDICT_NEXT_FRAME_TIME.
+ * Returns the type of predictor used by this sensor.
+ * @return the predictor type.
+ *
+ * @deprecated As of Java 3D version 1.4, prediction is not a
+ * supported feature.
*/
public int getPredictor(){
return predictorType;
}
/**
- * This function sets the prediction policy use by this sensor.
+ * Sets the prediction policy use by this sensor.
+ * Since prediction is not implemented (and never has been), this
+ * attribute has no effect.
* @param policy prediction policy one of NO_PREDICTOR, HEAD_PREDICTOR,
* or HAND_PREDICTOR
* @exception IllegalArgumentException if an invalid prediction policy
* is specified.
+ *
+ * @deprecated As of Java 3D version 1.4, prediction is not a
+ * supported feature.
*/
public void setPredictionPolicy(int policy){
if (policy != NO_PREDICTOR && policy != HEAD_PREDICTOR &&
@@ -291,9 +298,11 @@ public class Sensor {
}
/**
- * This function returns the prediction policy used by this sensor.
- * @return returns the prediction policy. one of NO_PREDICTOR,
- * HEAD_PREDICTOR, or HAND_PREDICTOR.
+ * Returns the prediction policy used by this sensor.
+ * @return the prediction policy.
+ *
+ * @deprecated As of Java 3D version 1.4, prediction is not a
+ * supported feature.
*/
public int getPredictionPolicy(){
return predictionPolicy;
@@ -332,79 +341,30 @@ public class Sensor {
}
/**
- * Computes the sensor reading consistent with the prediction policy
- * and copies that value into the specified argument; calling this method
- * with a prediction policy of NO_PREDICTOR will return the last sensor
- * reading; calling this method with a prediction policy of HAND_PREDICTOR,
- * or HEAD_PREDICTOR will extrapolate previous sensor readings to the
- * current time.
- * @param read The matrix that will receive the predicted sensor reading
+ * Retrieves the last sensor reading and copies that value into
+ * the specified argument.
+ *
+ * @param read the matrix that will receive the sensor reading
*/
- public void getRead(Transform3D read){
- long time;
-
+ public void getRead(Transform3D read) {
if(demand_driven == true)
device.pollAndProcessInput();
- time = System.currentTimeMillis();
-
- // before using prediction, fill in some values
- if(num_reads_so_far < 40*SENSOR_READ_COUNT_BUFFER) {
- num_reads_so_far++;
- read.set(readings[currentIndex].read);
- return;
- }
-
- switch(predictionPolicy) {
- case NO_PREDICTOR:
- read.set(readings[currentIndex].read);
- break;
- case HAND_PREDICTOR:
- read.set(readings[currentIndex].read);
- //getPredictedRead(read, time, 3, 2);
- break;
- case HEAD_PREDICTOR:
- read.set(readings[currentIndex].read);
- //getPredictedRead(read, time, 3, 2);
- break;
- }
+ read.set(readings[currentIndex].read);
}
/**
- * Computes the sensor reading consistent as of time deltaT in the future
- * and copies that value into the specified argument; the reading is
- * computed using the current prediction policy; a prediction policy of
- * NO_PREDICTOR will yield the most recent sensor reading for any
- * deltaT argument (i.e., this method is the same as getRead for a prediction
- * policy of NO_PREDICTOR). The time argument must be >= 0.
- * @param read the matrix that will receive the predicted sensor reading
- * @param deltaT the time delta into the future for this read
+ * Retrieves the last sensor reading and copies that value into
+ * the specified argument.
+ *
+ * @param read the matrix that will receive the sensor reading
+ * @param deltaT this parameter is ignored
+ *
+ * @deprecated As of Java 3D version 1.4, prediction is not a
+ * supported feature; use <code>getRead(Transform3D)</code> instead.
*/
public void getRead(Transform3D read, long deltaT){
- long current_time;
-
- if(deltaT < 0L) {
- throw new IllegalArgumentException(J3dI18N.getString("Sensor2"));
- }
-
- if(demand_driven == true)
- device.pollAndProcessInput();
-
- current_time = System.currentTimeMillis();
-
- switch(predictionPolicy) {
- case NO_PREDICTOR:
- read.set(readings[currentIndex].read);
- break;
- case HAND_PREDICTOR:
- read.set(readings[currentIndex].read);
- //getPredictedRead(read, current_time + deltaT, 3, 2);
- break;
- case HEAD_PREDICTOR:
- read.set(readings[currentIndex].read);
- //getPredictedRead(read, current_time + deltaT, 3, 2);
- break;
- }
+ getRead(read);
}
/**
@@ -566,132 +526,4 @@ public class Sensor {
currentIndex = temp;
}
- /**
- * This routine does an nth order fit of the last num_readings, which
- * can be plotted on a graph of time vs. sensor reading. There is a
- * separate fit done for each of the 16 matrix elements, then an SVD
- * done on the final matrix. The curve that is produced takes into
- * account non-constant times between each sample (it is fully general).
- * This curve can then be used to produce a prediction for any
- * time in the future by simply inserting a time value and using the
- * solution matrix.
- */
- void getPredictedRead(Transform3D transform, long time, int num_readings,
- int order) {
-
- int index = currentIndex; // lock in current_index for MT-safety
- long time_basis = readings[index].time;
- long tempTime;
-
- time -= time_basis;
-
- GMatrix A = new GMatrix(num_readings, order+1);
-
- for(int i=0 ; i<num_readings ; i++) {
- A.setElement(i, 0, 1.0);
- tempTime = lastTimeRelative(num_readings-i-1, index, time_basis);
- A.setElement(i, 1, (double)tempTime);
- for(int j=2; j<=order ; j++) {
- // powerAndDiv(time, n) = times^n/n
- A.setElement(i, j, powerAndDiv(tempTime, j));
- }
- }
-
- GMatrix A_Transpose = new GMatrix(A);
- A_Transpose.transpose();
- GMatrix M = new GMatrix(order+1, order+1);
- M.mul(A_Transpose, A);
- try {
- M.invert();
- } catch (SingularMatrixException e) {
- System.out.println("SINGULAR MATRIX EXCEPTION in prediction");
- System.out.println(M);
- }
-
- // TODO: can be class scope
- double[] transformArray = new double[16];
- GMatrix solMatrix = new GMatrix(order+1, num_readings);
- solMatrix.mul(M,A_Transpose);
-
- GVector P = new GVector(order+1);
-
- // fill in the time for which we are trying to predict a sensor value
- GVector predTimeVec = new GVector(order+1);
- predTimeVec.setElement(0, 1);
- predTimeVec.setElement(1, time);
- for(int i=2 ; i<=order ; i++) {
- predTimeVec.setElement(i, powerAndDiv(time, i));
- }
-
- GVector R = new GVector(num_readings);
-
- for(int transElement=0 ; transElement<16 ; transElement++) {
-
- for(int i=0 ; i<num_readings ; i++) {
- R.setElement(i, lastReadRelative(num_readings-i-1, index,
- transElement));
- }
-
- P.mul(solMatrix,R);
- transformArray[transElement] = P.dot(predTimeVec);
- }
-
- //Matrix4d temp = new Matrix4d(transformArray);
- //localSVD(temp);
- //transform.set(temp);
- transform.set(transformArray);
- transform.normalize();
- }
-
- /**
- * Extracts the kth most recent sensor reading and copies that value into
- * the specified argument; where 0 is the most recent sensor reading, 1 is
- * the next most recent sensor reading, etc.
- * @param read The matrix that will receive the most recent sensor reading
- * @param k The kth previous sensor reading
- */
- double lastReadRelative(int kth, int base_index, int mat_element){
- // kth should be < sensorReadCount
- return
- readings[previousIndexRelative(kth, base_index)].read.mat[mat_element];
- }
-
- /**
- * Returns the time associated with the kth most recent sensor reading;
- * where 0 is the most recent sensor reading, 1 is the next most recent
- * sensor reading, etc. However, unlike the public method, returns
- * the kth reading relative to the index given, instead of the
- * current_index and returns the time relative to timeBasis.
- * @return the time associated with the kthmost recent sensor reading.
- */
- long lastTimeRelative(int k, int base_index, long timeBasis){
- // kth should be < sensorReadCount
- long time;
- time = timeBasis - readings[previousIndexRelative(k, base_index)].time;
- return time;
- }
-
- // argument of 0 is last reading, argument of 1 means next to last
- // index, etc. , but all of these are relative to *base_index*
- int previousIndexRelative(int k, int base_index){
- int temp = base_index - k;
- return(temp >= 0 ? temp : MaxSensorReadIndex + temp + 1);
- }
-
- // this method returns (value^order)/order
- double powerAndDiv(double value, int order) {
-
- if(order == 0)
- return 1;
- else if(order == 1)
- return value;
-
- double total = 1.0;
- for(int i=0 ; i< order ; i++)
- total *= value;
-
- total = total / (double)order;
- return total;
- }
-
}
diff --git a/src/classes/share/javax/media/j3d/SetLiveState.java b/src/classes/share/javax/media/j3d/SetLiveState.java
index 84ff55a..6c81c4e 100644
--- a/src/classes/share/javax/media/j3d/SetLiveState.java
+++ b/src/classes/share/javax/media/j3d/SetLiveState.java
@@ -243,7 +243,7 @@ class SetLiveState extends Object {
localToVworldIndex = null;
localToVworldKeys = null;
- // TODO: optimization for targetThreads computation, require
+ // XXXX: optimization for targetThreads computation, require
// cleanup in GroupRetained.doSetLive()
//transformTargetThreads = 0;
diff --git a/src/classes/share/javax/media/j3d/Shader.java b/src/classes/share/javax/media/j3d/Shader.java
new file mode 100644
index 0000000..f5870ee
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/Shader.java
@@ -0,0 +1,131 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+/**
+ * The Shader object is the abstract base class for programmable
+ * shader code. Currently, only text-based source code shaders are
+ * supported, so the only subclass of Shader is SourceCodeShader. We
+ * leave open the possibility for binary (object code) shaders in the
+ * future.
+ *
+ * <p>
+ * Each instance of a Shader object allows an application to specify
+ * the source code used in programming the Graphics Pipeline Unit
+ * (GPU) of the graphics accelerator. A Shader object is constructed
+ * with modes that specify the <i>shading language</i> and the
+ * <i>shader type</i>.
+ *
+ * <p>
+ * The shading language specifies the language and runtime environment
+ * used to program the GPU. The currently defined shading languages
+ * are GLSL (also known as the OpenGL 2.0 shading language) and
+ * Cg. Note that not all shading languages are supported on all
+ * platforms. It is up to the application or utility to query whether
+ * a particular shading language is supported before using it. The
+ * value of the <code>shadingLanguage</code> mode is one of:
+ * <code>SHADING_LANGUAGE_GLSL</code> or
+ * <code>SHADING_LANGUAGE_CG</code>.
+ *
+ *<p>
+ * The shader type specifies whether the shader is a <i>vertex
+ * shader</i> or a <i>fragment shader</i>. A vertex shader replaces
+ * the fixed-function graphics pipeline for vertex operations
+ * (transformation and lighting). A fragment shader replaces the
+ * fixed-function graphics pipeline for fragment shading operations
+ * (texture mapping, texture application, coloring, shading, and so
+ * forth). The value of the <code>shaderType</code> mode is one of:
+ * <code>SHADER_TYPE_VERTEX</code> or
+ * <code>SHADER_TYPE_FRAGMENT</code>.
+ *
+ * <p>
+ * Both the shading language and shader type are immutable modes of
+ * the Shader object.
+ *
+ * <p>
+ * NOTE: Applications should <i>not</i> extend this class.
+ *
+ * @see ShaderProgram
+ * @see Canvas3D#isShadingLanguageSupported
+ *
+ * @since Java 3D 1.4
+ */
+
+public abstract class Shader extends NodeComponent {
+
+
+ /**
+ * This constant indicates the GLSL shading language. It is one
+ * of the possible values of the shadingLanguage parameter.
+ */
+ public static final int SHADING_LANGUAGE_GLSL = 1;
+
+ /**
+ * This constant indicates the Cg shading language. It is one
+ * of the possible values of the shadingLanguage parameter.
+ */
+ public static final int SHADING_LANGUAGE_CG = 2;
+
+
+ /**
+ * This constant indicates that the shader type is a vertex
+ * shader. It is one of the possible values of the shaderType
+ * parameter.
+ */
+ public static final int SHADER_TYPE_VERTEX = 1;
+
+ /**
+ * This constant indicates that the shader type is a fragment
+ * shader. It is one of the possible values of the shaderType
+ * parameter.
+ */
+ public static final int SHADER_TYPE_FRAGMENT = 2;
+
+
+ /**
+ * Not a public constructor, for internal use
+ */
+ Shader() {
+ }
+
+ /**
+ * Package scope constructor so it can't be subclassed by classes
+ * outside the javax.media.j3d package.
+ */
+ Shader(int shadingLanguage, int shaderType) {
+ ((ShaderRetained)this.retained).initializeShader(shadingLanguage, shaderType);
+ }
+
+ /**
+ * Returns the shading language of this shader.
+ *
+ * @return the shading language of this shader, one of:
+ * <code>SHADING_LANGUAGE_GLSL</code> or
+ * <code>SHADING_LANGUAGE_CG</code>.
+ */
+ public int getShadingLanguage() {
+ return ((ShaderRetained)this.retained).getShadingLanguage();
+ }
+
+ /**
+ * Returns the type of this shader.
+ *
+ * @return the shader type, one of:
+ * <code>SHADER_TYPE_VERTEX</code> or
+ * <code>SHADER_TYPE_FRAGMENT</code>.
+ */
+ public int getShaderType() {
+ return ((ShaderRetained)this.retained).getShaderType();
+ }
+}
+
diff --git a/src/classes/share/javax/media/j3d/ShaderAppearance.java b/src/classes/share/javax/media/j3d/ShaderAppearance.java
new file mode 100644
index 0000000..2b9be8c
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/ShaderAppearance.java
@@ -0,0 +1,285 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import java.util.Hashtable;
+
+/**
+ * <p>The ShaderAppearance object defines programmable shading attributes
+ * that can be set as a component object of a Shape3D node. The
+ * ShaderAppearance rendering state adds the following attributes in
+ * addition to those defined by Appearance:</p>
+ *
+ * <ul>
+ * <li>Shader program - specifies the shader program...</li>
+ *
+ * <p></p>
+ * <li>Shader attribute set - specifies the shader parameters, both as
+ * explicit attributes and as implicit bindings to Java 3D
+ * state...</li>
+ * </ul>
+ *
+ * <p>The ShaderAppearance object modifies the definition of some of the
+ * attributes in Appearance:</p>
+ *
+ * <ul>
+ * <li>Coloring attributes - XXXXX</li>
+ *
+ * <p></p>
+ * <li>Line attributes - XXXXX</li>
+ *
+ * <p></p>
+ * <li>Point attributes - XXXXX</li>
+ *
+ * <p></p>
+ * <li>Polygon attributes - XXXXX</li>
+ *
+ * <p></p>
+ * <li>Rendering attributes - XXXXX</li>
+ *
+ * <p></p>
+ * <li>Transparency attributes - XXXXX</li>
+ *
+ * <p></p>
+ * <li>Material - XXXXX</li>
+ *
+ * <p></p>
+ * <li>Texture - XXXXX</li>
+ *
+ * <p></p>
+ * <li>Texture attributes - XXXXX</li>
+ *
+ * <p></p>
+ * <li>Texture coordinate generation - XXXXX</li>
+ *
+ * <p></p>
+ * <li>Texture unit state - XXXXX</li>
+ * </ul>
+ *
+ * @see ShaderProgram
+ * @see ShaderAttributeSet
+ *
+ * @since Java 3D 1.4
+ */
+public class ShaderAppearance extends Appearance {
+ /**
+ * Specifies that this ShaderAppearance object allows reading its
+ * ShaderProgram component information.
+ */
+ public static final int
+ ALLOW_SHADER_PROGRAM_READ =
+ CapabilityBits.SHADER_APPEARANCE_ALLOW_SHADER_PROGRAM_READ;
+
+ /**
+ * Specifies that this ShaderAppearance object allows writing its
+ * ShaderProgram component information.
+ */
+ public static final int
+ ALLOW_SHADER_PROGRAM_WRITE =
+ CapabilityBits.SHADER_APPEARANCE_ALLOW_SHADER_PROGRAM_WRITE;
+
+ /**
+ * Specifies that this ShaderAppearance object allows reading its
+ * ShaderAttributeSet component information.
+ */
+ public static final int
+ ALLOW_SHADER_ATTRIBUTE_SET_READ =
+ CapabilityBits.SHADER_APPEARANCE_ALLOW_SHADER_ATTRIBUTE_SET_READ;
+
+ /**
+ * Specifies that this ShaderAppearance object allows writing its
+ * ShaderAttributeSet component information.
+ */
+ public static final int
+ ALLOW_SHADER_ATTRIBUTE_SET_WRITE =
+ CapabilityBits.SHADER_APPEARANCE_ALLOW_SHADER_ATTRIBUTE_SET_WRITE;
+
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_SHADER_PROGRAM_READ,
+ ALLOW_SHADER_ATTRIBUTE_SET_READ
+ };
+
+ /**
+ * Constructs a ShaderAppearance component object using defaults for all
+ * state variables. All component object references are initialized
+ * to null.
+ */
+ public ShaderAppearance() {
+ // Just use default values
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+ }
+
+ /**
+ * Creates the retained mode ShaderAppearanceRetained object that this
+ * ShaderAppearance component object will point to.
+ */
+ void createRetained() {
+ this.retained = new ShaderAppearanceRetained();
+ this.retained.setSource(this);
+ }
+
+ /**
+ * Sets the ShaderProgram object to the specified object. Setting it to
+ * null causes a default pass-through shader to be used ???
+ *
+ * @param shaderProgram object that specifies the desired shader program
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ */
+ public void setShaderProgram(ShaderProgram shaderProgram) {
+
+ if (isLiveOrCompiled()) {
+ if(!this.getCapability(ALLOW_SHADER_PROGRAM_WRITE))
+ throw new CapabilityNotSetException(J3dI18N.getString("ShaderAppearance0"));
+ }
+
+ ((ShaderAppearanceRetained)this.retained).setShaderProgram(shaderProgram);
+
+ }
+
+
+ /**
+ * Retrieves the current ShaderProgram object.
+ *
+ * @return the ShaderProgram object
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ */
+ public ShaderProgram getShaderProgram() {
+
+ if (isLiveOrCompiled()) {
+ if(!this.getCapability(ALLOW_SHADER_PROGRAM_READ))
+ throw new CapabilityNotSetException(J3dI18N.getString("ShaderAppearance1"));
+ }
+ return ((ShaderAppearanceRetained)this.retained).getShaderProgram();
+ }
+
+
+ /**
+ * Sets the ShaderAttributeSet object to the specified object. Setting it to
+ * null is equivalent to specifying an empty set of attributes.
+ *
+ * @param shaderAttributeSet object that specifies the desired shader attributes
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ */
+ public void setShaderAttributeSet(ShaderAttributeSet shaderAttributeSet) {
+ if (isLiveOrCompiled()) {
+ if(!this.getCapability(ALLOW_SHADER_ATTRIBUTE_SET_WRITE))
+ throw new CapabilityNotSetException(J3dI18N.getString("ShaderAppearance2"));
+ }
+
+ ((ShaderAppearanceRetained)this.retained).setShaderAttributeSet(shaderAttributeSet);
+ }
+
+
+ /**
+ * Retrieves the current ShaderAttributeSet object.
+ *
+ * @return the ShaderAttributeSet object
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ */
+ public ShaderAttributeSet getShaderAttributeSet() {
+ if (isLiveOrCompiled()) {
+ if(!this.getCapability(ALLOW_SHADER_ATTRIBUTE_SET_READ))
+ throw new CapabilityNotSetException(J3dI18N.getString("ShaderAppearance3"));
+ }
+ return ((ShaderAppearanceRetained)this.retained).getShaderAttributeSet();
+ }
+
+
+ /**
+ * @deprecated replaced with cloneNodeComponent(boolean forceDuplicate)
+ */
+ public NodeComponent cloneNodeComponent() {
+ ShaderAppearance a = new ShaderAppearance();
+ a.duplicateNodeComponent(this);
+ return a;
+ }
+
+ /**
+ * NOTE: Applications should <i>not</i> call this method directly.
+ * It should only be called by the cloneNode method.
+ *
+ * @deprecated replaced with duplicateNodeComponent(
+ * NodeComponent originalNodeComponent, boolean forceDuplicate)
+ */
+ public void duplicateNodeComponent(NodeComponent originalNodeComponent) {
+ checkDuplicateNodeComponent(originalNodeComponent);
+ }
+
+ /**
+ * Copies all ShaderAppearance information from
+ * <code>originalNodeComponent</code> into
+ * the current node. This method is called from the
+ * <code>cloneNode</code> method which is, in turn, called by the
+ * <code>cloneTree</code> method.<P>
+ *
+ * @param originalNodeComponent the original node to duplicate.
+ * @param forceDuplicate when set to <code>true</code>, causes the
+ * <code>duplicateOnCloneTree</code> flag to be ignored. When
+ * <code>false</code>, the value of each node's
+ * <code>duplicateOnCloneTree</code> variable determines whether
+ * NodeComponent data is duplicated or copied.
+ *
+ * @exception RestrictedAccessException if this object is part of a live
+ * or compiled scenegraph.
+ *
+ * @see Node#cloneTree
+ * @see NodeComponent#setDuplicateOnCloneTree
+ */
+ void duplicateAttributes(NodeComponent originalNodeComponent,
+ boolean forceDuplicate) {
+ super.duplicateAttributes(originalNodeComponent, forceDuplicate);
+
+ Hashtable hashtable = originalNodeComponent.nodeHashtable;
+
+ ShaderAppearanceRetained app =
+ (ShaderAppearanceRetained) originalNodeComponent.retained;
+
+ ShaderAppearanceRetained rt = (ShaderAppearanceRetained) retained;
+
+ rt.setShaderProgram((ShaderProgram) getNodeComponent(app.getShaderProgram(),
+ forceDuplicate,
+ hashtable));
+ }
+
+ /**
+ * This function is called from getNodeComponent() to see if any of
+ * the sub-NodeComponents duplicateOnCloneTree flag is true.
+ * If it is the case, current NodeComponent needs to
+ * duplicate also even though current duplicateOnCloneTree flag is false.
+ * This should be overwrite by NodeComponent which contains sub-NodeComponent.
+ */
+ boolean duplicateChild() {
+ if (super.duplicateChild())
+ return true;
+
+ if (getDuplicateOnCloneTree())
+ return true;
+
+ ShaderAppearanceRetained rt = (ShaderAppearanceRetained) retained;
+
+ NodeComponent nc;
+
+ nc = rt.getShaderProgram();
+ if ((nc != null) && nc.getDuplicateOnCloneTree())
+ return true;
+
+ return false;
+ }
+
+}
diff --git a/src/classes/share/javax/media/j3d/ShaderAppearanceRetained.java b/src/classes/share/javax/media/j3d/ShaderAppearanceRetained.java
new file mode 100644
index 0000000..b8a1936
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/ShaderAppearanceRetained.java
@@ -0,0 +1,360 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import java.util.Vector;
+import java.util.BitSet;
+import java.util.ArrayList;
+
+
+/**
+ * The Appearance object defines all rendering state that can be set
+ * as a component object of a Shape3D node.
+ */
+class ShaderAppearanceRetained extends AppearanceRetained {
+
+ //
+ // State variables: these should all be initialized to approproate
+ // Java 3D defaults.
+ //
+
+ protected ShaderProgramRetained shaderProgram = null;
+ protected ShaderAttributeSetRetained shaderAttributeSet = null;
+ protected boolean isMirror = false; // For Debugging.
+
+ static final int SHADER_PROGRAM = 0x0800;
+ static final int SHADER_ATTRIBUTE_SET = 0x1000;
+
+ /**
+ * Set the shader program object to the specified object.
+ * @param shaderProgram object that specifies the desired shader program
+ * and shader program attributes.
+ */
+ void setShaderProgram(ShaderProgram sp) {
+ synchronized(liveStateLock) {
+ if (source.isLive()) {
+ // System.out.println("**** ShaderAppearceRetained.setShaderProgram()");
+
+ if (this.shaderProgram != null) {
+ this.shaderProgram.clearLive(refCount);
+ this.shaderProgram.removeMirrorUsers(this);
+ }
+
+ if (sp != null) {
+ ((ShaderProgramRetained)sp.retained).setLive(inBackgroundGroup,
+ refCount);
+ ((ShaderProgramRetained)sp.retained).copyMirrorUsers(this);
+ }
+
+ sendMessage(SHADER_PROGRAM,
+ (sp != null ? ((ShaderProgramRetained)sp.retained).mirror : null));
+
+ }
+
+ if (sp == null) {
+ this.shaderProgram = null;
+ } else {
+ this.shaderProgram = (ShaderProgramRetained)sp.retained;
+ }
+ }
+ }
+
+
+ /**
+ * Retrieves the current shader program object.
+ * @return current shader program object
+ */
+ ShaderProgram getShaderProgram() {
+ return (shaderProgram == null ? null : (ShaderProgram)shaderProgram.source);
+ }
+
+
+ /**
+ * Sets the ShaderAttributeSet object to the specified object. Setting it to
+ * null is equivalent to specifying an empty set of attributes.
+ *
+ * @param shaderAttributeSet object that specifies the desired shader attributes
+ */
+ void setShaderAttributeSet(ShaderAttributeSet sas) {
+ synchronized(liveStateLock) {
+ if (source.isLive()) {
+ // System.out.println("**** ShaderAppearceRetained.setShaderAttributeSet()");
+
+ if (this.shaderAttributeSet != null) {
+ this.shaderAttributeSet.clearLive(refCount);
+ this.shaderAttributeSet.removeMirrorUsers(this);
+ }
+
+ if (sas != null) {
+ ((ShaderAttributeSetRetained)sas.retained).setLive(inBackgroundGroup,
+ refCount);
+ ((ShaderAttributeSetRetained)sas.retained).copyMirrorUsers(this);
+ }
+
+ // System.out.println(" -- testing needed!");
+ sendMessage(SHADER_ATTRIBUTE_SET,
+ (sas != null ?
+ ((ShaderAttributeSetRetained)sas.retained).mirror : null));
+
+ }
+
+ if (sas == null) {
+ this.shaderAttributeSet = null;
+ } else {
+ this.shaderAttributeSet = (ShaderAttributeSetRetained)sas.retained;
+ }
+ }
+ }
+
+
+ /**
+ * Retrieves the current ShaderAttributeSet object.
+ * @return current ShaderAttributeSet object
+ */
+ ShaderAttributeSet getShaderAttributeSet() {
+ return (shaderAttributeSet == null ? null : (ShaderAttributeSet)shaderAttributeSet.source);
+
+ }
+
+
+ public boolean equals(Object obj) {
+ System.out.println("ShaderAppearanceRetained : equals() not tested yet!");
+ return ((obj instanceof ShaderAppearanceRetained) &&
+ equals((ShaderAppearanceRetained) obj));
+ }
+
+ boolean equals(ShaderAppearanceRetained sApp) {
+ boolean flag;
+ flag = (sApp == this);
+
+ // If the reference is the same, we can stop check.
+ if(flag)
+ return flag;
+
+ // Check each member's reference for equal.
+ flag = ((sApp != null) &&
+ (shaderProgram == sApp.shaderProgram) &&
+ (shaderAttributeSet == sApp.shaderAttributeSet));
+
+
+ if (!flag)
+ return flag;
+
+ return super.equals(sApp);
+
+ }
+
+
+
+ synchronized void createMirrorObject() {
+ // System.out.println("ShaderAppearanceRetained : createMirrorObject()");
+
+ if (mirror == null) {
+ // we can't check isStatic() since it sub-NodeComponent
+ // create a new one, we should create a
+ // new AppearanceRetained() even though isStatic() = true.
+ // For simplicity, always create a retained side.
+ mirror = new ShaderAppearanceRetained();
+ ((ShaderAppearanceRetained)mirror).isMirror = true; // For Debugging.
+ }
+ initMirrorObject();
+ }
+
+ /**
+ * This routine updates the mirror appearance for this appearance.
+ * It also calls the update method for each node component if it
+ * is not null.
+ */
+ synchronized void initMirrorObject() {
+ // System.out.println("ShaderAppearanceRetained : initMirrorObject()");
+
+ super.initMirrorObject();
+
+ ShaderAppearanceRetained mirrorApp = (ShaderAppearanceRetained)mirror;
+
+ if(shaderProgram != null) {
+ mirrorApp.shaderProgram = (ShaderProgramRetained)shaderProgram.mirror;
+ }
+ else {
+ mirrorApp.shaderProgram = null;
+ }
+
+ if(shaderAttributeSet != null) {
+ mirrorApp.shaderAttributeSet =
+ (ShaderAttributeSetRetained)shaderAttributeSet.mirror;
+ }
+ else {
+ // System.out.println("shaderAttributeSet is null");
+ mirrorApp.shaderAttributeSet = null;
+ }
+
+ }
+
+ /**
+ * Update the "component" field of the mirror object with the
+ * given "value"
+ */
+ synchronized void updateMirrorObject(int component, Object value) {
+
+ // System.out.println("ShaderAppearanceRetained : updateMirrorObject() this " + this);
+ super.updateMirrorObject(component, value);
+ ShaderAppearanceRetained mirrorApp = (ShaderAppearanceRetained)mirror;
+ if ((component & SHADER_PROGRAM) != 0) {
+ mirrorApp.shaderProgram = (ShaderProgramRetained)value;
+ }
+ else if ((component & SHADER_ATTRIBUTE_SET) != 0) {
+ mirrorApp.shaderAttributeSet = (ShaderAttributeSetRetained)value;
+ }
+
+ }
+
+ /**
+ * This method calls the setLive method of all appearance bundle
+ * objects.
+ */
+ void doSetLive(boolean backgroundGroup, int refCount) {
+ // System.out.println("ShaderAppearceRetained.doSetLive()");
+
+
+ if (shaderProgram != null) {
+ shaderProgram.setLive(backgroundGroup, refCount);
+ }
+
+ if (shaderAttributeSet != null) {
+ shaderAttributeSet.setLive(backgroundGroup, refCount);
+ }
+
+
+ // Increment the reference count and initialize the appearance
+ // mirror object
+ super.doSetLive(backgroundGroup, refCount);
+ }
+
+
+ /**
+ * This clearLive routine first calls the superclass's method, then
+ * it removes itself to the list of lights
+ */
+ void clearLive(int refCount) {
+ super.clearLive(refCount);
+
+ if (shaderProgram != null) {
+ shaderProgram.clearLive(refCount);
+ }
+
+ if (shaderAttributeSet != null) {
+ shaderAttributeSet.clearLive(refCount);
+ }
+ }
+
+ synchronized void addAMirrorUser(Shape3DRetained shape) {
+
+ super.addAMirrorUser(shape);
+ if (shaderProgram != null)
+ shaderProgram.addAMirrorUser(shape);
+ if (shaderAttributeSet != null)
+ shaderAttributeSet.addAMirrorUser(shape);
+ }
+
+ synchronized void removeAMirrorUser(Shape3DRetained shape) {
+
+ super.removeAMirrorUser(shape);
+ if (shaderProgram != null)
+ shaderProgram.removeAMirrorUser(shape);
+ if (shaderAttributeSet != null)
+ shaderAttributeSet.removeAMirrorUser(shape);
+ }
+
+
+ final void sendMessage(int attrMask, Object attr) {
+ ArrayList univList = new ArrayList();
+ ArrayList gaList = Shape3DRetained.getGeomAtomsList(mirror.users, univList);
+ // Send to rendering attribute structure, regardless of
+ // whether there are users or not (alternate appearance case ..)
+ J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
+ createMessage.type = J3dMessage.SHADER_APPEARANCE_CHANGED;
+ createMessage.universe = null;
+ createMessage.args[0] = this;
+ createMessage.args[1]= new Integer(attrMask);
+ createMessage.args[2] = attr;
+ createMessage.args[3] = new Integer(changedFrequent);
+
+ VirtualUniverse.mc.processMessage(createMessage);
+
+ //System.out.println("univList.size is " + univList.size());
+ for(int i=0; i<univList.size(); i++) {
+ createMessage = VirtualUniverse.mc.getMessage();
+ createMessage.threads = J3dThread.UPDATE_RENDER;
+ createMessage.type = J3dMessage.SHADER_APPEARANCE_CHANGED;
+
+ createMessage.universe = (VirtualUniverse) univList.get(i);
+ createMessage.args[0] = this;
+ createMessage.args[1]= new Integer(attrMask);
+ createMessage.args[2] = attr;
+
+ ArrayList gL = (ArrayList) gaList.get(i);
+ GeometryAtom[] gaArr = new GeometryAtom[gL.size()];
+ gL.toArray(gaArr);
+ createMessage.args[3] = gaArr;
+
+ VirtualUniverse.mc.processMessage(createMessage);
+ }
+ }
+
+
+ boolean isStatic() {
+ if (!super.isStatic()) {
+ return false;
+ }
+
+ boolean flag =
+ source.capabilityBitsEmpty() &&
+ ((shaderProgram == null) ||
+ shaderProgram.source.capabilityBitsEmpty()) &&
+ ((shaderAttributeSet == null) ||
+ shaderAttributeSet.source.capabilityBitsEmpty());
+
+ return flag;
+ }
+
+
+
+ boolean isOpaque(int geoType) {
+
+ if (!super.isOpaque(geoType)) {
+ return false;
+ }
+
+ // TODO: IMPLEMENT THIS
+ // TODO: How do we determine whether a ShaderAppearance is opaque???
+ return true;
+ }
+
+ void handleFrequencyChange(int bit) {
+ // System.out.println("ShaderAppearanceRetained : handleFrequencyChange()");
+ super.handleFrequencyChange(bit);
+
+ int mask = 0;
+ if (bit == ShaderAppearance.ALLOW_SHADER_PROGRAM_WRITE)
+ mask = SHADER_PROGRAM;
+ else if (bit == ShaderAppearance.ALLOW_SHADER_ATTRIBUTE_SET_WRITE)
+ mask = SHADER_ATTRIBUTE_SET;
+
+
+ if (mask != 0)
+ setFrequencyChangeMask(bit, mask);
+ }
+}
+
+
diff --git a/src/classes/share/javax/media/j3d/ShaderAttribute.java b/src/classes/share/javax/media/j3d/ShaderAttribute.java
new file mode 100644
index 0000000..7618492
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/ShaderAttribute.java
@@ -0,0 +1,77 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import javax.vecmath.*;
+
+/**
+ * The ShaderAttribute object encapsulates a uniform attribute for a
+ * shader programs. Uniform attributes (variables) are those
+ * attributes whose values are constant during the rendering of a
+ * primitive. Their values may change from primitive to primitive, but
+ * are constant for each vertex (for vertex shaders) or fragment (for
+ * fragment shaders) of a single primitive. Examples of uniform
+ * attributes include a transformation matrix, a texture map, lights,
+ * lookup tables, etc.
+ *
+ * <p>
+ * There are two ways in which values can be specified for uniform
+ * attributes: explicitly, by providing a value; and implicitly, by
+ * defining a binding between a Java 3D system attribute and a uniform
+ * attribute. This functionality is provided by two subclasses of
+ * ShaderAttribute as follows:
+ *
+ * <ul>
+ * <li>ShaderAttributeObject, in which attributes are expressed as
+ * <code>(attrName,&nbsp;value)</code> pairs, is used for explicitly
+ * defined attributes</li>
+ * <li>ShaderAttributeBinding, in which attributes are expressed as
+ * <code>(attrName,&nbsp;j3dAttrName)</code> pairs, is used for
+ * implicitly defined, automatically tracked attributes</li>
+ * </ul>
+ *
+ * @see ShaderAttributeSet
+ * @see ShaderProgram
+ *
+ * @since Java 3D 1.4
+ */
+
+public abstract class ShaderAttribute extends NodeComponent {
+ /**
+ * Name of the shader attribute (immutable)
+ */
+
+ /**
+ * Package scope constructor
+ *
+ */
+ ShaderAttribute(String attrName) {
+ if (attrName == null) {
+ throw new NullPointerException();
+ }
+
+ ((ShaderAttributeRetained)this.retained).initializeAttrName(attrName);
+ }
+
+ /**
+ * Retrieves the name of this shader attribute.
+ *
+ * @return the name of this shader attribute
+ */
+ public String getAttributeName() {
+
+ return ((ShaderAttributeRetained)this.retained).getAttributeName();
+
+ }
+
+}
diff --git a/src/classes/share/javax/media/j3d/ShaderAttributeArray.java b/src/classes/share/javax/media/j3d/ShaderAttributeArray.java
new file mode 100644
index 0000000..c5ee3db
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/ShaderAttributeArray.java
@@ -0,0 +1,147 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import javax.vecmath.*;
+
+/**
+ * The ShaderAttributeArray object encapsulates a uniform shader
+ * attribute whose value is specified explicitly. The shader variable
+ * <code>attrName</code> is explicitly set to the specified
+ * <code>value</code> during rendering. <code>attrName</code> must be
+ * the name of a valid uniform attribute in the shader in which it is
+ * used. Otherwise, the attribute name will be ignored and a runtime
+ * error may be generated. The <code>value</code> must be an array
+ * of one of the allowed classes. The allowed classes are:
+ * <code>Integer[]</code>, <code>Float[]</code>,
+ * <code>Tuple{2,3,4}{i,f}[]</code>, <code>Matrix{3,4}f[]</code>. A
+ * ClassCastException will be thrown if a specified <code>value</code>
+ * object is not one of the allowed types. Further, the type and length of the
+ * value is immutable once a ShaderAttributeArray is constructed.
+ * Subsequent setValue operations must be called with an array of the
+ * same type and length as the one that was used to construct the
+ * ShaderAttributeArray. Finally, the type of the <code>value</code>
+ * object must match the type of the corresponding
+ * <code>attrName</code> variable in the shader in which it is
+ * used. Otherwise, the shader will not be able to use the attribute
+ * and a runtime error may be generated.
+ *
+ * @see ShaderAttributeSet
+ * @see ShaderProgram
+ *
+ * @since Java 3D 1.4
+ */
+
+public class ShaderAttributeArray extends ShaderAttributeObject {
+ /**
+ * Constructs a new ShaderAttributeArray object with the specified
+ * <code>(attrName,&nbsp;value)</code> pair. The specified value
+ * must be an array of one of the allowed class types.
+ * A deep copy of the array is stored.
+ *
+ * @param attrName the name of the shader attribute
+ * @param value the value of the shader attribute
+ *
+ * @exception NullPointerException if attrName or value is null
+ *
+ * @exception ClassCastException if value is not an array of
+ * one of the allowed classes
+ */
+ public ShaderAttributeArray(String attrName, Object value) {
+ super(attrName, value);
+ }
+
+ // Implement abstract getValue method
+ public Object getValue() {
+ if (isLiveOrCompiled())
+ if (!this.getCapability(ALLOW_VALUE_READ))
+ throw new CapabilityNotSetException(J3dI18N.getString("ShaderAttributeObject0"));
+
+ return ((ShaderAttributeArrayRetained)this.retained).getValue();
+ }
+
+ // Implement abstract setValue method
+ public void setValue(Object value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+
+ if (isLiveOrCompiled())
+ if (!this.getCapability(ALLOW_VALUE_WRITE))
+ throw new CapabilityNotSetException(J3dI18N.getString("ShaderAttributeObject1"));
+
+ if (isLive())
+ ((ShaderAttributeArrayRetained)this.retained).setValue(value);
+ else
+ ((ShaderAttributeArrayRetained)this.retained).initValue(value);
+
+ }
+
+
+ /**
+ * Sets the specified array element of the value of this shader
+ * attribute to the specified value.
+ * A copy of the object is stored.
+ *
+ * @param value the new value of the shader attribute
+ *
+ * @exception NullPointerException if value is null
+ *
+ * @exception ClassCastException if value is not an instance of
+ * the same base class as the individual elements of the array object
+ * used to construct this shader attribute object.
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ */
+ public void setValue(int index, Object value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+
+ if (isLiveOrCompiled())
+ if (!this.getCapability(ALLOW_VALUE_WRITE))
+ throw new CapabilityNotSetException(J3dI18N.getString("ShaderAttributeObject1"));
+
+ if (isLive())
+ ((ShaderAttributeArrayRetained)this.retained).setValue(index, value);
+ else {
+ ((ShaderAttributeArrayRetained)this.retained).initValue(index, value);
+ }
+ }
+
+ /**
+ * Returns the number of elements in the value array.
+ *
+ * @return the number of elements in the value array
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ */
+ public int length() {
+ if (isLiveOrCompiled())
+ if (!this.getCapability(ALLOW_VALUE_READ))
+ throw new CapabilityNotSetException(J3dI18N.getString("ShaderAttributeObject0"));
+
+ return ((ShaderAttributeArrayRetained)this.retained).length();
+ }
+
+ /**
+ * Creates a retained mode ShaderAttributeArrayRetained object that this
+ * ShaderAttributeArray component object will point to.
+ */
+ void createRetained() {
+ this.retained = new ShaderAttributeArrayRetained();
+ this.retained.setSource(this);
+ }
+}
diff --git a/src/classes/share/javax/media/j3d/ShaderAttributeArrayRetained.java b/src/classes/share/javax/media/j3d/ShaderAttributeArrayRetained.java
new file mode 100644
index 0000000..f4d4a42
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/ShaderAttributeArrayRetained.java
@@ -0,0 +1,996 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import javax.vecmath.*;
+
+/**
+ * The ShaderAttributeArray object encapsulates a uniform shader
+ * attribute whose value is specified explicitly. The shader variable
+ * <code>attrName</code> is explicitly set to the specified
+ * <code>value</code> during rendering. <code>attrName</code> must be
+ * the name of a valid uniform attribute in the shader in which it is
+ * used. Otherwise, the attribute name will be ignored and a runtime
+ * error may be generated. The <code>value</code> must be an array
+ * of one of the allowed classes. The allowed classes are:
+ * <code>Integer[]</code>, <code>Float[]</code>,
+ * <code>Tuple{2,3,4}{i,f}[]</code>, <code>Matrix{3,4}f[]</code>. A
+ * ClassCastException will be thrown if a specified <code>value</code>
+ * object is not one of the allowed types. Further, the type and length of the
+ * value is immutable once a ShaderAttributeArray is constructed.
+ * Subsequent setValue operations must be called with an array of the
+ * same type and length as the one that was used to construct the
+ * ShaderAttributeArray. Finally, the type of the <code>value</code>
+ * object must match the type of the corresponding
+ * <code>attrName</code> variable in the shader in which it is
+ * used. Otherwise, the shader will not be able to use the attribute
+ * and a runtime error may be generated.
+ *
+ * @see ShaderAttributeSet
+ * @see ShaderProgram
+ *
+ * @since Java 3D 1.4
+ */
+
+class ShaderAttributeArrayRetained extends ShaderAttributeObjectRetained {
+
+ ShaderAttributeArrayRetained() {
+ }
+
+ void initValue(int index, Object value) {
+ /*
+ System.err.println("ShaderAttributeObjectRetained : attrName = " + attrName +
+ ", index = " + index + ", value = " + value +
+ ", value.class = " + value.getClass());
+ */
+ ((ArrayWrapper)attrWrapper).set(index, value);
+
+ }
+
+
+ /**
+ * Sets the specified array element of the value of this shader
+ * attribute to the specified value.
+ * A copy of the object is stored.
+ *
+ * @param value the new value of the shader attribute
+ *
+ * @exception NullPointerException if value is null
+ *
+ * @exception ClassCastException if value is not an instance of
+ * the same base class as the individual elements of the array object
+ * used to construct this shader attribute object.
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ */
+ void setValue(int index, Object value) {
+ initValue(index, value);
+ // We should only need to update the array instead of replacing it.
+ // Until this become a really bottleneck, it will just be a convenience
+ // method for end user.
+ // An efficient approach is to
+ // (1) Create a new ShaderAttributeValue object for the "value" object
+ // and pass it to sendMessage(), (2) Create a new sendMessage that take in
+ // a third arguement, ie. index.
+ setValue(attrWrapper.getRef());
+ }
+
+ /**
+ * Returns the number of elements in the value array.
+ *
+ * @return the number of elements in the value array
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ */
+ int length() {
+ return ((ArrayWrapper)attrWrapper).length();
+
+ }
+
+ // Helper methods ...
+
+ synchronized void createMirrorObject() {
+ // System.out.println("ShaderAttributeArrayRetained : createMirrorObject");
+ // This method should only call by setLive().
+ if (mirror == null) {
+ ShaderAttributeArrayRetained mirrorSAA = new ShaderAttributeArrayRetained();
+ mirrorSAA.createObjectData(getValue());
+ mirror = mirrorSAA;
+ mirror.source = source;
+
+ }
+ initMirrorObject();
+ }
+
+
+ /**
+ * Computes the base class from the specified object. A
+ * ClassCastException is thrown if the object is not an array of
+ * one of the allowed classes.
+ */
+ int computeClassType(Object value) {
+ Class objClass = value.getClass();
+ if (!objClass.isArray()) {
+ throw new ClassCastException(objClass + " -- must be array class");
+ }
+
+ for (int i = 0; i < classTable.length; i++) {
+ if (classTableArr[i].isInstance(value)) {
+ return i;
+ }
+ }
+ throw new ClassCastException(objClass + " -- unrecognized class");
+ }
+
+ /**
+ * Returns the base class represented by the specified class type.
+ */
+ Class getBaseClass(int classType) {
+ return classTableArr[classType];
+ }
+
+ /**
+ * Creates an attribute wrapper object of the specified class
+ * type, and stores the specified array of objects.
+ */
+ AttrWrapper createAttrWrapper(Object value, int classType) {
+ ArrayWrapper attrWrapper = null;
+ switch (classType) {
+ case TYPE_INTEGER:
+ attrWrapper = new IntegerArrayWrapper();
+ break;
+ case TYPE_FLOAT:
+ attrWrapper = new FloatArrayWrapper();
+ break;
+// case TYPE_DOUBLE:
+// attrWrapper = new DoubleArrayWrapper();
+// break;
+ case TYPE_TUPLE2I:
+ attrWrapper = new Tuple2iArrayWrapper();
+ break;
+ case TYPE_TUPLE2F:
+ attrWrapper = new Tuple2fArrayWrapper();
+ break;
+// case TYPE_TUPLE2D:
+// attrWrapper = new Tuple2dArrayWrapper();
+// break;
+ case TYPE_TUPLE3I:
+ attrWrapper = new Tuple3iArrayWrapper();
+ break;
+ case TYPE_TUPLE3F:
+ attrWrapper = new Tuple3fArrayWrapper();
+ break;
+// case TYPE_TUPLE3D:
+// attrWrapper = new Tuple3dArrayWrapper();
+// break;
+ case TYPE_TUPLE4I:
+ attrWrapper = new Tuple4iArrayWrapper();
+ break;
+ case TYPE_TUPLE4F:
+ attrWrapper = new Tuple4fArrayWrapper();
+ break;
+// case TYPE_TUPLE4D:
+// attrWrapper = new Tuple4dArrayWrapper();
+// break;
+ case TYPE_MATRIX3F:
+ attrWrapper = new Matrix3fArrayWrapper();
+ break;
+// case TYPE_MATRIX3D:
+// attrWrapper = new Matrix3dArrayWrapper();
+// break;
+ case TYPE_MATRIX4F:
+ attrWrapper = new Matrix4fArrayWrapper();
+ break;
+// case TYPE_MATRIX4D:
+// attrWrapper = new Matrix4dArrayWrapper();
+// break;
+ default:
+ // Should never get here
+ assert false;
+ return null;
+ }
+
+ attrWrapper.set(value);
+ return attrWrapper;
+ }
+
+
+ //
+ // The following wrapper classes are used to store a copy of the
+ // user-specified shader attribute value. There is a wrapper class
+ // for each supported base class.
+ //
+
+ // Base wrapper class for array attribute types
+ static abstract class ArrayWrapper extends AttrWrapper {
+ int length = 0;
+
+ /**
+ * Returns the length of the array
+ */
+ int length() {
+ return length;
+ }
+
+ /**
+ * Sets the specified array element of the value of this
+ * shader attribute to the specified value.
+ */
+ abstract void set(int index, Object value);
+ }
+
+ // Wrapper class for Integer
+ static class IntegerArrayWrapper extends ArrayWrapper {
+ private int[] value = new int[0];
+
+ void set(Object value) {
+ Integer[] arr = (Integer[])value;
+ if (this.length != arr.length) {
+ this.length = arr.length;
+ this.value = new int[this.length];
+ }
+ for (int i = 0; i < this.length; i++) {
+ this.value[i] = arr[i].intValue();
+ }
+ }
+
+ void set(int index, Object value) {
+ this.value[index] = ((Integer)value).intValue();
+ }
+
+ Object get() {
+ Integer[] arr = new Integer[this.length];
+ for (int i = 0; i < this.length; i++) {
+ arr[i] = new Integer(this.value[i]);
+ }
+ return arr;
+ }
+
+ Object getRef() {
+ return this.value;
+ }
+ }
+
+ // Wrapper class for Float
+ static class FloatArrayWrapper extends ArrayWrapper {
+ private float[] value = new float[0];
+
+ void set(Object value) {
+ Float[] arr = (Float[])value;
+ if (this.length != arr.length) {
+ this.length = arr.length;
+ this.value = new float[this.length];
+ }
+ for (int i = 0; i < this.length; i++) {
+ this.value[i] = arr[i].floatValue();
+ }
+ }
+
+ void set(int index, Object value) {
+ this.value[index] = ((Float)value).floatValue();
+ }
+
+ Object get() {
+ Float[] arr = new Float[this.length];
+ for (int i = 0; i < this.length; i++) {
+ arr[i] = new Float(this.value[i]);
+ }
+ return arr;
+ }
+
+ Object getRef() {
+ return this.value;
+ }
+ }
+
+ /*
+ // Wrapper class for Double
+ static class DoubleArrayWrapper extends ArrayWrapper {
+ private double[] value = new double[0];
+
+ void set(Object value) {
+ Double[] arr = (Double[])value;
+ if (this.length != arr.length) {
+ this.length = arr.length;
+ this.value = new double[this.length];
+ }
+ for (int i = 0; i < this.length; i++) {
+ this.value[i] = arr[i].doubleValue();
+ }
+ }
+
+ void set(int index, Object value) {
+ this.value[index] = ((Double)value).doubleValue();
+ }
+
+ Object get() {
+ Double[] arr = new Double[this.length];
+ for (int i = 0; i < this.length; i++) {
+ arr[i] = new Double(this.value[i]);
+ }
+ return arr;
+ }
+
+ Object getRef() {
+ return this.value;
+ }
+ }
+ */
+
+ // Wrapper class for Tuple2i
+ static class Tuple2iArrayWrapper extends ArrayWrapper {
+ private int[] value = new int[0];
+
+ void set(Object value) {
+ Tuple2i[] arr = (Tuple2i[])value;
+ if (this.length != arr.length) {
+ this.length = arr.length;
+ this.value = new int[this.length*2];
+ }
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 2;
+ this.value[j+0] = arr[i].x;
+ this.value[j+1] = arr[i].y;
+ }
+ }
+
+ void set(int index, Object value) {
+ int j = index * 2;
+ this.value[j+0] = ((Tuple2i)value).x;
+ this.value[j+1] = ((Tuple2i)value).y;
+ }
+
+ Object get() {
+ Tuple2i[] arr = new Tuple2i[this.length];
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 2;
+ arr[i].x = this.value[j+0];
+ arr[i].y = this.value[j+1];
+ }
+ return arr;
+ }
+
+ Object getRef() {
+ return this.value;
+ }
+ }
+
+ // Wrapper class for Tuple2f
+ static class Tuple2fArrayWrapper extends ArrayWrapper {
+ private float[] value = new float[0];
+
+ void set(Object value) {
+ Tuple2f[] arr = (Tuple2f[])value;
+ if (this.length != arr.length) {
+ this.length = arr.length;
+ this.value = new float[this.length*2];
+ }
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 2;
+ this.value[j+0] = arr[i].x;
+ this.value[j+1] = arr[i].y;
+ }
+ }
+
+ void set(int index, Object value) {
+ int j = index * 2;
+ this.value[j+0] = ((Tuple2f)value).x;
+ this.value[j+1] = ((Tuple2f)value).y;
+ }
+
+ Object get() {
+ Tuple2f[] arr = new Tuple2f[this.length];
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 2;
+ arr[i].x = this.value[j+0];
+ arr[i].y = this.value[j+1];
+ }
+ return arr;
+ }
+
+ Object getRef() {
+ return this.value;
+ }
+ }
+
+ /*
+ // Wrapper class for Tuple2d
+ static class Tuple2dArrayWrapper extends ArrayWrapper {
+ private double[] value = new double[0];
+
+ void set(Object value) {
+ Tuple2d[] arr = (Tuple2d[])value;
+ if (this.length != arr.length) {
+ this.length = arr.length;
+ this.value = new double[this.length*2];
+ }
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 2;
+ this.value[j+0] = arr[i].x;
+ this.value[j+1] = arr[i].y;
+ }
+ }
+
+ void set(int index, Object value) {
+ int j = index * 2;
+ this.value[j+0] = ((Tuple2d)value).x;
+ this.value[j+1] = ((Tuple2d)value).y;
+ }
+
+ Object get() {
+ Tuple2d[] arr = new Tuple2d[this.length];
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 2;
+ arr[i].x = this.value[j+0];
+ arr[i].y = this.value[j+1];
+ }
+ return arr;
+ }
+
+ Object getRef() {
+ return this.value;
+ }
+ }
+ */
+
+ // Wrapper class for Tuple3i
+ static class Tuple3iArrayWrapper extends ArrayWrapper {
+ private int[] value = new int[0];
+
+ void set(Object value) {
+ Tuple3i[] arr = (Tuple3i[])value;
+ if (this.length != arr.length) {
+ this.length = arr.length;
+ this.value = new int[this.length*3];
+ }
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 3;
+ this.value[j+0] = arr[i].x;
+ this.value[j+1] = arr[i].y;
+ this.value[j+2] = arr[i].z;
+ }
+ }
+
+ void set(int index, Object value) {
+ int j = index * 3;
+ this.value[j+0] = ((Tuple3i)value).x;
+ this.value[j+1] = ((Tuple3i)value).y;
+ this.value[j+2] = ((Tuple3i)value).z;
+ }
+
+ Object get() {
+ Tuple3i[] arr = new Tuple3i[this.length];
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 3;
+ arr[i].x = this.value[j+0];
+ arr[i].y = this.value[j+1];
+ arr[i].z = this.value[j+2];
+ }
+ return arr;
+ }
+
+ Object getRef() {
+ return this.value;
+ }
+ }
+
+ // Wrapper class for Tuple3f
+ static class Tuple3fArrayWrapper extends ArrayWrapper {
+ private float[] value = new float[0];
+
+ void set(Object value) {
+ Tuple3f[] arr = (Tuple3f[])value;
+ if (this.length != arr.length) {
+ this.length = arr.length;
+ this.value = new float[this.length*3];
+ }
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 3;
+ this.value[j+0] = arr[i].x;
+ this.value[j+1] = arr[i].y;
+ this.value[j+2] = arr[i].z;
+ }
+ }
+
+ void set(int index, Object value) {
+ int j = index * 3;
+ this.value[j+0] = ((Tuple3f)value).x;
+ this.value[j+1] = ((Tuple3f)value).y;
+ this.value[j+2] = ((Tuple3f)value).z;
+ }
+
+ Object get() {
+ Tuple3f[] arr = new Tuple3f[this.length];
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 3;
+ arr[i].x = this.value[j+0];
+ arr[i].y = this.value[j+1];
+ arr[i].z = this.value[j+2];
+ }
+ return arr;
+ }
+
+ Object getRef() {
+ return this.value;
+ }
+ }
+
+ /*
+ // Wrapper class for Tuple3d
+ static class Tuple3dArrayWrapper extends ArrayWrapper {
+ private double[] value = new double[0];
+
+ void set(Object value) {
+ Tuple3d[] arr = (Tuple3d[])value;
+ if (this.length != arr.length) {
+ this.length = arr.length;
+ this.value = new double[this.length*3];
+ }
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 3;
+ this.value[j+0] = arr[i].x;
+ this.value[j+1] = arr[i].y;
+ this.value[j+2] = arr[i].z;
+ }
+ }
+
+ void set(int index, Object value) {
+ int j = index * 3;
+ this.value[j+0] = ((Tuple3d)value).x;
+ this.value[j+1] = ((Tuple3d)value).y;
+ this.value[j+2] = ((Tuple3d)value).z;
+ }
+
+ Object get() {
+ Tuple3d[] arr = new Tuple3d[this.length];
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 3;
+ arr[i].x = this.value[j+0];
+ arr[i].y = this.value[j+1];
+ arr[i].z = this.value[j+2];
+ }
+ return arr;
+ }
+
+ Object getRef() {
+ return this.value;
+ }
+ }
+ */
+
+ // Wrapper class for Tuple4i
+ static class Tuple4iArrayWrapper extends ArrayWrapper {
+ private int[] value = new int[0];
+
+ void set(Object value) {
+ Tuple4i[] arr = (Tuple4i[])value;
+ if (this.length != arr.length) {
+ this.length = arr.length;
+ this.value = new int[this.length*4];
+ }
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 4;
+ this.value[j+0] = arr[i].x;
+ this.value[j+1] = arr[i].y;
+ this.value[j+2] = arr[i].z;
+ this.value[j+3] = arr[i].w;
+ }
+ }
+
+ void set(int index, Object value) {
+ int j = index * 4;
+ this.value[j+0] = ((Tuple4i)value).x;
+ this.value[j+1] = ((Tuple4i)value).y;
+ this.value[j+2] = ((Tuple4i)value).z;
+ this.value[j+3] = ((Tuple4i)value).w;
+ }
+
+ Object get() {
+ Tuple4i[] arr = new Tuple4i[this.length];
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 4;
+ arr[i].x = this.value[j+0];
+ arr[i].y = this.value[j+1];
+ arr[i].z = this.value[j+2];
+ arr[i].w = this.value[j+3];
+ }
+ return arr;
+ }
+
+ Object getRef() {
+ return this.value;
+ }
+ }
+
+ // Wrapper class for Tuple4f
+ static class Tuple4fArrayWrapper extends ArrayWrapper {
+ private float[] value = new float[0];
+
+ void set(Object value) {
+ Tuple4f[] arr = (Tuple4f[])value;
+ if (this.length != arr.length) {
+ this.length = arr.length;
+ this.value = new float[this.length*4];
+ }
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 4;
+ this.value[j+0] = arr[i].x;
+ this.value[j+1] = arr[i].y;
+ this.value[j+2] = arr[i].z;
+ this.value[j+3] = arr[i].w;
+ }
+ }
+
+ void set(int index, Object value) {
+ int j = index * 4;
+ this.value[j+0] = ((Tuple4f)value).x;
+ this.value[j+1] = ((Tuple4f)value).y;
+ this.value[j+2] = ((Tuple4f)value).z;
+ this.value[j+3] = ((Tuple4f)value).w;
+ }
+
+ Object get() {
+ Tuple4f[] arr = new Tuple4f[this.length];
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 4;
+ arr[i].x = this.value[j+0];
+ arr[i].y = this.value[j+1];
+ arr[i].z = this.value[j+2];
+ arr[i].w = this.value[j+3];
+ }
+ return arr;
+ }
+
+ Object getRef() {
+ return this.value;
+ }
+ }
+
+ /*
+ // Wrapper class for Tuple4d
+ static class Tuple4dArrayWrapper extends ArrayWrapper {
+ private double[] value = new double[0];
+
+ void set(Object value) {
+ Tuple4d[] arr = (Tuple4d[])value;
+ if (this.length != arr.length) {
+ this.length = arr.length;
+ this.value = new double[this.length*4];
+ }
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 4;
+ this.value[j+0] = arr[i].x;
+ this.value[j+1] = arr[i].y;
+ this.value[j+2] = arr[i].z;
+ this.value[j+3] = arr[i].w;
+ }
+ }
+
+ void set(int index, Object value) {
+ int j = index * 4;
+ this.value[j+0] = ((Tuple4d)value).x;
+ this.value[j+1] = ((Tuple4d)value).y;
+ this.value[j+2] = ((Tuple4d)value).z;
+ this.value[j+3] = ((Tuple4d)value).w;
+ }
+
+ Object get() {
+ Tuple4d[] arr = new Tuple4d[this.length];
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 4;
+ arr[i].x = this.value[j+0];
+ arr[i].y = this.value[j+1];
+ arr[i].z = this.value[j+2];
+ arr[i].w = this.value[j+3];
+ }
+ return arr;
+ }
+
+ Object getRef() {
+ return this.value;
+ }
+ }
+ */
+
+ // Wrapper class for Matrix3f
+ static class Matrix3fArrayWrapper extends ArrayWrapper {
+ private float[] value = new float[0];
+
+ void set(Object value) {
+ Matrix3f[] arr = (Matrix3f[])value;
+ if (this.length != arr.length) {
+ this.length = arr.length;
+ this.value = new float[this.length * 9];
+ }
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 9;
+ this.value[j+0] = arr[i].m00;
+ this.value[j+1] = arr[i].m01;
+ this.value[j+2] = arr[i].m02;
+ this.value[j+3] = arr[i].m10;
+ this.value[j+4] = arr[i].m11;
+ this.value[j+5] = arr[i].m12;
+ this.value[j+6] = arr[i].m20;
+ this.value[j+7] = arr[i].m21;
+ this.value[j+8] = arr[i].m22;
+ }
+ }
+
+ void set(int index, Object value) {
+ int j = index * 9;
+ Matrix3f m = (Matrix3f)value;
+
+ this.value[j+0] = m.m00;
+ this.value[j+1] = m.m01;
+ this.value[j+2] = m.m02;
+ this.value[j+3] = m.m10;
+ this.value[j+4] = m.m11;
+ this.value[j+5] = m.m12;
+ this.value[j+6] = m.m20;
+ this.value[j+7] = m.m21;
+ this.value[j+8] = m.m22;
+ }
+
+ Object get() {
+ Matrix3f[] arr = new Matrix3f[this.length];
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 9;
+ arr[i].m00 = this.value[j+0];
+ arr[i].m01 = this.value[j+1];
+ arr[i].m02 = this.value[j+2];
+ arr[i].m10 = this.value[j+3];
+ arr[i].m11 = this.value[j+4];
+ arr[i].m12 = this.value[j+5];
+ arr[i].m20 = this.value[j+6];
+ arr[i].m21 = this.value[j+7];
+ arr[i].m22 = this.value[j+8];
+ }
+ return arr;
+ }
+
+ Object getRef() {
+ return this.value;
+ }
+ }
+
+ /*
+ // Wrapper class for Matrix3d
+ static class Matrix3dArrayWrapper extends ArrayWrapper {
+ private double[] value = new double[0];
+
+ void set(Object value) {
+ Matrix3d[] arr = (Matrix3d[])value;
+ if (this.length != arr.length) {
+ this.length = arr.length;
+ this.value = new double[this.length * 9];
+ }
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 9;
+ this.value[j+0] = arr[i].m00;
+ this.value[j+1] = arr[i].m01;
+ this.value[j+2] = arr[i].m02;
+ this.value[j+3] = arr[i].m10;
+ this.value[j+4] = arr[i].m11;
+ this.value[j+5] = arr[i].m12;
+ this.value[j+6] = arr[i].m20;
+ this.value[j+7] = arr[i].m21;
+ this.value[j+8] = arr[i].m22;
+ }
+ }
+
+ void set(int index, Object value) {
+ int j = index * 9;
+ Matrix3d m = (Matrix3d)value;
+
+ this.value[j+0] = m.m00;
+ this.value[j+1] = m.m01;
+ this.value[j+2] = m.m02;
+ this.value[j+3] = m.m10;
+ this.value[j+4] = m.m11;
+ this.value[j+5] = m.m12;
+ this.value[j+6] = m.m20;
+ this.value[j+7] = m.m21;
+ this.value[j+8] = m.m22;
+ }
+
+ Object get() {
+ Matrix3d[] arr = new Matrix3d[this.length];
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 9;
+ arr[i].m00 = this.value[j+0];
+ arr[i].m01 = this.value[j+1];
+ arr[i].m02 = this.value[j+2];
+ arr[i].m10 = this.value[j+3];
+ arr[i].m11 = this.value[j+4];
+ arr[i].m12 = this.value[j+5];
+ arr[i].m20 = this.value[j+6];
+ arr[i].m21 = this.value[j+7];
+ arr[i].m22 = this.value[j+8];
+ }
+ return arr;
+ }
+
+ Object getRef() {
+ return this.value;
+ }
+ }
+ */
+
+ // Wrapper class for Matrix4f
+ static class Matrix4fArrayWrapper extends ArrayWrapper {
+ private float[] value = new float[0];
+
+ void set(Object value) {
+ Matrix4f[] arr = (Matrix4f[])value;
+ if (this.length != arr.length) {
+ this.length = arr.length;
+ this.value = new float[this.length * 16];
+ }
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 16;
+ this.value[j+0] = arr[i].m00;
+ this.value[j+1] = arr[i].m01;
+ this.value[j+2] = arr[i].m02;
+ this.value[j+3] = arr[i].m03;
+ this.value[j+4] = arr[i].m10;
+ this.value[j+5] = arr[i].m11;
+ this.value[j+6] = arr[i].m12;
+ this.value[j+7] = arr[i].m13;
+ this.value[j+8] = arr[i].m20;
+ this.value[j+9] = arr[i].m21;
+ this.value[j+10] = arr[i].m22;
+ this.value[j+11] = arr[i].m23;
+ this.value[j+12] = arr[i].m30;
+ this.value[j+13] = arr[i].m31;
+ this.value[j+14] = arr[i].m32;
+ this.value[j+15] = arr[i].m33;
+ }
+ }
+
+ void set(int index, Object value) {
+ int j = index * 16;
+ Matrix4f m = (Matrix4f)value;
+
+ this.value[j+0] = m.m00;
+ this.value[j+1] = m.m01;
+ this.value[j+2] = m.m02;
+ this.value[j+3] = m.m03;
+ this.value[j+4] = m.m10;
+ this.value[j+5] = m.m11;
+ this.value[j+6] = m.m12;
+ this.value[j+7] = m.m13;
+ this.value[j+8] = m.m20;
+ this.value[j+9] = m.m21;
+ this.value[j+10] = m.m22;
+ this.value[j+11] = m.m23;
+ this.value[j+12] = m.m30;
+ this.value[j+13] = m.m31;
+ this.value[j+14] = m.m32;
+ this.value[j+15] = m.m33;
+ }
+
+ Object get() {
+ Matrix4f[] arr = new Matrix4f[this.length];
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 16;
+ arr[i].m00 = this.value[j+0];
+ arr[i].m01 = this.value[j+1];
+ arr[i].m02 = this.value[j+2];
+ arr[i].m03 = this.value[j+3];
+ arr[i].m10 = this.value[j+4];
+ arr[i].m11 = this.value[j+5];
+ arr[i].m12 = this.value[j+6];
+ arr[i].m13 = this.value[j+7];
+ arr[i].m20 = this.value[j+8];
+ arr[i].m21 = this.value[j+9];
+ arr[i].m22 = this.value[j+10];
+ arr[i].m23 = this.value[j+11];
+ arr[i].m30 = this.value[j+12];
+ arr[i].m31 = this.value[j+13];
+ arr[i].m32 = this.value[j+14];
+ arr[i].m33 = this.value[j+15];
+ }
+ return arr;
+ }
+
+ Object getRef() {
+ return this.value;
+ }
+ }
+
+ /*
+ // Wrapper class for Matrix4d
+ static class Matrix4dArrayWrapper extends ArrayWrapper {
+ private double[] value = new double[0];
+
+ void set(Object value) {
+ Matrix4d[] arr = (Matrix4d[])value;
+ if (this.length != arr.length) {
+ this.length = arr.length;
+ this.value = new double[this.length * 16];
+ }
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 16;
+ this.value[j+0] = arr[i].m00;
+ this.value[j+1] = arr[i].m01;
+ this.value[j+2] = arr[i].m02;
+ this.value[j+3] = arr[i].m03;
+ this.value[j+4] = arr[i].m10;
+ this.value[j+5] = arr[i].m11;
+ this.value[j+6] = arr[i].m12;
+ this.value[j+7] = arr[i].m13;
+ this.value[j+8] = arr[i].m20;
+ this.value[j+9] = arr[i].m21;
+ this.value[j+10] = arr[i].m22;
+ this.value[j+11] = arr[i].m23;
+ this.value[j+12] = arr[i].m30;
+ this.value[j+13] = arr[i].m31;
+ this.value[j+14] = arr[i].m32;
+ this.value[j+15] = arr[i].m33;
+ }
+ }
+
+ void set(int index, Object value) {
+ int j = index * 16;
+ Matrix4d m = (Matrix4d)value;
+
+ this.value[j+0] = m.m00;
+ this.value[j+1] = m.m01;
+ this.value[j+2] = m.m02;
+ this.value[j+3] = m.m03;
+ this.value[j+4] = m.m10;
+ this.value[j+5] = m.m11;
+ this.value[j+6] = m.m12;
+ this.value[j+7] = m.m13;
+ this.value[j+8] = m.m20;
+ this.value[j+9] = m.m21;
+ this.value[j+10] = m.m22;
+ this.value[j+11] = m.m23;
+ this.value[j+12] = m.m30;
+ this.value[j+13] = m.m31;
+ this.value[j+14] = m.m32;
+ this.value[j+15] = m.m33;
+ }
+
+ Object get() {
+ Matrix4d[] arr = new Matrix4d[this.length];
+ for (int i = 0; i < this.length; i++) {
+ int j = i * 16;
+ arr[i].m00 = this.value[j+0];
+ arr[i].m01 = this.value[j+1];
+ arr[i].m02 = this.value[j+2];
+ arr[i].m03 = this.value[j+3];
+ arr[i].m10 = this.value[j+4];
+ arr[i].m11 = this.value[j+5];
+ arr[i].m12 = this.value[j+6];
+ arr[i].m13 = this.value[j+7];
+ arr[i].m20 = this.value[j+8];
+ arr[i].m21 = this.value[j+9];
+ arr[i].m22 = this.value[j+10];
+ arr[i].m23 = this.value[j+11];
+ arr[i].m30 = this.value[j+12];
+ arr[i].m31 = this.value[j+13];
+ arr[i].m32 = this.value[j+14];
+ arr[i].m33 = this.value[j+15];
+ }
+ return arr;
+ }
+
+ Object getRef() {
+ return this.value;
+ }
+ }
+ */
+}
diff --git a/src/classes/share/javax/media/j3d/ShaderAttributeBinding.java b/src/classes/share/javax/media/j3d/ShaderAttributeBinding.java
new file mode 100644
index 0000000..608fbfc
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/ShaderAttributeBinding.java
@@ -0,0 +1,128 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import javax.vecmath.*;
+
+/**
+ * The ShaderAttributeBinding object encapsulates a uniform attribute
+ * whose value is bound to a Java&nbsp;3D system attribute. The
+ * shader variable <code>attrName</code> is implicitly set to the
+ * value of the corresponding Java&nbsp;3D system attribute
+ * <code>j3dAttrName</code> during rendering. <code>attrName</code>
+ * must be the name of a valid uniform attribute in the shader in
+ * which it is used. Otherwise, the attribute name will be ignored and
+ * a runtime error may be generated. <code>j3dAttrName</code> must be
+ * the name of a predefined Java&nbsp;3D system attribute. An
+ * IllegalArgumentException will be thrown if the specified
+ * <code>j3dAttrName</code> is not one of the predefined system
+ * attributes. Further, the type of the <code>j3dAttrName</code>
+ * attribute must match the type of the corresponding
+ * <code>attrName</code> variable in the shader in which it is
+ * used. Otherwise, the shader will not be able to use the attribute
+ * and a runtime error may be generated.
+ *
+ * <p>
+ * Following is the list of predefined Java&nbsp;3D system attributes:<br>
+ *
+ * <ul>
+ * <font color="#ff0000"><i>TODO: replace the following with
+ * the real system attributes table</i></font><br>
+ * <table BORDER=1 CELLSPACING=2 CELLPADDING=2>
+ * <tr>
+ * <td><b>Name</b></td>
+ * <td><b>Type</b></td>
+ * <td><b>Description</b></td>
+ * </tr>
+ * <tr>
+ * <td><code>something</code></td>
+ * <td>Float</td>
+ * <td>This is something (of course)</td>
+ * </tr>
+ * <tr>
+ * <td><code>somethingElse</code></td>
+ * <td>Tuple3f</td>
+ * <td>This is something else</td>
+ * </tr>
+ * </table>
+ * </ul>
+ *
+ * <p>
+ * Depending on the shading language (and profile) being used, several
+ * Java 3D state attributes are automatically made available to the
+ * shader program as pre-defined uniform attributes. The application
+ * doesn't need to do anything to pass these attributes in to the
+ * shader program. The implementation of each shader language (e.g.,
+ * Cg, GLSL) defines its own mapping from Java 3D attribute to uniform
+ * variable name.
+ *
+ * <p>
+ * A list of these attributes for each shader language can be found in
+ * the concrete subclass of ShaderProgram for that shader language.
+ *
+ * <p>
+ * <font color="#ff0000"><i>NOTE: This class is not yet
+ * implemented.</i></font><br>
+ *
+ * @see ShaderAttributeSet
+ * @see ShaderProgram
+ *
+ * @since Java 3D 1.4
+ */
+
+public class ShaderAttributeBinding extends ShaderAttribute {
+
+ /**
+ * Constructs a new ShaderAttributeBinding from the specified
+ * <code>(attrName,&nbsp;j3dAttrName)</code> pair.
+ *
+ * @param attrName the name of the shader attribute to be added
+ * @param j3dAttrName the name of the Java&nbsp;3D attribute
+ * to bind to the shader attribute
+ *
+ * @exception UnsupportedOperationException this class is not
+ * yet implemented
+ *
+ * @exception NullPointerException if attrName or j3dAttrName is null
+ *
+ * @exception IllegalArgumentException if j3dAttrName is not the name
+ * of a valid predefined Java&nbsp;3D system attribute
+ */
+ public ShaderAttributeBinding(String attrName, String j3dAttrName) {
+ super(attrName);
+ ((ShaderAttributeBindingRetained)this.retained).initJ3dAttrName(j3dAttrName);
+ // TODO: implement this class
+ throw new UnsupportedOperationException(J3dI18N.getString("ShaderAttributeBinding0"));
+ }
+
+ /**
+ * Retrieves the name of the Java 3D system attribute that is bound to this
+ * shader attribute.
+ *
+ * @return the name of the Java 3D system attribute that is bound to this
+ * shader attribute
+ */
+ public String getJ3DAttributeName() {
+ return ((ShaderAttributeBindingRetained)this.retained).getJ3DAttributeName();
+ }
+
+ /**
+ * Creates a retained mode ShaderAttributeBindingRetained object that this
+ * ShaderAttributeBinding component object will point to.
+ */
+ void createRetained() {
+ this.retained = new ShaderAttributeBindingRetained();
+ this.retained.setSource(this);
+ }
+
+}
diff --git a/src/classes/share/javax/media/j3d/ShaderAttributeBindingRetained.java b/src/classes/share/javax/media/j3d/ShaderAttributeBindingRetained.java
new file mode 100644
index 0000000..b580406
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/ShaderAttributeBindingRetained.java
@@ -0,0 +1,57 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import javax.vecmath.*;
+
+/**
+ * The ShaderAttributeBinding object encapsulates a uniform attribute
+ * whose value is bound to a Java&nbsp;3D system attribute. The
+ * shader variable <code>attrName</code> is implicitly set to the
+ * value of the corresponding Java&nbsp;3D system attribute
+ * <code>j3dAttrName</code> during rendering. <code>attrName</code>
+ * must be the name of a valid uniform attribute in the shader in
+ * which it is used. Otherwise, the attribute name will be ignored and
+ * a runtime error may be generated. <code>j3dAttrName</code> must be
+ * the name of a predefined Java&nbsp;3D system attribute. An
+ * IllegalArgumentException will be thrown if the specified
+ * <code>j3dAttrName</code> is not one of the predefined system
+ * attributes. Further, the type of the <code>j3dAttrName</code>
+ * attribute must match the type of the corresponding
+ * <code>attrName</code> variable in the shader in which it is
+ * used. Otherwise, the shader will not be able to use the attribute
+ * and a runtime error may be generated.
+ */
+
+class ShaderAttributeBindingRetained extends ShaderAttributeRetained {
+ String j3dAttrName;
+
+ ShaderAttributeBindingRetained() {
+ }
+
+ void initJ3dAttrName(String j3dAttrName) {
+ this.j3dAttrName = j3dAttrName;
+ }
+
+ /**
+ * Retrieves the name of the Java 3D system attribute that is bound to this
+ * shader attribute.
+ *
+ * @return the name of the Java 3D system attribute that is bound to this
+ * shader attribute
+ */
+ String getJ3DAttributeName() {
+ return j3dAttrName;
+ }
+
+}
diff --git a/src/classes/share/javax/media/j3d/ShaderAttributeObject.java b/src/classes/share/javax/media/j3d/ShaderAttributeObject.java
new file mode 100644
index 0000000..b3a275d
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/ShaderAttributeObject.java
@@ -0,0 +1,130 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import javax.vecmath.*;
+
+/**
+ * The ShaderAttributeObject class is an abstract class that
+ * encapsulates a uniform shader attribute whose value is specified
+ * explicitly. This class has concrete subclasses for single-value
+ * attributes (ShaderAttributeValue) and array attributes
+ * (ShaderAttributeArray). The shader variable <code>attrName</code>
+ * is explicitly set to the specified <code>value</code> during
+ * rendering. <code>attrName</code> must be the name of a valid
+ * uniform attribute in the shader in which it is used. Otherwise, the
+ * attribute name will be ignored and a runtime error may be
+ * generated. The <code>value</code> must be an instance of one of the
+ * allowed classes or an array of one the allowed classes. The allowed
+ * classes are: <code>Integer</code>, <code>Float</code>,
+ * <code>Tuple{2,3,4}{i,f}</code>,
+ * <code>Matrix{3,4}f</code>. A ClassCastException will be thrown
+ * if a specified <code>value</code> object is not one of the allowed
+ * types. Further, the type of the value is immutable once a
+ * ShaderAttributeObject is constructed. Subsequent setValue
+ * operations must be called with an object of the same type as the
+ * one that was used to construct the ShaderAttributeObject. Finally,
+ * the type of the <code>value</code> object must match the type of
+ * the corresponding <code>attrName</code> variable in the shader in
+ * which it is used. Otherwise, the shader will not be able to use the
+ * attribute and a runtime error may be generated.
+ *
+ * @see ShaderAttributeSet
+ * @see ShaderProgram
+ *
+ * @since Java 3D 1.4
+ */
+
+public abstract class ShaderAttributeObject extends ShaderAttribute {
+
+ /**
+ * Specifies that this ShaderAttributeObject allows reading its value.
+ */
+ public static final int
+ ALLOW_VALUE_READ =
+ CapabilityBits.SHADER_ATTRIBUTE_OBJECT_ALLOW_VALUE_READ;
+
+ /**
+ * Specifies that this ShaderAttributeObject allows writing its value.
+ */
+ public static final int
+ ALLOW_VALUE_WRITE =
+ CapabilityBits.SHADER_ATTRIBUTE_OBJECT_ALLOW_VALUE_WRITE;
+
+
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_VALUE_READ
+ };
+
+
+ /**
+ * Package scope constructor
+ */
+ ShaderAttributeObject(String attrName, Object value) {
+ super(attrName);
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((ShaderAttributeObjectRetained)this.retained).createObjectData(value);
+ }
+
+
+ /**
+ * Retrieves the value of this shader attribute.
+ * A copy of the object is returned.
+ *
+ * @return a copy of the value of this shader attribute
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ */
+ public abstract Object getValue();
+
+ /**
+ * Sets the value of this shader attribute to the specified value.
+ * A copy of the object is stored.
+ *
+ * @param value the new value of the shader attribute
+ *
+ * @exception NullPointerException if value is null
+ *
+ * @exception ClassCastException if value is not an instance of
+ * the same base class as the object used to construct this shader
+ * attribute object.
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ */
+ public abstract void setValue(Object value);
+
+ /**
+ * Retrieves the base class of the value of this shader attribute.
+ * This class will always be one of the allowable classes, even if
+ * a subclass was used to construct this shader attribute object.
+ * For example, if this shader attribute object was constructed
+ * with an instance of <code>javax.vecmath.Point3f</code>, the
+ * returned class would be <code>javax.vecmath.Tuple3f</code>.
+ *
+ * @return the base class of the value of this shader attribute
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ */
+ public Class getValueClass() {
+
+ return ((ShaderAttributeObjectRetained)this.retained).getValueClass();
+ }
+
+}
diff --git a/src/classes/share/javax/media/j3d/ShaderAttributeObjectRetained.java b/src/classes/share/javax/media/j3d/ShaderAttributeObjectRetained.java
new file mode 100644
index 0000000..a66335c
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/ShaderAttributeObjectRetained.java
@@ -0,0 +1,311 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import java.util.ArrayList;
+import javax.vecmath.*;
+
+/**
+ * The ShaderAttributeObjectRetained class is an abstract class that
+ * encapsulates a uniform shader attribute whose value is specified
+ * explicitly. This class has concrete subclasses for single-value
+ * attributes (ShaderAttributeValueRetained) and array attributes
+ * (ShaderAttributeArrayRetained). The shader variable <code>attrName</code>
+ * is explicitly set to the specified <code>value</code> during
+ * rendering. <code>attrName</code> must be the name of a valid
+ * uniform attribute in the shader in which it is used. Otherwise, the
+ * attribute name will be ignored and a runtime error may be
+ * generated. The <code>value</code> must be an instance of one of the
+ * allowed classes or an array of one the allowed classes. The allowed
+ * classes are: <code>Integer</code>, <code>Float</code>,
+ * <code>Tuple{2,3,4}{i,f}</code>,
+ * <code>Matrix{3,4}f</code>. A ClassCastException will be thrown
+ * if a specified <code>value</code> object is not one of the allowed
+ * types. Further, the type of the value is immutable once a
+ * ShaderAttributeObjectRetained is constructed. Subsequent setValue
+ * operations must be called with an object of the same type as the
+ * one that was used to construct the ShaderAttributeObjectRetained.
+ * Finally, the type of the <code>value</code> object must match the type
+ * of the corresponding <code>attrName</code> variable in the shader in
+ * which it is used. Otherwise, the shader will not be able to use the
+ * attribute and a runtime error may be generated.
+ *
+ * @see ShaderAttributeSetRetained
+ * @see ShaderProgramRetained
+ *
+ * @since Java 3D 1.4
+ */
+
+abstract class ShaderAttributeObjectRetained extends ShaderAttributeRetained {
+
+ private int classType;
+ private Class baseClass;
+ AttrWrapper attrWrapper;
+
+ /**
+ * Package scope constructor
+ */
+ ShaderAttributeObjectRetained() {
+ }
+
+ void createObjectData(Object value) {
+
+ classType = computeClassType(value);
+ baseClass = getBaseClass(classType);
+ attrWrapper = createAttrWrapper(value, classType);
+ /*
+ System.err.println(" classType = " + classType +
+ ", baseClass = " + baseClass +
+ ", attrWrapper.get() = " + attrWrapper.get());
+ */
+ }
+
+
+ void initValue(Object value) {
+ /*
+ System.err.println("ShaderAttributeObjectRetained : attrName = " + attrName +
+ ", value = " + value +
+ ", value.class = " + value.getClass());
+ */
+ attrWrapper.set(value);
+
+ }
+
+ /**
+ * Retrieves the value of this shader attribute.
+ * A copy of the object is returned.
+ */
+ Object getValue() {
+ return attrWrapper.get();
+ }
+
+ /**
+ * Sets the value of this shader attribute to the specified value.
+ * A copy of the object is stored.
+ *
+ * @param value the new value of the shader attribute
+ *
+ * @exception NullPointerException if value is null
+ *
+ * @exception ClassCastException if value is not an instance of
+ * the same base class as the object used to construct this shader
+ * attribute object.
+ *
+ */
+ void setValue(Object value) {
+ initValue(value);
+ AttrWrapper valueWrapper = createAttrWrapper(value, this.classType);
+ sendMessage(SHADER_ATTRIBUTE_VALUE_UPDATE, valueWrapper);
+ }
+
+ /**
+ * Retrieves the base class of the value of this shader attribute.
+ * This class will always be one of the allowable classes, even if
+ * a subclass was used to construct this shader attribute object.
+ * For example, if this shader attribute object was constructed
+ * with an instance of <code>javax.vecmath.Point3f</code>, the
+ * returned class would be <code>javax.vecmath.Tuple3f</code>.
+ *
+ * @return the base class of the value of this shader attribute
+ */
+ Class getValueClass() {
+ return baseClass;
+ }
+
+ /**
+ * Initializes a mirror object.
+ */
+ synchronized void initMirrorObject() {
+ super.initMirrorObject();
+ ((ShaderAttributeObjectRetained)mirror).initValue(getValue());
+ }
+
+ /**
+ * Update the "component" field of the mirror object with the given "value"
+ */
+ synchronized void updateMirrorObject(int component, Object value) {
+
+ //System.out.println("ShaderAttributeObjectRetained : updateMirrorObject");
+ ShaderAttributeObjectRetained mirrorSAV = (ShaderAttributeObjectRetained)mirror;
+ if ((component & SHADER_ATTRIBUTE_VALUE_UPDATE) != 0) {
+ //System.out.println(" -- SHADER_ATTRIBUTE_VALUE_UPDATE");
+ mirrorSAV.attrWrapper = (AttrWrapper) value;
+ }
+ }
+
+ final void sendMessage(int attrMask, Object attr) {
+
+ ArrayList univList = new ArrayList();
+ ArrayList gaList = Shape3DRetained.getGeomAtomsList(mirror.users, univList);
+
+ // Send to rendering attribute structure, regardless of
+ // whether there are users or not (alternate appearance case ..)
+ J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
+ createMessage.type = J3dMessage.SHADER_ATTRIBUTE_CHANGED;
+ createMessage.universe = null;
+ createMessage.args[0] = this;
+ createMessage.args[1]= new Integer(attrMask);
+ createMessage.args[2] = attr;
+ // System.out.println("changedFreqent1 = "+changedFrequent);
+ createMessage.args[3] = new Integer(changedFrequent);
+ VirtualUniverse.mc.processMessage(createMessage);
+
+ // System.out.println("univList.size is " + univList.size());
+ for(int i=0; i<univList.size(); i++) {
+ createMessage = VirtualUniverse.mc.getMessage();
+ createMessage.threads = J3dThread.UPDATE_RENDER;
+ createMessage.type = J3dMessage.SHADER_ATTRIBUTE_CHANGED;
+
+ createMessage.universe = (VirtualUniverse) univList.get(i);
+ createMessage.args[0] = this;
+ createMessage.args[1]= new Integer(attrMask);
+ createMessage.args[2] = attr;
+
+ ArrayList gL = (ArrayList)gaList.get(i);
+ GeometryAtom[] gaArr = new GeometryAtom[gL.size()];
+ gL.toArray(gaArr);
+ createMessage.args[3] = gaArr;
+
+ VirtualUniverse.mc.processMessage(createMessage);
+ }
+
+ }
+
+
+ // Enumerated types representing allowed classes for shader
+ // attributes.
+ //
+ // NOTE that the values for these enums are used as an index into
+ // the tables of classes, so the values must start at 0 and
+ // increment by 1. Also, the order must be the same as the order
+ // of the entries in each of the two class tables.
+ static final int TYPE_INTEGER = 0;
+ static final int TYPE_FLOAT = 1;
+ static final int TYPE_TUPLE2I = 2;
+ static final int TYPE_TUPLE2F = 3;
+ static final int TYPE_TUPLE3I = 4;
+ static final int TYPE_TUPLE3F = 5;
+ static final int TYPE_TUPLE4I = 6;
+ static final int TYPE_TUPLE4F = 7;
+ static final int TYPE_MATRIX3F = 8;
+ static final int TYPE_MATRIX4F = 9;
+
+ // Double-precision is not supported in the current version. Uncomment the
+ // following if future support is done.
+// static final int TYPE_DOUBLE = 10;
+// static final int TYPE_TUPLE2D = 11;
+// static final int TYPE_TUPLE3D = 12;
+// static final int TYPE_TUPLE4D = 13;
+// static final int TYPE_MATRIX3D = 14;
+// static final int TYPE_MATRIX4D = 15;
+
+ static final Class classTable[] = {
+ Integer.class,
+ Float.class,
+ Tuple2i.class,
+ Tuple2f.class,
+ Tuple3i.class,
+ Tuple3f.class,
+ Tuple4i.class,
+ Tuple4f.class,
+ Matrix3f.class,
+ Matrix4f.class,
+
+ // Double-precision is not supported in the current version. Uncomment the
+ // following if future support is done.
+// Double.class,
+// Tuple2d.class,
+// Tuple3d.class,
+// Tuple4d.class,
+// Matrix3d.class,
+// Matrix4d.class,
+ };
+
+ static final Class classTableArr[] = {
+ Integer[].class,
+ Float[].class,
+ Tuple2i[].class,
+ Tuple2f[].class,
+ Tuple3i[].class,
+ Tuple3f[].class,
+ Tuple4i[].class,
+ Tuple4f[].class,
+ Matrix3f[].class,
+ Matrix4f[].class,
+
+ // Double-precision is not supported in the current version. Uncomment the
+ // following if future support is done.
+// Double[].class,
+// Tuple2d[].class,
+// Tuple3d[].class,
+// Tuple4d[].class,
+// Matrix3d[].class,
+// Matrix4d[].class,
+ };
+
+
+ /**
+ * Computes the base class from the specified object. A
+ * ClassCastException is thrown if the object is not an instance
+ * or array of one of the allowed classes.
+ */
+ abstract int computeClassType(Object value);
+
+ /**
+ * Returns the base class represented by the specified class type.
+ */
+ abstract Class getBaseClass(int classType);
+
+ /**
+ * Creates an attribute wrapper object of the specified class
+ * type, and stores the specified object.
+ */
+ abstract AttrWrapper createAttrWrapper(Object value, int classType);
+
+
+ /**
+ * Base wrapper class for subclasses that are used to store a copy
+ * of the user-specified shader attribute value. There is a
+ * wrapper class for each supported base class in ShaderAttributeValue
+ * and ShaderAttributeArray. The value is stored in a Java primitive array.
+ */
+ static abstract class AttrWrapper {
+ /**
+ * Stores a copy of the specified object in the wrapper object
+ */
+ abstract void set(Object value);
+
+ /**
+ * Returns a copy of the wrapped object
+ */
+ abstract Object get();
+
+ /**
+ * Returns a reference to the internal primitive array used to
+ * wrap the object; note that the caller of this method must
+ * treat the data as read-only. It is intended only as a means
+ * to pass data down to native methods.
+ */
+ abstract Object getRef();
+ }
+
+ int getClassType() {
+ return classType;
+ }
+
+ void setClassType(int classType) {
+ this.classType = classType;
+ }
+
+}
diff --git a/src/classes/share/javax/media/j3d/ShaderAttributeRetained.java b/src/classes/share/javax/media/j3d/ShaderAttributeRetained.java
new file mode 100644
index 0000000..64cbdc0
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/ShaderAttributeRetained.java
@@ -0,0 +1,82 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import javax.vecmath.*;
+
+/**
+ * The ShaderAttributeRetained object encapsulates a uniform attribute for a
+ * shader programs. Uniform attributes (variables) are those
+ * attributes whose values are constant during the rendering of a
+ * primitive. Their values may change from primitive to primitive, but
+ * are constant for each vertex (for vertex shaders) or fragment (for
+ * fragment shaders) of a single primitive. Examples of uniform
+ * attributes include a transformation matrix, a texture map, lights,
+ * lookup tables, etc.
+ *
+ * <p>
+ * There are two ways in which values can be specified for uniform
+ * attributes: explicitly, by providing a value; and implicitly, by
+ * defining a binding between a Java 3D system attribute and a uniform
+ * attribute. This functionality is provided by two subclasses of
+ * ShaderAttributeRetained as follows:
+ *
+ * <ul>
+ * <li>ShaderAttributeObjectRetained, in which attributes are expressed as
+ * <code>(attrName,&nbsp;value)</code> pairs, is used for explicitly
+ * defined attributes</li>
+ * <li>ShaderAttributeBindingRetained, in which attributes are expressed as
+ * <code>(attrName,&nbsp;j3dAttrName)</code> pairs, is used for
+ * implicitly defined, automatically tracked attributes</li>
+ * </ul>
+ *
+ * @see ShaderAttributeSetRetained
+ * @see ShaderProgramRetained
+ *
+ * @since Java 3D 1.4
+ */
+
+abstract class ShaderAttributeRetained extends NodeComponentRetained {
+ // A list of pre-defined bits to indicate which component
+ // in this ShaderAttribute object changed.
+ static final int SHADER_ATTRIBUTE_VALUE_UPDATE = 0x001;
+
+ /**
+ * Name of the shader attribute (immutable)
+ */
+ String attrName;
+
+ /**
+ * Package scope constructor
+ */
+ ShaderAttributeRetained() {
+ }
+
+ void initializeAttrName(String attrName) {
+ this.attrName = attrName;
+ }
+
+ /**
+ * Retrieves the name of this shader attribute.
+ *
+ * @return the name of this shader attribute
+ */
+ String getAttributeName() {
+ return attrName;
+ }
+
+ void initMirrorObject() {
+ ((ShaderAttributeObjectRetained)mirror).initializeAttrName(this.attrName);
+ }
+
+}
diff --git a/src/classes/share/javax/media/j3d/ShaderAttributeSet.java b/src/classes/share/javax/media/j3d/ShaderAttributeSet.java
new file mode 100644
index 0000000..ad75b11
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/ShaderAttributeSet.java
@@ -0,0 +1,263 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.HashMap;
+import javax.vecmath.*;
+
+/**
+ * The ShaderAttributeSet object provides uniform attributes to shader
+ * programs. Uniform attributes (variables) are those attributes whose
+ * values are constant during the rendering of a primitive. Their
+ * values may change from primitive to primitive, but are constant for
+ * each vertex (for vertex shaders) or fragment (for fragment shaders)
+ * of a single primitive. Examples of uniform attributes include a
+ * transformation matrix, a texture map, lights, lookup tables, etc.
+ * The ShaderAttributeSet object contains a set of ShaderAttribute
+ * objects. Each ShaderAttribute object defines the value of a single
+ * uniform shader variable. The set of attributes is unique with respect
+ * to attribute names: no two attributes in the set will have the same
+ * name.
+ *
+ * <p>
+ * There are two ways in which values can be specified for uniform
+ * attributes: explicitly, by providing a value; and implicitly, by
+ * defining a binding between a Java 3D system attribute and a uniform
+ * attribute. This functionality is provided by two subclasses of
+ * ShaderAttribute: ShaderAttributeObject, which is used to specify
+ * explicitly defined attributes; and ShaderAttributeBinding, which is
+ * used to specify implicitly defined, automatically tracked attributes.
+ *
+ * <p>
+ * Depending on the shading language (and profile) being used, several
+ * Java 3D state attributes are automatically made available to the
+ * shader program as pre-defined uniform attributes. The application
+ * doesn't need to do anything to pass these attributes in to the
+ * shader program. The implementation of each shader language (e.g.,
+ * Cg, GLSL) defines its own bindings from Java 3D attribute to uniform
+ * variable name. A list of these attributes for each shader language
+ * can be found in the concrete subclass of ShaderProgram for that
+ * shader language.
+ *
+ * @see ShaderAttribute
+ * @see ShaderProgram
+ * @see ShaderAppearance#setShaderAttributeSet
+ *
+ * @since Java 3D 1.4
+ */
+
+public class ShaderAttributeSet extends NodeComponent {
+
+ /**
+ * Specifies that this ShaderAttributeSet object allows reading
+ * its attributes.
+ */
+ public static final int
+ ALLOW_ATTRIBUTES_READ =
+ CapabilityBits.SHADER_ATTRIBUTE_SET_ALLOW_ATTRIBUTES_READ;
+
+ /**
+ * Specifies that this ShaderAttributeSet object allows writing
+ * its attributes.
+ */
+ public static final int
+ ALLOW_ATTRIBUTES_WRITE =
+ CapabilityBits.SHADER_ATTRIBUTE_SET_ALLOW_ATTRIBUTES_WRITE;
+
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_ATTRIBUTES_READ
+ };
+
+ /**
+ * Constructs an empty ShaderAttributeSet object. The attributes set
+ * is initially empty.
+ */
+ public ShaderAttributeSet() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+ }
+
+ //
+ // Methods for dealing with the (name, value) pairs for explicit
+ // attributes
+ //
+
+ /**
+ * Adds the specified shader attribute to the attributes set.
+ * The newly specified attribute replaces an attribute with the
+ * same name, if one already exists in the attributes set.
+ *
+ * @param attr the shader attribute to be added to the set
+ *
+ * @exception NullPointerException if attr is null
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ */
+ public void put(ShaderAttribute attr) {
+ if (attr == null) {
+ throw new NullPointerException();
+ }
+
+ if (isLiveOrCompiled())
+ if (!this.getCapability(ALLOW_ATTRIBUTES_WRITE))
+ throw new CapabilityNotSetException(J3dI18N.getString("ShaderAttributeSet1"));
+
+ ((ShaderAttributeSetRetained)this.retained).put(attr);
+
+ }
+
+ /**
+ * Retrieves the shader attribute with the specified
+ * <code>attrName</code> from the attributes set. If attrName does
+ * not exist in the attributes set, null is returned.
+ *
+ * @param attrName the name of the shader attribute to be retrieved
+ *
+ * @exception NullPointerException if attrName is null
+ *
+ * @return a the shader attribute associated with the specified
+ * attribute name, or null if the name is not in the attributes
+ * set
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ */
+ public ShaderAttribute get(String attrName) {
+
+ if (attrName == null) {
+ throw new NullPointerException();
+ }
+
+ if (isLiveOrCompiled())
+ if (!this.getCapability(ALLOW_ATTRIBUTES_READ))
+ throw new CapabilityNotSetException(J3dI18N.getString("ShaderAttributeSet0"));
+
+ return ((ShaderAttributeSetRetained)this.retained).get(attrName);
+ }
+
+ /**
+ * Removes the shader attribute with the specified
+ * <code>attrName</code> from the attributes set. If attrName does
+ * not exist in the attributes set then nothing happens.
+ *
+ * @param attrName the name of the shader attribute to be removed
+ *
+ * @exception NullPointerException if attrName is null
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ */
+ public void remove(String attrName) {
+ if (attrName == null) {
+ throw new NullPointerException();
+ }
+
+ if (isLiveOrCompiled())
+ if (!this.getCapability(ALLOW_ATTRIBUTES_WRITE))
+ throw new CapabilityNotSetException(J3dI18N.getString("ShaderAttributeSet1"));
+
+ ((ShaderAttributeSetRetained)this.retained).remove(attrName);
+ }
+
+ /**
+ * Removes the specified shader attribute from the attributes
+ * set. If the attribute does not exist in the attributes set then
+ * nothing happens. Note that this method will <i>not</i> remove a
+ * shader object other than the one specified, even if it has the
+ * same name as the specified attribute. Applications that wish to
+ * remove an attribute by name should use
+ * <code>removeAttribute(String)</code>.
+ *
+ * @param attr the shader attribute to be removed
+ *
+ * @exception NullPointerException if attr is null
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ */
+ public void remove(ShaderAttribute attr) {
+ if (attr == null) {
+ throw new NullPointerException();
+ }
+
+ if (isLiveOrCompiled())
+ if (!this.getCapability(ALLOW_ATTRIBUTES_WRITE))
+ throw new CapabilityNotSetException(J3dI18N.getString("ShaderAttributeSet1"));
+
+ ((ShaderAttributeSetRetained)this.retained).remove(attr);
+ }
+
+ /**
+ * Removes all shader attributes from the attributes set. The
+ * attributes set will be empty following this call.
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ */
+ public void clear() {
+
+ if (isLiveOrCompiled())
+ if (!this.getCapability(ALLOW_ATTRIBUTES_WRITE))
+ throw new CapabilityNotSetException(J3dI18N.getString("ShaderAttributeSet1"));
+
+ ((ShaderAttributeSetRetained)this.retained).clear();
+ }
+
+ /**
+ * Returns a shallow copy of the attributes set.
+ *
+ * @return a shallow copy of the attributes set
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ */
+ public ShaderAttribute[] getAll() {
+
+ if (isLiveOrCompiled())
+ if (!this.getCapability(ALLOW_ATTRIBUTES_READ))
+ throw new CapabilityNotSetException(J3dI18N.getString("ShaderAttributeSet0"));
+
+ return ((ShaderAttributeSetRetained)this.retained).getAll();
+ }
+
+ /**
+ * Returns the number of elements in the attributes set.
+ *
+ * @return the number of elements in the attributes set
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ */
+ public int size() {
+
+ if (isLiveOrCompiled())
+ if (!this.getCapability(ALLOW_ATTRIBUTES_READ))
+ throw new CapabilityNotSetException(J3dI18N.getString("ShaderAttributeSet0"));
+
+ return ((ShaderAttributeSetRetained)this.retained).size();
+ }
+
+ /**
+ * Creates a retained mode ShaderAttributeSetRetained object that this
+ * ShaderAttributeSet component object will point to.
+ */
+ void createRetained() {
+ // System.out.println("ShaderAttributeSet : createRetained() ...");
+ this.retained = new ShaderAttributeSetRetained();
+ this.retained.setSource(this);
+ }
+}
diff --git a/src/classes/share/javax/media/j3d/ShaderAttributeSetRetained.java b/src/classes/share/javax/media/j3d/ShaderAttributeSetRetained.java
new file mode 100644
index 0000000..965387b
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/ShaderAttributeSetRetained.java
@@ -0,0 +1,390 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.ArrayList;
+import javax.vecmath.*;
+
+/**
+ * The ShaderAttributeSet object provides uniform attributes to shader
+ * programs. Uniform attributes (variables) are those attributes whose
+ * values are constant during the rendering of a primitive. Their
+ * values may change from primitive to primitive, but are constant for
+ * each vertex (for vertex shaders) or fragment (for fragment shaders)
+ * of a single primitive. Examples of uniform attributes include a
+ * transformation matrix, a texture map, lights, lookup tables, etc.
+ * The ShaderAttributeSet object contains a set of ShaderAttribute
+ * objects. Each ShaderAttribute object defines the value of a single
+ * uniform shader variable. The set of attributes is unique with respect
+ * to attribute names: no two attributes in the set will have the same
+ * name.
+ *
+ * <p>
+ * There are two ways in which values can be specified for uniform
+ * attributes: explicitly, by providing a value; and implicitly, by
+ * defining a binding between a Java 3D system attribute and a uniform
+ * attribute. This functionality is provided by two subclasses of
+ * ShaderAttribute: ShaderAttributeObject, which is used to specify
+ * explicitly defined attributes; and ShaderAttributeBinding, which is
+ * used to specify implicitly defined, automatically tracked attributes.
+ *
+ * <p>
+ * Depending on the shading language (and profile) being used, several
+ * Java 3D state attributes are automatically made available to the
+ * shader program as pre-defined uniform attributes. The application
+ * doesn't need to do anything to pass these attributes in to the
+ * shader program. The implementation of each shader language (e.g.,
+ * Cg, GLSL) defines its own bindings from Java 3D attribute to uniform
+ * variable name. A list of these attributes for each shader language
+ * can be found in the concrete subclass of ShaderProgram for that
+ * shader language.
+ *
+ * @see ShaderAttribute
+ * @see ShaderProgram
+ * @see ShaderAppearance#setShaderAttributeSet
+ *
+ * @since Java 3D 1.4
+ */
+
+class ShaderAttributeSetRetained extends NodeComponentRetained {
+ // A list of pre-defined bits to indicate which attribute
+ // operation in this ShaderAttributeSet object is needed.
+ static final int ATTRIBUTE_SET_PUT = 0x01;
+
+ static final int ATTRIBUTE_SET_REMOVE = 0x02;
+
+ static final int ATTRIBUTE_SET_CLEAR = 0x04;
+
+ private Map attrs = new HashMap();
+
+ // Lock used for synchronization of live state
+ Object liveStateLock = new Object();
+
+ /**
+ * Constructs an empty ShaderAttributeSetretained object. The attributes set
+ * is initially empty.
+ */
+ ShaderAttributeSetRetained() {
+ }
+
+ //
+ // Methods for dealing with the (name, value) pairs for explicit
+ // attributes
+ //
+
+ /**
+ * Adds the specified shader attribute to the attributes set.
+ * The newly specified attribute replaces an attribute with the
+ * same name, if one already exists in the attributes set.
+ *
+ * @param attr the shader attribute to be added to the set
+ *
+ */
+ void put(ShaderAttribute attr) {
+ synchronized(liveStateLock) {
+ // System.out.println("ShaderAttributeSetRetained : put()");
+ ShaderAttributeRetained sAttr = (ShaderAttributeRetained)attr.retained;
+ // System.out.println("attr is " + attr );
+ // System.out.println("attrName is " + sAttr.attrName + " attr.Retained is "+ sAttr );
+ assert(sAttr != null);
+ attrs.put(sAttr.attrName, sAttr);
+
+ if (source.isLive()) {
+ sAttr.setLive(inBackgroundGroup, refCount);
+ sAttr.copyMirrorUsers(this);
+
+ sendMessage(ATTRIBUTE_SET_PUT, sAttr.mirror);
+ }
+ }
+ }
+
+ /**
+ * Retrieves the shader attribute with the specified
+ * <code>attrName</code> from the attributes set. If attrName does
+ * not exist in the attributes set, null is returned.
+ *
+ * @param attrName the name of the shader attribute to be retrieved
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ */
+ ShaderAttribute get(String attrName) {
+ return (ShaderAttribute)((ShaderAttributeRetained)attrs.get(attrName)).source;
+ }
+
+ /**
+ * Removes the shader attribute with the specified
+ * <code>attrName</code> from the attributes set. If attrName does
+ * not exist in the attributes set then nothing happens.
+ *
+ * @param attrName the name of the shader attribute to be removed
+ */
+ void remove(String attrName) {
+ synchronized(liveStateLock) {
+ ShaderAttributeRetained sAttr = (ShaderAttributeRetained)attrs.get(attrName);
+ attrs.remove(attrName);
+ if (source.isLive()) {
+ sAttr.clearLive(refCount);
+ sAttr.removeMirrorUsers(this);
+
+ sendMessage(ATTRIBUTE_SET_REMOVE, attrName);
+ }
+ }
+ }
+
+ /**
+ * Removes the specified shader attribute from the attributes
+ * set. If the attribute does not exist in the attributes set then
+ * nothing happens. Note that this method will <i>not</i> remove a
+ * shader object other than the one specified, even if it has the
+ * same name as the specified attribute. Applications that wish to
+ * remove an attribute by name should use
+ * <code>removeAttribute(String)</code>.
+ *
+ * @param attr the shader attribute to be removed
+ */
+ void remove(ShaderAttribute attr) {
+ synchronized(liveStateLock) {
+ String attrName = attr.getAttributeName();
+ if (attrs.get(attrName) == attr) {
+ attrs.remove(attrName);
+ if (source.isLive()) {
+ ((ShaderAttributeRetained)attr.retained).clearLive(refCount);
+ ((ShaderAttributeRetained)attr.retained).removeMirrorUsers(this);
+
+ sendMessage(ATTRIBUTE_SET_REMOVE, attrName);
+ }
+ }
+ }
+ }
+
+ /**
+ * Removes all shader attributes from the attributes set. The
+ * attributes set will be empty following this call.
+ *
+ */
+ void clear() {
+ synchronized(liveStateLock) {
+ attrs.clear();
+ if(source.isLive()) {
+ ShaderAttributeRetained[] sAttrs = new ShaderAttributeRetained[attrs.size()];
+ sAttrs = (ShaderAttributeRetained[])attrs.values().toArray(sAttrs);
+ for (int i = 0; i < sAttrs.length; i++) {
+ sAttrs[i].clearLive(refCount);
+ sAttrs[i].removeMirrorUsers(this);
+ }
+ sendMessage(ATTRIBUTE_SET_CLEAR, null);
+ }
+ }
+ }
+
+ /**
+ * Returns a shallow copy of the attributes set.
+ *
+ * @return a shallow copy of the attributes set
+ *
+ */
+ ShaderAttribute[] getAll() {
+
+ ShaderAttributeRetained[] sAttrsRetained = new ShaderAttributeRetained[attrs.size()];
+ ShaderAttribute[] sAttrs = new ShaderAttribute[sAttrsRetained.length];
+ sAttrsRetained = (ShaderAttributeRetained[])attrs.values().toArray(sAttrsRetained);
+ for(int i=0; i < sAttrsRetained.length; i++) {
+ sAttrs[i] = (ShaderAttribute) sAttrsRetained[i].source;
+ }
+
+ return sAttrs;
+ }
+
+ /**
+ * Returns the number of elements in the attributes set.
+ *
+ * @return the number of elements in the attributes set
+ *
+ */
+ int size() {
+ return attrs.size();
+ }
+
+
+ void updateNative(Canvas3D cv, ShaderProgramRetained shaderProgram) {
+ shaderProgram.setShaderAttributes(cv, this);
+ }
+
+ Map getAttrs() {
+ return attrs;
+ }
+
+
+ void setLive(boolean backgroundGroup, int refCount) {
+
+ // System.out.println("ShaderAttributeSetRetained.setLive()");
+ ShaderAttributeRetained[] sAttrsRetained = new ShaderAttributeRetained[attrs.size()];
+ sAttrsRetained = (ShaderAttributeRetained[])attrs.values().toArray(sAttrsRetained);
+ for(int i=0; i < sAttrsRetained.length; i++) {
+ sAttrsRetained[i].setLive(backgroundGroup, refCount);
+ }
+
+ super.doSetLive(backgroundGroup, refCount);
+ super.markAsLive();
+ }
+
+ synchronized void addAMirrorUser(Shape3DRetained shape) {
+
+ super.addAMirrorUser(shape);
+
+ ShaderAttributeRetained[] sAttrsRetained = new ShaderAttributeRetained[attrs.size()];
+ sAttrsRetained = (ShaderAttributeRetained[])attrs.values().toArray(sAttrsRetained);
+ for(int i=0; i < sAttrsRetained.length; i++) {
+ sAttrsRetained[i].addAMirrorUser(shape);
+ }
+ }
+
+ synchronized void removeAMirrorUser(Shape3DRetained shape) {
+ super.removeAMirrorUser(shape);
+
+ ShaderAttributeRetained[] sAttrsRetained = new ShaderAttributeRetained[attrs.size()];
+ sAttrsRetained = (ShaderAttributeRetained[])attrs.values().toArray(sAttrsRetained);
+ for(int i=0; i < sAttrsRetained.length; i++) {
+ sAttrsRetained[i].removeAMirrorUser(shape);
+ }
+ }
+
+
+ synchronized void removeMirrorUsers(NodeComponentRetained node) {
+ super.removeMirrorUsers(node);
+
+ ShaderAttributeRetained[] sAttrsRetained = new ShaderAttributeRetained[attrs.size()];
+ sAttrsRetained = (ShaderAttributeRetained[])attrs.values().toArray(sAttrsRetained);
+ for(int i=0; i < sAttrsRetained.length; i++) {
+ sAttrsRetained[i].removeMirrorUsers(node);
+ }
+ }
+
+ synchronized void copyMirrorUsers(NodeComponentRetained node) {
+ super.copyMirrorUsers(node);
+
+ ShaderAttributeRetained[] sAttrsRetained = new ShaderAttributeRetained[attrs.size()];
+ sAttrsRetained = (ShaderAttributeRetained[])attrs.values().toArray(sAttrsRetained);
+ for(int i=0; i < sAttrsRetained.length; i++) {
+ sAttrsRetained[i].copyMirrorUsers(node);
+ }
+ }
+
+ void clearLive(int refCount) {
+ // System.out.println("ShaderAttributeSetRetained.clearLive()");
+
+ super.clearLive(refCount);
+
+ ShaderAttributeRetained[] sAttrsRetained = new ShaderAttributeRetained[attrs.size()];
+ sAttrsRetained = (ShaderAttributeRetained[])attrs.values().toArray(sAttrsRetained);
+ for(int i=0; i < sAttrsRetained.length; i++) {
+ sAttrsRetained[i].clearLive(refCount);
+ }
+ }
+
+ synchronized void createMirrorObject() {
+ // System.out.println("ShaderAttributeSetRetained : createMirrorObject");
+ // This method should only call by setLive().
+ if (mirror == null) {
+ ShaderAttributeSetRetained mirrorSAS = new ShaderAttributeSetRetained();
+ mirror = mirrorSAS;
+ mirror.source = source;
+
+ }
+ initMirrorObject();
+ }
+
+ void initMirrorObject() {
+
+ ShaderAttributeRetained[] sAttrs = new ShaderAttributeRetained[attrs.size()];
+ sAttrs = (ShaderAttributeRetained[])attrs.values().toArray(sAttrs);
+ // Need to copy the mirror attrs
+ for (int i = 0; i < sAttrs.length; i++) {
+ ShaderAttributeRetained mirrorSA = (ShaderAttributeRetained) sAttrs[i].mirror;
+ assert(mirrorSA != null);
+ ((ShaderAttributeSetRetained)mirror).attrs.put(mirrorSA.attrName, mirrorSA);
+ }
+ }
+
+ /**
+ * Update the "component" field of the mirror object with the given "value"
+ */
+ synchronized void updateMirrorObject(int component, Object value) {
+
+ // System.out.println("ShaderAttributeSetRetained : updateMirrorObject");
+
+ ShaderAttributeSetRetained mirrorSAS = (ShaderAttributeSetRetained)mirror;
+
+ if ((component & ATTRIBUTE_SET_PUT) != 0) {
+ // System.out.println(" -- ATTRIBUTE_SET_PUT");
+ ShaderAttributeRetained mirrorSA = (ShaderAttributeRetained)value;
+ assert(mirrorSA != null);
+ ((ShaderAttributeSetRetained)mirror).attrs.put(mirrorSA.attrName, mirrorSA);
+ }
+ else if((component & ATTRIBUTE_SET_REMOVE) != 0) {
+ // System.out.println(" -- ATTRIBUTE_SET_REMOVE");
+ ((ShaderAttributeSetRetained)mirror).attrs.remove((String)value);
+ }
+ else if((component & ATTRIBUTE_SET_CLEAR) != 0) {
+ // System.out.println(" -- ATTRIBUTE_SET_CLEAR");
+ ((ShaderAttributeSetRetained)mirror).attrs.clear();
+ }
+ else {
+ assert(false);
+ }
+ }
+
+ final void sendMessage(int attrMask, Object attr) {
+
+ ArrayList univList = new ArrayList();
+ ArrayList gaList = Shape3DRetained.getGeomAtomsList(mirror.users, univList);
+
+ // Send to rendering attribute structure, regardless of
+ // whether there are users or not (alternate appearance case ..)
+ J3dMessage createMessage = VirtualUniverse.mc.getMessage();
+ createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
+ createMessage.type = J3dMessage.SHADER_ATTRIBUTE_SET_CHANGED;
+ createMessage.universe = null;
+ createMessage.args[0] = this;
+ createMessage.args[1]= new Integer(attrMask);
+ createMessage.args[2] = attr;
+ // System.out.println("changedFreqent1 = "+changedFrequent);
+ createMessage.args[3] = new Integer(changedFrequent);
+ VirtualUniverse.mc.processMessage(createMessage);
+
+ // System.out.println("univList.size is " + univList.size());
+ for(int i=0; i<univList.size(); i++) {
+ createMessage = VirtualUniverse.mc.getMessage();
+ createMessage.threads = J3dThread.UPDATE_RENDER;
+ createMessage.type = J3dMessage.SHADER_ATTRIBUTE_SET_CHANGED;
+
+ createMessage.universe = (VirtualUniverse) univList.get(i);
+ createMessage.args[0] = this;
+ createMessage.args[1]= new Integer(attrMask);
+ createMessage.args[2] = attr;
+
+ ArrayList gL = (ArrayList)gaList.get(i);
+ GeometryAtom[] gaArr = new GeometryAtom[gL.size()];
+ gL.toArray(gaArr);
+ createMessage.args[3] = gaArr;
+
+ VirtualUniverse.mc.processMessage(createMessage);
+ }
+
+ }
+
+}
diff --git a/src/classes/share/javax/media/j3d/ShaderAttributeValue.java b/src/classes/share/javax/media/j3d/ShaderAttributeValue.java
new file mode 100644
index 0000000..1f9dc0a
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/ShaderAttributeValue.java
@@ -0,0 +1,100 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import javax.vecmath.*;
+
+/**
+ * The ShaderAttributeValue object encapsulates a uniform shader
+ * attribute whose value is specified explicitly. The shader variable
+ * <code>attrName</code> is explicitly set to the specified
+ * <code>value</code> during rendering. <code>attrName</code> must be
+ * the name of a valid uniform attribute in the shader in which it is
+ * used. Otherwise, the attribute name will be ignored and a runtime
+ * error may be generated. The <code>value</code> must be an instance
+ * of one of the allowed classes. The allowed classes are:
+ * <code>Integer</code>, <code>Float</code>,
+ * <code>Tuple{2,3,4}{i,f}</code>, <code>Matrix{3,4}f</code>. A
+ * ClassCastException will be thrown if a specified <code>value</code>
+ * object is not one of the allowed types. Further, the type of the
+ * value is immutable once a ShaderAttributeValue is constructed.
+ * Subsequent setValue operations must be called with an object of the
+ * same type as the one that was used to construct the
+ * ShaderAttributeValue. Finally, the type of the <code>value</code>
+ * object must match the type of the corresponding
+ * <code>attrName</code> variable in the shader in which it is
+ * used. Otherwise, the shader will not be able to use the attribute
+ * and a runtime error may be generated.
+ *
+ * @see ShaderAttributeSet
+ * @see ShaderProgram
+ *
+ * @since Java 3D 1.4
+ */
+
+public class ShaderAttributeValue extends ShaderAttributeObject {
+ /**
+ * Constructs a new ShaderAttributeValue object with the specified
+ * <code>(attrName,&nbsp;value)</code> pair.
+ * A copy of the object is stored.
+ *
+ * @param attrName the name of the shader attribute
+ * @param value the value of the shader attribute
+ *
+ * @exception NullPointerException if attrName or value is null
+ *
+ * @exception ClassCastException if value is not an instance of
+ * one of the allowed classes
+ */
+ public ShaderAttributeValue(String attrName, Object value) {
+ super(attrName, value);
+ }
+
+ // Implement abstract getValue method
+ public Object getValue() {
+
+ if (isLiveOrCompiled())
+ if (!this.getCapability(ALLOW_VALUE_READ))
+ throw new CapabilityNotSetException(J3dI18N.getString("ShaderAttributeObject0"));
+
+ return ((ShaderAttributeValueRetained)this.retained).getValue();
+ }
+
+ // Implement abstract setValue method
+ public void setValue(Object value) {
+
+ if (value == null) {
+ throw new NullPointerException();
+ }
+
+ if (isLiveOrCompiled())
+ if (!this.getCapability(ALLOW_VALUE_WRITE))
+ throw new CapabilityNotSetException(J3dI18N.getString("ShaderAttributeObject1"));
+
+ if (isLive())
+ ((ShaderAttributeValueRetained)this.retained).setValue(value);
+ else
+ ((ShaderAttributeValueRetained)this.retained).initValue(value);
+
+ }
+
+ /**
+ * Creates a retained mode ShaderAttributeValueRetained object that this
+ * ShaderAttributeValue component object will point to.
+ */
+ void createRetained() {
+ this.retained = new ShaderAttributeValueRetained();
+ this.retained.setSource(this);
+ }
+
+}
diff --git a/src/classes/share/javax/media/j3d/ShaderAttributeValueRetained.java b/src/classes/share/javax/media/j3d/ShaderAttributeValueRetained.java
new file mode 100644
index 0000000..758672c
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/ShaderAttributeValueRetained.java
@@ -0,0 +1,499 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import javax.vecmath.*;
+
+/**
+ * The ShaderAttributeValueRetained object encapsulates a uniform shader
+ * attribute whose value is specified explicitly. The shader variable
+ * <code>attrName</code> is explicitly set to the specified
+ * <code>value</code> during rendering. <code>attrName</code> must be
+ * the name of a valid uniform attribute in the shader in which it is
+ * used. Otherwise, the attribute name will be ignored and a runtime
+ * error may be generated. The <code>value</code> must be an instance
+ * of one of the allowed classes. The allowed classes are:
+ * <code>Integer</code>, <code>Float</code>,
+ * <code>Tuple{2,3,4}{i,f}</code>, <code>Matrix{3,4}f</code>. A
+ * ClassCastException will be thrown if a specified <code>value</code>
+ * object is not one of the allowed types. Further, the type of the
+ * value is immutable once a ShaderAttributeValue is constructed.
+ * Subsequent setValue operations must be called with an object of the
+ * same type as the one that was used to construct the
+ * ShaderAttributeValue. Finally, the type of the <code>value</code>
+ * object must match the type of the corresponding
+ * <code>attrName</code> variable in the shader in which it is
+ * used. Otherwise, the shader will not be able to use the attribute
+ * and a runtime error may be generated.
+ *
+ * @see ShaderAttributeSetRetained
+ * @see ShaderProgramRetained
+ *
+ * @since Java 3D 1.4
+ */
+
+class ShaderAttributeValueRetained extends ShaderAttributeObjectRetained {
+
+ ShaderAttributeValueRetained() {
+ }
+
+ synchronized void createMirrorObject() {
+ // System.out.println("ShaderAttributeValueRetained : createMirrorObject");
+ // This method should only call by setLive().
+ if (mirror == null) {
+ ShaderAttributeValueRetained mirrorSAV = new ShaderAttributeValueRetained();
+ mirrorSAV.createObjectData(getValue());
+ mirror = mirrorSAV;
+ mirror.source = source;
+
+ }
+ initMirrorObject();
+ }
+
+ /**
+ * Computes the base class from the specified object. A
+ * ClassCastException is thrown if the object is not an instance
+ * of one of the allowed classes.
+ */
+ int computeClassType(Object value) {
+ Class objClass = value.getClass();
+ if (objClass.isArray()) {
+ throw new ClassCastException(objClass + " -- array class not allowed");
+ }
+
+ for (int i = 0; i < classTable.length; i++) {
+ if (classTable[i].isInstance(value)) {
+ return i;
+ }
+ }
+ throw new ClassCastException(objClass + " -- unrecognized class");
+ }
+
+ /**
+ * Returns the base class represented by the specified class type.
+ */
+ Class getBaseClass(int classType) {
+ return classTable[classType];
+ }
+
+ /**
+ * Creates an attribute wrapper object of the specified class
+ * type, and stores the specified object.
+ */
+ AttrWrapper createAttrWrapper(Object value, int classType) {
+ ValueWrapper attrWrapper = null;
+ switch (classType) {
+ case TYPE_INTEGER:
+ attrWrapper = new IntegerWrapper();
+ break;
+ case TYPE_FLOAT:
+ attrWrapper = new FloatWrapper();
+ break;
+// case TYPE_DOUBLE:
+// attrWrapper = new DoubleWrapper();
+// break;
+ case TYPE_TUPLE2I:
+ attrWrapper = new Tuple2iWrapper();
+ break;
+ case TYPE_TUPLE2F:
+ attrWrapper = new Tuple2fWrapper();
+ break;
+// case TYPE_TUPLE2D:
+// attrWrapper = new Tuple2dWrapper();
+// break;
+ case TYPE_TUPLE3I:
+ attrWrapper = new Tuple3iWrapper();
+ break;
+ case TYPE_TUPLE3F:
+ attrWrapper = new Tuple3fWrapper();
+ break;
+// case TYPE_TUPLE3D:
+// attrWrapper = new Tuple3dWrapper();
+// break;
+ case TYPE_TUPLE4I:
+ attrWrapper = new Tuple4iWrapper();
+ break;
+ case TYPE_TUPLE4F:
+ attrWrapper = new Tuple4fWrapper();
+ break;
+// case TYPE_TUPLE4D:
+// attrWrapper = new Tuple4dWrapper();
+// break;
+ case TYPE_MATRIX3F:
+ attrWrapper = new Matrix3fWrapper();
+ break;
+// case TYPE_MATRIX3D:
+// attrWrapper = new Matrix3dWrapper();
+// break;
+ case TYPE_MATRIX4F:
+ attrWrapper = new Matrix4fWrapper();
+ break;
+// case TYPE_MATRIX4D:
+// attrWrapper = new Matrix4dWrapper();
+// break;
+ default:
+ // Should never get here
+ assert false;
+ return null;
+ }
+
+ attrWrapper.set(value);
+ return attrWrapper;
+ }
+
+ //
+ // The following wrapper classes are used to store a copy of the
+ // user-specified shader attribute value. There is a wrapper class
+ // for each supported base class.
+ //
+
+ // Base wrapper class for non-array attribute types
+ static abstract class ValueWrapper extends AttrWrapper {
+ // No additional fields or methods are defined in this class
+ }
+
+ // Wrapper class for Integer
+ static class IntegerWrapper extends ValueWrapper {
+ private int[] value = new int[1];
+
+ void set(Object value) {
+ this.value[0] = ((Integer)value).intValue();
+ }
+
+ Object get() {
+ return new Integer(this.value[0]);
+ }
+
+ Object getRef() {
+ return this.value;
+ }
+ }
+
+ // Wrapper class for Float
+ static class FloatWrapper extends ValueWrapper {
+ private float[] value = new float[1];
+
+ void set(Object value) {
+ this.value[0] = ((Float)value).floatValue();
+ }
+
+ Object get() {
+ return new Float(this.value[0]);
+ }
+
+ Object getRef() {
+ return this.value;
+ }
+ }
+
+ /*
+ // Wrapper class for Double
+ static class DoubleWrapper extends ValueWrapper {
+ private double[] value = new double[1];
+
+ void set(Object value) {
+ this.value[0] = ((Double)value).doubleValue();
+ }
+
+ Object get() {
+ return new Double(value[0]);
+ }
+
+ Object getRef() {
+ return value;
+ }
+ }
+ */
+
+ // Wrapper class for Tuple2i
+ static class Tuple2iWrapper extends ValueWrapper {
+ private int[] value = new int[2];
+
+ void set(Object value) {
+ ((Tuple2i)value).get(this.value);
+ }
+
+ Object get() {
+ return new Point2i(value);
+ }
+
+ Object getRef() {
+ return value;
+ }
+ }
+
+ // Wrapper class for Tuple2f
+ static class Tuple2fWrapper extends ValueWrapper {
+ private float[] value = new float[2];
+
+ void set(Object value) {
+ ((Tuple2f)value).get(this.value);
+ }
+
+ Object get() {
+ return new Point2f(value);
+ }
+
+ Object getRef() {
+ return value;
+ }
+ }
+
+ /*
+ // Wrapper class for Tuple2d
+ static class Tuple2dWrapper extends ValueWrapper {
+ private double[] value = new double[2];
+
+ void set(Object value) {
+ ((Tuple2d)value).get(this.value);
+ }
+
+ Object get() {
+ return new Point2d(value);
+ }
+
+ Object getRef() {
+ return value;
+ }
+ }
+ */
+
+ // Wrapper class for Tuple3i
+ static class Tuple3iWrapper extends ValueWrapper {
+ private int[] value = new int[3];
+
+ void set(Object value) {
+ ((Tuple3i)value).get(this.value);
+ }
+
+ Object get() {
+ return new Point3i(value);
+ }
+
+ Object getRef() {
+ return value;
+ }
+ }
+
+ // Wrapper class for Tuple3f
+ static class Tuple3fWrapper extends ValueWrapper {
+ private float[] value = new float[3];
+
+ void set(Object value) {
+ ((Tuple3f)value).get(this.value);
+ }
+
+ Object get() {
+ return new Point3f(value);
+ }
+
+ Object getRef() {
+ return value;
+ }
+ }
+
+ /*
+ // Wrapper class for Tuple3d
+ static class Tuple3dWrapper extends ValueWrapper {
+ private double[] value = new double[3];
+
+ void set(Object value) {
+ ((Tuple3d)value).get(this.value);
+ }
+
+ Object get() {
+ return new Point3d(value);
+ }
+
+ Object getRef() {
+ return value;
+ }
+ }
+ */
+
+ // Wrapper class for Tuple4i
+ static class Tuple4iWrapper extends ValueWrapper {
+ private int[] value = new int[4];
+
+ void set(Object value) {
+ ((Tuple4i)value).get(this.value);
+ }
+
+ Object get() {
+ return new Point4i(value);
+ }
+
+ Object getRef() {
+ return value;
+ }
+ }
+
+ // Wrapper class for Tuple4f
+ static class Tuple4fWrapper extends ValueWrapper {
+ private float[] value = new float[4];
+
+ void set(Object value) {
+ ((Tuple4f)value).get(this.value);
+ }
+
+ Object get() {
+ return new Point4f(value);
+ }
+
+ Object getRef() {
+ return value;
+ }
+ }
+
+ /*
+ // Wrapper class for Tuple4d
+ static class Tuple4dWrapper extends ValueWrapper {
+ private double[] value = new double[4];
+
+ void set(Object value) {
+ ((Tuple4d)value).get(this.value);
+ }
+
+ Object get() {
+ return new Point4d(value);
+ }
+
+ Object getRef() {
+ return value;
+ }
+ }
+ */
+
+ // Wrapper class for Matrix3f
+ static class Matrix3fWrapper extends ValueWrapper {
+ private float[] value = new float[9];
+
+ void set(Object value) {
+ Matrix3f m = (Matrix3f)value;
+ this.value[0] = m.m00;
+ this.value[1] = m.m01;
+ this.value[2] = m.m02;
+ this.value[3] = m.m10;
+ this.value[4] = m.m11;
+ this.value[5] = m.m12;
+ this.value[6] = m.m20;
+ this.value[7] = m.m21;
+ this.value[8] = m.m22;
+ }
+
+ Object get() {
+ return new Matrix3f(value);
+ }
+
+ Object getRef() {
+ return value;
+ }
+ }
+
+ /*
+ // Wrapper class for Matrix3d
+ static class Matrix3dWrapper extends ValueWrapper {
+ private double[] value = new double[9];
+
+ void set(Object value) {
+ Matrix3d m = (Matrix3d)value;
+ this.value[0] = m.m00;
+ this.value[1] = m.m01;
+ this.value[2] = m.m02;
+ this.value[3] = m.m10;
+ this.value[4] = m.m11;
+ this.value[5] = m.m12;
+ this.value[6] = m.m20;
+ this.value[7] = m.m21;
+ this.value[8] = m.m22;
+ }
+
+ Object get() {
+ return new Matrix3d(value);
+ }
+
+ Object getRef() {
+ return value;
+ }
+ }
+ */
+
+ // Wrapper class for Matrix4f
+ static class Matrix4fWrapper extends ValueWrapper {
+ private float[] value = new float[16];
+
+ void set(Object value) {
+ Matrix4f m = (Matrix4f)value;
+ this.value[0] = m.m00;
+ this.value[1] = m.m01;
+ this.value[2] = m.m02;
+ this.value[3] = m.m03;
+ this.value[4] = m.m10;
+ this.value[5] = m.m11;
+ this.value[6] = m.m12;
+ this.value[7] = m.m13;
+ this.value[8] = m.m20;
+ this.value[9] = m.m21;
+ this.value[10] = m.m22;
+ this.value[11] = m.m23;
+ this.value[12] = m.m30;
+ this.value[13] = m.m31;
+ this.value[14] = m.m32;
+ this.value[15] = m.m33;
+ }
+
+ Object get() {
+ return new Matrix4f(value);
+ }
+
+ Object getRef() {
+ return value;
+ }
+ }
+
+ /*
+ // Wrapper class for Matrix4d
+ static class Matrix4dWrapper extends ValueWrapper {
+ private double[] value = new double[16];
+
+ void set(Object value) {
+ Matrix4d m = (Matrix4d)value;
+ this.value[0] = m.m00;
+ this.value[1] = m.m01;
+ this.value[2] = m.m02;
+ this.value[3] = m.m03;
+ this.value[4] = m.m10;
+ this.value[5] = m.m11;
+ this.value[6] = m.m12;
+ this.value[7] = m.m13;
+ this.value[8] = m.m20;
+ this.value[9] = m.m21;
+ this.value[10] = m.m22;
+ this.value[11] = m.m23;
+ this.value[12] = m.m30;
+ this.value[13] = m.m31;
+ this.value[14] = m.m32;
+ this.value[15] = m.m33;
+ }
+
+ Object get() {
+ return new Matrix4d(value);
+ }
+
+ Object getRef() {
+ return value;
+ }
+ }
+ */
+
+}
diff --git a/src/classes/share/javax/media/j3d/ShaderBin.java b/src/classes/share/javax/media/j3d/ShaderBin.java
new file mode 100644
index 0000000..0e4ad74
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/ShaderBin.java
@@ -0,0 +1,363 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import javax.vecmath.*;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.ArrayList;
+
+
+// XXXX : We should have a common Bin object that all other Bins extend from.
+
+
+//class ShaderBin extends Object implements ObjectUpdate, NodeComponentUpdate {
+class ShaderBin implements ObjectUpdate {
+
+ /**
+ * Node component dirty mask.
+ */
+ static final int SHADER_PROGRAM_DIRTY = 0x1;
+ static final int SHADER_ATTRIBUTE_SET_DIRTY = 0x2;
+
+
+ /**
+ * The RenderBin for this object
+ */
+ RenderBin renderBin = null;
+
+ /**
+ * The AttributeBin that this ShaderBin resides
+ */
+ AttributeBin attributeBin = null;
+
+ /**
+ * The references to the next and previous ShaderBins in the
+ * list.
+ */
+ ShaderBin next = null;
+ ShaderBin prev = null;
+
+ /**
+ * The list of TextureBins in this ShaderBin
+ */
+ TextureBin textureBinList = null;
+
+ /**
+ * The list of TextureBins to be added for the next frame
+ */
+ ArrayList addTextureBins = new ArrayList();
+
+ boolean onUpdateList = false;
+
+ int numEditingTextureBins = 0;
+
+ int componentDirty = 0;
+ ShaderAppearanceRetained shaderAppearance = null;
+ ShaderProgramRetained shaderProgram = null;
+ ShaderAttributeSetRetained shaderAttributeSet = new ShaderAttributeSetRetained();
+
+ ShaderBin(ShaderAppearanceRetained sApp, RenderBin rBin) {
+ reset(sApp, rBin);
+ }
+
+ void reset(ShaderAppearanceRetained sApp, RenderBin rBin) {
+ prev = null;
+ next = null;
+ renderBin = rBin;
+ attributeBin = null;
+ textureBinList = null;
+ onUpdateList = false;
+ numEditingTextureBins = 0;
+ addTextureBins.clear();
+ if(sApp != null) {
+ shaderProgram = sApp.shaderProgram;
+ shaderAttributeSet = sApp.shaderAttributeSet;
+ }
+ else {
+ shaderProgram = null;
+ shaderAttributeSet = null;
+ }
+ shaderAppearance = sApp;
+ }
+
+ void clear() {
+ reset(null, null);
+ }
+
+ /**
+ * This tests if the qiven ra.shaderProgram match this shaderProgram
+ */
+ boolean equals(ShaderAppearanceRetained sApp) {
+
+ ShaderProgramRetained sp;
+ ShaderAttributeSetRetained ss;
+
+ if (sApp == null) {
+ sp = null;
+ ss = null;
+ } else {
+ sp = sApp.shaderProgram;
+ ss = sApp.shaderAttributeSet;
+ }
+
+ if((shaderProgram != sp) || (shaderAttributeSet != ss)) {
+ return false;
+ }
+
+ return true;
+
+ }
+
+ public void updateObject() {
+ TextureBin t;
+ int i;
+
+ if (addTextureBins.size() > 0) {
+ t = (TextureBin)addTextureBins.get(0);
+ if (textureBinList == null) {
+ textureBinList = t;
+
+ }
+ else {
+ // Look for a TextureBin that has the same texture
+ insertTextureBin(t);
+ }
+ for (i = 1; i < addTextureBins.size() ; i++) {
+ t = (TextureBin)addTextureBins.get(i);
+ // Look for a TextureBin that has the same texture
+ insertTextureBin(t);
+
+ }
+ }
+ addTextureBins.clear();
+ onUpdateList = false;
+
+ }
+
+ void insertTextureBin(TextureBin t) {
+ TextureBin tb;
+ int i;
+ TextureRetained texture = null;
+
+ if (t.texUnitState != null && t.texUnitState.length > 0) {
+ if (t.texUnitState[0] != null) {
+ texture = t.texUnitState[0].texture;
+ }
+ }
+
+ // use the texture in the first texture unit as the sorting criteria
+ if (texture != null) {
+ tb = textureBinList;
+ while (tb != null) {
+ if (tb.texUnitState == null || tb.texUnitState[0] == null ||
+ tb.texUnitState[0].texture != texture) {
+ tb = tb.next;
+ } else {
+ // put it here
+ t.next = tb;
+ t.prev = tb.prev;
+ if (tb.prev == null) {
+ textureBinList = t;
+ }
+ else {
+ tb.prev.next = t;
+ }
+ tb.prev = t;
+ return;
+ }
+ }
+ }
+ // Just put it up front
+ t.prev = null;
+ t.next = textureBinList;
+ textureBinList.prev = t;
+ textureBinList = t;
+
+ t.tbFlag &= ~TextureBin.RESORT;
+ }
+
+
+ /**
+ * reInsert textureBin if the first texture is different from
+ * the previous bin and different from the next bin
+ */
+ void reInsertTextureBin(TextureBin tb) {
+
+ TextureRetained texture = null,
+ prevTexture = null,
+ nextTexture = null;
+
+ if (tb.texUnitState != null && tb.texUnitState[0] != null) {
+ texture = tb.texUnitState[0].texture;
+ }
+
+ if (tb.prev != null && tb.prev.texUnitState != null) {
+ prevTexture = tb.prev.texUnitState[0].texture;
+ }
+
+ if (texture != prevTexture) {
+ if (tb.next != null && tb.next.texUnitState != null) {
+ nextTexture = tb.next.texUnitState[0].texture;
+ }
+ if (texture != nextTexture) {
+ if (tb.prev != null && tb.next != null) {
+ tb.prev.next = tb.next;
+ tb.next.prev = tb.prev;
+ insertTextureBin(tb);
+ }
+ }
+ }
+ }
+
+
+
+ /**
+ * Adds the given TextureBin to this AttributeBin.
+ */
+ void addTextureBin(TextureBin t, RenderBin rb, RenderAtom ra) {
+
+ t.environmentSet = this.attributeBin.environmentSet;
+ t.attributeBin = this.attributeBin;
+ t.shaderBin = this;
+
+ attributeBin.updateFromShaderBin(ra);
+ addTextureBins.add(t);
+
+ if (!onUpdateList) {
+ rb.objUpdateList.add(this);
+ onUpdateList = true;
+ }
+ }
+
+ /**
+ * Removes the given TextureBin from this ShaderBin.
+ */
+ void removeTextureBin(TextureBin t) {
+
+ // If the TextureBin being remove is contained in addTextureBins,
+ // then remove the TextureBin from the addList
+ if (addTextureBins.contains(t)) {
+ addTextureBins.remove(addTextureBins.indexOf(t));
+ }
+ else {
+ if (t.prev == null) { // At the head of the list
+ textureBinList = t.next;
+ if (t.next != null) {
+ t.next.prev = null;
+ }
+ } else { // In the middle or at the end.
+ t.prev.next = t.next;
+ if (t.next != null) {
+ t.next.prev = t.prev;
+ }
+ }
+ }
+
+ t.shaderBin = null;
+ t.prev = null;
+ t.next = null;
+
+ t.clear();
+
+ renderBin.textureBinFreelist.add(t);
+
+ if (textureBinList == null && addTextureBins.size() == 0 ) {
+ // Note: Removal of this shaderBin as a user of the rendering
+ // atttrs is done during removeRenderAtom() in RenderMolecule.java
+ attributeBin.removeShaderBin(this);
+ }
+ }
+
+ /**
+ * Renders this ShaderBin
+ */
+ void render(Canvas3D cv) {
+
+ TextureBin tb;
+
+ // System.out.println("ShaderBin.render() shaderProgram = " + shaderProgram);
+
+ // include this ShaderBin to the to-be-updated list in canvas
+ cv.setStateToUpdate(Canvas3D.SHADERBIN_BIT, this);
+
+ tb = textureBinList;
+ while (tb != null) {
+ tb.render(cv);
+ tb = tb.next;
+ }
+ }
+
+ void updateTransparentAttributes(Canvas3D cv) {
+
+ // include this ShaderBin to the to-be-updated state set in canvas
+ cv.setStateToUpdate(Canvas3D.SHADERBIN_BIT, this);
+ }
+
+ void updateAttributes(Canvas3D cv) {
+
+ // System.out.println("ShaderBin.updateAttributes() shaderProgram is " + shaderProgram);
+ if (shaderProgram != null) {
+ // Compile, link, and enable shader program
+ shaderProgram.updateNative(cv, true);
+
+ if (shaderAttributeSet != null) {
+ shaderAttributeSet.updateNative(cv, shaderProgram);
+ }
+
+ }
+ else {
+ if (cv.shaderProgram != null) {
+ // Disable shader program
+ cv.shaderProgram.updateNative(cv, false);
+ }
+ }
+
+ cv.shaderBin = this;
+ cv.shaderProgram = shaderProgram;
+ }
+
+ void updateNodeComponent() {
+ // System.out.println("ShaderBin.updateNodeComponent() ...");
+
+ // We don't need to clone shaderProgram.
+ // ShaderProgram object can't be modified once it is live,
+ // so each update should be a new reference.
+ if ((componentDirty & SHADER_PROGRAM_DIRTY) != 0) {
+ // System.out.println(" - SHADER_PROGRAM_DIRTY");
+
+ shaderProgram = shaderAppearance.shaderProgram;
+ }
+
+ // We need to clone the shaderAttributeSet.
+ if ((componentDirty & SHADER_ATTRIBUTE_SET_DIRTY) != 0) {
+ // System.out.println(" - SHADER_ATTRIBUTE_SET_DIRTY");
+
+ HashMap attrs = (HashMap)shaderAttributeSet.getAttrs();
+ attrs.clear();
+ if(shaderAppearance.shaderAttributeSet != null) {
+ attrs.putAll(shaderAppearance.shaderAttributeSet.getAttrs());
+ }
+ }
+
+ componentDirty = 0;
+ }
+
+ void incrActiveTextureBin() {
+ numEditingTextureBins++;
+ }
+
+ void decrActiveTextureBin() {
+ numEditingTextureBins--;
+ }
+}
diff --git a/src/classes/share/javax/media/j3d/ShaderError.java b/src/classes/share/javax/media/j3d/ShaderError.java
new file mode 100644
index 0000000..52c60f7
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/ShaderError.java
@@ -0,0 +1,410 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import java.io.PrintStream;
+
+/**
+ * ShaderError is a container object that holds the details of
+ * a runtime error that occurs while compiling or executing a
+ * programmable shader.
+ *
+ * @since Java 3D 1.4
+ */
+public class ShaderError extends Object {
+ private int errorCode = NO_ERROR;
+ private String errorMessage = null;
+ private String detailMessage = null;
+ private Canvas3D canvas = null;
+ private Shape3D shape = null;
+ private Geometry geometry = null;
+ private ShaderAppearance shaderApp = null;
+ private ShaderProgram shaderProgram = null;
+ private Shader shader = null;
+ private ShaderAttributeSet shaderAttributeSet = null;
+ private ShaderAttribute shaderAttribute = null;
+
+ /**
+ * Indicates that no error occurred.
+ */
+ public static final int NO_ERROR = 0;
+
+ /**
+ * Indicates that an error occurred while compiling a shader.
+ */
+ public static final int COMPILE_ERROR = 1;
+
+ /**
+ * Indicates that an error occurred while linking a shader.
+ */
+ public static final int LINK_ERROR = 2;
+
+ /**
+ * Indicates a error in looking up a vertex attribute
+ * name within a given shader program.
+ */
+ public static final int VERTEX_ATTRIBUTE_LOOKUP_ERROR = 3;
+
+ /**
+ * Indicates a error in looking up the location of a uniform
+ * shader attribute name within a given shader program.
+ */
+ public static final int SHADER_ATTRIBUTE_LOOKUP_ERROR = 4;
+
+ /**
+ * Indicates a error caused by a ShaderAttribute whose name does not
+ * appear in the list of shader attribute names in the corresponding
+ * ShaderProgram object.
+ */
+ public static final int SHADER_ATTRIBUTE_NAME_NOT_SET_ERROR = 5;
+
+ /**
+ * Indicates a error in the type of the attribute versus what the shader
+ * program was expecting.
+ */
+ public static final int SHADER_ATTRIBUTE_TYPE_ERROR = 6;
+
+ /**
+ * Indicates that the specified shading language is not supported
+ * on the screen display device.
+ */
+ public static final int UNSUPPORTED_LANGUAGE_ERROR = 7;
+
+
+ /**
+ * Constructs a new ShaderError object indicating no error. The
+ * error code is set to <code>NO_ERROR</code>. All other fields
+ * are initialized to null, including the error message.
+ */
+ public ShaderError() {
+ }
+
+ /**
+ * Constructs a new ShaderError object with the given error code
+ * and message. All other fields are initialized to null.
+ *
+ * @param errorCode the error code for this shader error.
+ *
+ * @param errorMessage a short error message describing this
+ * shader error.
+ */
+ public ShaderError(int errorCode, String errorMessage) {
+ this.errorCode = errorCode;
+ this.errorMessage = errorMessage;
+ }
+
+ /**
+ * Prints a verbose error report to System.err. This verbose
+ * output includes the error code, error message, detail message,
+ * and all relevant Java 3D objects.
+ */
+ public void printVerbose() {
+ printVerbose(System.err);
+ }
+
+ /**
+ * Prints a verbose error report to the specified PrintStream.
+ * This verbose output includes the error code, error message,
+ * detail message, and all relevant Java 3D objects.
+ *
+ * @param printStream the print stream on which to print the error
+ * report.
+ */
+ public void printVerbose(PrintStream printStream) {
+ printStream.println(this);
+ if (canvas != null) {
+ printStream.println("canvas = " + canvas);
+ }
+ if (shape != null) {
+ printStream.println("shape = " + shape);
+ }
+ if (geometry != null) {
+ printStream.println("geometry = " + geometry);
+ }
+ if (shaderApp != null) {
+ printStream.println("shaderApp = " + shaderApp);
+ }
+ if (shaderProgram != null) {
+ printStream.println("shaderProgram = " + shaderProgram);
+ }
+ if (shader != null) {
+ printStream.println("shader = " + shader);
+ }
+ if (shaderAttributeSet != null) {
+ printStream.println("shaderAttributeSet = " + shaderAttributeSet);
+ }
+ if (shaderAttribute != null) {
+ printStream.println("shaderAttribute = " + shaderAttribute);
+ }
+
+ if (detailMessage != null) {
+ printStream.println();
+ printStream.println("Detail Message");
+ printStream.println("--------------");
+ printStream.println(detailMessage);
+ }
+ }
+
+ /**
+ * Sets the error code for this shader error. This represents the
+ * type of error that occurred.
+ *
+ * @param errorCode the error code for this shader error.
+ */
+ public void setErrorCode(int errorCode) {
+ this.errorCode = errorCode;
+ }
+
+ /**
+ * Returns the error code for this shader error.
+ *
+ * @return the error code.
+ */
+ public int getErrorCode() {
+ return errorCode;
+ }
+
+ /**
+ * Sets the error message for this shader error. This is a short
+ * message describing the error, and is included as part of
+ * toString().
+ *
+ * @param errorMessage a short error message describing this
+ * shader error.
+ */
+ public void setErrorMessage(String errorMessage) {
+ this.errorMessage = errorMessage;
+ }
+
+ /**
+ * Returns the error message for this shader error.
+ *
+ * @return a short error message describing this shader error.
+ */
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ /**
+ * Sets the detail message for this shader error. This is a
+ * detailed error message, typically produced by the shader
+ * compiler, and is not included as part of toString().
+ *
+ * @param detailMessage a detailed message describing this shader
+ * error in more detail.
+ */
+ public void setDetailMessage(String detailMessage) {
+ this.detailMessage = detailMessage;
+ }
+
+ /**
+ * Returns the detail message for this shader error.
+ *
+ * @return the detail message for this shader error.
+ */
+ public String getDetailMessage() {
+ return detailMessage;
+ }
+
+ /**
+ * Sets the canvas associated with this shader error.
+ *
+ * @param canvas the canvas associated with this shader error.
+ */
+ public void setCanvas3D(Canvas3D canvas) {
+ this.canvas = canvas;
+ }
+
+ /**
+ * Returns the canvas associated with this shader error.
+ *
+ * @return the canvas associated with this shader error.
+ */
+ public Canvas3D getCanvas3D() {
+ return this.canvas;
+ }
+
+ /**
+ * Sets the shape node associated with this shader error.
+ *
+ * @param shape the shape node associated with this shader error.
+ */
+ public void setShape3D(Shape3D shape) {
+ this.shape = shape;
+ }
+
+ /**
+ * Returns the shape node associated with this shader error.
+ *
+ * @return the shape node associated with this shader error.
+ */
+ public Shape3D getShape3D() {
+ return this.shape;
+ }
+
+ /**
+ * Sets the geometry associated with this shader error.
+ *
+ * @param geometry the geometry associated with this shader error.
+ */
+ public void setGeometry(Geometry geometry) {
+ this.geometry = geometry;
+ }
+
+ /**
+ * Returns the geometry associated with this shader error.
+ *
+ * @return the geometry associated with this shader error.
+ */
+ public Geometry getGeometry() {
+ return this.geometry;
+ }
+
+ /**
+ * Sets the shader appearance associated with this shader error.
+ *
+ * @param shaderApp the shader appearance associated with this shader error.
+ */
+ public void setShaderAppearance(ShaderAppearance shaderApp) {
+ this.shaderApp = shaderApp;
+ }
+
+ /**
+ * Returns the shader appearance associated with this shader error.
+ *
+ * @return the shader appearance associated with this shader error.
+ */
+ public ShaderAppearance getShaderAppearance() {
+ return this.shaderApp;
+ }
+
+ /**
+ * Sets the shader program associated with this shader error.
+ *
+ * @param shaderProgram the shader program associated with this shader error.
+ */
+ public void setShaderProgram(ShaderProgram shaderProgram) {
+ this.shaderProgram = shaderProgram;
+ }
+
+ /**
+ * Returns the shader program associated with this shader error.
+ *
+ * @return the shader program associated with this shader error.
+ */
+ public ShaderProgram getShaderProgram() {
+ return this.shaderProgram;
+ }
+
+ /**
+ * Sets the shader object associated with this shader error.
+ *
+ * @param shader the shader object associated with this shader error.
+ */
+ public void setShader(Shader shader) {
+ this.shader = shader;
+ }
+
+ /**
+ * Returns the shader object associated with this shader error.
+ *
+ * @return the shader object associated with this shader error.
+ */
+ public Shader getShader() {
+ return this.shader;
+ }
+
+ /**
+ * Sets the shader attribute set associated with this shader error.
+ *
+ * @param shaderAttributeSet the shader attribute set associated with this shader error.
+ */
+ public void setShaderAttributeSet(ShaderAttributeSet shaderAttributeSet) {
+ this.shaderAttributeSet = shaderAttributeSet;
+ }
+
+ /**
+ * Returns the shader attribute set associated with this shader error.
+ *
+ * @return the shader attribute set associated with this shader error.
+ */
+ public ShaderAttributeSet getShaderAttributeSet() {
+ return this.shaderAttributeSet;
+ }
+
+ /**
+ * Sets the shader attribute associated with this shader error.
+ *
+ * @param shaderAttribute the shader attribute associated with this shader error.
+ */
+ public void setShaderAttribute(ShaderAttribute shaderAttribute) {
+ this.shaderAttribute = shaderAttribute;
+ }
+
+ /**
+ * Returns the shader attribute associated with this shader error.
+ *
+ * @return the shader attribute associated with this shader error.
+ */
+ public ShaderAttribute getShaderAttribute() {
+ return this.shaderAttribute;
+ }
+
+
+ /**
+ * Returns a short string that describes this shader error. The
+ * string is composed of the textual description of the errorCode,
+ * a ": ", and the errorMessage field. If the errorMessage is
+ * null then the ": " and the errorMessage are omitted.
+ *
+ * @return a string representation of this shader error.
+ */
+ public String toString() {
+ // Concatenate string representation of error code with error message
+ String errorCodeStr;
+ switch (errorCode) {
+ case NO_ERROR:
+ errorCodeStr = "NO_ERROR";
+ break;
+ case COMPILE_ERROR:
+ errorCodeStr = "COMPILE_ERROR";
+ break;
+ case LINK_ERROR:
+ errorCodeStr = "LINK_ERROR";
+ break;
+ case VERTEX_ATTRIBUTE_LOOKUP_ERROR:
+ errorCodeStr = "VERTEX_ATTRIBUTE_LOOKUP_ERROR";
+ break;
+ case SHADER_ATTRIBUTE_LOOKUP_ERROR:
+ errorCodeStr = "SHADER_ATTRIBUTE_LOOKUP_ERROR";
+ break;
+ case SHADER_ATTRIBUTE_NAME_NOT_SET_ERROR:
+ errorCodeStr = "SHADER_ATTRIBUTE_NAME_NOT_SET_ERROR";
+ break;
+ case SHADER_ATTRIBUTE_TYPE_ERROR:
+ errorCodeStr = "SHADER_ATTRIBUTE_TYPE_ERROR";
+ break;
+ case UNSUPPORTED_LANGUAGE_ERROR:
+ errorCodeStr = "UNSUPPORTED_LANGUAGE_ERROR";
+ break;
+ default:
+ errorCodeStr = "UNKNOWN ERROR CODE (" + errorCode + ")";
+ }
+
+ if (errorMessage == null) {
+ return errorCodeStr;
+ }
+
+ return errorCodeStr + ": " + errorMessage;
+ }
+}
diff --git a/src/classes/share/javax/media/j3d/ShaderErrorListener.java b/src/classes/share/javax/media/j3d/ShaderErrorListener.java
new file mode 100644
index 0000000..978a251
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/ShaderErrorListener.java
@@ -0,0 +1,33 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+/**
+ * Listener interface for monitoring errors in Shader Programs.
+ * Compile and link errors are reported by the shader compiler, as are
+ * runtime errors, such as those resulting from shader attributes that
+ * aren't found or are of the wrong type.
+ *
+ * @see VirtualUniverse#addShaderErrorListener
+ *
+ * @since Java 3D 1.4
+ */
+public interface ShaderErrorListener {
+ /**
+ * Invoked when an error occurs while compiling, linking or
+ * executing a programmable shader.
+ *
+ * @param error object that contains the details of the error.
+ */
+ public void errorOccurred(ShaderError error);
+}
diff --git a/src/classes/share/javax/media/j3d/ShaderProgram.java b/src/classes/share/javax/media/j3d/ShaderProgram.java
new file mode 100644
index 0000000..2d4fc72
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/ShaderProgram.java
@@ -0,0 +1,194 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+/**
+ * The ShaderProgram node component object is the abstract base class
+ * for programmable shader programs. Each concrete instance of a
+ * ShaderProgram is a container for a set of Shader objects. The set
+ * of Shaders contained in the ShaderProgram is a complete program for
+ * the Graphics Pipeline Unit (GPU) of the graphics accelerator. It is
+ * specified using the shader language defined by the
+ * ShaderProgram. The currently defined shader languages are: Cg and
+ * GLSL.
+ *
+ * <p>
+ * NOTE: Applications should <i>not</i> extend this class.
+ *
+ * @see Shader
+ * @see ShaderAppearance#setShaderProgram
+ *
+ * @since Java 3D 1.4
+ */
+
+public abstract class ShaderProgram extends NodeComponent {
+
+ /**
+ * Specifies that this ShaderProgram object allows reading
+ * its shaders.
+ */
+ public static final int ALLOW_SHADERS_READ =
+ CapabilityBits.SHADER_PROGRAM_ALLOW_SHADERS_READ;
+
+ /**
+ * Specifies that this ShaderProgram object allows reading
+ * its shader or vertex attribute names.
+ */
+ public static final int ALLOW_NAMES_READ =
+ CapabilityBits.SHADER_PROGRAM_ALLOW_NAMES_READ;
+
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_SHADERS_READ,
+ ALLOW_NAMES_READ
+ };
+
+ /*
+ * Default values (copied from GeometryArray.java):
+ *
+ * vertexAttrNames : null<br>
+ */
+
+ /**
+ * Package scope constructor so it can't be subclassed by classes
+ * outside the javax.media.j3d package.
+ */
+ ShaderProgram() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+ }
+
+ /**
+ * Sets the vertex attribute names array for this ShaderProgram
+ * object. Each element in the array specifies the shader
+ * attribute name that is bound to the corresponding numbered
+ * vertex attribute within a GeometryArray object that uses this
+ * shader program. Array element 0 specifies the name of
+ * GeometryArray vertex attribute 0, array element 1 specifies the
+ * name of GeometryArray vertex attribute 1, and so forth.
+ * The array of names may be null or empty (0 length), but the
+ * elements of the array must be non-null.
+ *
+ * @param vertexAttrNames array of vertex attribute names for this
+ * shader program. A copy of this array is made.
+ *
+ * @exception RestrictedAccessException if the method is called
+ * when this object is part of live or compiled scene graph.
+ *
+ * @exception NullPointerException if any element in the
+ * vertexAttrNames array is null.
+ */
+ public abstract void setVertexAttrNames(String[] vertexAttrNames);
+
+ /**
+ * Retrieves the vertex attribute names array from this
+ * ShaderProgram object.
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @return a copy of this ShaderProgram's array of vertex attribute names.
+ */
+ public abstract String[] getVertexAttrNames();
+
+
+ /**
+ * Sets the shader attribute names array for this ShaderProgram
+ * object. Each element in the array specifies a shader
+ * attribute name that may be set via a ShaderAttribute object.
+ * Only those attributes whose names that appear in the shader
+ * attribute names array can be set for a given shader program.
+ * The array of names may be null or empty (0 length), but the
+ * elements of the array must be non-null.
+ *
+ * <p>
+ * TODO: finish this.
+ *
+ * @param shaderAttrNames array of shader attribute names for this
+ * shader program. A copy of this array is made.
+ *
+ * @exception RestrictedAccessException if the method is called
+ * when this object is part of live or compiled scene graph.
+ *
+ * @exception NullPointerException if any element in the
+ * shaderAttrNames array is null.
+ */
+ public abstract void setShaderAttrNames(String[] shaderAttrNames);
+
+ /**
+ * Retrieves the shader attribute names array from this
+ * ShaderProgram object.
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @return a copy of this ShaderProgram's array of shader attribute names.
+ */
+ public abstract String[] getShaderAttrNames();
+
+
+ /**
+ * Copies the specified array of shaders into this shader
+ * program. This method makes a shallow copy of the array. The
+ * array of shaders may be null or empty (0 length), but the
+ * elements of the array must be non-null. The shading
+ * language of each shader in the array must match the
+ * subclass. Subclasses may impose additional restrictions.
+ *
+ * @param shaders array of Shader objects to be copied into this
+ * ShaderProgram
+ *
+ * @exception RestrictedAccessException if the method is called
+ * when this object is part of live or compiled scene graph.
+ *
+ * @exception IllegalArgumentException if the shading language of
+ * any shader in the shaders array doesn't match the type of the
+ * subclass.
+ *
+ * @exception NullPointerException if any element in the
+ * shaders array is null.
+ */
+ public abstract void setShaders(Shader[] shaders);
+
+ /**
+ * Retrieves the array of shaders from this shader program. A
+ * shallow copy of the array is returned. The return value may
+ * be null.
+ *
+ * @return a copy of this ShaderProgram's array of Shader objects
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ */
+ public abstract Shader[] getShaders();
+
+
+ // Default shader error listener class
+ private static ShaderErrorListener defaultErrorListener = null;
+
+ synchronized static ShaderErrorListener getDefaultErrorListener() {
+ if (defaultErrorListener == null) {
+ defaultErrorListener = new DefaultErrorListener();
+ }
+
+ return defaultErrorListener;
+ }
+
+ static class DefaultErrorListener implements ShaderErrorListener {
+ public void errorOccurred(ShaderError error) {
+ System.err.println();
+ System.err.println("DefaultShaderErrorListener.errorOccurred:");
+ error.printVerbose();
+ }
+ }
+}
diff --git a/src/classes/share/javax/media/j3d/ShaderProgramRetained.java b/src/classes/share/javax/media/j3d/ShaderProgramRetained.java
new file mode 100644
index 0000000..fadcda0
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/ShaderProgramRetained.java
@@ -0,0 +1,1196 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import java.util.*;
+import javax.vecmath.*;
+
+/**
+ * The ShaderProgramRetained object is a component object of an AppearanceRetained
+ * object that defines the shader properties used when programmable shader is
+ * enabled. ShaderProgramRetained object is an abstract class. All shader program
+ * objects must be created as either a GLSLShaderProgramRetained object or a
+ * CgShaderProgramRetained object.
+ */
+abstract class ShaderProgramRetained extends NodeComponentRetained {
+
+ // Each element in the array corresponds to a unique renderer if shared
+ // context or a unique canvas otherwise.
+ protected ShaderProgramData shaderProgramData[];
+
+ // Flag indicating whether an UNSUPPORTED_LANGUAGE_ERROR has
+ // already been reported for this shader program object. It is
+ // set in verifyShaderProgram and cleared in setLive or clearLive.
+ // TODO KCR: Add code to clear this in setLive or clearLive
+ private boolean unsupportedErrorReported = false;
+
+ // Flag indicating whether a LINK_ERROR has occurred for this shader program
+ // object. It is set in updateNative to indicate that the linkShaderProgram
+ // operation failed. It is cleared in setLive or clearLive.
+ // TODO KCR: Add code to clear this in setLive or clearLive
+ private boolean linkErrorOccurred = false;
+
+ // an array of shaders used by this shader program
+ protected ShaderRetained[] shaders;
+
+ // an array of vertex attribute names
+ protected String[] vertexAttrNames;
+
+ // an array of (uniform) shader attribute names
+ protected String[] shaderAttrNames;
+
+ // Set of ShaderAttribute objects for which we have already reported an error
+ private HashSet shaderAttrErrorSet = null;
+
+ // need to synchronize access from multiple rendering threads
+ Object resourceLock = new Object();
+
+ /**
+ * Sets the vertex attribute names array for this ShaderProgram
+ * object. Each element in the array specifies the shader
+ * attribute name that is bound to the corresponding numbered
+ * vertex attribute within a GeometryArray object that uses this
+ * shader program. Array element 0 specifies the name of
+ * GeometryArray vertex attribute 0, array element 1 specifies the
+ * name of GeometryArray vertex attribute 1, and so forth.
+ * The array of names may be null or empty (0 length), but the
+ * elements of the array must be non-null.
+ *
+ * @param vertexAttrNames array of vertex attribute names for this
+ * shader program. A copy of this array is made.
+ */
+ void setVertexAttrNames(String[] vertexAttrNames) {
+ if (vertexAttrNames == null) {
+ this.vertexAttrNames = null;
+ }
+ else {
+ this.vertexAttrNames = (String[])vertexAttrNames.clone();
+ }
+ }
+
+
+ /**
+ * Retrieves the vertex attribute names array from this
+ * ShaderProgram object.
+ *
+ * @return a copy of this ShaderProgram's array of vertex attribute names.
+ */
+ String[] getVertexAttrNames() {
+
+ if (vertexAttrNames == null) {
+ return null;
+ }
+
+ return (String[])vertexAttrNames.clone();
+
+ }
+
+
+ /**
+ * Sets the shader attribute names array for this ShaderProgram
+ * object. Each element in the array specifies a shader
+ * attribute name that may be set via a ShaderAttribute object.
+ * Only those attributes whose names that appear in the shader
+ * attribute names array can be set for a given shader program.
+ * The array of names may be null or empty (0 length), but the
+ * elements of the array must be non-null.
+ *
+ * @param shaderAttrNames array of shader attribute names for this
+ * shader program. A copy of this array is made.
+ */
+ void setShaderAttrNames(String[] shaderAttrNames) {
+ if (shaderAttrNames == null) {
+ this.shaderAttrNames = null;
+ }
+ else {
+ this.shaderAttrNames = (String[])shaderAttrNames.clone();
+ }
+ }
+
+
+ /**
+ * Retrieves the shader attribute names array from this
+ * ShaderProgram object.
+ *
+ * @return a copy of this ShaderProgram's array of shader attribute names.
+ */
+
+ String[] getShaderAttrNames() {
+
+ if (shaderAttrNames == null) {
+ return null;
+ }
+
+ return (String[])shaderAttrNames.clone();
+
+ }
+
+
+
+ /**
+ * Copies the specified array of shaders into this shader
+ * program. This method makes a shallow copy of the array. The
+ * array of shaders may be null or empty (0 length), but the
+ * elements of the array must be non-null. The shading
+ * language of each shader in the array must match the
+ * subclass. Subclasses may impose additional restrictions.
+ *
+ * @param shaders array of Shader objects to be copied into this
+ * ShaderProgram
+ *
+ * @exception CapabilityNotSetException if appropriate capability is
+ * not set and this object is part of live or compiled scene graph
+ *
+ * @exception IllegalArgumentException if the shading language of
+ * any shader in the shaders array doesn't match the type of the
+ * subclass.
+ */
+ void setShaders(Shader[] shaders) {
+
+ if (shaders == null) {
+ this.shaders = null;
+ return;
+ }
+
+ this.shaders = new ShaderRetained[shaders.length];
+
+ // Copy vertex and fragment shader
+ for (int i = 0; i < shaders.length; i++) {
+ this.shaders[i] = (ShaderRetained)shaders[i].retained;
+ }
+
+ }
+
+ /**
+ * Retrieves the array of shaders from this shader program. A
+ * shallow copy of the array is returned. The return value may
+ * be null.
+ *
+ * @return a copy of this ShaderProgram's array of Shader objects
+ *
+ */
+ Shader[] getShaders() {
+
+ if (shaders == null) {
+ return null;
+ } else {
+ Shader shads[] =
+ new Shader[shaders.length];
+ for (int i = 0; i < shaders.length; i++) {
+ if (shaders[i] != null) {
+ shads[i] = (Shader) shaders[i].source;
+ } else {
+ shads[i] = null;
+ }
+ }
+ return shads;
+ }
+ }
+
+ /**
+ * Method to create the native shader.
+ */
+ abstract ShaderError createShader(long ctx, ShaderRetained shader, long[] shaderIdArr);
+
+ /**
+ * Method to destroy the native shader.
+ */
+ abstract ShaderError destroyShader(long ctx, long shaderId);
+
+ /**
+ * Method to compile the native shader.
+ */
+ abstract ShaderError compileShader(long ctx, long shaderId, String source);
+
+ /**
+ * Method to create the native shader program.
+ */
+ abstract ShaderError createShaderProgram(long ctx, long[] shaderProgramIdArr);
+
+ /**
+ * Method to destroy the native shader program.
+ */
+ abstract ShaderError destroyShaderProgram(long ctx, long shaderProgramId);
+
+ /**
+ * Method to link the native shader program.
+ */
+ abstract ShaderError linkShaderProgram(long ctx, long shaderProgramId, long[] shaderIds);
+
+ /**
+ * Method to bind a vertex attribute name to the specified index.
+ */
+ abstract ShaderError bindVertexAttrName(long ctx, long shaderProgramId, String attrName, int attrIndex);
+
+ /**
+ * Method to lookup a list of (uniform) shader attribute names and return
+ * information about the attributes.
+ */
+ abstract void lookupShaderAttrNames(long ctx, long shaderProgramId, String[] attrNames, AttrNameInfo[] attrNameInfoArr);
+
+ /*
+ * Method to lookup a list of vertex attribute names.
+ */
+ abstract void lookupVertexAttrNames(long ctx, long shaderProgramId, String[] attrNames, boolean[] errArr);
+
+ /**
+ * Method to use the native shader program.
+ */
+ abstract ShaderError enableShaderProgram(long ctx, long shaderProgramId);
+
+ /**
+ * Method to disable the native shader program.
+ */
+ abstract ShaderError disableShaderProgram(long ctx);
+
+ // ShaderAttributeValue methods
+
+ abstract ShaderError setUniform1i(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int value);
+
+ abstract ShaderError setUniform1f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float value);
+
+ abstract ShaderError setUniform2i(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int[] value);
+
+ abstract ShaderError setUniform2f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+ abstract ShaderError setUniform3i(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int[] value);
+
+ abstract ShaderError setUniform3f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+ abstract ShaderError setUniform4i(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int[] value);
+
+ abstract ShaderError setUniform4f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+ abstract ShaderError setUniformMatrix3f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+ abstract ShaderError setUniformMatrix4f(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ float[] value);
+
+
+ // ShaderAttributeArray methods
+
+ abstract ShaderError setUniform1iArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ int[] value);
+
+ abstract ShaderError setUniform1fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ abstract ShaderError setUniform2iArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ int[] value);
+
+ abstract ShaderError setUniform2fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ abstract ShaderError setUniform3iArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ int[] value);
+
+ abstract ShaderError setUniform3fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ abstract ShaderError setUniform4iArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ int[] value);
+
+ abstract ShaderError setUniform4fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ abstract ShaderError setUniformMatrix3fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+ abstract ShaderError setUniformMatrix4fArray(long ctx,
+ long shaderProgramId,
+ long uniformLocation,
+ int numElements,
+ float[] value);
+
+
+ /**
+ * Method to return a flag indicating whether this
+ * ShaderProgram is supported on the specified Canvas.
+ */
+ abstract boolean isSupported(Canvas3D cv);
+
+
+ void setLive(boolean backgroundGroup, int refCount) {
+
+ // System.out.println("ShaderProgramRetained.setLive()");
+
+ if (shaders != null) {
+ for (int i = 0; i < shaders.length; i++){
+ shaders[i].setLive(backgroundGroup, refCount);
+ }
+ }
+
+ super.doSetLive(backgroundGroup, refCount);
+ super.markAsLive();
+
+ }
+
+ void clearLive(int refCount) {
+
+ // System.out.println("ShaderProgramRetained.clearLive()");
+
+ super.clearLive(refCount);
+
+ if (shaders != null) {
+ for (int i = 0; i < shaders.length; i++) {
+ shaders[i].clearLive(refCount);
+ }
+ }
+ }
+
+ /**
+ * Method to enable the native shader program.
+ */
+ private ShaderError enableShaderProgram(Canvas3D cv, int cvRdrIndex) {
+ assert(cvRdrIndex >= 0);
+ synchronized(resourceLock) {
+ return enableShaderProgram(cv.ctx,
+ shaderProgramData[cvRdrIndex].getShaderProgramId());
+ }
+
+ }
+
+ /**
+ * Method to disable the native shader program.
+ */
+ private ShaderError disableShaderProgram(Canvas3D cv) {
+ return disableShaderProgram(cv.ctx);
+ }
+
+ /**
+ * Initializes a mirror object.
+ */
+ synchronized void initMirrorObject() {
+
+ // Create mirror copy of shaders
+ if (this.shaders == null) {
+ ((ShaderProgramRetained)mirror).shaders = null;
+ }
+ else {
+ ((ShaderProgramRetained)mirror).shaders = new ShaderRetained[this.shaders.length];
+ // Copy vertex and fragment shader
+ for (int i = 0; i < this.shaders.length; i++) {
+ ((ShaderProgramRetained)mirror).shaders[i] =
+ (ShaderRetained)this.shaders[i].mirror;
+ }
+ }
+ ((ShaderProgramRetained)mirror).shaderProgramData = null;
+
+ // Create mirror copy of vertex attribute names
+ if (this.vertexAttrNames == null) {
+ ((ShaderProgramRetained)mirror).vertexAttrNames = null;
+ }
+ else {
+ ((ShaderProgramRetained)mirror).vertexAttrNames = (String[])this.vertexAttrNames.clone();
+ }
+
+ // Create mirror copy of shader attribute names
+ if (this.shaderAttrNames == null) {
+ ((ShaderProgramRetained)mirror).shaderAttrNames = null;
+ }
+ else {
+ ((ShaderProgramRetained)mirror).shaderAttrNames = (String[])this.shaderAttrNames.clone();
+ }
+
+ // Clear shader attribute error set
+ ((ShaderProgramRetained)mirror).shaderAttrErrorSet = null;
+ }
+
+ /**
+ * Update the "component" field of the mirror object with the given "value"
+ */
+ synchronized void updateMirrorObject(int component, Object value) {
+
+ // ShaderProgram can't be modified once it is live.
+ assert(false);
+ System.out.println("ShaderProgramRetained : updateMirrorObject NOT IMPLEMENTED YET");
+ }
+
+ /**
+ * Method to create a ShaderProgramData object for the specified
+ * canvas/renderer if it doesn't already exist
+ */
+ private void createShaderProgramData(int cvRdrIndex) {
+ // Create shaderProgram resources if it has not been done.
+ synchronized(resourceLock) {
+ if(shaderProgramData == null) {
+ // We rely on Java to initial the array elements to null.
+ shaderProgramData = new ShaderProgramData[cvRdrIndex+1];
+ }
+ else if(shaderProgramData.length <= cvRdrIndex) {
+ // We rely on Java to initial the array elements to null.
+ ShaderProgramData[] tempSPData = new ShaderProgramData[cvRdrIndex+1];
+ System.arraycopy(shaderProgramData, 0,
+ tempSPData, 0,
+ shaderProgramData.length);
+ shaderProgramData = tempSPData;
+ }
+
+ if(shaderProgramData[cvRdrIndex] == null) {
+ shaderProgramData[cvRdrIndex] = new ShaderProgramData();
+ }
+ }
+ }
+
+ /**
+ * Method to create the native shader program. We must already have
+ * called createShaderProgramData for this cvRdrIndex.
+ */
+ private ShaderError createShaderProgram(Canvas3D cv, int cvRdrIndex) {
+ // Create shaderProgram resources if it has not been done.
+ synchronized(resourceLock) {
+ assert(shaderProgramData[cvRdrIndex].getShaderProgramId() == 0);
+
+ long[] spIdArr = new long[1];
+ ShaderError err = createShaderProgram(cv.ctx, spIdArr);
+ if(err != null) {
+ return err;
+ }
+ shaderProgramData[cvRdrIndex].setShaderProgramId(spIdArr[0]);
+ }
+
+ return null;
+ }
+
+ /**
+ * Method to link the native shader program.
+ */
+ private ShaderError linkShaderProgram(Canvas3D cv, int cvRdrIndex,
+ ShaderRetained[] shaders) {
+ synchronized(resourceLock) {
+ long[] shaderIds = new long[shaders.length];
+ for(int i=0; i<shaders.length; i++) {
+ synchronized(shaders[i]) {
+ shaderIds[i] = shaders[i].shaderIds[cvRdrIndex];
+ }
+ }
+ ShaderError err =
+ linkShaderProgram(cv.ctx,
+ shaderProgramData[cvRdrIndex].getShaderProgramId(),
+ shaderIds);
+ if(err != null) {
+ return err;
+ }
+ shaderProgramData[cvRdrIndex].setLinked(true);
+ }
+
+ return null;
+ }
+
+
+ private ShaderError bindVertexAttrName(Canvas3D cv, int cvRdrIndex, String attrName, int attrIndex) {
+ assert(attrName != null);
+ synchronized(resourceLock) {
+ long shaderProgramId = shaderProgramData[cvRdrIndex].getShaderProgramId();
+// System.err.println("attrName = " + attrName);
+ ShaderError err = bindVertexAttrName(cv.ctx, shaderProgramId, attrName, attrIndex);
+ if (err != null) {
+ return err;
+ }
+ }
+ return null;
+ }
+
+ private void lookupVertexAttrNames(Canvas3D cv, int cvRdrIndex, String[] attrNames) {
+ synchronized(resourceLock) {
+ long shaderProgramId = shaderProgramData[cvRdrIndex].getShaderProgramId();
+
+ boolean[] errArr = new boolean[attrNames.length];
+ lookupVertexAttrNames(cv.ctx, shaderProgramId, attrNames, errArr);
+
+ for (int i = 0; i < attrNames.length; i++) {
+ // Report non-fatal error if detected
+ if (errArr[i]) {
+ String errMsg = "Vertex Attribute name lookup failed: " + attrNames[i];
+ ShaderError err = new ShaderError(ShaderError.VERTEX_ATTRIBUTE_LOOKUP_ERROR, errMsg);
+ err.setShaderProgram((ShaderProgram)this.source);
+ err.setCanvas3D(cv);
+ notifyErrorListeners(cv, err);
+ }
+ }
+ }
+ }
+
+
+ private void lookupShaderAttrNames(Canvas3D cv, int cvRdrIndex, String[] attrNames) {
+ synchronized(resourceLock) {
+ long shaderProgramId = shaderProgramData[cvRdrIndex].getShaderProgramId();
+
+ AttrNameInfo[] attrNameInfoArr = new AttrNameInfo[attrNames.length];
+ lookupShaderAttrNames(cv.ctx, shaderProgramId, attrNames, attrNameInfoArr);
+
+ for (int i = 0; i < attrNames.length; i++) {
+ shaderProgramData[cvRdrIndex].setAttrNameInfo(attrNames[i], attrNameInfoArr[i]);
+
+ // Report non-fatal error if location is invalid (-1)
+ if (attrNameInfoArr[i].getLocation() == -1) {
+ String errMsg = "Attribute name lookup failed: " + attrNames[i];
+ ShaderError err = new ShaderError(ShaderError.SHADER_ATTRIBUTE_LOOKUP_ERROR, errMsg);
+ err.setShaderProgram((ShaderProgram)this.source);
+ err.setCanvas3D(cv);
+ notifyErrorListeners(cv, err);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Method to return the shaderProgram data for the specified canvas or renderer
+ */
+ private ShaderProgramData getShaderProgramData(int cvRdrIndex) {
+ synchronized(resourceLock) {
+ return shaderProgramData[cvRdrIndex];
+ }
+ }
+
+ /**
+ * Method to create the native shader.
+ */
+ private ShaderError createShader(Canvas3D cv, int cvRdrIndex, ShaderRetained shader) {
+
+ // Create shaderProgram resources if it has not been done.
+ synchronized(shader.resourceLock) {
+ if(shader.shaderIds == null){
+ // We rely on Java to initial the array elements to 0 or false;
+ shader.shaderIds = new long[cvRdrIndex+1];
+ shader.compiled = new boolean[cvRdrIndex+1];
+ } else if( shader.shaderIds.length <= cvRdrIndex) {
+ // We rely on Java to initial the array elements to 0 or false;
+ long[] tempSIds = new long[cvRdrIndex+1];
+ boolean[] tempCompiled = new boolean[cvRdrIndex+1];
+
+ System.arraycopy(shader.shaderIds, 0,
+ tempSIds, 0,
+ shader.shaderIds.length);
+ shader.shaderIds = tempSIds;
+
+ System.arraycopy(shader.compiled, 0,
+ tempCompiled, 0,
+ shader.compiled.length);
+ shader.compiled = tempCompiled;
+ }
+
+ if(shader.shaderIds[cvRdrIndex] != 0) {
+ // We have already created the shaderId for this Canvas.
+ return null;
+ }
+
+ long[] shaderIdArr = new long[1];
+ ShaderError err = createShader(cv.ctx, shader, shaderIdArr);
+ if(err != null) {
+ return err;
+ }
+ shader.shaderIds[cvRdrIndex] = shaderIdArr[0];
+ }
+ return null;
+ }
+
+ /**
+ * Method to compile the native shader.
+ */
+ private ShaderError compileShader(Canvas3D cv, int cvRdrIndex, ShaderRetained shader) {
+
+ synchronized(shader.resourceLock) {
+
+ if(shader.compiled[cvRdrIndex] == true) {
+ // We have already compiled the shaderId for this Canvas.
+ return null;
+ }
+
+ String source = ((SourceCodeShaderRetained)shader).getShaderSource();
+ ShaderError err = compileShader(cv.ctx, shader.shaderIds[cvRdrIndex], source);
+ if(err != null) {
+ return err;
+ }
+ shader.compiled[cvRdrIndex] = true;
+ }
+
+ return null;
+ }
+
+ /**
+ * Send a message to the notification thread, which will call the
+ * shader error listeners.
+ */
+ void notifyErrorListeners(Canvas3D cv, ShaderError err) {
+ J3dNotification notification = new J3dNotification();
+ notification.type = J3dNotification.SHADER_ERROR;
+ notification.universe = cv.view.universe;
+ notification.args[0] = err;
+ VirtualUniverse.mc.sendNotification(notification);
+ }
+
+
+ /**
+ * This method checks whether this ShaderProgram is supported on
+ * the specified Canvas. If it isn't supported, it will report a
+ * ShaderError unless an error has already been reported for this
+ * shader program.
+ */
+ private boolean verifyShaderProgramSupported(Canvas3D cv) {
+ boolean supported = isSupported(cv);
+ if (!supported && !unsupportedErrorReported) {
+ String errorMsg = J3dI18N.getString("ShaderProgramRetained0");
+ ShaderError err = new ShaderError(ShaderError.UNSUPPORTED_LANGUAGE_ERROR, errorMsg);
+ err.setShaderProgram((ShaderProgram)this.source);
+ err.setCanvas3D(cv);
+ notifyErrorListeners(cv, err);
+ unsupportedErrorReported = true;
+ }
+ return supported;
+ }
+
+ /**
+ * Method to destroy the native shader.
+ */
+ void destroyShader(Canvas3D cv, int cvRdrIndex, ShaderRetained shader) {
+ if (!verifyShaderProgramSupported(cv)) {
+ return;
+ }
+
+ // Destroy shader resource if it exists
+ synchronized(shader.resourceLock) {
+ // Check whether an entry in the shaderIds array has been allocated
+ if (shader.shaderIds == null || shader.shaderIds.length <= cvRdrIndex) {
+ return;
+ }
+
+ // Nothing to do if the shaderId is 0
+ if (shader.shaderIds[cvRdrIndex] == 0) {
+ return;
+ }
+
+ // Destroy the native resource and set the ID to 0 for this canvas/renderer
+ // Ignore any possible shader error, because there is no meaningful way to report it
+ destroyShader(cv.ctx, shader.shaderIds[cvRdrIndex]);
+ shader.shaderIds[cvRdrIndex] = 0;
+ }
+ }
+
+
+ /**
+ * Method to destroy the native shader program.
+ */
+ void destroyShaderProgram(Canvas3D cv, int cvRdrIndex) {
+ if (!verifyShaderProgramSupported(cv)) {
+ return;
+ }
+
+ // Destroy shaderProgram resource if it exists
+ synchronized(resourceLock) {
+ assert(shaderProgramData != null &&
+ shaderProgramData.length > cvRdrIndex &&
+ shaderProgramData[cvRdrIndex] != null);
+
+// // Check whether an entry in the shaderProgramData array has been allocated
+// if (shaderProgramData == null ||
+// shaderProgramData.length <= cvRdrIndex ||
+// shaderProgramData[cvRdrIndex] == null) {
+// return;
+// }
+
+ long shaderProgramId = shaderProgramData[cvRdrIndex].getShaderProgramId();
+ // Nothing to do if the shaderProgramId is 0
+ if (shaderProgramId == 0) {
+ return;
+ }
+
+ // Destroy the native resource, set the ID to 0 for this canvas/renderer,
+ // and clear the bit in the resourceCreationMask
+ // Ignore any possible shader error, because there is no meaningful way to report it
+ destroyShaderProgram(cv.ctx, shaderProgramId);
+ // Reset this ShaderProgramData object.
+ shaderProgramData[cvRdrIndex].reset();
+ }
+ }
+
+
+ /**
+ * updateNative is called while traversing the RenderBin to
+ * update the shader program state
+ */
+ void updateNative(Canvas3D cv, boolean enable) {
+ // System.out.println("ShaderProgramRetained.updateNative : ");
+
+ final boolean useSharedCtx = cv.useSharedCtx && cv.screen.renderer.sharedCtx != 0;
+ final int cvRdrIndex = useSharedCtx ? cv.screen.renderer.rendererId : cv.canvasId;
+
+ // Create ShaderProgramData object for this canvas/renderer if it doesn't already exist
+ createShaderProgramData(cvRdrIndex);
+
+ // Check whether this shader program type is supported for this canvas
+ if (!verifyShaderProgramSupported(cv)) {
+ return;
+ }
+
+ // Just disable shader program and return if enable parameter is set to false
+ if (!enable) {
+ // Given the current design, disableShaderProgram cannot return a non-null value,
+ // so no need to check it
+ disableShaderProgram(cv);
+ return;
+ }
+
+ // Just disable shader program and return if array of shaders is empty,
+ // or if a previous attempt to link resulted in an error
+ if (shaders == null || shaders.length == 0 || linkErrorOccurred) {
+ disableShaderProgram(cv);
+ return;
+ }
+
+ boolean loadShaderProgram = false; // flag indicating whether to reload all shaderProgram states
+ if (getShaderProgramData(cvRdrIndex).getShaderProgramId() == 0) {
+ loadShaderProgram = true;
+ }
+
+ //System.out.println(".... loadShaderProgram = " + loadShaderProgram);
+ //System.out.println(".... resourceCreationMask= " + resourceCreationMask);
+
+ ShaderError err = null;
+ boolean errorOccurred = false;
+ if (loadShaderProgram) {
+ if (useSharedCtx) {
+ // TODO : Need to test useSharedCtx case. ** Untested case **
+ cv.makeCtxCurrent(cv.screen.renderer.sharedCtx);
+ }
+
+ // Create shader resources if not already done
+ for(int i=0; i < shaders.length; i++) {
+ if (shaders[i].compileErrorOccurred) {
+ errorOccurred = true;
+ }
+ else {
+ err = createShader(cv, cvRdrIndex, shaders[i]);
+ if (err != null) {
+ err.setShaderProgram((ShaderProgram)this.source);
+ err.setShader((Shader)shaders[i].source);
+ err.setCanvas3D(cv);
+ notifyErrorListeners(cv, err);
+ errorOccurred = true;
+ }
+ else {
+ err = compileShader(cv, cvRdrIndex, shaders[i]);
+ if (err != null) {
+ err.setShaderProgram((ShaderProgram)this.source);
+ err.setShader((Shader)shaders[i].source);
+ err.setCanvas3D(cv);
+ notifyErrorListeners(cv, err);
+ destroyShader(cv, cvRdrIndex, shaders[i]);
+ shaders[i].compileErrorOccurred = true;
+ errorOccurred = true;
+ }
+ }
+ }
+ }
+
+ // Create shader program
+ if (!errorOccurred) {
+ err = createShaderProgram(cv, cvRdrIndex);
+ if (err != null) {
+ err.setShaderProgram((ShaderProgram)this.source);
+ err.setCanvas3D(cv);
+ notifyErrorListeners(cv, err);
+ errorOccurred = true;
+ }
+ }
+
+ boolean linked = getShaderProgramData(cvRdrIndex).isLinked();
+ if (!linked) {
+ // Bind vertex attribute names
+ if (!errorOccurred) {
+ if (vertexAttrNames != null) {
+// System.err.println("vertexAttrNames.length = " + vertexAttrNames.length);
+ for (int i = 0; i < vertexAttrNames.length; i++) {
+ err = bindVertexAttrName(cv, cvRdrIndex, vertexAttrNames[i], i);
+ // Report non-fatal error, if one was detected
+ if (err != null) {
+ err.setShaderProgram((ShaderProgram)this.source);
+ err.setCanvas3D(cv);
+ notifyErrorListeners(cv, err);
+ }
+ }
+ }
+ }
+
+ // Link shader program
+ if (!errorOccurred) {
+ err = linkShaderProgram(cv, cvRdrIndex, shaders);
+ if (err != null) {
+ err.setShaderProgram((ShaderProgram)this.source);
+ err.setCanvas3D(cv);
+ notifyErrorListeners(cv, err);
+ destroyShaderProgram(cv, cvRdrIndex);
+ linkErrorOccurred = true;
+ errorOccurred = true;
+ }
+ }
+
+ // lookup vertex attribute names
+ if (!errorOccurred) {
+ if (vertexAttrNames != null) {
+ lookupVertexAttrNames(cv, cvRdrIndex, vertexAttrNames);
+ }
+ }
+
+ // Lookup shader attribute names
+ if (!errorOccurred) {
+ if (shaderAttrNames != null) {
+// System.err.println("shaderAttrNames.length = " + shaderAttrNames.length);
+ lookupShaderAttrNames(cv, cvRdrIndex, shaderAttrNames);
+ }
+ }
+ }
+
+ // Restore current context if we changed it to the shareCtx
+ if (useSharedCtx) {
+ cv.makeCtxCurrent(cv.ctx);
+ }
+
+ // If compilation or link error occured, disable shader program and return
+ if (errorOccurred) {
+ disableShaderProgram(cv);
+ return;
+ }
+ }
+
+ // Now we can enable the shader program
+ enableShaderProgram(cv, cvRdrIndex);
+ }
+
+ /**
+ * Update native value for ShaderAttributeValue class
+ */
+ ShaderError setUniformAttrValue(long ctx, long shaderProgramId, long loc,
+ ShaderAttributeValueRetained sav) {
+
+ switch (sav.getClassType()) {
+ case ShaderAttributeObjectRetained.TYPE_INTEGER:
+ return setUniform1i(ctx, shaderProgramId, loc,
+ ((int[])sav.attrWrapper.getRef())[0]);
+
+ case ShaderAttributeObjectRetained.TYPE_FLOAT:
+ return setUniform1f(ctx, shaderProgramId, loc,
+ ((float[])sav.attrWrapper.getRef())[0]);
+
+ case ShaderAttributeObjectRetained.TYPE_TUPLE2I:
+ return setUniform2i(ctx, shaderProgramId, loc,
+ (int[])sav.attrWrapper.getRef());
+
+ case ShaderAttributeObjectRetained.TYPE_TUPLE2F:
+ return setUniform2f(ctx, shaderProgramId, loc,
+ (float[])sav.attrWrapper.getRef());
+
+ case ShaderAttributeObjectRetained.TYPE_TUPLE3I:
+ return setUniform3i(ctx, shaderProgramId, loc,
+ (int[])sav.attrWrapper.getRef());
+
+ case ShaderAttributeObjectRetained.TYPE_TUPLE3F:
+ return setUniform3f(ctx, shaderProgramId, loc,
+ (float[])sav.attrWrapper.getRef());
+
+ case ShaderAttributeObjectRetained.TYPE_TUPLE4I:
+ return setUniform4i(ctx, shaderProgramId, loc,
+ (int[])sav.attrWrapper.getRef());
+
+ case ShaderAttributeObjectRetained.TYPE_TUPLE4F:
+ return setUniform4f(ctx, shaderProgramId, loc,
+ (float[])sav.attrWrapper.getRef());
+
+ case ShaderAttributeObjectRetained.TYPE_MATRIX3F:
+ return setUniformMatrix3f(ctx, shaderProgramId, loc,
+ (float[])sav.attrWrapper.getRef());
+
+ case ShaderAttributeObjectRetained.TYPE_MATRIX4F:
+ return setUniformMatrix4f(ctx, shaderProgramId, loc,
+ (float[])sav.attrWrapper.getRef());
+
+ default:
+ // Should never get here
+ assert false : "Unrecognized ShaderAttributeValue classType";
+ return null;
+ }
+ }
+
+ /**
+ * Update native value for ShaderAttributeArray class
+ */
+ ShaderError setUniformAttrArray(long ctx, long shaderProgramId, long loc,
+ ShaderAttributeArrayRetained saa) {
+
+ switch (saa.getClassType()) {
+ case ShaderAttributeObjectRetained.TYPE_INTEGER:
+ return setUniform1iArray(ctx, shaderProgramId, loc, saa.length(),
+ ((int[])saa.attrWrapper.getRef()));
+
+ case ShaderAttributeObjectRetained.TYPE_FLOAT:
+ return setUniform1fArray(ctx, shaderProgramId, loc, saa.length(),
+ ((float[])saa.attrWrapper.getRef()));
+
+ case ShaderAttributeObjectRetained.TYPE_TUPLE2I:
+ return setUniform2iArray(ctx, shaderProgramId, loc, saa.length(),
+ (int[])saa.attrWrapper.getRef());
+
+ case ShaderAttributeObjectRetained.TYPE_TUPLE2F:
+ return setUniform2fArray(ctx, shaderProgramId, loc, saa.length(),
+ (float[])saa.attrWrapper.getRef());
+
+ case ShaderAttributeObjectRetained.TYPE_TUPLE3I:
+ return setUniform3iArray(ctx, shaderProgramId, loc, saa.length(),
+ (int[])saa.attrWrapper.getRef());
+
+ case ShaderAttributeObjectRetained.TYPE_TUPLE3F:
+ return setUniform3fArray(ctx, shaderProgramId, loc, saa.length(),
+ (float[])saa.attrWrapper.getRef());
+
+ case ShaderAttributeObjectRetained.TYPE_TUPLE4I:
+ return setUniform4iArray(ctx, shaderProgramId, loc, saa.length(),
+ (int[])saa.attrWrapper.getRef());
+
+ case ShaderAttributeObjectRetained.TYPE_TUPLE4F:
+ return setUniform4fArray(ctx, shaderProgramId, loc, saa.length(),
+ (float[])saa.attrWrapper.getRef());
+
+ case ShaderAttributeObjectRetained.TYPE_MATRIX3F:
+ return setUniformMatrix3fArray(ctx, shaderProgramId, loc, saa.length(),
+ (float[])saa.attrWrapper.getRef());
+
+ case ShaderAttributeObjectRetained.TYPE_MATRIX4F:
+ return setUniformMatrix4fArray(ctx, shaderProgramId, loc, saa.length(),
+ (float[])saa.attrWrapper.getRef());
+
+ default:
+ // Should never get here
+ assert false : "Unrecognized ShaderAttributeArray classType";
+ return null;
+ }
+
+ }
+
+
+ void setShaderAttributes(Canvas3D cv, ShaderAttributeSetRetained attributeSet) {
+ final boolean useSharedCtx = cv.useSharedCtx && cv.screen.renderer.sharedCtx != 0;
+ final int cvRdrIndex = useSharedCtx ? cv.screen.renderer.rendererId : cv.canvasId;
+ ShaderProgramData spData = getShaderProgramData(cvRdrIndex);
+
+ // Just return if shader program wasn't linked successfully
+ if (!spData.isLinked()) {
+ return;
+ }
+
+ long shaderProgramId = spData.getShaderProgramId();
+
+ Iterator attrs = attributeSet.getAttrs().values().iterator();
+ while (attrs.hasNext()) {
+ ShaderError err = null;
+ ShaderAttributeRetained saRetained = (ShaderAttributeRetained)attrs.next();
+
+ // Lookup attribute info for the specified attrName; null means
+ // that the name does not appear in the ShaderProgram, so we will
+ // report an error.
+ AttrNameInfo attrNameInfo = spData.getAttrNameInfo(saRetained.getAttributeName());
+ if(attrNameInfo == null) {
+// System.err.println("ShaderProgramRetained : attrLocation (" + saRetained.getAttributeName() + ") is null.");
+ String errMsg = "Attribute name not set in ShaderProgram: " + saRetained.getAttributeName(); // TODO: I18N
+ err = new ShaderError(ShaderError.SHADER_ATTRIBUTE_NAME_NOT_SET_ERROR, errMsg);
+ } else {
+ long loc = attrNameInfo.getLocation();
+ if (loc != -1) {
+ if (saRetained instanceof ShaderAttributeValueRetained) {
+ ShaderAttributeValueRetained savRetained = (ShaderAttributeValueRetained)saRetained;
+ if (attrNameInfo.isArray() ||
+ (savRetained.getClassType() != attrNameInfo.getType())) {
+ String errMsg = "Attribute type mismatch: " + savRetained.getAttributeName(); // TODO: I18N
+ err = new ShaderError(ShaderError.SHADER_ATTRIBUTE_TYPE_ERROR, errMsg);
+ }
+ else {
+ err = setUniformAttrValue(cv.ctx, shaderProgramId, loc, savRetained);
+ }
+ } else if (saRetained instanceof ShaderAttributeArrayRetained) {
+ ShaderAttributeArrayRetained saaRetained = (ShaderAttributeArrayRetained)saRetained;
+ if (!attrNameInfo.isArray() ||
+ (saaRetained.getClassType() != attrNameInfo.getType())) {
+ String errMsg = "Attribute type mismatch: " + saaRetained.getAttributeName(); // TODO: I18N
+ err = new ShaderError(ShaderError.SHADER_ATTRIBUTE_TYPE_ERROR, errMsg);
+ }
+ else {
+ err = setUniformAttrArray(cv.ctx, shaderProgramId, loc, saaRetained);
+ }
+ } else if (saRetained instanceof ShaderAttributeBindingRetained) {
+ assert false;
+ throw new RuntimeException("not implemented");
+ } else {
+ assert false;
+ }
+ }
+ }
+
+ if (err != null) {
+ // Before reporting the ShaderAttribute error, check
+ // whether it has already been reported for this ShaderProgram
+ if (shaderAttrErrorSet == null) {
+ shaderAttrErrorSet = new HashSet();
+ }
+ if (shaderAttrErrorSet.add(saRetained.source)) {
+ err.setShaderProgram((ShaderProgram)this.source);
+ err.setShaderAttributeSet((ShaderAttributeSet)attributeSet.source);
+ err.setShaderAttribute((ShaderAttribute)saRetained.source);
+ err.setCanvas3D(cv);
+ notifyErrorListeners(cv, err);
+ }
+ }
+ }
+ }
+
+ class ShaderProgramData extends Object {
+
+ // shaderProgramId use by native code.
+ private long shaderProgramId = 0;
+
+ // linked flag for native.
+ private boolean linked = false;
+
+ // A map of locations for ShaderAttributes.
+ private HashMap attrNameInfoMap = new HashMap();
+
+ /** ShaderProgramData Constructor */
+ ShaderProgramData() {
+ }
+
+ void reset() {
+ shaderProgramId = 0;
+ linked = false;
+ attrNameInfoMap.clear();
+ }
+
+ void setShaderProgramId(long shaderProgramId) {
+ this.shaderProgramId = shaderProgramId;
+ }
+
+ long getShaderProgramId() {
+ return this.shaderProgramId;
+ }
+
+ void setLinked(boolean linked) {
+ this.linked = linked;
+ }
+
+ boolean isLinked() {
+ return linked;
+ }
+
+ void setAttrNameInfo(String shaderAttribute, AttrNameInfo attrNameInfo) {
+ assert(shaderAttribute != null);
+ attrNameInfoMap.put(shaderAttribute, attrNameInfo);
+ }
+
+ AttrNameInfo getAttrNameInfo(String shaderAttribute) {
+ return (AttrNameInfo) attrNameInfoMap.get(shaderAttribute);
+ }
+
+
+ }
+
+ // Data associated with an attribute name
+ class AttrNameInfo {
+ void setLocation(long loc) {
+ this.loc = loc;
+ }
+
+ long getLocation() {
+ return loc;
+ }
+
+ void setType(int type) {
+ this.type = type;
+ }
+
+ int getType() {
+ return type;
+ }
+
+ boolean isArray() {
+ return isArray;
+ }
+
+ void setArray(boolean isArray) {
+ this.isArray = isArray;
+ }
+
+ // Location of attribute name in linked shader program
+ private long loc;
+
+ // boolean indicating whether the attribute is an array
+ private boolean isArray;
+
+ // type of shader attribute
+ private int type;
+ }
+
+}
diff --git a/src/classes/share/javax/media/j3d/ShaderRetained.java b/src/classes/share/javax/media/j3d/ShaderRetained.java
new file mode 100644
index 0000000..a050b50
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/ShaderRetained.java
@@ -0,0 +1,78 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+import java.util.*;
+
+/**
+ * The ShaderRetained object is the abstract base class for programmable
+ * shader code. Currently, only text-based source code shaders are
+ * supported, so the only subclass of Shader is SourceCodeShader. We
+ * leave open the possibility for binary (object code) shaders in the
+ * future.
+ */
+abstract class ShaderRetained extends NodeComponentRetained {
+ int shadingLanguage;
+ int shaderType;
+
+ // shaderId use by native code. One per Canvas.
+ long[] shaderIds;
+ boolean[] compiled;
+
+ // Flag indicating whether a COMPILE_ERROR has occurred for this shader
+ // object. It is set in updateNative to indicate that the compileShader
+ // operation failed. It is cleared in setLive or clearLive.
+ // TODO KCR: Add code to clear this in setLive or clearLive
+ boolean compileErrorOccurred = false;
+
+ // need to synchronize access from multiple rendering threads
+ Object resourceLock = new Object();
+
+ void initializeShader(int shadingLanguage, int shaderType) {
+ this.shadingLanguage = shadingLanguage;
+ this.shaderType = shaderType;
+ }
+
+ int getShadingLanguage() {
+ return shadingLanguage;
+ }
+
+ int getShaderType() {
+ return shaderType;
+ }
+
+ void setLive(boolean inBackgroundGroup, int refCount) {
+ // System.out.println("SourceCodeShaderRetained.setLive()");
+ super.setLive(inBackgroundGroup, refCount);
+ }
+
+ void clearLive(int refCount) {
+ // System.out.println("SourceCodeShaderRetained.clearLive()");
+ super.clearLive(refCount);
+ }
+
+ /**
+ * Shader object doesn't really have mirror object.
+ * But it's using the updateMirrorObject interface to propagate
+ * the changes to the users
+ */
+ synchronized void updateMirrorObject(int component, Object value) {
+ System.out.println("Shader.updateMirrorObject not implemented yet!");
+ }
+
+ void handleFrequencyChange(int bit) {
+ System.out.println("Shader.handleFrequencyChange not implemented yet!");
+ }
+
+}
+
diff --git a/src/classes/share/javax/media/j3d/Shape3D.java b/src/classes/share/javax/media/j3d/Shape3D.java
index 6a9f5d7..5c4394c 100644
--- a/src/classes/share/javax/media/j3d/Shape3D.java
+++ b/src/classes/share/javax/media/j3d/Shape3D.java
@@ -111,6 +111,14 @@ public class Shape3D extends Leaf {
public static final int ALLOW_APPEARANCE_OVERRIDE_WRITE =
CapabilityBits.SHAPE3D_ALLOW_APPEARANCE_OVERRIDE_WRITE;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_GEOMETRY_READ,
+ ALLOW_APPEARANCE_READ,
+ ALLOW_COLLISION_BOUNDS_READ,
+ ALLOW_APPEARANCE_OVERRIDE_READ
+ };
+
/**
* Constructs a Shape3D node with default parameters. The default
* values are as follows:
@@ -127,6 +135,8 @@ public class Shape3D extends Leaf {
* that default values are used for all appearance attributes.
*/
public Shape3D() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -141,7 +151,10 @@ public class Shape3D extends Leaf {
* this shape node.
*/
public Shape3D(Geometry geometry) {
- ((Shape3DRetained)retained).setGeometry(geometry, 0);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((Shape3DRetained)retained).setGeometry(geometry, 0);
}
/**
@@ -155,7 +168,10 @@ public class Shape3D extends Leaf {
* @param appearance the appearance component of the shape node
*/
public Shape3D(Geometry geometry, Appearance appearance) {
- ((Shape3DRetained)retained).setGeometry(geometry, 0);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((Shape3DRetained)retained).setGeometry(geometry, 0);
((Shape3DRetained)retained).setAppearance(appearance);
}
diff --git a/src/classes/share/javax/media/j3d/Shape3DCompileRetained.java b/src/classes/share/javax/media/j3d/Shape3DCompileRetained.java
index e4514d4..a3e604d 100644
--- a/src/classes/share/javax/media/j3d/Shape3DCompileRetained.java
+++ b/src/classes/share/javax/media/j3d/Shape3DCompileRetained.java
@@ -424,81 +424,139 @@ class Shape3DCompileRetained extends Shape3DRetained {
* @exception IllegalArgumentException if <code>path</code> is
* invalid.
*/
-
boolean intersect(SceneGraphPath path,
- PickShape pickShape, double[] dist) {
-
- // This method will not do bound intersect check, as it assume
- // caller has already done that. ( For performance and code
- // simplification reasons. )
-
- Transform3D localToVworld = path.getTransform();
- int i;
-
- if (localToVworld == null) {
+ PickShape pickShape, double[] dist) {
+
+ int flags;
+ PickInfo pickInfo = new PickInfo();
+
+ Transform3D localToVworld = path.getTransform();
+ if (localToVworld == null) {
throw new IllegalArgumentException(J3dI18N.getString("Shape3DRetained3"));
}
-
- Transform3D t3d = VirtualUniverse.mc.getTransform3D(null);
- t3d.invert(localToVworld);
- PickShape newPS = pickShape.transform(t3d);
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D, t3d);
-
- Shape3D shape = (Shape3D) path.getObject();
+ pickInfo.setLocalToVWorldRef( localToVworld);
+
+ Shape3D shape = (Shape3D) path.getObject();
// Get the geometries for this shape only, since the compiled
// geomtryList contains several shapes
- ArrayList glist = (ArrayList) geometryInfo.get(shape.id);
-
- int geomListSize = glist.size();
-
- Point3d iPnt = Shape3DRetained.getPoint3d();
+ ArrayList glist = (ArrayList) geometryInfo.get(shape.id);
+
+ // System.out.println("Shape3DCompileRetained.intersect() : ");
+ if (dist == null) {
+ // System.out.println(" no dist request ....");
+ return intersect(pickInfo, pickShape, 0, glist);
+ }
+
+ flags = PickInfo.CLOSEST_DISTANCE;
+ if (intersect(pickInfo, pickShape, flags, glist)) {
+ dist[0] = pickInfo.getClosestDistance();
+ return true;
+ }
+
+ return false;
+
+ }
+
+ boolean intersect(PickInfo pickInfo, PickShape pickShape, int flags,
+ ArrayList geometryList) {
+
+ Transform3D localToVworld = pickInfo.getLocalToVWorldRef();
+
+ Transform3D t3d = new Transform3D();
+ t3d.invert(localToVworld);
+ PickShape newPS = pickShape.transform(t3d);
+
+ int geomListSize = geometryList.size();
GeometryRetained geometry;
- if (dist == null) {
- for (i=0; i < geomListSize; i++) {
- Geometry g = (Geometry) glist.get(i);
- if (g != null && g.retained != null) {
- geometry = (GeometryRetained)g.retained;
+ if (((flags & PickInfo.CLOSEST_INTERSECTION_POINT) == 0) &&
+ ((flags & PickInfo.CLOSEST_DISTANCE) == 0) &&
+ ((flags & PickInfo.CLOSEST_GEOM_INFO) == 0) &&
+ ((flags & PickInfo.ALL_GEOM_INFO) == 0)) {
+
+ for (int i=0; i < geomListSize; i++) {
+ geometry = (GeometryRetained) geometryList.get(i);
+ if (geometry != null) {
if (geometry.mirrorGeometry != null) {
geometry = geometry.mirrorGeometry;
}
-
- if (geometry.intersect(newPS, null, iPnt)) {
- Shape3DRetained.freePoint3d(iPnt);
+ // Need to modify this method
+ // if (geometry.intersect(newPS, null, null)) {
+ if (geometry.intersect(newPS, null, 0, null)) {
return true;
}
}
}
- } else {
+ }
+ else {
+ double distance;
double minDist = Double.POSITIVE_INFINITY;
- // TODO : BugId 4351579 -- Need to return the index of nearest
- // intersected geometry too.
-
- for (i=0; i < geomListSize; i++) {
- Geometry g = (Geometry) glist.get(i);
- if (g != null && g.retained != null) {
- geometry = (GeometryRetained)g.retained;
+ Point3d closestIPnt = new Point3d();
+ Point3d iPnt = new Point3d();
+ Point3d iPntVW = new Point3d();
+ PickInfo.IntersectionInfo closestInfo = null;
+ PickInfo.IntersectionInfo intersectionInfo
+ = pickInfo.createIntersectionInfo();
+
+ if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
+ closestInfo = pickInfo.createIntersectionInfo();
+ }
+
+ for (int i=0; i < geomListSize; i++) {
+ geometry = (GeometryRetained) geometryList.get(i);
+ if (geometry != null) {
if (geometry.mirrorGeometry != null) {
geometry = geometry.mirrorGeometry;
}
- if (geometry.intersect(newPS, dist, iPnt)) {
- localToVworld.transform(iPnt);
- dist[0] = pickShape.distance(iPnt);
- if (minDist > dist[0]) {
- minDist = dist[0];
- }
+ if (geometry.intersect(newPS, intersectionInfo, flags, iPnt)) {
+
+ iPntVW.set(iPnt);
+ localToVworld.transform(iPntVW);
+ distance = pickShape.distance(iPntVW);
+
+ if (minDist > distance) {
+ minDist = distance;
+ closestIPnt.set(iPnt);
+
+ if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
+ closestInfo.setGeometry((Geometry) geometry.source);
+ closestInfo.setGeometryIndex(i);
+ closestInfo.setIntersectionPoint(closestIPnt);
+ closestInfo.setDistance(distance);
+ closestInfo.setVertexIndices(intersectionInfo.getVertexIndices());
+ }
+ }
+
+ if ((flags & PickInfo.ALL_GEOM_INFO) != 0) {
+
+ intersectionInfo.setGeometry((Geometry) geometry.source);
+ intersectionInfo.setGeometryIndex(i);
+ intersectionInfo.setIntersectionPoint(iPnt);
+ intersectionInfo.setDistance(distance);
+ // VertexIndices has been computed in intersect method.
+ pickInfo.insertIntersectionInfo(intersectionInfo);
+ intersectionInfo = pickInfo.createIntersectionInfo();
+ }
}
}
}
-
- if (minDist < Double.POSITIVE_INFINITY) {
- dist[0] = minDist;
- Shape3DRetained.freePoint3d(iPnt);
+
+ if (minDist < Double.POSITIVE_INFINITY) {
+ if ((flags & PickInfo.CLOSEST_DISTANCE) != 0) {
+ pickInfo.setClosestDistance(minDist);
+ }
+ if((flags & PickInfo.CLOSEST_INTERSECTION_POINT) != 0) {
+ pickInfo.setClosestIntersectionPoint(closestIPnt);
+ }
+ if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
+ pickInfo.insertIntersectionInfo(closestInfo);
+ }
return true;
}
}
-
- Shape3DRetained.freePoint3d(iPnt);
+
return false;
- }
+
+ }
+
}
diff --git a/src/classes/share/javax/media/j3d/Shape3DRetained.java b/src/classes/share/javax/media/j3d/Shape3DRetained.java
index 8e097bd..8d3002c 100644
--- a/src/classes/share/javax/media/j3d/Shape3DRetained.java
+++ b/src/classes/share/javax/media/j3d/Shape3DRetained.java
@@ -580,97 +580,6 @@ class Shape3DRetained extends LeafRetained {
return (appearance == null ? null: (Appearance) appearance.source);
}
-
- /**
- * Check if the geometry component of this shape node under path
- * intersects with the pickShape.
- * This is an expensive method. It should only be called if and only
- * if the path's bound intersects pickShape.
- * @exception IllegalArgumentException if <code>path</code> is
- * invalid.
- */
-
- boolean intersect(SceneGraphPath path,
- PickShape pickShape, double[] dist) {
-
- // This method will not do bound intersect check, as it assume
- // caller has already done that. ( For performance and code
- // simplification reasons. )
-
- Transform3D localToVworld = path.getTransform();
- int i;
-
- if (localToVworld == null) {
- throw new IllegalArgumentException(J3dI18N.getString("Shape3DRetained3"));
- }
-
- // Support OrientedShape3D here.
- // TODO - BugId : 4363899 - APIs issue : OrientedShape3D's intersect needs view
- // info. temp. fix use the primary view.
- if (this instanceof OrientedShape3DRetained) {
- Transform3D orientedTransform = ((OrientedShape3DRetained)this).
- getOrientedTransform(getPrimaryViewIdx());
- localToVworld.mul(orientedTransform);
- }
-
- Transform3D t3d = VirtualUniverse.mc.getTransform3D(null);
- t3d.invert(localToVworld);
- PickShape newPS = pickShape.transform(t3d);
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D, t3d);
-
- // TODO: For optimization - Should do a geobounds check of
- // each geometry first. But this doesn't work for
- // OrientedShape3D case...
- int geomListSize = geometryList.size();
- Point3d iPnt = getPoint3d();
- GeometryRetained geometry;
-
- if (dist == null) {
- for (i=0; i < geomListSize; i++) {
- geometry = (GeometryRetained) geometryList.get(i);
- if (geometry != null) {
- if (geometry.mirrorGeometry != null) {
- geometry = geometry.mirrorGeometry;
- }
- if (geometry.intersect(newPS, null, iPnt)) {
- freePoint3d(iPnt);
- return true;
- }
- }
- }
- } else {
- double minDist = Double.POSITIVE_INFINITY;
- // TODO : BugId 4351579 -- Need to return the index of nearest
- // intersected geometry too.
-
- for (i=0; i < geomListSize; i++) {
- geometry = (GeometryRetained) geometryList.get(i);
- if (geometry != null) {
- if (geometry.mirrorGeometry != null) {
- geometry = geometry.mirrorGeometry;
- }
- if (geometry.intersect(newPS, dist, iPnt)) {
- localToVworld.transform(iPnt);
- dist[0] = pickShape.distance(iPnt);
- if (minDist > dist[0]) {
- minDist = dist[0];
- }
- }
- }
- }
-
- if (minDist < Double.POSITIVE_INFINITY) {
- dist[0] = minDist;
- freePoint3d(iPnt);
- return true;
- }
- }
-
- freePoint3d(iPnt);
-
- return false;
- }
-
void setAppearanceOverrideEnable(boolean flag) {
if (((Shape3D)this.source).isLive()) {
@@ -703,7 +612,153 @@ class Shape3DRetained extends LeafRetained {
boolean getAppearanceOverrideEnable() {
return appearanceOverrideEnable;
}
+
+ boolean intersect(PickInfo pickInfo, PickShape pickShape, int flags ) {
+
+ Transform3D localToVworld = pickInfo.getLocalToVWorldRef();
+
+ // Support OrientedShape3D here.
+ // Note - BugId : 4363899 - APIs issue : OrientedShape3D's intersect needs view
+ // info. temp. fix use the primary view.
+ if (this instanceof OrientedShape3DRetained) {
+ Transform3D orientedTransform = ((OrientedShape3DRetained)this).
+ getOrientedTransform(getPrimaryViewIdx());
+ localToVworld.mul(orientedTransform);
+ }
+
+ Transform3D t3d = new Transform3D();
+ t3d.invert(localToVworld);
+ PickShape newPS = pickShape.transform(t3d);
+ // Note: For optimization - Should do a geobounds check of
+ // each geometry first. But this doesn't work for
+ // OrientedShape3D case...
+ int geomListSize = geometryList.size();
+ GeometryRetained geometry;
+
+ if (((flags & PickInfo.CLOSEST_INTERSECTION_POINT) == 0) &&
+ ((flags & PickInfo.CLOSEST_DISTANCE) == 0) &&
+ ((flags & PickInfo.CLOSEST_GEOM_INFO) == 0) &&
+ ((flags & PickInfo.ALL_GEOM_INFO) == 0)) {
+
+ for (int i=0; i < geomListSize; i++) {
+ geometry = (GeometryRetained) geometryList.get(i);
+ if (geometry != null) {
+ if (geometry.mirrorGeometry != null) {
+ geometry = geometry.mirrorGeometry;
+ }
+ if (geometry.intersect(newPS, null, 0, null)) {
+ return true;
+ }
+ }
+ }
+ } else {
+ double distance;
+ double minDist = Double.POSITIVE_INFINITY;
+ Point3d closestIPnt = new Point3d();
+ Point3d iPnt = new Point3d();
+ Point3d iPntVW = new Point3d();
+ PickInfo.IntersectionInfo closestInfo = null;
+ PickInfo.IntersectionInfo intersectionInfo
+ = pickInfo.createIntersectionInfo();
+
+ if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
+ closestInfo = pickInfo.createIntersectionInfo();
+ }
+
+ for (int i=0; i < geomListSize; i++) {
+ geometry = (GeometryRetained) geometryList.get(i);
+ if (geometry != null) {
+ if (geometry.mirrorGeometry != null) {
+ geometry = geometry.mirrorGeometry;
+ }
+ if (geometry.intersect(newPS, intersectionInfo, flags, iPnt)) {
+
+ iPntVW.set(iPnt);
+ localToVworld.transform(iPntVW);
+ distance = pickShape.distance(iPntVW);
+
+ if (minDist > distance) {
+ minDist = distance;
+ closestIPnt.set(iPnt);
+
+ if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
+ closestInfo.setGeometry((Geometry) geometry.source);
+ closestInfo.setGeometryIndex(i);
+ closestInfo.setIntersectionPoint(closestIPnt);
+ closestInfo.setDistance(distance);
+ closestInfo.setVertexIndices(intersectionInfo.getVertexIndices());
+ }
+ }
+
+ if ((flags & PickInfo.ALL_GEOM_INFO) != 0) {
+
+ intersectionInfo.setGeometry((Geometry) geometry.source);
+ intersectionInfo.setGeometryIndex(i);
+ intersectionInfo.setIntersectionPoint(iPnt);
+ intersectionInfo.setDistance(distance);
+ // VertexIndices has been computed in intersect method.
+ pickInfo.insertIntersectionInfo(intersectionInfo);
+ intersectionInfo = pickInfo.createIntersectionInfo();
+ }
+ }
+ }
+ }
+
+ if (minDist < Double.POSITIVE_INFINITY) {
+ if ((flags & PickInfo.CLOSEST_DISTANCE) != 0) {
+ pickInfo.setClosestDistance(minDist);
+ }
+ if((flags & PickInfo.CLOSEST_INTERSECTION_POINT) != 0) {
+ pickInfo.setClosestIntersectionPoint(closestIPnt);
+ }
+ if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
+ pickInfo.insertIntersectionInfo(closestInfo);
+ }
+ return true;
+ }
+ }
+
+ return false;
+
+ }
+
+
+ /**
+ * Check if the geometry component of this shape node under path
+ * intersects with the pickShape.
+ * This is an expensive method. It should only be called if and only
+ * if the path's bound intersects pickShape.
+ * @exception IllegalArgumentException if <code>path</code> is
+ * invalid.
+ */
+
+ boolean intersect(SceneGraphPath path,
+ PickShape pickShape, double[] dist) {
+
+ int flags;
+ PickInfo pickInfo = new PickInfo();
+
+ Transform3D localToVworld = path.getTransform();
+ if (localToVworld == null) {
+ throw new IllegalArgumentException(J3dI18N.getString("Shape3DRetained3"));
+ }
+ pickInfo.setLocalToVWorldRef( localToVworld);
+ //System.out.println("Shape3DRetained.intersect() : ");
+ if (dist == null) {
+ //System.out.println(" no dist request ....");
+ return intersect(pickInfo, pickShape, 0);
+ }
+
+ flags = PickInfo.CLOSEST_DISTANCE;
+ if (intersect(pickInfo, pickShape, flags)) {
+ dist[0] = pickInfo.getClosestDistance();
+ return true;
+ }
+
+ return false;
+
+ }
/**
* This sets the immedate mode context flag
diff --git a/src/classes/share/javax/media/j3d/SharedGroup.java b/src/classes/share/javax/media/j3d/SharedGroup.java
index 3f7ce8d..446c3f2 100644
--- a/src/classes/share/javax/media/j3d/SharedGroup.java
+++ b/src/classes/share/javax/media/j3d/SharedGroup.java
@@ -67,11 +67,17 @@ public class SharedGroup extends Group {
public static final int
ALLOW_LINK_READ = CapabilityBits.SHARED_GROUP_ALLOW_LINK_READ;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_LINK_READ
+ };
/**
* Constructs and initializes a new SharedGroup node object.
*/
public SharedGroup() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
@@ -82,10 +88,12 @@ public class SharedGroup extends Group {
* @since Java 3D 1.3
*/
public Link[] getLinks() {
- if (isLiveOrCompiled())
- if (!this.getCapability(ALLOW_LINK_READ))
+ if (isLiveOrCompiled()) {
+ if (!this.getCapability(ALLOW_LINK_READ)) {
throw new CapabilityNotSetException(J3dI18N.getString("SharedGroup1"));
- return ((SharedGroupRetained)retained).getLinks();
+ }
+ }
+ return ((SharedGroupRetained)retained).getLinks();
}
diff --git a/src/classes/share/javax/media/j3d/SharedGroupRetained.java b/src/classes/share/javax/media/j3d/SharedGroupRetained.java
index ed69d9f..694671f 100644
--- a/src/classes/share/javax/media/j3d/SharedGroupRetained.java
+++ b/src/classes/share/javax/media/j3d/SharedGroupRetained.java
@@ -329,7 +329,7 @@ class SharedGroupRetained extends GroupRetained implements TargetsInterface {
s.transformTargets = savedTransformTargets;
s.hashkeyIndex = savedHashkeyIndex;
/*
-// TODO : port this
+// XXXX : port this
for (int i=0; i < children.size(); i++) {
if ((childContains[i][0] & ILLEGAL_LEAF_MASK) != 0) {
throw new IllegalSharingException(J3dI18N.getString("SharedGroupRetained0")); }
@@ -472,7 +472,7 @@ class SharedGroupRetained extends GroupRetained implements TargetsInterface {
s.switchTargets = null;
- // TODO: This is a hack since removeNodeData is called before
+ // XXXX: This is a hack since removeNodeData is called before
// children are clearLives
int[] tempIndex = null;
// Don't keep the indices if everything will be cleared
@@ -778,7 +778,7 @@ class SharedGroupRetained extends GroupRetained implements TargetsInterface {
public void propagateTargetThreads(int type, int childTargetThreads) {
if (type == TargetsInterface.TRANSFORM_TARGETS) {
LinkRetained ln;
- // TODO : For now we'll OR more than exact.
+ // XXXX : For now we'll OR more than exact.
//targetThreads = localTargetThreads | childTargetThreads;
targetThreads = targetThreads | childTargetThreads;
for(int i=0; i<parents.size(); i++) {
diff --git a/src/classes/share/javax/media/j3d/Sound.java b/src/classes/share/javax/media/j3d/Sound.java
index a11d8a9..ac70b9b 100644
--- a/src/classes/share/javax/media/j3d/Sound.java
+++ b/src/classes/share/javax/media/j3d/Sound.java
@@ -440,7 +440,26 @@ public abstract class Sound extends Leaf {
*/
public static final int INFINITE_LOOPS = -1;
-
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_CHANNELS_USED_READ,
+ ALLOW_CONT_PLAY_READ,
+ ALLOW_DURATION_READ,
+ ALLOW_ENABLE_READ,
+ ALLOW_INITIAL_GAIN_READ,
+ ALLOW_IS_PLAYING_READ,
+ ALLOW_IS_READY_READ,
+ ALLOW_LOOP_READ,
+ ALLOW_MUTE_READ,
+ ALLOW_PAUSE_READ,
+ ALLOW_PRIORITY_READ,
+ ALLOW_RATE_SCALE_FACTOR_READ,
+ ALLOW_RELEASE_READ,
+ ALLOW_SCHEDULING_BOUNDS_READ,
+ ALLOW_SOUND_DATA_READ
+ };
+
+
/**
* Constructs and initializes a new Sound node using default
* parameters. The following defaults values are used:
@@ -460,6 +479,8 @@ public abstract class Sound extends Leaf {
* </ul>
*/
public Sound() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -471,6 +492,9 @@ public abstract class Sound extends Leaf {
* @param initialGain overall amplitude scale factor applied to sound source
*/
public Sound(MediaContainer soundData, float initialGain) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((SoundRetained)this.retained).setSoundData(soundData);
((SoundRetained)this.retained).setInitialGain(initialGain);
}
@@ -498,6 +522,9 @@ public abstract class Sound extends Leaf {
boolean enable,
Bounds region,
float priority ) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((SoundRetained)this.retained).setSoundData(soundData);
((SoundRetained)this.retained).setInitialGain(initialGain);
((SoundRetained)this.retained).setLoop(loopCount);
@@ -533,6 +560,9 @@ public abstract class Sound extends Leaf {
Bounds region,
float priority,
float rateFactor ) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((SoundRetained)this.retained).setSoundData(soundData);
((SoundRetained)this.retained).setInitialGain(initialGain);
((SoundRetained)this.retained).setLoop(loopCount);
diff --git a/src/classes/share/javax/media/j3d/SoundRetained.java b/src/classes/share/javax/media/j3d/SoundRetained.java
index 5d6e744..f0b2145 100644
--- a/src/classes/share/javax/media/j3d/SoundRetained.java
+++ b/src/classes/share/javax/media/j3d/SoundRetained.java
@@ -448,7 +448,7 @@ abstract class SoundRetained extends LeafRetained
if (debugFlag)
debugPrint("setSchedulingBounds for a NULL region");
}
- // TODO: test that this works - could not new Bounds() since
+ // XXXX: test that this works - could not new Bounds() since
// Bounds is an abstract class and can't be instantiated
dispatchAttribChange(BOUNDS_DIRTY_BIT, region);
if (source != null && source.isLive()) {
@@ -501,7 +501,7 @@ abstract class SoundRetained extends LeafRetained
} else {
boundingLeaf = null;
}
- // TODO: since BoundingLeaf constructor only takes Bounds
+ // XXXX: since BoundingLeaf constructor only takes Bounds
// test if region passed into dispatchAttribChange correctly.
dispatchAttribChange(BOUNDING_LEAF_DIRTY_BIT, region);
if (source != null && source.isLive()) {
@@ -628,7 +628,7 @@ abstract class SoundRetained extends LeafRetained
}
loadedAtoms[atomCount-1] = atom; // store reference to new atom
// all atoms sample durations SHOULD be the same so store it in node
- this.duration = atom.sampleLength; // TODO: refine later? in ms
+ this.duration = atom.sampleLength; // XXXX: refine later? in ms
}
else { // atom is NOT loaded or has been unloaded; remove from list
if (atomCount == 0)
@@ -1004,7 +1004,7 @@ abstract class SoundRetained extends LeafRetained
ms.inImmCtx = inImmCtx;
ms.setSoundData(getSoundData());
-// TODO: copy ms.atoms array from this.atoms
+// XXXX: copy ms.atoms array from this.atoms
ms.parent = parent;
ms.inSharedGroup = false;
@@ -1136,7 +1136,7 @@ abstract class SoundRetained extends LeafRetained
super.clearLive(s);
-// TODO: if (inSharedGroup)
+// XXXX: if (inSharedGroup)
if (s.inSharedGroup) {
for (int i=0; i<s.keys.length; i++) {
@@ -1195,7 +1195,7 @@ abstract class SoundRetained extends LeafRetained
/*
// This makes passed in sound look just like this sound
// QUESTION: DOesn't appread to be called
-// TODO: ...if so, remove...
+// XXXX: ...if so, remove...
synchronized void update(SoundRetained sound) {
if (debugFlag)
debugPrint("Sound.update ******** entered ***** this = " + this +
@@ -1219,13 +1219,13 @@ abstract class SoundRetained extends LeafRetained
// QUESTION: With code below, no sound schedulingRegion found
// sound.schedulingRegion = schedulingRegion;
// sound.boundingLeaf = boundingLeaf;
-// TODO: clone of region used in Traverse code, why not here???
+// XXXX: clone of region used in Traverse code, why not here???
// if (schedulingRegion != null)
// sound.schedulingRegion = (Bounds)schedulingRegion.clone();
-// TODO: BoundingLeafRetained boundingLeaf ...
+// XXXX: BoundingLeafRetained boundingLeaf ...
// WHAT ABOUT transformedRegion??
-// TODO: Update ALL fields
+// XXXX: Update ALL fields
// ALL THE BELOW USED TO COMMENTED OUT vvvvvvvvvvvvvvvvvvvvvvvvvvvvv
sound.sampleLength = sampleLength;
sound.loopStartOffset = loopStartOffset;
diff --git a/src/classes/share/javax/media/j3d/SoundScheduler.java b/src/classes/share/javax/media/j3d/SoundScheduler.java
index 778c366..15981b6 100644
--- a/src/classes/share/javax/media/j3d/SoundScheduler.java
+++ b/src/classes/share/javax/media/j3d/SoundScheduler.java
@@ -102,7 +102,7 @@ class SoundScheduler extends J3dStructure {
* This prioritized sound list is NO longer re-create instead sounds
* are insert, shuffled or removed as messages are processed.
*/
- // TODO: (Enhancement) should have a seperate list for
+ // XXXX: (Enhancement) should have a seperate list for
// background sound and a list for positional sounds
ArrayList prioritizedSounds = new ArrayList();
@@ -322,7 +322,7 @@ class SoundScheduler extends J3dStructure {
auralAttribsChanged = true;
}
else if (node instanceof ViewPlatformRetained) {
- // TODO: don't support multiple viewPlatforms per scheduler
+ // XXXX: don't support multiple viewPlatforms per scheduler
/*
// useful for resetting VP ??
addViewPlatform((ViewPlatformRetained) node);
@@ -753,7 +753,7 @@ class SoundScheduler extends J3dStructure {
debugPrint(".deactivate()");
//
- // TODO: The following code is clearly erroneous.
+ // XXXX: The following code is clearly erroneous.
// The indendation, along with the 2nd test of
// "if (debugFlag)" in the else clause, suggests that
// the intent was to make the else clause apply to
@@ -858,7 +858,7 @@ class SoundScheduler extends J3dStructure {
return;
}
- // TODO: Does not support multiple canvases per view, thus
+ // XXXX: Does not support multiple canvases per view, thus
// multiple GraphicsContext3Ds
// QUESTION: what does that mean for sound -
// being applied to only ONE graphics context?
@@ -929,7 +929,7 @@ class SoundScheduler extends J3dStructure {
int numActiveSounds = 0;
if (debugFlag)
debugPrint(" renderChanges begun");
- // TODO: BUG?? should wait if audioDevice is NULL or nSounds = 0
+ // XXXX: BUG?? should wait if audioDevice is NULL or nSounds = 0
// when a new sound is added or deleted from list, or
// when the audioDevice is set into PhysicalEnvironment
@@ -955,7 +955,7 @@ class SoundScheduler extends J3dStructure {
if (debugFlag)
debugPrint(" "+ nIntersected +
" active SoundScapes found");
- // TODO: (Performance) calling clone everytime, even
+ // XXXX: (Performance) calling clone everytime, even
// though closest AA has NOT changed, is expensive
aaRetained = (AuralAttributesRetained)
(findClosestAAttribs(nIntersected)).clone();
@@ -1007,7 +1007,7 @@ class SoundScheduler extends J3dStructure {
if (!prioritizedSounds.isEmpty()) {
prioritizedSounds.clear();
}
- // TODO: sync soundStructure sound list
+ // XXXX: sync soundStructure sound list
UnorderList retainedSounds = universe.soundStructure.getSoundList(view);
// QUESTION: what is in this sound list??
// mirror node or actual node???
@@ -1020,7 +1020,7 @@ class SoundScheduler extends J3dStructure {
addPrioritizedSound((SoundRetained)retainedSounds.get(i));
nRetainedSounds++;
}
- // TODO: sync canvases
+ // XXXX: sync canvases
Enumeration canvases = view.getAllCanvas3Ds();
while (canvases.hasMoreElements()) {
Canvas3D canvas = (Canvas3D)canvases.nextElement();
@@ -1300,7 +1300,7 @@ class SoundScheduler extends J3dStructure {
if (attribs != null) {
synchronized (attribs) {
/*
- // TODO: remove use of aaDirty from AuralAttrib node
+ // XXXX: remove use of aaDirty from AuralAttrib node
if ((attribs != lastAA) || attribs.aaDirty)
*/
if (debugFlag) {
@@ -1476,7 +1476,7 @@ class SoundScheduler extends J3dStructure {
// Sounds that have finished playing are not put into list
if ((soundAtom.status == SoundSchedulerAtom.SOUND_COMPLETE) &&
(soundAtom.enabled != SoundSchedulerAtom.PENDING_ON )) {
- // TODO:/QUESTION test for immediate mode (?)
+ // XXXX:/QUESTION test for immediate mode (?)
// Unless the sound has been re-started, there's no need
// to process sound the finished playing the last time thru
@@ -2050,7 +2050,7 @@ class SoundScheduler extends J3dStructure {
synchronized (prioritizedSounds) {
nAtoms = prioritizedSounds.size();
for (int i=0; i<nAtoms; i++) {
- // TODO: (Enhancement) Get all sound node fields here
+ // XXXX: (Enhancement) Get all sound node fields here
// and store locally for performance
soundAtom = (SoundSchedulerAtom)prioritizedSounds.get(i);
mirSound = soundAtom.sound;
@@ -2070,7 +2070,7 @@ class SoundScheduler extends J3dStructure {
// check to see if aural attributes changed and have to be updated
// must be done before list of sound processed so that Aural Attributes
// that affect Sound fields can be set in AudioDevice
- // TODO: this is not effient if auralAttribs always the same
+ // XXXX: this is not effient if auralAttribs always the same
if (sound.getInImmCtx()) {
if (graphicsCtx !=null && graphicsCtx.auralAttributes !=null) {
aaImmed = (AuralAttributesRetained)
@@ -2154,7 +2154,7 @@ class SoundScheduler extends J3dStructure {
case SoundSchedulerAtom.MAKE_SILENT:
// change status to silent AFTER calling render so
// that a currently audible sound will be muted.
- // TODO: why set status AFTER??
+ // XXXX: why set status AFTER??
render(false, soundAtom, attribs);
soundAtom.status = SoundSchedulerAtom.SOUND_SILENT;
numActiveSounds++;
@@ -2373,7 +2373,7 @@ class SoundScheduler extends J3dStructure {
if (debugFlag)
debugPrint("silenceAll " + nAtoms + " Sounds");
for (int i=0; i<nAtoms; i++) {
- // TODO: (Enhancement) Get all sound node fields here
+ // XXXX: (Enhancement) Get all sound node fields here
// and store locally for performance
soundAtom = (SoundSchedulerAtom)prioritizedSounds.get(i);
mirSound = soundAtom.sound;
@@ -2430,7 +2430,7 @@ class SoundScheduler extends J3dStructure {
if (debugFlag)
debugPrint(":pauseAll " + nAtoms + " Sounds");
for (int i=0; i<nAtoms; i++) {
- // TODO: (Enhancement) Get all sound node fields here
+ // XXXX: (Enhancement) Get all sound node fields here
// and store locally for performance
SoundSchedulerAtom soundAtom =
(SoundSchedulerAtom)prioritizedSounds.get(i);
@@ -2475,7 +2475,7 @@ class SoundScheduler extends J3dStructure {
debugPrint(": resumeAll " + nAtoms + " Sounds ");
for (int i=0; i<nAtoms; i++) {
- // TODO: (Enhancement) Get all sound node fields here
+ // XXXX: (Enhancement) Get all sound node fields here
// and store locally for performance
SoundSchedulerAtom soundAtom =
(SoundSchedulerAtom)prioritizedSounds.get(i);
@@ -2528,7 +2528,7 @@ class SoundScheduler extends J3dStructure {
debugPrint(": stopAll " + nAtoms + " Sounds ");
for (int i=0; i<nAtoms; i++) {
- // TODO: (Enhancement) Get all sound node fields here
+ // XXXX: (Enhancement) Get all sound node fields here
// and store locally for performance
SoundSchedulerAtom soundAtom =
(SoundSchedulerAtom)prioritizedSounds.get(i);
@@ -2547,7 +2547,7 @@ class SoundScheduler extends J3dStructure {
debugPrint(".stopAllSounds exited");
}
- // TODO: Mute All Sounds, complementary to Stop All Sounds
+ // XXXX: Mute All Sounds, complementary to Stop All Sounds
// "should return from run loop - but simply WAIT until sounds
// are unmuted. " ???
@@ -2618,7 +2618,7 @@ class SoundScheduler extends J3dStructure {
// Set Transform
/*
- // TODO: per sound tranforms can now be passed to AudioDevice
+ // XXXX: per sound tranforms can now be passed to AudioDevice
// modify and execute the code below
// MoveAppBoundingLeaf > ~/Current/MoveAppBoundingLeaf.outted,
@@ -2652,7 +2652,7 @@ class SoundScheduler extends J3dStructure {
}
audioDevice3D.setVworldXfrm(index, xform);
soundAtom.clearStateDirtyFlag( SoundRetained.XFORM_DIRTY_BIT);
- // TODO: make sure position and direction are already transformed and stored
+ // XXXX: make sure position and direction are already transformed and stored
// into xformXxxxxxx fields.
}
// ^^^^^^^^^^^^^^^^^^^^^
@@ -2679,7 +2679,7 @@ class SoundScheduler extends J3dStructure {
ConeSoundRetained cn = (ConeSoundRetained)mirrorPtSound;
ConeSoundRetained cnSound = (ConeSoundRetained)mirrorPtSound.sgSound;
if (updateAll ||
- // TODO: test for XFORM_DIRTY only in for 1.2
+ // XXXX: test for XFORM_DIRTY only in for 1.2
soundAtom.testDirtyFlag(soundAtom.attribsDirty,
(SoundRetained.DIRECTION_DIRTY_BIT |
SoundRetained.XFORM_DIRTY_BIT) ) ) {
@@ -2992,7 +2992,7 @@ class SoundScheduler extends J3dStructure {
soundAtom.sampleLength = duration;
soundAtom.loopLength = soundAtom.sampleLength;
- // TODO: for most this will be 0 but not all
+ // XXXX: for most this will be 0 but not all
soundAtom.loopStartOffset = 0;
soundAtom.attackLength = 0; // portion of sample before loop section
soundAtom.releaseLength = 0; // portion of sample after loop section
@@ -3027,7 +3027,7 @@ class SoundScheduler extends J3dStructure {
atomFound++;
// orginal app node pass into method
// QUESTION: is mirror node still correct?
- // TODO: ensure only mirror nodes passed into method
+ // XXXX: ensure only mirror nodes passed into method
if (atomFound == nthInstance) {
returnAtom = soundAtom;
break;
diff --git a/src/classes/share/javax/media/j3d/SoundSchedulerAtom.java b/src/classes/share/javax/media/j3d/SoundSchedulerAtom.java
index 1ebf628..a4dcccc 100644
--- a/src/classes/share/javax/media/j3d/SoundSchedulerAtom.java
+++ b/src/classes/share/javax/media/j3d/SoundSchedulerAtom.java
@@ -241,7 +241,7 @@ class SoundSchedulerAtom extends Object {
}
-// TODO: remove this
+// XXXX: remove this
// just set the state after debug no longer needed
void setEnableState(int state) {
enabled = state;
@@ -269,7 +269,7 @@ class SoundSchedulerAtom extends Object {
}
}
-// TODO: remove this
+// XXXX: remove this
// just set the state after debug no longer needed
void setMuteState(int state) {
muted = state;
@@ -297,7 +297,7 @@ class SoundSchedulerAtom extends Object {
}
}
-// TODO: remove this
+// XXXX: remove this
// just set the state after debug no longer needed
void setPauseState(int state) {
paused = state;
@@ -603,8 +603,8 @@ class SoundSchedulerAtom extends Object {
return (action);
} // end of calcInactiveSchedAction
-// TODO isPLaying
-// TODO setLoadingState
+// XXXX: isPLaying
+// XXXX: setLoadingState
// Debug print mechanism for Sound nodes
static final boolean debugFlag = false;
diff --git a/src/classes/share/javax/media/j3d/SoundStructure.java b/src/classes/share/javax/media/j3d/SoundStructure.java
index 90fdba5..e2407b6 100644
--- a/src/classes/share/javax/media/j3d/SoundStructure.java
+++ b/src/classes/share/javax/media/j3d/SoundStructure.java
@@ -99,7 +99,7 @@ class SoundStructure extends J3dStructure {
break;
case J3dMessage.SOUNDSCAPE_CHANGED:
case J3dMessage.AURALATTRIBUTES_CHANGED:
- // TODO: this needs to be changed
+ // XXXX: this needs to be changed
changeNodeAttrib(m);
break;
case J3dMessage.TRANSFORM_CHANGED:
@@ -115,7 +115,7 @@ class SoundStructure extends J3dStructure {
case J3dMessage.VIEWSPECIFICGROUP_CHANGED:
updateViewSpecificGroupChanged(m);
break;
- // TODO: case J3dMessage.BOUNDINGLEAF_CHANGED
+ // XXXX: case J3dMessage.BOUNDINGLEAF_CHANGED
}
/*
@@ -187,7 +187,7 @@ class SoundStructure extends J3dStructure {
}
}
/*
- // TODO:
+ // XXXX:
if (node instanceof AuralAttributesRetained) {
}
else if (node instanceof ViewPlatformRetained) {
@@ -326,7 +326,7 @@ class SoundStructure extends J3dStructure {
if (debugFlag)
debugPrint(" Sound node dirty bit = " + attribDirty);
if ((attribDirty & SoundRetained.PRIORITY_DIRTY_BIT) > 0) {
- // TODO: shuffle in SoundScheduler
+ // XXXX: shuffle in SoundScheduler
/*
shuffleSound((SoundRetained) node);
*/
@@ -346,7 +346,7 @@ class SoundStructure extends J3dStructure {
/*
}
*/
-// TODO: have no dirty flag for soundscape, just auralAttributes...
+// XXXX: have no dirty flag for soundscape, just auralAttributes...
// what if reference to AA changes in soundscape???
}
@@ -400,7 +400,7 @@ class SoundStructure extends J3dStructure {
View[] views = vpLists[i].getViewList();
for (int j=(views.length-1); j>=0; j--) {
View v = (View)(views[j]);
-// TODO: Shouldn't this be done with messages??
+// XXXX: Shouldn't this be done with messages??
v.soundScheduler.loadSound(sound, forceLoad);
}
}
@@ -501,7 +501,7 @@ class SoundStructure extends J3dStructure {
/*
-// TODO: how is immediate mode handled? below code taken from SoundSchedule
+// XXXX: how is immediate mode handled? below code taken from SoundSchedule
// Don't know how we'll process immediate mode sounds;
// Append immediate mode sounds to live sounds list
if (graphicsCtx != null) {
diff --git a/src/classes/share/javax/media/j3d/Soundscape.java b/src/classes/share/javax/media/j3d/Soundscape.java
index b995bc9..2e61e42 100644
--- a/src/classes/share/javax/media/j3d/Soundscape.java
+++ b/src/classes/share/javax/media/j3d/Soundscape.java
@@ -72,7 +72,12 @@ public class Soundscape extends Leaf {
public static final int
ALLOW_ATTRIBUTES_WRITE = CapabilityBits.SOUNDSCAPE_ALLOW_ATTRIBUTES_WRITE;
- /**
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_APPLICATION_BOUNDS_READ,
+ ALLOW_ATTRIBUTES_READ
+ };
+ /**
* Constructs and initializes a new Sound node using following
* defaults:
*<UL> application region: null (no active region)</UL>
@@ -80,6 +85,8 @@ public class Soundscape extends Leaf {
*/
public Soundscape() {
// Just use default values
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -90,6 +97,9 @@ public class Soundscape extends Leaf {
*/
public Soundscape(Bounds region,
AuralAttributes attributes) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((SoundscapeRetained)this.retained).setApplicationBounds(region);
((SoundscapeRetained)this.retained).setAuralAttributes(attributes);
}
diff --git a/src/classes/share/javax/media/j3d/SourceCodeShader.java b/src/classes/share/javax/media/j3d/SourceCodeShader.java
new file mode 100644
index 0000000..b940255
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/SourceCodeShader.java
@@ -0,0 +1,121 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+/**
+ * The SourceCodeShader object is a shader that is defined using
+ * text-based source code. It is used to define the source code for
+ * both vertex and fragment shaders. The currently supported shading
+ * languages are Cg and GLSL.
+ *
+ * @see ShaderProgram
+ *
+ * @since Java 3D 1.4
+ */
+
+public class SourceCodeShader extends Shader {
+
+ /**
+ * Not a public constructor, for internal use
+ */
+ SourceCodeShader() {
+ }
+
+ /**
+ * Constructs a new shader object of the specified shading
+ * language and shader type from the specified source string.
+ *
+ * @param shadingLanguage the specified shading language, one of:
+ * <code>SHADING_LANGUAGE_GLSL</code> or
+ * <code>SHADING_LANGUAGE_CG</code>.
+ *
+ * @param shaderType the shader type, one of:
+ * <code>SHADER_TYPE_VERTEX</code> or
+ * <code>SHADER_TYPE_FRAGMENT</code>.
+ *
+ * @param shaderSource the shader source code
+ *
+ * @exception NullPointerException if shaderSource is null.
+ */
+
+ public SourceCodeShader(int shadingLanguage, int shaderType, String shaderSource) {
+ super(shadingLanguage, shaderType);
+ if (shaderSource == null) {
+ throw new NullPointerException();
+ }
+ ((SourceCodeShaderRetained)this.retained).initShaderSource(shaderSource);
+ }
+
+ /**
+ * Retrieves the shader source string from this shader object.
+ *
+ * @return the shader source string.
+ */
+ public String getShaderSource() {
+ return ((SourceCodeShaderRetained)this.retained).getShaderSource();
+ }
+
+
+ /**
+ * Creates a retained mode SourceCodeShaderRetained object that this
+ * SourceCodeShader component object will point to.
+ */
+ void createRetained() {
+ this.retained = new SourceCodeShaderRetained();
+ this.retained.setSource(this);
+ // System.out.println("SourceCodeShader.createRetained()");
+ }
+
+ /**
+ * @deprecated replaced with cloneNodeComponent(boolean forceDuplicate)
+ */
+ public NodeComponent cloneNodeComponent() {
+ SourceCodeShaderRetained scsRetained = (SourceCodeShaderRetained) retained;
+
+ SourceCodeShader scs = new SourceCodeShader(scsRetained.getShadingLanguage(),
+ scsRetained.getShaderType(),
+ scsRetained.getShaderSource());
+ scs.duplicateNodeComponent(this);
+ return scs;
+ }
+
+
+ /**
+ * Copies all node information from <code>originalNodeComponent</code>
+ * into the current node. This method is called from the
+ * <code>duplicateNode</code> method. This routine does
+ * the actual duplication of all "local data" (any data defined in
+ * this object).
+ *
+ * @param originalNodeComponent the original node to duplicate
+ * @param forceDuplicate when set to <code>true</code>, causes the
+ * <code>duplicateOnCloneTree</code> flag to be ignored. When
+ * <code>false</code>, the value of each node's
+ * <code>duplicateOnCloneTree</code> variable determines whether
+ * NodeComponent data is duplicated or copied.
+ *
+ * @see Node#cloneTree
+ * @see NodeComponent#setDuplicateOnCloneTree
+ */
+ void duplicateAttributes(NodeComponent originalNodeComponent,
+ boolean forceDuplicate) {
+ super.duplicateAttributes(originalNodeComponent, forceDuplicate);
+
+ String sc = ((SourceCodeShaderRetained) originalNodeComponent.retained).getShaderSource();
+
+ if (sc != null) {
+ ((SourceCodeShaderRetained) retained).setShaderSource(sc);
+ }
+ }
+
+}
diff --git a/src/classes/share/javax/media/j3d/SourceCodeShaderRetained.java b/src/classes/share/javax/media/j3d/SourceCodeShaderRetained.java
new file mode 100644
index 0000000..d415ae8
--- /dev/null
+++ b/src/classes/share/javax/media/j3d/SourceCodeShaderRetained.java
@@ -0,0 +1,85 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package javax.media.j3d;
+
+/**
+ * The SourceCodeShaderRetained object is a shader that is defined using
+ * text-based source code. It is used to define the source code for
+ * both vertex and fragment shaders. The currently supported shading
+ * languages are Cg and GLSL.
+ */
+
+class SourceCodeShaderRetained extends ShaderRetained {
+
+ private String shaderSource = null;
+
+ /**
+ * Constructs a new shader retained object of the specified shading
+ * language and shader type from the specified source string.
+ */
+
+ SourceCodeShaderRetained() {
+ }
+
+ // This method is similar to setShaderSource().
+ // To conform to j3d frame in retained creation, we will stick with method
+ // with init name.
+ final void initShaderSource(String shaderSource) {
+ this.shaderSource = shaderSource;
+ }
+
+ final void set(int shadingLanguage, int shaderType, String shaderSource) {
+ this.shadingLanguage = shadingLanguage;
+ this.shaderType = shaderType;
+ this.shaderSource = shaderSource;
+ }
+
+ /**
+ * Retrieves the shader source string from this shader object.
+ *
+ * @return the shader source string.
+ */
+ final String getShaderSource() {
+ return shaderSource;
+ }
+
+ final void setShaderSource(String shaderSource) {
+ this.shaderSource = shaderSource;
+ }
+
+ synchronized void createMirrorObject() {
+ // System.out.println("SourceCodeShaderRetained : createMirrorObject");
+
+ if (mirror == null) {
+ SourceCodeShaderRetained mirrorSCS = new SourceCodeShaderRetained();
+ mirror = mirrorSCS;
+ }
+
+ initMirrorObject();
+ }
+
+ /**
+ * Initializes a mirror object.
+ */
+ synchronized void initMirrorObject() {
+ mirror.source = source;
+
+ ((SourceCodeShaderRetained) mirror).set(shadingLanguage, shaderType, shaderSource);
+ ((SourceCodeShaderRetained) mirror).shaderIds = null;
+ }
+
+ synchronized void updateMirrorObject(int component, Object value) {
+ System.out.println("SourceCodeShader.updateMirrorObject not implemented yet!");
+ }
+
+}
diff --git a/src/classes/share/javax/media/j3d/SpotLight.java b/src/classes/share/javax/media/j3d/SpotLight.java
index b8fc2fc..9f2900d 100644
--- a/src/classes/share/javax/media/j3d/SpotLight.java
+++ b/src/classes/share/javax/media/j3d/SpotLight.java
@@ -94,6 +94,13 @@ public class SpotLight extends PointLight {
public static final int
ALLOW_DIRECTION_READ = CapabilityBits.SPOT_LIGHT_ALLOW_DIRECTION_READ;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_SPREAD_ANGLE_READ,
+ ALLOW_CONCENTRATION_READ,
+ ALLOW_DIRECTION_READ
+ };
+
/**
* Constructs a SpotLight node with default parameters.
* The default values are as follows:
@@ -104,6 +111,8 @@ public class SpotLight extends PointLight {
* </ul>
*/
public SpotLight() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -124,6 +133,10 @@ public class SpotLight extends PointLight {
float spreadAngle,
float concentration) {
super(color, position, attenuation);
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((SpotLightRetained)this.retained).initDirection(direction);
((SpotLightRetained)this.retained).initSpreadAngle(spreadAngle);
((SpotLightRetained)this.retained).initConcentration(concentration);
@@ -148,6 +161,10 @@ public class SpotLight extends PointLight {
float spreadAngle,
float concentration) {
super(lightOn, color, position, attenuation);
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((SpotLightRetained)this.retained).initDirection(direction);
((SpotLightRetained)this.retained).initSpreadAngle(spreadAngle);
((SpotLightRetained)this.retained).initConcentration(concentration);
diff --git a/src/classes/share/javax/media/j3d/Switch.java b/src/classes/share/javax/media/j3d/Switch.java
index 28acc2a..359e365 100644
--- a/src/classes/share/javax/media/j3d/Switch.java
+++ b/src/classes/share/javax/media/j3d/Switch.java
@@ -64,6 +64,11 @@ public class Switch extends Group {
*/
public static final int CHILD_MASK = -3;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_SWITCH_READ
+ };
+
/**
* Constructs a Switch node with default parameters.
* The default values are as follows:
@@ -73,6 +78,8 @@ public class Switch extends Group {
* </ul>
*/
public Switch() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -81,7 +88,10 @@ public class Switch extends Group {
* @param whichChild the initial child selection index
*/
public Switch(int whichChild) {
- ((SwitchRetained)this.retained).setWhichChild(whichChild, true);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((SwitchRetained)this.retained).setWhichChild(whichChild, true);
}
/**
@@ -91,7 +101,10 @@ public class Switch extends Group {
* @param childMask the initial child selection mask
*/
public Switch(int whichChild, BitSet childMask){
- ((SwitchRetained)this.retained).setWhichChild(whichChild, true);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((SwitchRetained)this.retained).setWhichChild(whichChild, true);
((SwitchRetained)this.retained).setChildMask(childMask);
}
diff --git a/src/classes/share/javax/media/j3d/TexCoordGeneration.java b/src/classes/share/javax/media/j3d/TexCoordGeneration.java
index 2915a27..f19c34c 100644
--- a/src/classes/share/javax/media/j3d/TexCoordGeneration.java
+++ b/src/classes/share/javax/media/j3d/TexCoordGeneration.java
@@ -230,6 +230,14 @@ public class TexCoordGeneration extends NodeComponent {
*/
public static final int TEXTURE_COORDINATE_4 = 2;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_ENABLE_READ,
+ ALLOW_FORMAT_READ,
+ ALLOW_MODE_READ,
+ ALLOW_PLANE_READ
+ };
+
/**
* Constructs a TexCoordGeneration object with default parameters.
* The default values are as follows:
@@ -245,6 +253,8 @@ public class TexCoordGeneration extends NodeComponent {
*/
public TexCoordGeneration() {
// Just use the defaults
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -259,7 +269,10 @@ public class TexCoordGeneration extends NodeComponent {
* @see Canvas3D#queryProperties
*/
public TexCoordGeneration(int genMode, int format) {
- ((TexCoordGenerationRetained)this.retained).initGenMode(genMode);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((TexCoordGenerationRetained)this.retained).initGenMode(genMode);
((TexCoordGenerationRetained)this.retained).initFormat(format);
}
@@ -276,7 +289,10 @@ public class TexCoordGeneration extends NodeComponent {
* @see Canvas3D#queryProperties
*/
public TexCoordGeneration(int genMode, int format, Vector4f planeS) {
- ((TexCoordGenerationRetained)this.retained).initGenMode(genMode);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((TexCoordGenerationRetained)this.retained).initGenMode(genMode);
((TexCoordGenerationRetained)this.retained).initFormat(format);
((TexCoordGenerationRetained)this.retained).initPlaneS(planeS);
}
@@ -296,7 +312,10 @@ public class TexCoordGeneration extends NodeComponent {
*/
public TexCoordGeneration(int genMode, int format, Vector4f planeS,
Vector4f planeT) {
- ((TexCoordGenerationRetained)this.retained).initGenMode(genMode);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((TexCoordGenerationRetained)this.retained).initGenMode(genMode);
((TexCoordGenerationRetained)this.retained).initFormat(format);
((TexCoordGenerationRetained)this.retained).initPlaneS(planeS);
((TexCoordGenerationRetained)this.retained).initPlaneT(planeT);
@@ -317,7 +336,10 @@ public class TexCoordGeneration extends NodeComponent {
*/
public TexCoordGeneration(int genMode, int format, Vector4f planeS,
Vector4f planeT, Vector4f planeR) {
- ((TexCoordGenerationRetained)this.retained).initGenMode(genMode);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((TexCoordGenerationRetained)this.retained).initGenMode(genMode);
((TexCoordGenerationRetained)this.retained).initFormat(format);
((TexCoordGenerationRetained)this.retained).initPlaneS(planeS);
((TexCoordGenerationRetained)this.retained).initPlaneT(planeT);
@@ -343,7 +365,10 @@ public class TexCoordGeneration extends NodeComponent {
public TexCoordGeneration(int genMode, int format, Vector4f planeS,
Vector4f planeT, Vector4f planeR,
Vector4f planeQ) {
- ((TexCoordGenerationRetained)this.retained).initGenMode(genMode);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((TexCoordGenerationRetained)this.retained).initGenMode(genMode);
((TexCoordGenerationRetained)this.retained).initFormat(format);
((TexCoordGenerationRetained)this.retained).initPlaneS(planeS);
((TexCoordGenerationRetained)this.retained).initPlaneT(planeT);
diff --git a/src/classes/share/javax/media/j3d/Text3D.java b/src/classes/share/javax/media/j3d/Text3D.java
index af9e81d..c62fee4 100644
--- a/src/classes/share/javax/media/j3d/Text3D.java
+++ b/src/classes/share/javax/media/j3d/Text3D.java
@@ -206,6 +206,17 @@ public class Text3D extends Geometry {
*/
public static final int PATH_DOWN = 3;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_FONT3D_READ,
+ ALLOW_STRING_READ,
+ ALLOW_POSITION_READ,
+ ALLOW_ALIGNMENT_READ,
+ ALLOW_PATH_READ,
+ ALLOW_CHARACTER_SPACING_READ,
+ ALLOW_BOUNDING_BOX_READ
+ };
+
/**
* Constructs a Text3D object with default parameters.
* The default values are as follows:
@@ -219,6 +230,8 @@ public class Text3D extends Geometry {
* </ul>
*/
public Text3D() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -227,6 +240,9 @@ public class Text3D extends Geometry {
* @see Font3D
*/
public Text3D(Font3D font3D) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((Text3DRetained)this.retained).setFont3D(font3D);
}
@@ -239,6 +255,9 @@ public class Text3D extends Geometry {
* @see Font3D
*/
public Text3D(Font3D font3D, String string) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((Text3DRetained)this.retained).setFont3D(font3D);
((Text3DRetained)this.retained).setString(string);
}
@@ -252,6 +271,9 @@ public class Text3D extends Geometry {
* @see Font3D
*/
public Text3D(Font3D font3D, String string, Point3f position) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((Text3DRetained)this.retained).setFont3D(font3D);
((Text3DRetained)this.retained).setString(string);
((Text3DRetained)this.retained).setPosition(position);
@@ -268,6 +290,9 @@ public class Text3D extends Geometry {
*/
public Text3D(Font3D font3D, String string, Point3f position,
int alignment, int path) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((Text3DRetained)this.retained).setFont3D(font3D);
((Text3DRetained)this.retained).setString(string);
((Text3DRetained)this.retained).setPosition(position);
diff --git a/src/classes/share/javax/media/j3d/Text3DRetained.java b/src/classes/share/javax/media/j3d/Text3DRetained.java
index f446850..23c2ae6 100644
--- a/src/classes/share/javax/media/j3d/Text3DRetained.java
+++ b/src/classes/share/javax/media/j3d/Text3DRetained.java
@@ -472,7 +472,7 @@ class Text3DRetained extends GeometryRetained {
// use its bounds and not localBounds.
// bounds is actually a reference to
// mirrorShape3D.source.localBounds.
- // TODO : Should only need to update distinct localBounds.
+ // XXXX : Should only need to update distinct localBounds.
s.getCombineBounds((BoundingBox)s.bounds);
}
@@ -838,45 +838,39 @@ class Text3DRetained extends GeometryRetained {
super.markAsLive();
}
-
- boolean intersect(PickShape pickShape, double dist[], Point3d iPnt) {
- Transform3D tempT3D = VirtualUniverse.mc.getTransform3D(null);
+ boolean intersect(PickShape pickShape, PickInfo.IntersectionInfo iInfo, int flags, Point3d iPnt) {
+ Transform3D tempT3D = new Transform3D();
GeometryArrayRetained geo = null;
int sIndex = -1;
PickShape newPS;
- double x = 0, y = 0, z = 0;
double minDist = Double.MAX_VALUE;
-
+ double distance =0.0;
+ Point3d closestIPnt = new Point3d();
+
for (int i=0; i < numChars; i++) {
geo= geometryList[i];
if (geo != null) {
tempT3D.invert(charTransforms[i]);
newPS = pickShape.transform(tempT3D);
- if (geo.intersect(newPS, dist, iPnt)) {
- if (dist == null) {
+ if (geo.intersect(newPS, iInfo, flags, iPnt)) {
+ if (flags == 0) {
return true;
}
- if (dist[0] < minDist) {
+ distance = newPS.distance(iPnt);
+ if (distance < minDist) {
sIndex = i;
- minDist = dist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minDist = distance;
+ closestIPnt.set(iPnt);
}
}
}
}
- FreeListManager.freeObject(FreeListManager.TRANSFORM3D, tempT3D);
-
if (sIndex >= 0) {
// We need to transform iPnt to the vworld to compute the actual distance.
// In this method we'll transform iPnt by its char. offset. Shape3D will
// do the localToVworld transform.
- iPnt.x = x;
- iPnt.y = y;
- iPnt.z = z;
- dist[0] = minDist;
+ iPnt.set(closestIPnt);
charTransforms[sIndex].transform(iPnt);
return true;
}
diff --git a/src/classes/share/javax/media/j3d/Texture.java b/src/classes/share/javax/media/j3d/Texture.java
index 4eaae1e..7e28ef8 100644
--- a/src/classes/share/javax/media/j3d/Texture.java
+++ b/src/classes/share/javax/media/j3d/Texture.java
@@ -534,6 +534,22 @@ public abstract class Texture extends NodeComponent {
*/
public static final int ANISOTROPIC_SINGLE_VALUE = 1;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_ANISOTROPIC_FILTER_READ,
+ ALLOW_BOUNDARY_COLOR_READ,
+ ALLOW_BOUNDARY_MODE_READ,
+ ALLOW_ENABLE_READ,
+ ALLOW_FILTER4_READ,
+ ALLOW_FILTER_READ,
+ ALLOW_FORMAT_READ,
+ ALLOW_IMAGE_READ,
+ ALLOW_LOD_RANGE_READ,
+ ALLOW_MIPMAP_MODE_READ,
+ ALLOW_SHARPEN_TEXTURE_READ,
+ ALLOW_SIZE_READ
+ };
+
/**
* Constructs a Texture object with default parameters.
* The default values are as follows:
@@ -566,6 +582,8 @@ public abstract class Texture extends NodeComponent {
*/
public Texture() {
// Just use default values
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -600,6 +618,9 @@ public abstract class Texture extends NodeComponent {
(format != RGB) && (format != RGBA)) {
throw new IllegalArgumentException(J3dI18N.getString("Texture1"));
}
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
int widPower = getPowerOf2(width);
if (widPower == -1)
@@ -654,6 +675,9 @@ public abstract class Texture extends NodeComponent {
throw new IllegalArgumentException(J3dI18N.getString("Texture1"));
}
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
int widPower = getPowerOf2(width);
if (widPower == -1)
throw new IllegalArgumentException(J3dI18N.getString("Texture2"));
@@ -1722,7 +1746,8 @@ public abstract class Texture extends NodeComponent {
rt.initImage(i, image);
}
}
- // TODO: clone new v1.2 attributes
+ // XXXX: clone new v1.2 attributes?
+ // NOTE: This sppears to have already been done
}
/**
diff --git a/src/classes/share/javax/media/j3d/Texture2D.java b/src/classes/share/javax/media/j3d/Texture2D.java
index 5fa7be7..dc5be50 100644
--- a/src/classes/share/javax/media/j3d/Texture2D.java
+++ b/src/classes/share/javax/media/j3d/Texture2D.java
@@ -131,7 +131,10 @@ public class Texture2D extends Texture {
*/
public static final int DETAIL_MODULATE = 1;
-
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_DETAIL_TEXTURE_READ
+ };
/**
* Constructs a texture object using default values.
@@ -149,6 +152,9 @@ public class Texture2D extends Texture {
*/
public Texture2D() {
super();
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
}
/**
@@ -173,6 +179,9 @@ public class Texture2D extends Texture {
int height){
super(mipMapMode, format, width, height);
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
@@ -209,6 +218,9 @@ public class Texture2D extends Texture {
int boundaryWidth) {
super(mipMapMode, format, width, height, boundaryWidth);
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
diff --git a/src/classes/share/javax/media/j3d/TextureAttributes.java b/src/classes/share/javax/media/j3d/TextureAttributes.java
index d302e50..cb2f002 100644
--- a/src/classes/share/javax/media/j3d/TextureAttributes.java
+++ b/src/classes/share/javax/media/j3d/TextureAttributes.java
@@ -411,6 +411,15 @@ public class TextureAttributes extends NodeComponent {
*/
public static final int COMBINE_ONE_MINUS_SRC_ALPHA = 3;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_BLEND_COLOR_READ,
+ ALLOW_COLOR_TABLE_READ,
+ ALLOW_COMBINE_READ,
+ ALLOW_MODE_READ,
+ ALLOW_TRANSFORM_READ
+ };
+
/**
* Constructs a TextureAttributes object with default parameters.
* The default values are as follows:
@@ -441,6 +450,8 @@ public class TextureAttributes extends NodeComponent {
* </ul>
*/
public TextureAttributes() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -474,7 +485,10 @@ public class TextureAttributes extends NodeComponent {
throw new IllegalArgumentException(J3dI18N.getString("TextureAttributes9"));
}
- ((TextureAttributesRetained)this.retained).initTextureMode(textureMode);
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
+ ((TextureAttributesRetained)this.retained).initTextureMode(textureMode);
((TextureAttributesRetained)this.retained).initTextureBlendColor(textureBlendColor);
((TextureAttributesRetained)this.retained).initTextureTransform(transform);
((TextureAttributesRetained)this.retained).initPerspectiveCorrectionMode(perspCorrectionMode);
diff --git a/src/classes/share/javax/media/j3d/TextureAttributesRetained.java b/src/classes/share/javax/media/j3d/TextureAttributesRetained.java
index c77e743..d4b0993 100644
--- a/src/classes/share/javax/media/j3d/TextureAttributesRetained.java
+++ b/src/classes/share/javax/media/j3d/TextureAttributesRetained.java
@@ -525,9 +525,11 @@ class TextureAttributesRetained extends NodeComponentRetained {
int[] combineRgbFcn, int[] combineAlphaFcn,
int combineRgbScale, int combineAlphaScale);
- native void restoreBlend1Pass(long ctx);
- native void updateBlend2Pass(long ctx);
-
+ // NOTE: the following native methods are not used any more, since
+ // we no longer do simulated multi-pass by default
+ // (and with shaders, this won't work anyway)
+// native void restoreBlend1Pass(long ctx);
+// native void updateBlend2Pass(long ctx);
void updateNative(Canvas3D cv, boolean simulate, int textureFormat) {
@@ -653,31 +655,31 @@ class TextureAttributesRetained extends NodeComponentRetained {
case TextureAttributes.COMBINE:
case TextureAttributes.REPLACE:
cv.setBlendFunc(cv.ctx,
- TransparencyAttributesRetained.BLEND_ONE,
- TransparencyAttributesRetained.BLEND_ZERO);
+ TransparencyAttributes.BLEND_ONE,
+ TransparencyAttributes.BLEND_ZERO);
break;
case TextureAttributes.MODULATE:
cv.setBlendFunc(cv.ctx,
- TransparencyAttributesRetained.BLEND_DST_COLOR,
- TransparencyAttributesRetained.BLEND_ZERO);
+ TransparencyAttributes.BLEND_DST_COLOR,
+ TransparencyAttributes.BLEND_ZERO);
break;
case TextureAttributes.DECAL:
if (textureFormat == Texture.RGBA) {
cv.setBlendFunc(cv.ctx,
- TransparencyAttributesRetained.BLEND_SRC_ALPHA,
- TransparencyAttributesRetained.BLEND_ONE_MINUS_SRC_ALPHA);
+ TransparencyAttributes.BLEND_SRC_ALPHA,
+ TransparencyAttributes.BLEND_ONE_MINUS_SRC_ALPHA);
} else {
cv.setBlendFunc(cv.ctx,
- TransparencyAttributesRetained.BLEND_ONE,
- TransparencyAttributesRetained.BLEND_ZERO);
+ TransparencyAttributes.BLEND_ONE,
+ TransparencyAttributes.BLEND_ZERO);
}
break;
case TextureAttributes.BLEND:
cv.setBlendColor(cv.ctx, textureBlendColor.x, textureBlendColor.y,
textureBlendColor.z, textureBlendColor.w);
cv.setBlendFunc(cv.ctx,
- TransparencyAttributesRetained.BLEND_CONSTANT_COLOR,
- TransparencyAttributesRetained.BLEND_ONE_MINUS_SRC_COLOR);
+ TransparencyAttributes.BLEND_CONSTANT_COLOR,
+ TransparencyAttributes.BLEND_ONE_MINUS_SRC_COLOR);
break;
}
}
diff --git a/src/classes/share/javax/media/j3d/TextureBin.java b/src/classes/share/javax/media/j3d/TextureBin.java
index 7145adf..3e1c91f 100644
--- a/src/classes/share/javax/media/j3d/TextureBin.java
+++ b/src/classes/share/javax/media/j3d/TextureBin.java
@@ -27,10 +27,10 @@ class TextureBin extends Object implements ObjectUpdate {
TextureUnitStateRetained [] texUnitState = null;
// last active texture unit
- int lastActiveTexUnitIndex;
+ private int lastActiveTexUnitIndex;
// number of active texture unit
- int numActiveTexUnit;
+ private int numActiveTexUnit;
/**
* The RenderBin for this object
@@ -38,11 +38,21 @@ class TextureBin extends Object implements ObjectUpdate {
RenderBin renderBin = null;
/**
- * The AttribureBin that this TextureBin resides
+ * The EnvironmentSet that this TextureBin resides
+ */
+ EnvironmentSet environmentSet = null;
+
+ /**
+ * The AttributeBin that this TextureBin resides
*/
AttributeBin attributeBin = null;
/**
+ * The ShaderBin that this TextureBin resides
+ */
+ ShaderBin shaderBin = null;
+
+ /**
* The references to the next and previous TextureBins in the
* list.
*/
@@ -172,7 +182,6 @@ class TextureBin extends Object implements ObjectUpdate {
int i, j;
boolean foundDisableUnit = false;
numActiveTexUnit = 0;
- boolean d3dBlendMode = false;
lastActiveTexUnitIndex = 0;
boolean soleUser = ((tbFlag & TextureBin.SOLE_USER) != 0);
TextureRetained prevFirstTexture = null;
@@ -321,11 +330,13 @@ class TextureBin extends Object implements ObjectUpdate {
}
- // track the last active texture unit
- // and the total number of active texture unit
+ // Track the last active texture unit and the total number
+ // of active texture units. Note that this total number
+ // now includes disabled units so that there is always
+ // a one-to-one mapping. We no longer remap texture units.
if (texUnitState[i].isTextureEnabled()) {
- numActiveTexUnit++;
lastActiveTexUnitIndex = i;
+ numActiveTexUnit = i + 1;
if (foundDisableUnit) {
@@ -337,7 +348,7 @@ class TextureBin extends Object implements ObjectUpdate {
foundDisableUnit = true;
}
}
- }
+ }
// check to see if the TextureBin sorting criteria is
// modified for this textureBin; if yes, mark that
@@ -698,12 +709,14 @@ class TextureBin extends Object implements ObjectUpdate {
tbFlag |= TextureBin.CONTIGUOUS_ACTIVE_UNITS;
for (int i = 0; i < texUnitState.length; i++) {
- // track the last active texture unit
- // and the total number of active texture unit
+ // Track the last active texture unit and the total number
+ // of active texture units. Note that this total number
+ // now includes disabled units so that there is always
+ // a one-to-one mapping. We no longer remap texture units.
if (texUnitState[i] != null &&
texUnitState[i].isTextureEnabled()) {
- numActiveTexUnit++;
lastActiveTexUnitIndex = i;
+ numActiveTexUnit = i + 1;
if (foundDisableUnit) {
@@ -754,7 +767,7 @@ class TextureBin extends Object implements ObjectUpdate {
// sorted transparency
if (transparentRMList == null &&
(renderBin.transpSortMode == View.TRANSPARENCY_SORT_NONE ||
- attributeBin.environmentSet.lightBin.geometryBackground != null)) {
+ environmentSet.lightBin.geometryBackground != null)) {
// System.out.println("========> addTransparentTextureBin "+this);
transparentRMList = addAll(transparentRenderMoleculeMap,
addTransparentRMs, transparentRMList, false);
@@ -895,7 +908,7 @@ class TextureBin extends Object implements ObjectUpdate {
}
- // TODO: Could the analysis be done during insertRenderMolecule?
+ // XXXX: Could the analysis be done during insertRenderMolecule?
// Return the head of the list,
// if the insertion occurred at beginning of the list
RenderMolecule insertRenderMolecule(RenderMolecule r,
@@ -1046,7 +1059,7 @@ class TextureBin extends Object implements ObjectUpdate {
}
// If the renderMolecule removed is not opaque then ..
if (!r.isOpaqueOrInOG && transparentRMList == null && (renderBin.transpSortMode == View.TRANSPARENCY_SORT_NONE ||
- attributeBin.environmentSet.lightBin.geometryBackground != null)) {
+ environmentSet.lightBin.geometryBackground != null)) {
renderBin.removeTransparentObject(this);
}
// If the rm removed is the one that is referenced in the tinfo
@@ -1065,12 +1078,11 @@ class TextureBin extends Object implements ObjectUpdate {
renderBin.removeTextureBin(this);
}
- attributeBin.removeTextureBin(this);
+ shaderBin.removeTextureBin(this);
texUnitState = null;
}
}
-
/**
* This method is called to update the state for this
* TextureBin. This is only applicable in the single-pass case.
@@ -1078,28 +1090,48 @@ class TextureBin extends Object implements ObjectUpdate {
* state update.
*/
void updateAttributes(Canvas3D cv, int pass) {
-
+
boolean dirty = ((cv.canvasDirty & (Canvas3D.TEXTUREBIN_DIRTY|
Canvas3D.TEXTUREATTRIBUTES_DIRTY)) != 0);
-
if (cv.textureBin == this && !dirty) {
return;
}
cv.textureBin = this;
-
+
// save the current number of active texture unit so as
// to be able to reset the one that is not enabled in this bin
int lastActiveTexUnitIdx = -1;
- // set the number active texture unit in Canvas3D
- cv.setNumActiveTexUnit(numActiveTexUnit);
+ // Get the number of available texture units; this depends on
+ // whether or not shaders are being used.
+ boolean useShaders = (shaderBin.shaderProgram != null);
+ int availableTextureUnits =
+ useShaders ? cv.maxTextureImageUnits : cv.maxTextureUnits;
+
+ // If the number of active texture units is greater than the number of
+ // supported units, and we don't allow simulated multi-texture, then we
+ // need to set a flag indicating that the texture units are invalid.
+ boolean disableTexture = false;
+
+ if (pass < 0 && numActiveTexUnit > availableTextureUnits) {
+ disableTexture = true;
+// System.err.println("*** TextureBin : number of texture units exceeded");
+ }
+
+ // set the number active texture unit in Canvas3D
+ if (disableTexture) {
+ cv.setNumActiveTexUnit(0);
+ }
+ else {
+ cv.setNumActiveTexUnit(numActiveTexUnit);
+ }
// state update
- if (numActiveTexUnit <= 0) {
- if (cv.getLastActiveTexUnit() >= 0) {
+ if (numActiveTexUnit <= 0 || disableTexture) {
+ if (cv.getLastActiveTexUnit() >= 0) {
// no texture units enabled
// when the canvas supports multi texture units,
@@ -1117,20 +1149,8 @@ class TextureBin extends Object implements ObjectUpdate {
cv.setLastActiveTexUnit(-1);
}
} else if (pass < 0) {
- int j = 0;
- boolean oneToOneMapping;
-
- if ((pass == USE_VERTEXARRAY) || VirtualUniverse.mc.isD3D()) {
- // d3d or when the texUnitStateMap requires more texture
- // units than what is supported by the canvas, then
- // we'll need a compact texture unit mapping, that is,
- // only the enabled texUnitStates will be mapped to
- // texture units. And as a matter of fact, the
- // render atoms will be rendered as vertex array.
- oneToOneMapping = false;
- } else {
- oneToOneMapping = true;
- }
+
+ int j = 0;
for (int i = 0; i < texUnitState.length; i++) {
@@ -1156,24 +1176,13 @@ class TextureBin extends Object implements ObjectUpdate {
// unit to a texture unit state
lastActiveTexUnitIdx = j;
- cv.setTexUnitStateMap(i, j++);
-
-
- } else if (oneToOneMapping) {
- // one to one mapping is needed when display list
- // is used to render multi-textured geometries,
- // since when display list is created, the texture
- // unit state to texture unit mapping is based on
- // the geometry texCoordMap only. At render time,
- // the texture unit state enable flags could have
- // been changed. In keeping a one to one mapping,
- // we'll not need to rebuild the display list
+ } else {
if (j <= cv.getLastActiveTexUnit()) {
cv.resetTexture(cv.ctx, j);
}
-
- cv.setTexUnitStateMap(i, j++);
}
+
+ j++;
}
// make sure to disable the remaining texture units
@@ -1196,7 +1205,7 @@ class TextureBin extends Object implements ObjectUpdate {
cv.activeTextureUnit(cv.ctx, 0);
} else {
- // update the last active texture unit state
+ // update the last active texture unit state
if (dirty || cv.texUnitState[0].mirror == null ||
cv.texUnitState[0].mirror !=
texUnitState[lastActiveTexUnitIndex].mirror) {
@@ -1205,7 +1214,6 @@ class TextureBin extends Object implements ObjectUpdate {
cv.texUnitState[0].mirror =
texUnitState[lastActiveTexUnitIndex].mirror;
- cv.setTexUnitStateMap(0, 0);
cv.setLastActiveTexUnit(0);
}
}
@@ -1222,46 +1230,43 @@ class TextureBin extends Object implements ObjectUpdate {
void render(Canvas3D cv, Object rlist) {
- boolean d3dBlendMode = false;
cv.texLinearMode = false;
/*
System.out.println("TextureBin/render " + this +
" numActiveTexUnit= " + numActiveTexUnit +
- " numTexUnitSupported= " + cv.numTexUnitSupported);
+ " maxTextureUnits= " + cv.maxTextureUnits);
*/
// include this TextureBin to the to-be-updated state set in canvas
cv.setStateToUpdate(Canvas3D.TEXTUREBIN_BIT, this);
-
- if ((texUnitState != null) &&
- VirtualUniverse.mc.isD3D()) {
+
+ // For D3D - set the texLinearMode flag in the canvas if texcoord
+ // generation is enabled in object_linear mode for any texture unit.
+ if ((texUnitState != null) && VirtualUniverse.mc.isD3D()) {
TextureUnitStateRetained tus;
- // use multi-pass if one of the stage use blend mode
for (int i = 0; i < texUnitState.length; i++) {
tus = texUnitState[i];
- if ((tus != null) &&
- tus.isTextureEnabled()) {
- if (tus.needBlend2Pass(cv)) {
- d3dBlendMode = true;
- }
+ if ((tus != null) && tus.isTextureEnabled()) {
if ((tus.texGen != null) &&
- (tus.texGen.genMode ==
- TexCoordGeneration.OBJECT_LINEAR)) {
+ (tus.texGen.genMode == TexCoordGeneration.OBJECT_LINEAR)) {
cv.texLinearMode = true;
}
}
}
- }
+ }
+
+ // If shaders are not being used, and if allowSimulatedMultiTexture
+ // property is set, then we will use simulated (multi-pass)
+ // multi-texture when the requested number of texture units exceeds
+ // the available number of texture units
+ boolean useShaders = (shaderBin.shaderProgram != null);
+ int availableTextureUnits =
+ useShaders ? cv.maxTextureImageUnits : cv.maxTextureUnits;
- if ((numActiveTexUnit > cv.numTexUnitSupported) ||
- d3dBlendMode) {
+ if (!useShaders && (numActiveTexUnit > availableTextureUnits) &&
+ VirtualUniverse.mc.allowSimulatedMultiTexture) {
multiPassRender(cv, rlist);
- } else if ((numActiveTexUnit > 0) &&
- !VirtualUniverse.mc.isD3D() &&
- (texUnitState.length > cv.numTexUnitSupported) &&
- ((tbFlag & TextureBin.CONTIGUOUS_ACTIVE_UNITS) == 0)) {
- renderList(cv, USE_VERTEXARRAY, rlist);
} else {
renderList(cv, USE_DISPLAYLIST, rlist);
}
@@ -1286,7 +1291,7 @@ class TextureBin extends Object implements ObjectUpdate {
*/
void renderList(Canvas3D cv, int pass, RenderMolecule rlist) {
- // bit mask of all attr fields that are equivalent across
+ // bit mask of all attr fields that are equivalent across
// renderMolecules thro. ORing of invisible RMs.
int combinedDirtyBits = 0;
boolean rmVisible = true;
@@ -1330,9 +1335,11 @@ class TextureBin extends Object implements ObjectUpdate {
/**
* multi rendering pass to simulate multiple texture units
*/
- void multiPassRender(Canvas3D cv, Object rlist) {
+ private void multiPassRender(Canvas3D cv, Object rlist) {
+
+ assert VirtualUniverse.mc.allowSimulatedMultiTexture;
- boolean startToSimulate = false;
+ boolean startToSimulate = false;
boolean isFogEnabled = false;
// No lazy download of texture for multi-pass,
@@ -1366,7 +1373,7 @@ class TextureBin extends Object implements ObjectUpdate {
// first check if there is fog in the path
// if there is, then turn off fog now and turn it back on
// for the last pass only
- isFogEnabled = (attributeBin.environmentSet.fog != null);
+ isFogEnabled = (environmentSet.fog != null);
TextureUnitStateRetained tus;
@@ -1388,31 +1395,12 @@ class TextureBin extends Object implements ObjectUpdate {
}
}
- if (!tus.needBlend2Pass(cv)) {
- // turn on fog again in the last pass
+ // turn on fog again in the last pass
- if (i == lastActiveTexUnitIndex && isFogEnabled) {
- cv.setFogEnableFlag(cv.ctx, true);
- }
- renderList(cv, i, rlist);
-
- } else {
- // D3d needs two passes to simulate Texture.Blend mode
- tus.texAttrs.updateNative(cv, false, tus.texture.format);
- renderList(cv, i, rlist);
-
- tus.texAttrs.updateBlend2Pass(cv.ctx);
-
- // turn on fog again in the last pass
-
- if (i == lastActiveTexUnitIndex && isFogEnabled) {
- cv.setFogEnableFlag(cv.ctx, true);
- }
- renderList(cv, i, rlist);
-
- // restore original blend mode in case
- tus.texAttrs.restoreBlend1Pass(cv.ctx);
- }
+ if (i == lastActiveTexUnitIndex && isFogEnabled) {
+ cv.setFogEnableFlag(cv.ctx, true);
+ }
+ renderList(cv, i, rlist);
}
}
@@ -1465,16 +1453,22 @@ class TextureBin extends Object implements ObjectUpdate {
transparentRMList = head;
if (transparentRMList == null &&
(renderBin.transpSortMode == View.TRANSPARENCY_SORT_NONE ||
- attributeBin.environmentSet.lightBin.geometryBackground != null)) {
+ environmentSet.lightBin.geometryBackground != null)) {
renderBin.removeTransparentObject(this);
}
+ // Issue 129: remove the RM's render atoms from the
+ // list of transparent render atoms
+ if ((renderBin.transpSortMode == View.TRANSPARENCY_SORT_GEOMETRY) &&
+ (environmentSet.lightBin.geometryBackground == null)) {
+ r.addRemoveTransparentObject(renderBin, false);
+ }
}
}
HashMap renderMoleculeMap;
RenderMolecule startList;
// Now insert in the other bin
- r.evalAlphaUsage(attributeBin.definingRenderingAttributes, texUnitState);
+ r.evalAlphaUsage(shaderBin.attributeBin.definingRenderingAttributes, texUnitState);
r.isOpaqueOrInOG = r.isOpaque() ||r.inOrderedGroup;
if (r.isOpaqueOrInOG) {
startList = opaqueRMList;
@@ -1565,14 +1559,20 @@ class TextureBin extends Object implements ObjectUpdate {
// If transparent and not in bg geometry and inodepth sorted transparency
if (transparentRMList == null&&
(renderBin.transpSortMode == View.TRANSPARENCY_SORT_NONE ||
- attributeBin.environmentSet.lightBin.geometryBackground != null)) {
+ environmentSet.lightBin.geometryBackground != null)) {
transparentRMList = startList;
renderBin.addTransparentObject(this);
}
else {
transparentRMList = startList;
}
-
+ // Issue 129: add the RM's render atoms to the list of
+ // transparent render atoms
+ // XXXX: do we need to resort the list after the add???
+ if ((renderBin.transpSortMode == View.TRANSPARENCY_SORT_GEOMETRY) &&
+ (environmentSet.lightBin.geometryBackground == null)) {
+ r.addRemoveTransparentObject(renderBin, true);
+ }
}
}
@@ -1659,10 +1659,10 @@ class TextureBin extends Object implements ObjectUpdate {
if (numEditingRenderMolecules == 0) {
// if number of editing renderMolecules goes to 0,
- // inform the attributeBin that this textureBin goes to
+ // inform the shaderBin that this textureBin goes to
// zombie state
- attributeBin.decrActiveTextureBin();
+ shaderBin.decrActiveTextureBin();
}
}
@@ -1671,9 +1671,9 @@ class TextureBin extends Object implements ObjectUpdate {
if (numEditingRenderMolecules == 0) {
// if this textureBin is in zombie state, inform
- // the attributeBin that this textureBin is activated again.
+ // the shaderBin that this textureBin is activated again.
- attributeBin.incrActiveTextureBin();
+ shaderBin.incrActiveTextureBin();
}
numEditingRenderMolecules++;
diff --git a/src/classes/share/javax/media/j3d/TextureRetained.java b/src/classes/share/javax/media/j3d/TextureRetained.java
index 190c43b..545ad3a 100644
--- a/src/classes/share/javax/media/j3d/TextureRetained.java
+++ b/src/classes/share/javax/media/j3d/TextureRetained.java
@@ -12,9 +12,9 @@
package javax.media.j3d;
+import java.awt.image.BufferedImage;
import java.util.*;
import javax.vecmath.*;
-import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
/**
@@ -949,7 +949,7 @@ abstract class TextureRetained extends NodeComponentRetained {
super.doSetLive(backgroundGroup, refCount);
- // TODO: for now, do setLive for all the defined images.
+ // XXXX: for now, do setLive for all the defined images.
// But in theory, we only need to setLive those within the
// baseLevel and maximumLevel range. But then we'll need
// setLive and clearLive image when the range changes.
@@ -1366,8 +1366,9 @@ abstract class TextureRetained extends NodeComponentRetained {
yoffset = image.height - yoffset - height;
} else {
+ // Fix issue 132
imageData = ((DataBufferByte)
- image.bImage[0].getData().getDataBuffer()).getData();
+ ((BufferedImage)image.bImage[0]).getRaster().getDataBuffer()).getData();
// based on the yUp flag in the associated ImageComponent,
// adjust the yoffset
@@ -2031,12 +2032,12 @@ abstract class TextureRetained extends NodeComponentRetained {
if (arg == null) {
// no subimage info, so the entire image is to be updated
info.entireImage = true;
-
- } else if ((arg.width >= width/2) && (arg.height >= height/2)) {
-
- // if the subimage dimension is close to the complete dimension,
- // use the full update (it's more efficient)
- info.entireImage = true;
+ // Fix issue 117 using ogl subimage always
+// } else if ((arg.width >= width/2) && (arg.height >= height/2)) {
+//
+// // if the subimage dimension is close to the complete dimension,
+// // use the full update (it's more efficient)
+// info.entireImage = true;
} else {
info.entireImage = false;
}
@@ -2137,30 +2138,30 @@ abstract class TextureRetained extends NodeComponentRetained {
mirrorTexture.addImageUpdateInfo(level, face, null);
} else if ((component & IMAGES_CHANGED) != 0) {
-
+
Object [] arg = (Object []) value;
ImageComponent [] images = (ImageComponent[])arg[0];
- int face = ((Integer)arg[1]).intValue();
-
+ int face = ((Integer)arg[1]).intValue();
+
for (int i = 0; i < images.length; i++) {
-
+
// first remove texture from the userList of the current
- // referencing image
- if (mirrorTexture.images[face][i] != null) {
- mirrorTexture.images[face][i].removeUser(mirror);
- }
-
- // assign the new image and add texture to the userList
- if (images[i] == null) {
- mirrorTexture.images[face][i] = null;
- } else {
- mirrorTexture.images[face][i] =
- (ImageComponentRetained)images[i].retained;
- mirrorTexture.images[face][i].addUser(mirror);
- }
+ // referencing image
+ if (mirrorTexture.images[face][i] != null) {
+ mirrorTexture.images[face][i].removeUser(mirror);
+ }
+
+ // assign the new image and add texture to the userList
+ if (images[i] == null) {
+ mirrorTexture.images[face][i] = null;
+ } else {
+ mirrorTexture.images[face][i] =
+ (ImageComponentRetained)images[i].retained;
+ mirrorTexture.images[face][i].addUser(mirror);
+ }
}
mirrorTexture.updateResourceCreationMask();
-
+
// NOTE: the old images have to be removed from the
// renderBins' NodeComponentList and new image have to be
// added to the lists. This will be taken care of
@@ -2169,7 +2170,7 @@ abstract class TextureRetained extends NodeComponentRetained {
} else if ((component & BASE_LEVEL_CHANGED) != 0) {
int level = ((Integer)value).intValue();
-
+
if (level < mirrorTexture.baseLevel) {
// add texture to the userList of those new levels of
diff --git a/src/classes/share/javax/media/j3d/TextureUnitState.java b/src/classes/share/javax/media/j3d/TextureUnitState.java
index 635a499..fa9949c 100644
--- a/src/classes/share/javax/media/j3d/TextureUnitState.java
+++ b/src/classes/share/javax/media/j3d/TextureUnitState.java
@@ -66,7 +66,11 @@ public class TextureUnitState extends NodeComponent {
public static final int ALLOW_STATE_WRITE =
CapabilityBits.TEXTURE_UNIT_STATE_ALLOW_STATE_WRITE;
-
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_STATE_READ
+ };
+
/**
* Constructs a TextureUnitState component object using defaults for all
* state variables. All component object references are initialized
@@ -74,6 +78,8 @@ public class TextureUnitState extends NodeComponent {
*/
public TextureUnitState() {
// Just use default values
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -90,6 +96,8 @@ public class TextureUnitState extends NodeComponent {
public TextureUnitState(Texture texture,
TextureAttributes textureAttributes,
TexCoordGeneration texCoordGeneration) {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
((TextureUnitStateRetained)this.retained).initTexture(texture);
((TextureUnitStateRetained)this.retained).initTextureAttributes(
diff --git a/src/classes/share/javax/media/j3d/TextureUnitStateRetained.java b/src/classes/share/javax/media/j3d/TextureUnitStateRetained.java
index 86dce99..266ef12 100644
--- a/src/classes/share/javax/media/j3d/TextureUnitStateRetained.java
+++ b/src/classes/share/javax/media/j3d/TextureUnitStateRetained.java
@@ -592,17 +592,6 @@ class TextureUnitStateRetained extends NodeComponentRetained {
return (texture != null && texture.enable);
}
- // use by D3D to simulate OGL blend mode using multi-pass
- final boolean needBlend2Pass(Canvas3D cv) {
- return ((texAttrs != null) &&
- VirtualUniverse.mc.isD3D() &&
- ((cv.textureExtendedFeatures &
- Canvas3D.TEXTURE_LERP) == 0) &&
- (texAttrs.textureMode == TextureAttributes.BLEND) &&
- (texture.format != Texture.ALPHA) &&
- (texture.format != Texture.INTENSITY));
- }
-
void handleFrequencyChange(int bit) {
switch (bit) {
case TextureUnitState.ALLOW_STATE_WRITE: {
diff --git a/src/classes/share/javax/media/j3d/TimerThread.java b/src/classes/share/javax/media/j3d/TimerThread.java
index ae34fc6..a5f8878 100644
--- a/src/classes/share/javax/media/j3d/TimerThread.java
+++ b/src/classes/share/javax/media/j3d/TimerThread.java
@@ -33,7 +33,7 @@ class TimerThread extends Thread {
// Wakeup {all?} Sound Scheduler{s} for every sample time reach
// QUESTION: this sampling time is set to a very large value so Sound
// Schedulers are not pinged often unless explicitly requested
- // TODO: need a way to remove/null this condition when all
+ // XXXX: need a way to remove/null this condition when all
// soundschedulers are halted
private WakeupOnElapsedTime soundSchedCond =
new WakeupOnElapsedTime(120000); // every 2 minutes
@@ -61,7 +61,7 @@ class TimerThread extends Thread {
}
void addSoundSchedCond(long wakeupTime) {
- // TODO: there are potentially multiple sound schedulers.
+ // XXXX: there are potentially multiple sound schedulers.
// this code will force a wait up on ALL sound schedulers
// even though only one needs to process the sound that
// this wakeup condition is triggered by.
diff --git a/src/classes/share/javax/media/j3d/Transform3D.java b/src/classes/share/javax/media/j3d/Transform3D.java
index 69e5c62..99920d4 100644
--- a/src/classes/share/javax/media/j3d/Transform3D.java
+++ b/src/classes/share/javax/media/j3d/Transform3D.java
@@ -4588,7 +4588,7 @@ public class Transform3D {
double[] svdScales = new double[3];
- // TODO: initialize to 0's if alread allocd? Should not have to, since
+ // XXXX: initialize to 0's if alread allocd? Should not have to, since
// no operations depend on these being init'd to zero.
int converged, negCnt=0;
@@ -4833,7 +4833,7 @@ public class Transform3D {
}
}
- // TODO: could eliminate use of t1 and t1 by making a new method which
+ // XXXX: could eliminate use of t1 and t1 by making a new method which
// transposes and multiplies two matricies
transpose_mat(u1, t1);
transpose_mat(v1, t2);
diff --git a/src/classes/share/javax/media/j3d/TransformGroup.java b/src/classes/share/javax/media/j3d/TransformGroup.java
index 5aae8d2..a4b3f19 100644
--- a/src/classes/share/javax/media/j3d/TransformGroup.java
+++ b/src/classes/share/javax/media/j3d/TransformGroup.java
@@ -61,11 +61,18 @@ public class TransformGroup extends Group {
public static final int
ALLOW_TRANSFORM_WRITE = CapabilityBits.TRANSFORM_GROUP_ALLOW_TRANSFORM_WRITE;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_TRANSFORM_READ
+ };
+
/**
* Constructs and initializes a TransformGroup using an
* identity transform.
*/
public TransformGroup() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -74,11 +81,14 @@ public class TransformGroup extends Group {
* @param t1 the transform3D object
* @exception BadTransformException if the transform is not affine.
*/
- public TransformGroup(Transform3D t1) {
+ public TransformGroup(Transform3D t1) {
if (!t1.isAffine()) {
throw new BadTransformException(J3dI18N.getString("TransformGroup0"));
}
-
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
+
((TransformGroupRetained)this.retained).setTransform(t1);
}
diff --git a/src/classes/share/javax/media/j3d/TransformGroupData.java b/src/classes/share/javax/media/j3d/TransformGroupData.java
index e41a086..e14d3c3 100644
--- a/src/classes/share/javax/media/j3d/TransformGroupData.java
+++ b/src/classes/share/javax/media/j3d/TransformGroupData.java
@@ -14,8 +14,8 @@ package javax.media.j3d;
class TransformGroupData extends NodeData {
// per path node data
- // TODO: replace per path mirror objects with node data
- // TODO: move other TransfromGroup related data here
+ // XXXX: replace per path mirror objects with node data
+ // XXXX: move other TransfromGroup related data here
boolean switchDirty = false;
// use for eliminate multiple updates and generate unique targets
diff --git a/src/classes/share/javax/media/j3d/TransformGroupRetained.java b/src/classes/share/javax/media/j3d/TransformGroupRetained.java
index 734a6b3..0672359 100644
--- a/src/classes/share/javax/media/j3d/TransformGroupRetained.java
+++ b/src/classes/share/javax/media/j3d/TransformGroupRetained.java
@@ -92,7 +92,7 @@ class TransformGroupRetained extends GroupRetained implements TargetsInterface
// User copy.
CachedTargets[] cachedTargets = null;
- // Contains per path data, TODO: move to NodeRetained
+ // Contains per path data, XXXX: move to NodeRetained
TransformGroupData[] perPathData = null;
@@ -512,7 +512,7 @@ class TransformGroupRetained extends GroupRetained implements TargetsInterface
int len;
Object obj;
- // TODO - optimization for targetThreads computation, require
+ // XXXX - optimization for targetThreads computation, require
// cleanup in GroupRetained.doSetLive()
//int savedTargetThreads = 0;
//savedTargetThreads = s.transformTargetThreads;
@@ -765,7 +765,7 @@ class TransformGroupRetained extends GroupRetained implements TargetsInterface
}
}
}
- // TODO: recontruct targetThreads
+ // XXXX: recontruct targetThreads
}
@@ -1155,7 +1155,7 @@ class TransformGroupRetained extends GroupRetained implements TargetsInterface
// type is ignored here, only need for SharedGroup
if (type == TargetsInterface.TRANSFORM_TARGETS) {
- // TODO : For now we'll OR more than exact.
+ // XXXX : For now we'll OR more than exact.
//targetThreads = localTargetThreads | childTargetThreads;
targetThreads = targetThreads | childTargetThreads;
if (parentTransformLink != null) {
diff --git a/src/classes/share/javax/media/j3d/TransformStructure.java b/src/classes/share/javax/media/j3d/TransformStructure.java
index 0232f98..0edc91c 100644
--- a/src/classes/share/javax/media/j3d/TransformStructure.java
+++ b/src/classes/share/javax/media/j3d/TransformStructure.java
@@ -182,7 +182,7 @@ class TransformStructure extends J3dStructure implements ObjectUpdate {
}
processCurrentLocalToVworld();
- // TODO: temporary -- processVwcBounds will be
+ // XXXX: temporary -- processVwcBounds will be
// done in GeometryStructure
if (objectList.size() > 0) {
processGeometryAtomVwcBounds();
@@ -393,7 +393,7 @@ class TransformStructure extends J3dStructure implements ObjectUpdate {
tg = (TransformGroupRetained)dirtyTransformGroups.get(i);
// Check if the transformGroup is still alive
- // TODO: This is a hack, should be fixed after EA
+ // XXXX: This is a hack, should be fixed after EA
// Null pointer checking should be removed!
// should call trans = tg.getCurrentChildLocalToVworld(key);
synchronized(tg) {
diff --git a/src/classes/share/javax/media/j3d/TransparencyAttributes.java b/src/classes/share/javax/media/j3d/TransparencyAttributes.java
index 9e88f62..d5be231 100644
--- a/src/classes/share/javax/media/j3d/TransparencyAttributes.java
+++ b/src/classes/share/javax/media/j3d/TransparencyAttributes.java
@@ -14,18 +14,18 @@ package javax.media.j3d;
/**
* The TransparencyAttributes object defines all attributes affecting
- * transparency of the object. The transparency attributes are:<P>
- * <UL>
- * <LI>Transparency mode - defines how transparency is applied to
- * this Appearance component object:</LI><P>
- * <UL>
- * <LI>FASTEST - uses the fastest available method for transparency.</LI><P>
- * <LI>NICEST - uses the nicest available method for transparency.</LI><P>
- * <LI>SCREEN_DOOR - uses screen-door transparency. This is done using
+ * transparency of the object. The transparency attributes are:<p>
+ * <ul>
+ * <li>Transparency mode - defines how transparency is applied to
+ * this Appearance component object:</li><p>
+ * <ul>
+ * <li>FASTEST - uses the fastest available method for transparency.</li><p>
+ * <li>NICEST - uses the nicest available method for transparency.</li><p>
+ * <li>SCREEN_DOOR - uses screen-door transparency. This is done using
* an on/off stipple pattern in which the percentage of transparent pixels
* is approximately equal to the value specified by the transparency
- * parameter.</LI><P>
- * <LI>BLENDED - uses alpha blended transparency. The blend equation is
+ * parameter.</li><p>
+ * <li>BLENDED - uses alpha blended transparency. The blend equation is
* specified by the srcBlendFunction and dstBlendFunction attributes.
* The default equation is:
* <ul>
@@ -45,27 +45,36 @@ package javax.media.j3d;
* alpha<sub><font size=-1>pix</font></sub> *
* (1-transparency)</code>.
* </ul>
- * </LI><P>
- * <LI>NONE - no transparency; opaque object.</LI><P>
- * </UL>
- * <LI>Blend function - used in blended transparency and antialiasing
+ * </li><p>
+ * <li>NONE - no transparency; opaque object.</li><p>
+ * </ul>
+ * <li>Transparency value - the amount of transparency to be applied to this
+ * Appearance component object. The transparency values are in the
+ * range [0.0,&nbsp;1.0], with 0.0 being fully opaque and 1.0 being
+ * fully transparent.</li><p>
+ * <li>Blend function - used in blended transparency and antialiasing
* operations. The source function specifies the factor that is
* multiplied by the source color. This value is added to the product
* of the destination factor and the destination color. The default
* source blend function is BLEND_SRC_ALPHA. The source blend function
- * is one of the following:</LI><P>
- * <UL>
- * <LI>BLEND_ZERO - the blend function is <code>f = 0</code>.</LI>
- * <LI>BLEND_ONE - the blend function is <code>f = 1</code>.</LI>
- * <LI>BLEND_SRC_ALPHA - the blend function is <code>f =
- * alpha<sub><font size=-1>src</font></sub></code>.</LI>
- * <LI>BLEND_ONE_MINUS_SRC_ALPHA - the blend function is <code>f =
- * 1 - alpha<sub><font size=-1>src</font></sub></code>.</LI></UL><P>
- * <LI>Blend value - the amount of transparency to be applied to this
- * Appearance component object. The transparency values are in the
- * range [0.0, 1.0], with 0.0 being fully opaque and 1.0 being
- * fully transparent.</LI><P>
- * </UL>
+ * is one of the following:</li><p>
+ * <ul>
+ * <li>BLEND_ZERO - the blend function is <code>f = 0</code></li>
+ * <li>BLEND_ONE - the blend function is <code>f = 1</code></li>
+ * <li>BLEND_SRC_ALPHA - the blend function is <code>f =
+ * alpha<sub><font size=-1>src</font></sub></code></li>
+ * <li>BLEND_ONE_MINUS_SRC_ALPHA - the blend function is <code>f =
+ * 1 - alpha<sub><font size=-1>src</font></sub></code></li>
+ * <li>BLEND_DST_COLOR - the blend function is <code>f =
+ * color<sub><font size=-1>dst</font></sub></code></li>
+ * <li>BLEND_ONE_MINUS_DST_COLOR - the blend function is <code>f =
+ * 1 - color<sub><font size=-1>dst</font></sub></code></li>
+ * <li>BLEND_SRC_COLOR - the blend function is <code>f =
+ * color<sub><font size=-1>src</font></sub></code></li>
+ * <li>BLEND_ONE_MINUS_SRC_COLOR - the blend function is <code>f =
+ * 1 - color<sub><font size=-1>src</font></sub></code></li>
+ * </ul>
+ * </ul>
*/
public class TransparencyAttributes extends NodeComponent {
/**
@@ -173,6 +182,7 @@ public class TransparencyAttributes extends NodeComponent {
* Blend function: <code>f = 0</code>.
* @see #setSrcBlendFunction
* @see #setDstBlendFunction
+ *
* @since Java 3D 1.2
*/
public static final int BLEND_ZERO = 0;
@@ -181,6 +191,7 @@ public class TransparencyAttributes extends NodeComponent {
* Blend function: <code>f = 1</code>.
* @see #setSrcBlendFunction
* @see #setDstBlendFunction
+ *
* @since Java 3D 1.2
*/
public static final int BLEND_ONE = 1;
@@ -190,6 +201,7 @@ public class TransparencyAttributes extends NodeComponent {
* <code>f = alpha<sub><font size=-1>src</font></sub></code>.
* @see #setSrcBlendFunction
* @see #setDstBlendFunction
+ *
* @since Java 3D 1.2
*/
public static final int BLEND_SRC_ALPHA = 2;
@@ -199,12 +211,67 @@ public class TransparencyAttributes extends NodeComponent {
* <code>f = 1-alpha<sub><font size=-1>src</font></sub></code>.
* @see #setSrcBlendFunction
* @see #setDstBlendFunction
+ *
* @since Java 3D 1.2
*/
public static final int BLEND_ONE_MINUS_SRC_ALPHA = 3;
+ /**
+ * Blend function:
+ * <code>f = color<sub><font size=-1>dst</font></sub></code>.
+ * <p>Note that this function may <i>only</i> be used as a source
+ * blend function.</p>
+ * @see #setSrcBlendFunction
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int BLEND_DST_COLOR = 4;
+
+ /**
+ * Blend function:
+ * <code>f = 1-color<sub><font size=-1>dst</font></sub></code>.
+ * <p>Note that this function may <i>only</i> be used as a source
+ * blend function.</p>
+ * @see #setSrcBlendFunction
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int BLEND_ONE_MINUS_DST_COLOR = 5;
/**
+ * Blend function:
+ * <code>f = color<sub><font size=-1>src</font></sub></code>.
+ * <p>Note that this function may <i>only</i> be used as a destination
+ * blend function.</p>
+ * @see #setDstBlendFunction
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int BLEND_SRC_COLOR = 6;
+
+ /**
+ * Blend function:
+ * <code>f = 1-color<sub><font size=-1>src</font></sub></code>.
+ * <p>Note that this function may <i>only</i> be used as a destination
+ * blend function.</p>
+ * @see #setDstBlendFunction
+ *
+ * @since Java 3D 1.4
+ */
+ public static final int BLEND_ONE_MINUS_SRC_COLOR = 7;
+
+ static final int BLEND_CONSTANT_COLOR = 8;
+
+ static final int MAX_BLEND_FUNC_TABLE_SIZE = 9;
+
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_BLEND_FUNCTION_READ,
+ ALLOW_MODE_READ,
+ ALLOW_VALUE_READ
+ };
+
+ /**
* Constructs a TransparencyAttributes object with default parameters.
* The default values are as follows:
* <ul>
@@ -216,6 +283,8 @@ public class TransparencyAttributes extends NodeComponent {
*/
public TransparencyAttributes() {
// Just use the default for all attributes
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
@@ -238,20 +307,20 @@ public class TransparencyAttributes extends NodeComponent {
* @param tVal the transparency value
* @param srcBlendFunction the blend function to be used for the source
* color, one of <code>BLEND_ZERO</code>, <code>BLEND_ONE</code>,
- * <code>BLEND_SRC_ALPHA</code>, or <code>BLEND_ONE_MINUS_SRC_ALPHA</code>.
+ * <code>BLEND_SRC_ALPHA</code>, <code>BLEND_ONE_MINUS_SRC_ALPHA</code>,
+ * <code>BLEND_DST_COLOR</code>, or <code>BLEND_ONE_MINUS_DST_COLOR</code>.
* @param dstBlendFunction the blend function to be used for the
* destination
* color, one of <code>BLEND_ZERO</code>, <code>BLEND_ONE</code>,
- * <code>BLEND_SRC_ALPHA</code>, or <code>BLEND_ONE_MINUS_SRC_ALPHA</code>.
+ * <code>BLEND_SRC_ALPHA</code>, <code>BLEND_ONE_MINUS_SRC_ALPHA</code>,
+ * <code>BLEND_SRC_COLOR</code>, or <code>BLEND_ONE_MINUS_SRC_COLOR</code>.
* @exception IllegalArgumentException if
* <code>tMode</code> is a value other than
* <code>NONE</code>, <code>FASTEST</code>, <code>NICEST</code>,
* <code>SCREEN_DOOR</code>, or <code>BLENDED</code>
* @exception IllegalArgumentException if
* <code>srcBlendFunction</code> or <code>dstBlendFunction</code>
- * is a value other than <code>BLEND_ZERO</code>, <code>BLEND_ONE</code>,
- * <code>BLEND_SRC_ALPHA</code>, or
- * <code>BLEND_ONE_MINUS_SRC_ALPHA</code>.
+ * is a value other than one of the supported functions listed above.
*
* @since Java 3D 1.2
*/
@@ -263,15 +332,32 @@ public class TransparencyAttributes extends NodeComponent {
throw new IllegalArgumentException(J3dI18N.getString("TransparencyAttributes6"));
}
- if ((srcBlendFunction < BLEND_ZERO) ||
- (srcBlendFunction > BLEND_ONE_MINUS_SRC_ALPHA)) {
- throw new IllegalArgumentException(J3dI18N.getString("TransparencyAttributes7"));
- }
-
- if ((dstBlendFunction < BLEND_ZERO) ||
- (dstBlendFunction > BLEND_ONE_MINUS_SRC_ALPHA)) {
- throw new IllegalArgumentException(J3dI18N.getString("TransparencyAttributes8"));
- }
+ switch (srcBlendFunction) {
+ case BLEND_ZERO:
+ case BLEND_ONE:
+ case BLEND_SRC_ALPHA:
+ case BLEND_ONE_MINUS_SRC_ALPHA:
+ case BLEND_DST_COLOR:
+ case BLEND_ONE_MINUS_DST_COLOR:
+ break;
+ default:
+ throw new IllegalArgumentException(J3dI18N.getString("TransparencyAttributes7"));
+ }
+
+ switch (dstBlendFunction) {
+ case BLEND_ZERO:
+ case BLEND_ONE:
+ case BLEND_SRC_ALPHA:
+ case BLEND_ONE_MINUS_SRC_ALPHA:
+ case BLEND_SRC_COLOR:
+ case BLEND_ONE_MINUS_SRC_COLOR:
+ break;
+ default:
+ throw new IllegalArgumentException(J3dI18N.getString("TransparencyAttributes8"));
+ }
+
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
((TransparencyAttributesRetained)this.retained).initTransparencyMode(tMode);
((TransparencyAttributesRetained)this.retained).initTransparency(tVal);
@@ -370,15 +456,13 @@ public class TransparencyAttributes extends NodeComponent {
*
* @param blendFunction the blend function to be used for the source
* color, one of <code>BLEND_ZERO</code>, <code>BLEND_ONE</code>,
- * <code>BLEND_SRC_ALPHA</code>, or <code>BLEND_ONE_MINUS_SRC_ALPHA</code>.
+ * <code>BLEND_SRC_ALPHA</code>, <code>BLEND_ONE_MINUS_SRC_ALPHA</code>,
+ * <code>BLEND_DST_COLOR</code>, or <code>BLEND_ONE_MINUS_DST_COLOR</code>.
+ *
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
- * @exception IllegalArgumentException if
- * <code>blendFunction</code>
- * is a value other than <code>BLEND_ZERO</code>,
- * <code>BLEND_ONE</code>,
- * <code>BLEND_SRC_ALPHA</code>, or
- * <code>BLEND_ONE_MINUS_SRC_ALPHA</code>.
+ * @exception IllegalArgumentException if <code>blendFunction</code>
+ * is a value other than one of the supported functions listed above.
*
* @since Java 3D 1.2
*/
@@ -388,11 +472,17 @@ public class TransparencyAttributes extends NodeComponent {
throw new
CapabilityNotSetException(J3dI18N.getString("TransparencyAttributes4"));
- if ((blendFunction < BLEND_ZERO) ||
- (blendFunction > BLEND_ONE_MINUS_SRC_ALPHA)) {
- throw new IllegalArgumentException(J3dI18N.getString("TransparencyAttributes7"));
- }
-
+ switch (blendFunction) {
+ case BLEND_ZERO:
+ case BLEND_ONE:
+ case BLEND_SRC_ALPHA:
+ case BLEND_ONE_MINUS_SRC_ALPHA:
+ case BLEND_DST_COLOR:
+ case BLEND_ONE_MINUS_DST_COLOR:
+ break;
+ default:
+ throw new IllegalArgumentException(J3dI18N.getString("TransparencyAttributes7"));
+ }
if (isLive())
((TransparencyAttributesRetained)this.retained).setSrcBlendFunction(blendFunction);
@@ -428,15 +518,13 @@ public class TransparencyAttributes extends NodeComponent {
*
* @param blendFunction the blend function to be used for the destination
* color, one of <code>BLEND_ZERO</code>, <code>BLEND_ONE</code>,
- * <code>BLEND_SRC_ALPHA</code>, or <code>BLEND_ONE_MINUS_SRC_ALPHA</code>.
+ * <code>BLEND_SRC_ALPHA</code>, <code>BLEND_ONE_MINUS_SRC_ALPHA</code>,
+ * <code>BLEND_SRC_COLOR</code>, or <code>BLEND_ONE_MINUS_SRC_COLOR</code>.
+ *
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
- * @exception IllegalArgumentException if
- * <code>blendFunction</code>
- * is a value other than <code>BLEND_ZERO</code>,
- * <code>BLEND_ONE</code>,
- * <code>BLEND_SRC_ALPHA</code>, or
- * <code>BLEND_ONE_MINUS_SRC_ALPHA</code>.
+ * @exception IllegalArgumentException if <code>blendFunction</code>
+ * is a value other than one of the supported functions listed above.
*
* @since Java 3D 1.2
*/
@@ -445,10 +533,17 @@ public class TransparencyAttributes extends NodeComponent {
if (!this.getCapability(ALLOW_BLEND_FUNCTION_WRITE))
throw new CapabilityNotSetException(J3dI18N.getString("TransparencyAttributes4"));
- if ((blendFunction < BLEND_ZERO) ||
- (blendFunction > BLEND_ONE_MINUS_SRC_ALPHA)) {
- throw new IllegalArgumentException(J3dI18N.getString("TransparencyAttributes8"));
- }
+ switch (blendFunction) {
+ case BLEND_ZERO:
+ case BLEND_ONE:
+ case BLEND_SRC_ALPHA:
+ case BLEND_ONE_MINUS_SRC_ALPHA:
+ case BLEND_SRC_COLOR:
+ case BLEND_ONE_MINUS_SRC_COLOR:
+ break;
+ default:
+ throw new IllegalArgumentException(J3dI18N.getString("TransparencyAttributes8"));
+ }
if (isLive())
((TransparencyAttributesRetained)this.retained).setDstBlendFunction(blendFunction);
diff --git a/src/classes/share/javax/media/j3d/TransparencyAttributesRetained.java b/src/classes/share/javax/media/j3d/TransparencyAttributesRetained.java
index 0123fc2..defbb44 100644
--- a/src/classes/share/javax/media/j3d/TransparencyAttributesRetained.java
+++ b/src/classes/share/javax/media/j3d/TransparencyAttributesRetained.java
@@ -38,16 +38,6 @@ class TransparencyAttributesRetained extends NodeComponentRetained {
int srcBlendFunction = TransparencyAttributes.BLEND_SRC_ALPHA;
int dstBlendFunction = TransparencyAttributes.BLEND_ONE_MINUS_SRC_ALPHA;
- // Here are some blend functions that are used in multi-pass only
- static final int BLEND_ZERO = 0;
- static final int BLEND_ONE = 1;
- static final int BLEND_SRC_ALPHA = 2;
- static final int BLEND_ONE_MINUS_SRC_ALPHA = 3;
- static final int BLEND_DST_COLOR = 4;
- static final int BLEND_SRC_COLOR = 5;
- static final int BLEND_ONE_MINUS_SRC_COLOR = 6;
- static final int BLEND_CONSTANT_COLOR = 7;
-
/**
* Sets the transparency mode for this
* appearance component object.
diff --git a/src/classes/share/javax/media/j3d/TransparentRenderingInfo.java b/src/classes/share/javax/media/j3d/TransparentRenderingInfo.java
index bca1018..27c4e7d 100644
--- a/src/classes/share/javax/media/j3d/TransparentRenderingInfo.java
+++ b/src/classes/share/javax/media/j3d/TransparentRenderingInfo.java
@@ -11,10 +11,9 @@
*/
package javax.media.j3d;
-import javax.vecmath.*;
-import java.util.*;
-class TransparentRenderingInfo extends Object {
+
+class TransparentRenderingInfo extends Object implements com.sun.j3d.utils.scenegraph.transparency.TransparencySortGeom {
// For DepthSortedTransparency, rm is the rendermolecule
// that this rInfo is part of
// For non depth sorted transparency, rm is one of the rendermolecules
@@ -24,8 +23,9 @@ class TransparentRenderingInfo extends Object {
RenderAtomListInfo rInfo;
TransparentRenderingInfo prev;
TransparentRenderingInfo next;
+ GeometryAtom geometryAtom;
double zVal; // Used in DepthSorted Transparency
- // TODO: Add Dirty info
+ // XXXX: Add Dirty info
/**
* update state before rendering transparent objects
@@ -34,7 +34,8 @@ class TransparentRenderingInfo extends Object {
TextureBin textureBin = rm.textureBin;
AttributeBin attributeBin = textureBin.attributeBin;
-
+ ShaderBin shaderBin = textureBin.shaderBin;
+
// Get a collection to check if switch is on
RenderMolecule rm = textureBin.transparentRMList ;
@@ -57,40 +58,44 @@ class TransparentRenderingInfo extends Object {
return false;
}
- if (cv.environmentSet != attributeBin.environmentSet) {
-
- boolean visible = (attributeBin.definingRenderingAttributes == null ||
- attributeBin.definingRenderingAttributes.visible);
+ // XXXX : Code cleanup needed : The following code segment should simply test
+ // each bin independently and update it if necessary.
+ if (cv.environmentSet != attributeBin.environmentSet) {
+
+ boolean visible = (attributeBin.definingRenderingAttributes == null ||
+ attributeBin.definingRenderingAttributes.visible);
+
+ if ( (attributeBin.environmentSet.renderBin.view.viewCache.visibilityPolicy
+ == View.VISIBILITY_DRAW_VISIBLE && !visible) ||
+ (attributeBin.environmentSet.renderBin.view.viewCache.visibilityPolicy
+ == View.VISIBILITY_DRAW_INVISIBLE && visible)) {
+ return false;
+ }
+ attributeBin.environmentSet.lightBin.updateAttributes(cv);
+ attributeBin.environmentSet.updateAttributes(cv);
+ attributeBin.updateAttributes(cv);
+ shaderBin.updateTransparentAttributes(cv);
+ } else if (cv.attributeBin != attributeBin) {
+ boolean visible = (attributeBin.definingRenderingAttributes == null ||
+ attributeBin.definingRenderingAttributes.visible);
+
+ if ( (attributeBin.environmentSet.renderBin.view.viewCache.visibilityPolicy
+ == View.VISIBILITY_DRAW_VISIBLE && !visible) ||
+ (attributeBin.environmentSet.renderBin.view.viewCache.visibilityPolicy
+ == View.VISIBILITY_DRAW_INVISIBLE && visible)) {
+ return false;
+ }
+ attributeBin.updateAttributes(cv);
+ shaderBin.updateTransparentAttributes(cv);
+ } else if (cv.shaderBin != shaderBin) {
+ shaderBin.updateTransparentAttributes(cv);
+ }
- if ( (attributeBin.environmentSet.renderBin.view.viewCache.visibilityPolicy
- == View.VISIBILITY_DRAW_VISIBLE && !visible) ||
- (attributeBin.environmentSet.renderBin.view.viewCache.visibilityPolicy
- == View.VISIBILITY_DRAW_INVISIBLE && visible)) {
- return false;
- }
- attributeBin.environmentSet.lightBin.updateAttributes(cv);
- attributeBin.environmentSet.updateAttributes(cv);
- attributeBin.updateAttributes(cv);
- }
- else {
- if (cv.attributeBin != attributeBin) {
- boolean visible = (attributeBin.definingRenderingAttributes == null ||
- attributeBin.definingRenderingAttributes.visible);
-
- if ( (attributeBin.environmentSet.renderBin.view.viewCache.visibilityPolicy
- == View.VISIBILITY_DRAW_VISIBLE && !visible) ||
- (attributeBin.environmentSet.renderBin.view.viewCache.visibilityPolicy
- == View.VISIBILITY_DRAW_INVISIBLE && visible)) {
- return false;
- }
- attributeBin.updateAttributes(cv);
- }
- }
- return true;
+ return true;
}
void render(Canvas3D cv) {
- if (updateState(cv)) {
+ if (updateState(cv)) {
rm.textureBin.render(cv, rm.textureBin.transparentRMList);
}
}
@@ -101,4 +106,25 @@ class TransparentRenderingInfo extends Object {
rm.textureBin.render(cv, this);
}
}
+
+ public double getDistanceSquared() {
+ return zVal;
+ }
+
+ public Geometry getGeometry() {
+ // XXXX: verify 0 is always the correct index. Assumption is that for
+ // Shape3D with multiple geometry each geometry is put in it's
+ // own geometryAtom.
+ if (geometryAtom.geometryArray[0]==null)
+ return null;
+ return (Geometry)geometryAtom.geometryArray[0].source;
+ }
+
+ public void getLocalToVWorld(Transform3D localToVW) {
+ localToVW.set(rm.localToVworld[NodeRetained.LAST_LOCAL_TO_VWORLD]);
+ }
+
+ public Shape3D getShape3D() {
+ return (Shape3D)geometryAtom.source.source;
+ }
}
diff --git a/src/classes/share/javax/media/j3d/TriangleArray.java b/src/classes/share/javax/media/j3d/TriangleArray.java
index 32bb57b..8487007 100644
--- a/src/classes/share/javax/media/j3d/TriangleArray.java
+++ b/src/classes/share/javax/media/j3d/TriangleArray.java
@@ -24,23 +24,22 @@ public class TriangleArray extends GeometryArray {
TriangleArray() {}
/**
- * Constructs an empty TriangleArray object with the specified
- * number of vertices, and vertex format.
- * @param vertexCount the number of vertex elements in this array
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.
+ * Constructs an empty TriangleArray object using the specified
+ * parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
* @exception IllegalArgumentException if vertexCount is less than 3
* or vertexCount is <i>not</i> a multiple of 3
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int)}
+ * for more exceptions that can be thrown
*/
public TriangleArray(int vertexCount, int vertexFormat) {
super(vertexCount,vertexFormat);
@@ -50,60 +49,30 @@ public class TriangleArray extends GeometryArray {
}
/**
- * Constructs an empty TriangleArray object with the specified
- * number of vertices, and vertex format, number of texture coordinate
- * sets, and texture coordinate mapping array.
- *
- * @param vertexCount the number of vertex elements in this array<p>
- *
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.<p>
- *
- * @param texCoordSetCount the number of texture coordinate sets
- * in this GeometryArray object. If <code>vertexFormat</code>
- * does not include one of <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetCount</code> parameter is not used.<p>
- *
- * @param texCoordSetMap an array that maps texture coordinate
- * sets to texture units. The array is indexed by texture unit
- * number for each texture unit in the associated Appearance
- * object. The values in the array specify the texture coordinate
- * set within this GeometryArray object that maps to the
- * corresponding texture
- * unit. All elements within the array must be less than
- * <code>texCoordSetCount</code>. A negative value specifies that
- * no texture coordinate set maps to the texture unit
- * corresponding to the index. If there are more texture units in
- * any associated Appearance object than elements in the mapping
- * array, the extra elements are assumed to be -1. The same
- * texture coordinate set may be used for more than one texture
- * unit. Each texture unit in every associated Appearance must
- * have a valid source of texture coordinates: either a
- * non-negative texture coordinate set must be specified in the
- * mapping array or texture coordinate generation must be enabled.
- * Texture coordinate generation will take precedence for those
- * texture units for which a texture coordinate set is specified
- * and texture coordinate generation is enabled. If
- * <code>vertexFormat</code> does not include one of
- * <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetMap</code> array is not used.
+ * Constructs an empty TriangleArray object using the specified
+ * parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
*
* @exception IllegalArgumentException if vertexCount is less than 3
* or vertexCount is <i>not</i> a multiple of 3
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for more exceptions that can be thrown
*
* @since Java 3D 1.2
*/
@@ -120,6 +89,54 @@ public class TriangleArray extends GeometryArray {
}
/**
+ * Constructs an empty TriangleArray object using the specified
+ * parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrSizes
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @exception IllegalArgumentException if vertexCount is less than 3
+ * or vertexCount is <i>not</i> a multiple of 3
+ * ;<br>
+ * See {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for more exceptions that can be thrown
+ *
+ * @since Java 3D 1.4
+ */
+ public TriangleArray(int vertexCount,
+ int vertexFormat,
+ int texCoordSetCount,
+ int[] texCoordSetMap,
+ int vertexAttrCount,
+ int[] vertexAttrSizes) {
+
+ super(vertexCount, vertexFormat,
+ texCoordSetCount, texCoordSetMap,
+ vertexAttrCount, vertexAttrSizes);
+
+ if (vertexCount < 3 || ((vertexCount%3) != 0))
+ throw new IllegalArgumentException(J3dI18N.getString("TriangleArray0"));
+ }
+
+
+ /**
* Creates the retained mode TriangleArrayRetained object that this
* TriangleArray object will point to.
*/
@@ -133,22 +150,26 @@ public class TriangleArray extends GeometryArray {
* @deprecated replaced with cloneNodeComponent(boolean forceDuplicate)
*/
public NodeComponent cloneNodeComponent() {
- TriangleArrayRetained rt = (TriangleArrayRetained) retained;
- int texSetCount = rt.getTexCoordSetCount();
- TriangleArray t;
-
- if (texSetCount == 0) {
- t = new TriangleArray(rt.getVertexCount(),
- rt.getVertexFormat());
- } else {
- int texMap[] = new int[rt.getTexCoordSetMapLength()];
- rt.getTexCoordSetMap(texMap);
- t = new TriangleArray(rt.getVertexCount(),
- rt.getVertexFormat(),
- texSetCount,
- texMap);
- }
- t.duplicateNodeComponent(this);
+ TriangleArrayRetained rt = (TriangleArrayRetained) retained;
+ int texSetCount = rt.getTexCoordSetCount();
+ int[] texMap = null;
+ int vertexAttrCount = rt.getVertexAttrCount();
+ int[] vertexAttrSizes = null;
+ if (texSetCount > 0) {
+ texMap = new int[rt.getTexCoordSetMapLength()];
+ rt.getTexCoordSetMap(texMap);
+ }
+ if (vertexAttrCount > 0) {
+ vertexAttrSizes = new int[vertexAttrCount];
+ rt.getVertexAttrSizes(vertexAttrSizes);
+ }
+ TriangleArray t = new TriangleArray(rt.getVertexCount(),
+ rt.getVertexFormat(),
+ texSetCount,
+ texMap,
+ vertexAttrCount,
+ vertexAttrSizes);
+ t.duplicateNodeComponent(this);
return t;
}
}
diff --git a/src/classes/share/javax/media/j3d/TriangleArrayRetained.java b/src/classes/share/javax/media/j3d/TriangleArrayRetained.java
index 6332bad..577495f 100644
--- a/src/classes/share/javax/media/j3d/TriangleArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/TriangleArrayRetained.java
@@ -27,14 +27,15 @@ class TriangleArrayRetained extends GeometryArrayRetained {
this.geoType = GEO_TYPE_TRI_SET;
}
- boolean intersect(PickShape pickShape, double dist[], Point3d iPnt) {
+ boolean intersect(PickShape pickShape, PickInfo.IntersectionInfo iInfo, int flags, Point3d iPnt) {
Point3d pnts[] = new Point3d[3];
double sdist[] = new double[1];
double minDist = Double.MAX_VALUE;
double x = 0, y = 0, z = 0;
int i = ((vertexFormat & GeometryArray.BY_REFERENCE) == 0 ?
initialVertexIndex : initialCoordIndex);
-
+ int count = 0;
+ int minICount = 0;
pnts[0] = new Point3d();
pnts[1] = new Point3d();
pnts[2] = new Point3d();
@@ -47,12 +48,14 @@ class TriangleArrayRetained extends GeometryArrayRetained {
getVertexData(i++, pnts[0]);
getVertexData(i++, pnts[1]);
getVertexData(i++, pnts[2]);
+ count += 3;
if (intersectRay(pnts, pickRay, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
- minDist = sdist[0];
+ minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -62,22 +65,24 @@ class TriangleArrayRetained extends GeometryArrayRetained {
break;
case PickShape.PICKSEGMENT:
PickSegment pickSegment = (PickSegment) pickShape;
- while (i < validVertexCount) {
+
+ while (i < validVertexCount) {
getVertexData(i++, pnts[0]);
getVertexData(i++, pnts[1]);
getVertexData(i++, pnts[2]);
+ count += 3;
if (intersectSegment(pnts, pickSegment.start,
- pickSegment.end, sdist, iPnt)
- && (sdist[0] <= 1.0)) {
- if (dist == null) {
+ pickSegment.end, sdist, iPnt)) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
- }
+ }
}
}
break;
@@ -89,15 +94,17 @@ class TriangleArrayRetained extends GeometryArrayRetained {
getVertexData(i++, pnts[0]);
getVertexData(i++, pnts[1]);
getVertexData(i++, pnts[2]);
+ count += 3;
if (intersectBoundingBox(pnts, bbox, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
- z = iPnt.z;
+ z = iPnt.z;
}
}
}
@@ -110,12 +117,14 @@ class TriangleArrayRetained extends GeometryArrayRetained {
getVertexData(i++, pnts[0]);
getVertexData(i++, pnts[1]);
getVertexData(i++, pnts[2]);
+ count += 3;
if (intersectBoundingSphere(pnts, bsphere, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -131,13 +140,15 @@ class TriangleArrayRetained extends GeometryArrayRetained {
getVertexData(i++, pnts[0]);
getVertexData(i++, pnts[1]);
getVertexData(i++, pnts[2]);
+ count += 3;
if (intersectBoundingPolytope(pnts, bpolytope,
sdist,iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -151,13 +162,15 @@ class TriangleArrayRetained extends GeometryArrayRetained {
getVertexData(i++, pnts[0]);
getVertexData(i++, pnts[1]);
getVertexData(i++, pnts[2]);
+ count += 3;
if (intersectCylinder(pnts, pickCylinder, sdist,
iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -172,12 +185,14 @@ class TriangleArrayRetained extends GeometryArrayRetained {
getVertexData(i++, pnts[0]);
getVertexData(i++, pnts[1]);
getVertexData(i++, pnts[2]);
+ count += 3;
if (intersectCone(pnts, pickCone, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -194,7 +209,15 @@ class TriangleArrayRetained extends GeometryArrayRetained {
if (minDist < Double.MAX_VALUE) {
- dist[0] = minDist;
+ assert(minICount >=3);
+ int[] vertexIndices = iInfo.getVertexIndices();
+ if (vertexIndices == null) {
+ vertexIndices = new int[3];
+ iInfo.setVertexIndices(vertexIndices);
+ }
+ vertexIndices[0] = minICount - 3;
+ vertexIndices[1] = minICount - 2;
+ vertexIndices[2] = minICount - 1;
iPnt.x = x;
iPnt.y = y;
iPnt.z = z;
@@ -263,8 +286,7 @@ class TriangleArrayRetained extends GeometryArrayRetained {
break;
}
return false;
- }
-
+ }
boolean intersect(Transform3D thisToOtherVworld,
GeometryRetained geom) {
diff --git a/src/classes/share/javax/media/j3d/TriangleFanArray.java b/src/classes/share/javax/media/j3d/TriangleFanArray.java
index d8a9539..e536158 100644
--- a/src/classes/share/javax/media/j3d/TriangleFanArray.java
+++ b/src/classes/share/javax/media/j3d/TriangleFanArray.java
@@ -30,28 +30,26 @@ public class TriangleFanArray extends GeometryStripArray {
TriangleFanArray() {}
/**
- * Constructs an empty TriangleFanArray object with the specified
- * number of vertices, vertex format, and
- * array of per-strip vertex counts.
- * @param vertexCount the number of vertex elements in this array
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.
- * @param stripVertexCounts array that specifies
- * the count of the number of vertices for each separate strip.
- * The length of this array is the number of separate strips.
+ * Constructs an empty TriangleFanArray object using the
+ * specified parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param stripVertexCounts
+ * see {@link GeometryStripArray#GeometryStripArray(int,int,int[])}
+ * for a description of this parameter.
*
* @exception IllegalArgumentException if vertexCount is less than 3
* or any element in the stripVertexCounts array is less than 3
+ * ;<br>
+ * See {@link GeometryStripArray#GeometryStripArray(int,int,int[])}
+ * for more exceptions that can be thrown
*/
public TriangleFanArray(int vertexCount,
int vertexFormat,
@@ -64,65 +62,34 @@ public class TriangleFanArray extends GeometryStripArray {
}
/**
- * Constructs an empty TriangleFanArray object with the specified
- * number of vertices, vertex format, number of texture coordinate
- * sets, texture coordinate mapping array, and
- * array of per-strip vertex counts.
- *
- * @param vertexCount the number of vertex elements in this array<p>
- *
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.<p>
- *
- * @param texCoordSetCount the number of texture coordinate sets
- * in this GeometryArray object. If <code>vertexFormat</code>
- * does not include one of <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetCount</code> parameter is not used.<p>
- *
- * @param texCoordSetMap an array that maps texture coordinate
- * sets to texture units. The array is indexed by texture unit
- * number for each texture unit in the associated Appearance
- * object. The values in the array specify the texture coordinate
- * set within this GeometryArray object that maps to the
- * corresponding texture
- * unit. All elements within the array must be less than
- * <code>texCoordSetCount</code>. A negative value specifies that
- * no texture coordinate set maps to the texture unit
- * corresponding to the index. If there are more texture units in
- * any associated Appearance object than elements in the mapping
- * array, the extra elements are assumed to be -1. The same
- * texture coordinate set may be used for more than one texture
- * unit. Each texture unit in every associated Appearance must
- * have a valid source of texture coordinates: either a
- * non-negative texture coordinate set must be specified in the
- * mapping array or texture coordinate generation must be enabled.
- * Texture coordinate generation will take precedence for those
- * texture units for which a texture coordinate set is specified
- * and texture coordinate generation is enabled. If
- * <code>vertexFormat</code> does not include one of
- * <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetMap</code> array is not used.<p>
- *
- * @param stripVertexCounts array that specifies
- * the count of the number of vertices for each separate strip.
- * The length of this array is the number of separate strips.
+ * Constructs an empty TriangleFanArray object using the
+ * specified parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param stripVertexCounts
+ * see {@link GeometryStripArray#GeometryStripArray(int,int,int,int[],int[])}
+ * for a description of this parameter.
*
* @exception IllegalArgumentException if vertexCount is less than 3
* or any element in the stripVertexCounts array is less than 3
+ * ;<br>
+ * See {@link GeometryStripArray#GeometryStripArray(int,int,int,int[],int[])}
+ * for more exceptions that can be thrown
*
* @since Java 3D 1.2
*/
@@ -141,6 +108,59 @@ public class TriangleFanArray extends GeometryStripArray {
}
/**
+ * Constructs an empty TriangleFanArray object using the
+ * specified parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrSizes
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param stripVertexCounts
+ * see {@link GeometryStripArray#GeometryStripArray(int,int,int,int[],int,int[],int[])}
+ * for a description of this parameter.
+ *
+ * @exception IllegalArgumentException if vertexCount is less than 3
+ * or any element in the stripVertexCounts array is less than 3
+ * ;<br>
+ * See {@link GeometryStripArray#GeometryStripArray(int,int,int,int[],int,int[],int[])}
+ * for more exceptions that can be thrown
+ *
+ * @since Java 3D 1.4
+ */
+ public TriangleFanArray(int vertexCount,
+ int vertexFormat,
+ int texCoordSetCount,
+ int[] texCoordSetMap,
+ int vertexAttrCount,
+ int[] vertexAttrSizes,
+ int[] stripVertexCounts) {
+
+ super(vertexCount, vertexFormat,
+ texCoordSetCount, texCoordSetMap,
+ vertexAttrCount, vertexAttrSizes,
+ stripVertexCounts);
+
+ if (vertexCount < 3 )
+ throw new IllegalArgumentException(J3dI18N.getString("TriangleFanArray0"));
+ }
+
+ /**
* Creates the retained mode TriangleFanArrayRetained object that this
* TriangleFanArray object will point to.
*/
@@ -154,25 +174,29 @@ public class TriangleFanArray extends GeometryStripArray {
* @deprecated replaced with cloneNodeComponent(boolean forceDuplicate)
*/
public NodeComponent cloneNodeComponent() {
- TriangleFanArrayRetained rt = (TriangleFanArrayRetained) retained;
- int stripcounts[] = new int[rt.getNumStrips()];
- rt.getStripVertexCounts(stripcounts);
- int texSetCount = rt.getTexCoordSetCount();
- TriangleFanArray t;
- if (texSetCount == 0) {
- t = new TriangleFanArray(rt.getVertexCount(),
- rt.getVertexFormat(),
- stripcounts);
- } else {
- int texMap[] = new int[rt.getTexCoordSetMapLength()];
- rt.getTexCoordSetMap(texMap);
- t = new TriangleFanArray(rt.getVertexCount(),
- rt.getVertexFormat(),
- texSetCount,
- texMap,
- stripcounts);
- }
- t.duplicateNodeComponent(this);
+ TriangleFanArrayRetained rt = (TriangleFanArrayRetained) retained;
+ int stripcounts[] = new int[rt.getNumStrips()];
+ rt.getStripVertexCounts(stripcounts);
+ int texSetCount = rt.getTexCoordSetCount();
+ int[] texMap = null;
+ int vertexAttrCount = rt.getVertexAttrCount();
+ int[] vertexAttrSizes = null;
+ if (texSetCount > 0) {
+ texMap = new int[rt.getTexCoordSetMapLength()];
+ rt.getTexCoordSetMap(texMap);
+ }
+ if (vertexAttrCount > 0) {
+ vertexAttrSizes = new int[vertexAttrCount];
+ rt.getVertexAttrSizes(vertexAttrSizes);
+ }
+ TriangleFanArray t = new TriangleFanArray(rt.getVertexCount(),
+ rt.getVertexFormat(),
+ texSetCount,
+ texMap,
+ vertexAttrCount,
+ vertexAttrSizes,
+ stripcounts);
+ t.duplicateNodeComponent(this);
return t;
}
diff --git a/src/classes/share/javax/media/j3d/TriangleFanArrayRetained.java b/src/classes/share/javax/media/j3d/TriangleFanArrayRetained.java
index ba29127..1c77d6c 100644
--- a/src/classes/share/javax/media/j3d/TriangleFanArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/TriangleFanArrayRetained.java
@@ -32,14 +32,16 @@ class TriangleFanArrayRetained extends GeometryStripArrayRetained {
this.geoType = GEO_TYPE_TRI_FAN_SET;
}
- boolean intersect(PickShape pickShape, double dist[], Point3d iPnt) {
+ boolean intersect(PickShape pickShape, PickInfo.IntersectionInfo iInfo, int flags, Point3d iPnt) {
Point3d pnts[] = new Point3d[3];
double sdist[] = new double[1];
double minDist = Double.MAX_VALUE;
double x = 0, y = 0, z = 0;
int i = 0;
int j, end;
-
+ int count = 0, fSCount;
+ int minICount = 0;
+ int minFSCount = 0;
pnts[0] = new Point3d();
pnts[1] = new Point3d();
pnts[2] = new Point3d();
@@ -51,19 +53,24 @@ class TriangleFanArrayRetained extends GeometryStripArrayRetained {
while (i < stripVertexCounts.length) {
j = stripStartVertexIndices[i];
end = j + stripVertexCounts[i++];
+ fSCount = count;
getVertexData(j++, pnts[0]);
getVertexData(j++, pnts[1]);
+ count += 2;
while (j < end) {
getVertexData(j++, pnts[2]);
- if (intersectRay(pnts, pickRay, sdist, iPnt)) {
- if (dist == null) {
+ count++;
+ if (intersectRay(pnts, pickRay, sdist, iPnt)) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minFSCount = count;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[1].set(pnts[2]);
@@ -76,20 +83,25 @@ class TriangleFanArrayRetained extends GeometryStripArrayRetained {
while (i < stripVertexCounts.length) {
j = stripStartVertexIndices[i];
end = j + stripVertexCounts[i++];
+ fSCount = count;
getVertexData(j++, pnts[0]);
getVertexData(j++, pnts[1]);
+ count += 2;
while (j < end) {
getVertexData(j++, pnts[2]);
- if (intersectSegment(pnts, pickSegment.start,
+ count++;
+ if (intersectSegment(pnts, pickSegment.start,
pickSegment.end, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minFSCount = fSCount;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[1].set(pnts[2]);
@@ -103,19 +115,24 @@ class TriangleFanArrayRetained extends GeometryStripArrayRetained {
while (i < stripVertexCounts.length) {
j = stripStartVertexIndices[i];
end = j + stripVertexCounts[i++];
+ fSCount = count;
getVertexData(j++, pnts[0]);
getVertexData(j++, pnts[1]);
+ count += 2;
while (j < end) {
getVertexData(j++, pnts[2]);
+ count++;
if (intersectBoundingBox(pnts, bbox, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minFSCount = fSCount;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[1].set(pnts[2]);
@@ -129,20 +146,25 @@ class TriangleFanArrayRetained extends GeometryStripArrayRetained {
while (i < stripVertexCounts.length) {
j = stripStartVertexIndices[i];
end = j + stripVertexCounts[i++];
- getVertexData(j++, pnts[0]);
+ fSCount = count;
+ getVertexData(j++, pnts[0]);
getVertexData(j++, pnts[1]);
- while (j < end) {
+ count += 2;
+ while (j < end) {
getVertexData(j++, pnts[2]);
- if (intersectBoundingSphere(pnts, bsphere, sdist,
+ count++;
+ if (intersectBoundingSphere(pnts, bsphere, sdist,
iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minFSCount = fSCount;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[1].set(pnts[2]);
@@ -156,20 +178,25 @@ class TriangleFanArrayRetained extends GeometryStripArrayRetained {
while (i < stripVertexCounts.length) {
j = stripStartVertexIndices[i];
end = j + stripVertexCounts[i++];
+ fSCount = count;
getVertexData(j++, pnts[0]);
getVertexData(j++, pnts[1]);
+ count += 2;
while (j < end) {
getVertexData(j++, pnts[2]);
- if (intersectBoundingPolytope(pnts, bpolytope,
+ count++;
+ if (intersectBoundingPolytope(pnts, bpolytope,
sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minFSCount = fSCount;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[1].set(pnts[2]);
@@ -184,17 +211,22 @@ class TriangleFanArrayRetained extends GeometryStripArrayRetained {
end = j + stripVertexCounts[i++];
getVertexData(j++, pnts[0]);
getVertexData(j++, pnts[1]);
+ fSCount = count;
+ count += 2;
while (j < end) {
getVertexData(j++, pnts[2]);
+ count++;
if (intersectCylinder(pnts, pickCylinder, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minFSCount = fSCount;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[1].set(pnts[2]);
@@ -207,19 +239,24 @@ class TriangleFanArrayRetained extends GeometryStripArrayRetained {
while (i < stripVertexCounts.length) {
j = stripStartVertexIndices[i];
end = j + stripVertexCounts[i++];
- getVertexData(j++, pnts[0]);
+ fSCount = count;
+ getVertexData(j++, pnts[0]);
getVertexData(j++, pnts[1]);
+ count += 2;
while (j < end) {
getVertexData(j++, pnts[2]);
+ count++;
if (intersectCone(pnts, pickCone, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
- x = iPnt.x;
- y = iPnt.y;
- z = iPnt.z;
+ minFSCount = fSCount;
+ minICount = count;
+ x = iPnt.x;
+ y = iPnt.y;
+ z = iPnt.z;
}
}
pnts[1].set(pnts[2]);
@@ -234,14 +271,22 @@ class TriangleFanArrayRetained extends GeometryStripArrayRetained {
}
if (minDist < Double.MAX_VALUE) {
- dist[0] = minDist;
+ assert(minICount >= 3);
+ int[] vertexIndices = iInfo.getVertexIndices();
+ if (vertexIndices == null) {
+ vertexIndices = new int[3];
+ iInfo.setVertexIndices(vertexIndices);
+ }
+ vertexIndices[0] = minFSCount;
+ vertexIndices[1] = minICount - 2;
+ vertexIndices[2] = minICount - 1;
iPnt.x = x;
iPnt.y = y;
iPnt.z = z;
- return true;
+ return true;
}
return false;
- }
+ }
// intersect pnts[] with every triangle in this object
boolean intersect(Point3d[] pnts) {
diff --git a/src/classes/share/javax/media/j3d/TriangleStripArray.java b/src/classes/share/javax/media/j3d/TriangleStripArray.java
index 9c6c324..e6c9ed8 100644
--- a/src/classes/share/javax/media/j3d/TriangleStripArray.java
+++ b/src/classes/share/javax/media/j3d/TriangleStripArray.java
@@ -29,28 +29,26 @@ public class TriangleStripArray extends GeometryStripArray {
TriangleStripArray() {}
/**
- * Constructs an empty TriangleStripArray object with the specified
- * number of vertices, vertex format, and
- * array of per-strip vertex counts.
- * @param vertexCount the number of vertex elements in this array
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.
- * @param stripVertexCounts array that specifies
- * the count of the number of vertices for each separate strip.
- * The length of this array is the number of separate strips.
+ * Constructs an empty TriangleStripArray object using the
+ * specified parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int)}
+ * for a description of this parameter.
+ *
+ * @param stripVertexCounts
+ * see {@link GeometryStripArray#GeometryStripArray(int,int,int[])}
+ * for a description of this parameter.
*
* @exception IllegalArgumentException if vertexCount is less than 3
* or any element in the stripVertexCounts array is less than 3
+ * ;<br>
+ * See {@link GeometryStripArray#GeometryStripArray(int,int,int[])}
+ * for more exceptions that can be thrown
*/
public TriangleStripArray(int vertexCount,
int vertexFormat,
@@ -63,65 +61,34 @@ public class TriangleStripArray extends GeometryStripArray {
}
/**
- * Constructs an empty TriangleStripArray object with the specified
- * number of vertices, vertex format, number of texture coordinate
- * sets, texture coordinate mapping array, and
- * array of per-strip vertex counts.
- *
- * @param vertexCount the number of vertex elements in this array<p>
- *
- * @param vertexFormat a mask indicating which components are
- * present in each vertex. This is specified as one or more
- * individual flags that are bitwise "OR"ed together to describe
- * the per-vertex data.
- * The flags include: COORDINATES, to signal the inclusion of
- * vertex positions--always present; NORMALS, to signal
- * the inclusion of per vertex normals; one of COLOR_3,
- * COLOR_4, to signal the inclusion of per vertex
- * colors (without or with color information); and one of
- * TEXTURE_COORDINATE_2, TEXTURE_COORDINATE_3 or TEXTURE_COORDINATE_4,
- * to signal the
- * inclusion of per-vertex texture coordinates 2D, 3D or 4D.<p>
- *
- * @param texCoordSetCount the number of texture coordinate sets
- * in this GeometryArray object. If <code>vertexFormat</code>
- * does not include one of <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3 or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetCount</code> parameter is not used.<p>
- *
- * @param texCoordSetMap an array that maps texture coordinate
- * sets to texture units. The array is indexed by texture unit
- * number for each texture unit in the associated Appearance
- * object. The values in the array specify the texture coordinate
- * set within this GeometryArray object that maps to the
- * corresponding texture
- * unit. All elements within the array must be less than
- * <code>texCoordSetCount</code>. A negative value specifies that
- * no texture coordinate set maps to the texture unit
- * corresponding to the index. If there are more texture units in
- * any associated Appearance object than elements in the mapping
- * array, the extra elements are assumed to be -1. The same
- * texture coordinate set may be used for more than one texture
- * unit. Each texture unit in every associated Appearance must
- * have a valid source of texture coordinates: either a
- * non-negative texture coordinate set must be specified in the
- * mapping array or texture coordinate generation must be enabled.
- * Texture coordinate generation will take precedence for those
- * texture units for which a texture coordinate set is specified
- * and texture coordinate generation is enabled. If
- * <code>vertexFormat</code> does not include one of
- * <code>TEXTURE_COORDINATE_2</code>,
- * <code>TEXTURE_COORDINATE_3</code> or
- * <code>TEXTURE_COORDINATE_4</code>, the
- * <code>texCoordSetMap</code> array is not used.<p>
- *
- * @param stripVertexCounts array that specifies
- * the count of the number of vertices for each separate strip.
- * The length of this array is the number of separate strips.
+ * Constructs an empty TriangleStripArray object using the
+ * specified parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[])}
+ * for a description of this parameter.
+ *
+ * @param stripVertexCounts
+ * see {@link GeometryStripArray#GeometryStripArray(int,int,int,int[],int[])}
+ * for a description of this parameter.
*
* @exception IllegalArgumentException if vertexCount is less than 3
* or any element in the stripVertexCounts array is less than 3
+ * ;<br>
+ * See {@link GeometryStripArray#GeometryStripArray(int,int,int,int[],int[])}
+ * for more exceptions that can be thrown
*
* @since Java 3D 1.2
*/
@@ -140,6 +107,59 @@ public class TriangleStripArray extends GeometryStripArray {
}
/**
+ * Constructs an empty TriangleStripArray object using the
+ * specified parameters.
+ *
+ * @param vertexCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexFormat
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param texCoordSetMap
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrCount
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param vertexAttrSizes
+ * see {@link GeometryArray#GeometryArray(int,int,int,int[],int,int[])}
+ * for a description of this parameter.
+ *
+ * @param stripVertexCounts
+ * see {@link GeometryStripArray#GeometryStripArray(int,int,int,int[],int,int[],int[])}
+ * for a description of this parameter.
+ *
+ * @exception IllegalArgumentException if vertexCount is less than 3
+ * or any element in the stripVertexCounts array is less than 3
+ * ;<br>
+ * See {@link GeometryStripArray#GeometryStripArray(int,int,int,int[],int,int[],int[])}
+ * for more exceptions that can be thrown
+ *
+ * @since Java 3D 1.4
+ */
+ public TriangleStripArray(int vertexCount,
+ int vertexFormat,
+ int texCoordSetCount,
+ int[] texCoordSetMap,
+ int vertexAttrCount,
+ int[] vertexAttrSizes,
+ int[] stripVertexCounts) {
+
+ super(vertexCount, vertexFormat,
+ texCoordSetCount, texCoordSetMap,
+ vertexAttrCount, vertexAttrSizes,
+ stripVertexCounts);
+
+ if (vertexCount < 3 )
+ throw new IllegalArgumentException(J3dI18N.getString("TriangleStripArray0"));
+ }
+
+ /**
* Creates the retained mode TriangleStripArrayRetained object that this
* TriangleStripArray object will point to.
*/
@@ -153,26 +173,29 @@ public class TriangleStripArray extends GeometryStripArray {
* @deprecated replaced with cloneNodeComponent(boolean forceDuplicate)
*/
public NodeComponent cloneNodeComponent() {
- TriangleStripArrayRetained rt = (TriangleStripArrayRetained) retained;
+ TriangleStripArrayRetained rt = (TriangleStripArrayRetained) retained;
int stripcounts[] = new int[rt.getNumStrips()];
- rt.getStripVertexCounts(stripcounts);
- int texSetCount = rt.getTexCoordSetCount();
- TriangleStripArray t;
- if (texSetCount == 0) {
- t = new TriangleStripArray(rt.getVertexCount(),
- rt.getVertexFormat(),
- stripcounts);
- } else {
- int texMap[] = new int[rt.getTexCoordSetMapLength()];
- rt.getTexCoordSetMap(texMap);
- t = new TriangleStripArray(rt.getVertexCount(),
- rt.getVertexFormat(),
- texSetCount,
- texMap,
- stripcounts);
-
- }
- t.duplicateNodeComponent(this);
+ rt.getStripVertexCounts(stripcounts);
+ int texSetCount = rt.getTexCoordSetCount();
+ int[] texMap = null;
+ int vertexAttrCount = rt.getVertexAttrCount();
+ int[] vertexAttrSizes = null;
+ if (texSetCount > 0) {
+ texMap = new int[rt.getTexCoordSetMapLength()];
+ rt.getTexCoordSetMap(texMap);
+ }
+ if (vertexAttrCount > 0) {
+ vertexAttrSizes = new int[vertexAttrCount];
+ rt.getVertexAttrSizes(vertexAttrSizes);
+ }
+ TriangleStripArray t = new TriangleStripArray(rt.getVertexCount(),
+ rt.getVertexFormat(),
+ texSetCount,
+ texMap,
+ vertexAttrCount,
+ vertexAttrSizes,
+ stripcounts);
+ t.duplicateNodeComponent(this);
return t;
}
}
diff --git a/src/classes/share/javax/media/j3d/TriangleStripArrayRetained.java b/src/classes/share/javax/media/j3d/TriangleStripArrayRetained.java
index db4b8ba..14c177a 100644
--- a/src/classes/share/javax/media/j3d/TriangleStripArrayRetained.java
+++ b/src/classes/share/javax/media/j3d/TriangleStripArrayRetained.java
@@ -30,15 +30,16 @@ class TriangleStripArrayRetained extends GeometryStripArrayRetained {
TriangleStripArrayRetained() {
this.geoType = GEO_TYPE_TRI_STRIP_SET;
}
-
- boolean intersect(PickShape pickShape, double dist[], Point3d iPnt) {
+
+ boolean intersect(PickShape pickShape, PickInfo.IntersectionInfo iInfo, int flags, Point3d iPnt) {
Point3d pnts[] = new Point3d[3];
double sdist[] = new double[1];
double minDist = Double.MAX_VALUE;
double x = 0, y = 0, z = 0;
+ int count = 0;
+ int minICount = 0;
int i = 0;
int j, end;
-
pnts[0] = new Point3d();
pnts[1] = new Point3d();
pnts[2] = new Point3d();
@@ -52,18 +53,21 @@ class TriangleStripArrayRetained extends GeometryStripArrayRetained {
end = j + stripVertexCounts[i++];
getVertexData(j++, pnts[0]);
getVertexData(j++, pnts[1]);
+ count += 2;
while (j < end) {
getVertexData(j++, pnts[2]);
+ count++;
if (intersectRay(pnts, pickRay, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
- }
+ }
}
pnts[0].set(pnts[1]);
pnts[1].set(pnts[2]);
@@ -78,15 +82,18 @@ class TriangleStripArrayRetained extends GeometryStripArrayRetained {
end = j + stripVertexCounts[i++];
getVertexData(j++, pnts[0]);
getVertexData(j++, pnts[1]);
+ count += 2;
while (j < end) {
getVertexData(j++, pnts[2]);
+ count++;
if (intersectSegment(pnts, pickSegment.start,
pickSegment.end, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -106,14 +113,17 @@ class TriangleStripArrayRetained extends GeometryStripArrayRetained {
end = j + stripVertexCounts[i++];
getVertexData(j++, pnts[0]);
getVertexData(j++, pnts[1]);
+ count += 2;
while (j < end) {
getVertexData(j++, pnts[2]);
+ count++;
if (intersectBoundingBox(pnts, bbox, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -133,15 +143,18 @@ class TriangleStripArrayRetained extends GeometryStripArrayRetained {
end = j + stripVertexCounts[i++];
getVertexData(j++, pnts[0]);
getVertexData(j++, pnts[1]);
+ count += 2;
while (j < end) {
getVertexData(j++, pnts[2]);
+ count++;
if (intersectBoundingSphere(pnts, bsphere, sdist,
iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -161,15 +174,18 @@ class TriangleStripArrayRetained extends GeometryStripArrayRetained {
end = j + stripVertexCounts[i++];
getVertexData(j++, pnts[0]);
getVertexData(j++, pnts[1]);
+ count += 2;
while (j < end) {
getVertexData(j++, pnts[2]);
- if (intersectBoundingPolytope(pnts, bpolytope,
+ count++;
+ if (intersectBoundingPolytope(pnts, bpolytope,
sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -188,14 +204,17 @@ class TriangleStripArrayRetained extends GeometryStripArrayRetained {
end = j + stripVertexCounts[i++];
getVertexData(j++, pnts[0]);
getVertexData(j++, pnts[1]);
+ count += 2;
while (j < end) {
getVertexData(j++, pnts[2]);
- if (intersectCylinder(pnts, pickCylinder, sdist, iPnt)) {
- if (dist == null) {
+ count++;
+ if (intersectCylinder(pnts, pickCylinder, sdist, iPnt)) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -214,14 +233,17 @@ class TriangleStripArrayRetained extends GeometryStripArrayRetained {
end = j + stripVertexCounts[i++];
getVertexData(j++, pnts[0]);
getVertexData(j++, pnts[1]);
+ count += 2;
while (j < end) {
getVertexData(j++, pnts[2]);
+ count++;
if (intersectCone(pnts, pickCone, sdist, iPnt)) {
- if (dist == null) {
+ if (flags == 0) {
return true;
}
if (sdist[0] < minDist) {
minDist = sdist[0];
+ minICount = count;
x = iPnt.x;
y = iPnt.y;
z = iPnt.z;
@@ -240,7 +262,15 @@ class TriangleStripArrayRetained extends GeometryStripArrayRetained {
}
if (minDist < Double.MAX_VALUE) {
- dist[0] = minDist;
+ assert(minICount >=3);
+ int[] vertexIndices = iInfo.getVertexIndices();
+ if (vertexIndices == null) {
+ vertexIndices = new int[3];
+ iInfo.setVertexIndices(vertexIndices);
+ }
+ vertexIndices[0] = minICount - 3;
+ vertexIndices[1] = minICount - 2;
+ vertexIndices[2] = minICount - 1;
iPnt.x = x;
iPnt.y = y;
iPnt.z = z;
diff --git a/src/classes/share/javax/media/j3d/View.java b/src/classes/share/javax/media/j3d/View.java
index 2b54b6a..daf6cd4 100644
--- a/src/classes/share/javax/media/j3d/View.java
+++ b/src/classes/share/javax/media/j3d/View.java
@@ -3305,7 +3305,7 @@ public class View extends Object {
}
// This is a temporary fix for bug 4267395
- // TODO:cleanup in RenderBin after View detach
+ // XXXX:cleanup in RenderBin after View detach
// universe.addViewIdToFreeList(viewId);
// using new property -Dj3d.forceReleaseView to disable bug fix 4267395
diff --git a/src/classes/share/javax/media/j3d/ViewCache.java b/src/classes/share/javax/media/j3d/ViewCache.java
index 5aeec71..b506793 100644
--- a/src/classes/share/javax/media/j3d/ViewCache.java
+++ b/src/classes/share/javax/media/j3d/ViewCache.java
@@ -312,8 +312,7 @@ class ViewCache extends Object {
trackerBaseToHeadTracker.setIdentity();
}
- // TODO: implement head to vworld tracking if userHeadToVworldEnable
- // is set
+ // XXXX: implement head to vworld tracking if userHeadToVworldEnable is set
userHeadToVworld.setIdentity();
}
diff --git a/src/classes/share/javax/media/j3d/ViewPlatform.java b/src/classes/share/javax/media/j3d/ViewPlatform.java
index 59ebf66..bd518f2 100644
--- a/src/classes/share/javax/media/j3d/ViewPlatform.java
+++ b/src/classes/share/javax/media/j3d/ViewPlatform.java
@@ -108,6 +108,11 @@ public class ViewPlatform extends Leaf {
public static final int
ALLOW_POLICY_WRITE = CapabilityBits.VIEW_PLATFORM_ALLOW_POLICY_WRITE;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_POLICY_READ
+ };
+
/**
* Constructs a ViewPlatform object with default parameters.
* The default values are as follows:
@@ -117,6 +122,8 @@ public class ViewPlatform extends Leaf {
* </ul>
*/
public ViewPlatform() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
/**
diff --git a/src/classes/share/javax/media/j3d/ViewPlatformRetained.java b/src/classes/share/javax/media/j3d/ViewPlatformRetained.java
index 230235a..c523108 100644
--- a/src/classes/share/javax/media/j3d/ViewPlatformRetained.java
+++ b/src/classes/share/javax/media/j3d/ViewPlatformRetained.java
@@ -164,7 +164,6 @@ class ViewPlatformRetained extends LeafRetained {
/**
* This sets the view that is associated with this view platform.
*/
- // TODO: This must be changed to a list of views!
void setView(View v) {
synchronized (viewList) {
if (!viewList.contains(v)) {
diff --git a/src/classes/share/javax/media/j3d/ViewSpecificGroup.java b/src/classes/share/javax/media/j3d/ViewSpecificGroup.java
index 8203551..bd87d04 100644
--- a/src/classes/share/javax/media/j3d/ViewSpecificGroup.java
+++ b/src/classes/share/javax/media/j3d/ViewSpecificGroup.java
@@ -71,11 +71,17 @@ public class ViewSpecificGroup extends Group {
public static final int
ALLOW_VIEW_WRITE = CapabilityBits.VIEW_SPECIFIC_GROUP_ALLOW_VIEW_WRITE;
+ // Array for setting default read capabilities
+ private static final int[] readCapabilities = {
+ ALLOW_VIEW_READ
+ };
/**
* Constructs and initializes a new ViewSpecificGroup node object.
*/
public ViewSpecificGroup() {
+ // set default read capabilities
+ setDefaultReadCapabilities(readCapabilities);
}
@@ -324,7 +330,7 @@ public class ViewSpecificGroup extends Group {
*/
void duplicateAttributes(Node originalNode, boolean forceDuplicate) {
- // TODO: implement this
+ // XXXX: implement this?
super.duplicateAttributes(originalNode, forceDuplicate);
ViewSpecificGroupRetained attr = (ViewSpecificGroupRetained) originalNode.retained;
diff --git a/src/classes/share/javax/media/j3d/ViewSpecificGroupRetained.java b/src/classes/share/javax/media/j3d/ViewSpecificGroupRetained.java
index 58cc08f..f60d052 100644
--- a/src/classes/share/javax/media/j3d/ViewSpecificGroupRetained.java
+++ b/src/classes/share/javax/media/j3d/ViewSpecificGroupRetained.java
@@ -517,7 +517,7 @@ class ViewSpecificGroupRetained extends GroupRetained {
// don't remove this group node
mergeFlag = SceneGraphObjectRetained.DONT_MERGE;
- // TODO: complete this
+ // XXXX: complete this
}
void setLive(SetLiveState s) {
@@ -549,7 +549,7 @@ class ViewSpecificGroupRetained extends GroupRetained {
s.viewScopedNodeList = new ArrayList();
s.scopedNodesViewList = new ArrayList();
}
- // TODO: This is a hack since removeNodeData is called before
+ // XXXX: This is a hack since removeNodeData is called before
// children are clearLives
int[] tempIndex = null;
// Don't keep the indices if everything will be cleared
diff --git a/src/classes/share/javax/media/j3d/VirtualUniverse.java b/src/classes/share/javax/media/j3d/VirtualUniverse.java
index bb9b14d..20c783b 100644
--- a/src/classes/share/javax/media/j3d/VirtualUniverse.java
+++ b/src/classes/share/javax/media/j3d/VirtualUniverse.java
@@ -15,6 +15,8 @@ package javax.media.j3d;
import java.util.Vector;
import java.util.ArrayList;
import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
import java.util.Map;
/**
@@ -155,6 +157,12 @@ public class VirtualUniverse extends Object {
boolean isSceneGraphLock = false;
private Object waitLock = new Object();
+
+ private HashSet structureChangeListenerSet = null;
+
+ private HashSet shaderErrorListenerSet = null;
+ private ShaderErrorListener defaultShaderErrorListener =
+ ShaderProgram.getDefaultErrorListener();
/**
* Constructs a new VirtualUniverse.
@@ -549,7 +557,7 @@ public class VirtualUniverse extends Object {
/**
* This returns the next available nodeId as a string.
*/
- // TODO: reuse of id's imply a slight collision problem in the
+ // XXXX: reuse of id's imply a slight collision problem in the
// render queue's.
// BUG 4181362
String getNodeId() {
@@ -990,4 +998,184 @@ public class VirtualUniverse extends Object {
isSceneGraphLock = false;
}
}
+
+ /**
+ * Adds the specified GraphStructureChangeListener to the set of listeners
+ * that will be notified when the graph structure is changed on a live
+ * scene graph. If the specifed listener is null no action is taken and no
+ * exception is thrown.
+ *
+ * @param listener the listener to add to the set.
+ *
+ * @since Java 3D 1.4
+ */
+ public void addGraphStructureChangeListener(GraphStructureChangeListener listener) {
+ if (listener == null) {
+ return;
+ }
+
+ if (structureChangeListenerSet == null) {
+ structureChangeListenerSet = new HashSet();
+ }
+
+ synchronized(structureChangeListenerSet) {
+ structureChangeListenerSet.add(listener);
+ }
+ }
+
+ /**
+ * Removes the specified GraphStructureChangeListener from the set of listeners. This
+ * method performs no function, nor does it throw an exception if the specified listener
+ * is not currently in the set or is null.
+ *
+ * @param listener the listener to remove from the set.
+ *
+ * @since Java 3D 1.4
+ */
+ public void removeGraphStructureChangeListener(GraphStructureChangeListener listener) {
+ if (structureChangeListenerSet == null) {
+ return;
+ }
+
+ synchronized(structureChangeListenerSet) {
+ structureChangeListenerSet.remove(listener);
+ }
+ }
+
+ /**
+ * Processes all live BranchGroup add and removes and notifies
+ * any registered listeners. Used for add and remove
+ */
+ void notifyStructureChangeListeners(boolean add, Object parent, BranchGroup child) {
+ if (structureChangeListenerSet == null) {
+ return;
+ }
+
+ synchronized(structureChangeListenerSet) {
+ Iterator it = structureChangeListenerSet.iterator();
+ while(it.hasNext()) {
+ GraphStructureChangeListener listener = (GraphStructureChangeListener)it.next();
+ try {
+ if (add) {
+ listener.branchGroupAdded(parent, child);
+ } else {
+ listener.branchGroupRemoved(parent, child);
+ }
+ }
+ catch (RuntimeException e) {
+ System.err.println("Exception occurred in GraphStructureChangeListener:");
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ /**
+ * Processes all live BranchGroup moves and notifies
+ * any registered listeners. Used for moveTo
+ */
+ void notifyStructureChangeListeners(Object oldParent, Object newParent, BranchGroup child) {
+ if (structureChangeListenerSet == null) {
+ return;
+ }
+
+ synchronized(structureChangeListenerSet) {
+ Iterator it = structureChangeListenerSet.iterator();
+ while(it.hasNext()) {
+ GraphStructureChangeListener listener = (GraphStructureChangeListener)it.next();
+ try {
+ listener.branchGroupMoved(oldParent, newParent, child);
+ }
+ catch (RuntimeException e) {
+ System.err.println("Exception occurred in GraphStructureChangeListener:");
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Adds the specified ShaderErrorListener to the set of listeners
+ * that will be notified when a programmable shader error is
+ * detected on a live scene graph. If the specifed listener is
+ * null no action is taken and no exception is thrown.
+ * If a shader error occurs, the listeners will be called
+ * asynchronously from a separate notification thread. The Java 3D
+ * renderer and behavior scheduler will continue to run as if the
+ * error had not occurred, except that shading will be disabled
+ * for the objects in error. If applications desire to detach or
+ * modify the scene graph as a result of the error, they should
+ * use a behavior post if they want that change to be
+ * synchronous with the renderer.
+ *
+ * @param listener the listener to add to the set.
+ *
+ * @since Java 3D 1.4
+ */
+ public void addShaderErrorListener(ShaderErrorListener listener) {
+ if (listener == null) {
+ return;
+ }
+
+ if (shaderErrorListenerSet == null) {
+ shaderErrorListenerSet = new HashSet();
+ }
+
+ synchronized(shaderErrorListenerSet) {
+ shaderErrorListenerSet.add(listener);
+ }
+ }
+
+ /**
+ * Removes the specified ShaderErrorListener from the set of
+ * listeners. This method performs no function, nor does it throw
+ * an exception if the specified listener is not currently in the
+ * set or is null.
+ *
+ * @param listener the listener to remove from the set.
+ *
+ * @since Java 3D 1.4
+ */
+ public void removeShaderErrorListener(ShaderErrorListener listener) {
+ if (shaderErrorListenerSet == null) {
+ return;
+ }
+
+ synchronized(shaderErrorListenerSet) {
+ shaderErrorListenerSet.remove(listener);
+ }
+ }
+
+ /**
+ * Notifies all listeners of a shader error. If no listeners exist, a default
+ * listener is notified.
+ */
+ void notifyShaderErrorListeners(ShaderError error) {
+ boolean errorReported = false;
+
+ // Notify all error listeners in the set
+ if (shaderErrorListenerSet != null) {
+ synchronized(shaderErrorListenerSet) {
+ Iterator it = shaderErrorListenerSet.iterator();
+ while(it.hasNext()) {
+ ShaderErrorListener listener = (ShaderErrorListener)it.next();
+ try {
+ listener.errorOccurred(error);
+ }
+ catch (RuntimeException e) {
+ System.err.println("Exception occurred in ShaderErrorListener:");
+ e.printStackTrace();
+ }
+ errorReported = true;
+ }
+ }
+ }
+
+ // Notify the default error listener if the set is null or empty
+ if (!errorReported) {
+ defaultShaderErrorListener.errorOccurred(error);
+ }
+ }
+
}
diff --git a/src/classes/share/javax/media/j3d/WakeupIndexedList.java b/src/classes/share/javax/media/j3d/WakeupIndexedList.java
index c0a52ec..4a20594 100644
--- a/src/classes/share/javax/media/j3d/WakeupIndexedList.java
+++ b/src/classes/share/javax/media/j3d/WakeupIndexedList.java
@@ -59,7 +59,7 @@ package javax.media.j3d;
class WakeupIndexedList implements Cloneable, java.io.Serializable {
- // TODO: set to false when release
+ // XXXX: set to false when release
final static boolean debug = false;
/**