Skip to main content

[JAVA3D-INTEREST] Weird exception while picking

5 replies [Last post]
Anonymous

I'm using 1.3.2 Beta 3 on Windows XP, using the DirectX renderer.

I've got and IndexedGeometryArray created with

new IndexedTriangleArray(n, GeometryArray.COORDINATES
| GeometryArray.NORMALS
| GeometryArray.TEXTURE_COORDINATE_2
| GeometryArray.USE_COORD_INDEX_ONLY,
1, new int[] {0, 0}, m);

n and m and all the geometry is all set up and look fine on screen. It
has been working for ages.

Now I am trying to do picking on this geometry. In a behaviour which
gets triggered by mouse clicks, I do:

pc = new PickCanvas(canvas3D, branchGroup);
pc.setMode(PickTool.GEOMETRY_INTERSECT_INFO);
pc.setShapeLocation(mouseEvent.getX(), mouseEvent.getY());
PickResult pr = pc.pickClosest();
PickIntersection pi =
pr.getClosestIntersection(pc.getStartPosition());

That also, I believe to be working fine, because up to now, I have been
doing

thing = pi.getClosestVertexCoordinates();

and doing stuff with thing that worked.

Finally we get to the problem. Now I am trying to do something more
sophisticated, namely

tc = pi.getPointTextureCoordinate(0);

That is, get the texture coordinates of the actual click point, not just
of the closest vertex. That generates the exception at the end of this
email.

Doing

Point3d p = pi.getPointCoordinates();

does not throw an exception. Nor does:

TexCoord2f clickPoint = new TexCoord2f();
((IndexedTriangleArray) pi.getGeometryArray())
.getTextureCoordinate(0, pi.getClosestVertexIndex(),
clickPoint);

Which only gets me the texture coordinates of the nearest vertex, not of
the actual click point. I can live with that for now, but I would like
to understand why the other method does not work, and whether there is
anything I can do about it.

((By the way, I have set all the necessary capabilities. I do not
believe how many CapabilityNotSetExceptions I have seen while developing
this application. Developing with Java3D certainly requires a sense of
humour.)

Thanks for any help you can give,

Tim.

This is the exception I get (apologies for any line-wrapping my Outlook
adds)

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
Exception occurred during Behavior execution:
java.lang.IllegalStateException: GeometryArray: must be in
TEXTURE_COORDINATE_3 mode to use this method
at javax.media.j3d.GeometryArray.getTextureCoordinate(Unknown
Source)
at
com.sun.j3d.utils.picking.PickIntersection.getPrimitiveTexCoords(Unknown
Source)
at
com.sun.j3d.utils.picking.PickIntersection.getPointTextureCoordinate(Unk
nown Source)
at
uk.ac.open.m338.surfaces.CountableSubdivisionScreen$SubdivisionClickHand
ler.handleMouseClick(CountableSubdivisionScreen.java:182)
at
uk.ac.open.m338.surfaces.PickingBehavior.processMouseClick(PickingBehavi
or.java:107)
at
uk.ac.open.m338.surfaces.PickingBehavior.processStimulus(PickingBehavior
.java:80)
at javax.media.j3d.BehaviorScheduler.doWork(Unknown Source)
at javax.media.j3d.J3dThread.run(Unknown Source)

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@java3d.dev.java.net
For additional commands, e-mail: interest-help@java3d.dev.java.net

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
T.J.Hunt

> Yes, I'm guessing that there is a bug in the picking
> utilities relating to USE_COORD_INDEX_ONLY. If the original
> poster has a simple test case, could they please file an Issue?

Thank you very much for looking at this.

I'm sorry I don't have a simple test-case (yet), nor time to make one
(at the moment. When I get time I will try to remember to do so.)

Can I suggest an improved javadoc:

getClosestVertexIndex()

Currently this says:

"Get index of closest vertex".

What it means is

"Return the index of the closest vertex within the arrays returned by
methods like getPrimitiveCoordinates()."

(and it does not mean return the index of the closest vertex in the
GeometryArray, which is what I want. It seems I need to use
getClosestVertexIndex() and getPrimitiveCoordinateIndices()).

Thanks,

Tim.

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@java3d.dev.java.net
For additional commands, e-mail: interest-help@java3d.dev.java.net

nvaidya
Offline
Joined: 2004-08-03

Hmmm...The warning message is issued because the USE_COORDINATE_INDEX_ONLY is set in the GeometryArray spec. Remove that flag and make appropriate changes and see how it goes...

Also, came across this piece of code in GeometryArray.java

[code]
* @exception IllegalStateException if TEXTURE_COORDINATE_2 or
* TEXTURE_COORDINATE_4 is specified in vertex format
*
* @since Java 3D 1.2
*/
public void setTextureCoordinates(int texCoordSet,
int index, TexCoord3f texCoords[]) {
if (isLiveOrCompiled())
if(!this.getCapability(ALLOW_TEXCOORD_WRITE))
throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray42"));

if (((((GeometryArrayRetained)this.retained).vertexFormat) &
(TEXTURE_COORDINATE_2 | TEXTURE_COORDINATE_3)) != 0)
throw new IllegalStateException(J3dI18N.getString("GeometryArray95"));

((GeometryArrayRetained)this.retained).setTextureCoordinates(
texCoordSet, index, texCoords, 0, texCoords.length);
}
[/code]

Should it be TEXTURE_COORDINATE_4 instead of _3 for the exception to get thrown ...

kcr
Offline
Joined: 2004-03-17

> Hmmm...The warning message is issued because the USE_COORDINATE_INDEX_ONLY is set in the GeometryArray
> spec. Remove that flag and make appropriate changes and see how it goes...

Yes, I'm guessing that there is a bug in the picking utilities relating to USE_COORD_INDEX_ONLY. If the original poster has a simple test case, could they please file an Issue?

> Also, came across this piece of code in GeometryArray.java
>
> * @exception IllegalStateException if TEXTURE_COORDINATE_2 or
> * TEXTURE_COORDINATE_4 is specified in vertex format
[...]
> if (((((GeometryArrayRetained)this.retained).vertexFormat) &
> (TEXTURE_COORDINATE_2 | TEXTURE_COORDINATE_3)) != 0)
> throw new IllegalStateException(J3dI18N.getString("GeometryArray95"));
>
> Should it be TEXTURE_COORDINATE_4 instead of _3 for the exception to get thrown ...

Yes, this is a bug (although not the one the original user reported, since his exception was in getTextureCoordinate not setTextureCoordinates). We'll fix this in 1.4.

-- Kevin

nvaidya
Offline
Joined: 2004-08-03

Thanks Kevin.

Just been looking at com.sun.j3d.utils.picking.PickIntersection.java.

The method getPrimitiveTexCoords(int index) unconditionally uses TexCoord3f as the parameter to getTextureCoordinate(..., TexCoord3f ) even when TEXTURE_COORDINATE_2 might have been specified in the GeometryArray. The getTextureCoordinate(..., TexCoord3f ) in GeometryArray does expect to see TexCoord3f and bales out with GeometryArray95 exception since the specified format is TEXTURE_COORDINATE_2.

Snippets below:

PickIntersection.java
[code]
/**
Get the texture coordinates of the intersected primitive at the specifed
index in the specified texture coordinate set.
null if the primitive does not contain texture coordinates.
If the geometry was defined
using GeometryArray.TEXTURE_COORDINATE_2, the 'z' value of the texture
coordinate will be set to 0.0.
@return an array of TexCoord3f's for the primitive that was intersected
*/
public TexCoord3f[] getPrimitiveTexCoords (int index) {
if (primitiveTexCoords == null) {
primitiveTexCoords = new TexCoord3f[primitiveVertexIndices.length];
int[] indices = getPrimitiveTexCoordIndices(index);
int vformat = geom.getVertexFormat();
if ((vformat & GeometryArray.BY_REFERENCE) == 0) {
for (int i = 0; i < indices.length; i++) {
primitiveTexCoords[i] = new TexCoord3f();
geom.getTextureCoordinate(index, indices[i], primitiveTexCoords[i]);
}
}
[/code]

GeometryArray.java

[code]
* @exception IllegalStateException if TEXTURE_COORDINATE_2 or
* TEXTURE_COORDINATE_4 is specified in vertex format
*
* @since Java 3D 1.2
*/
public void getTextureCoordinate(int texCoordSet,
int index, TexCoord3f texCoord) {
if (isLiveOrCompiled())
if(!this.getCapability(ALLOW_TEXCOORD_READ))
throw new CapabilityNotSetException(J3dI18N.getString("GeometryArray72"));

int format = ((GeometryArrayRetained)this.retained).vertexFormat;
if ((format & BY_REFERENCE) != 0)
throw new IllegalStateException(J3dI18N.getString("GeometryArray82"));

if ((format & TEXTURE_COORDINATE ) == 0)
throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray79"));

if (((((GeometryArrayRetained)this.retained).vertexFormat) &
(TEXTURE_COORDINATE_2 | TEXTURE_COORDINATE_4)) != 0)
throw new IllegalStateException(J3dI18N.getString("GeometryArray95"));
((GeometryArrayRetained)this.retained).getTextureCoordinate(
texCoordSet, index, texCoord);
}
[/code]

pepe
Offline
Joined: 2003-06-10

i've had that looong time ago, and reported that there was an inconsistency with the docs.
Now that we have sources, i might dig-in to finally find what's wrong with this. Stay tuned a bit.