Help with picking for a n00b :)

Hi All,

I am new 3D programming, so bear with me here.

I have installed Xith3D and all relating libraries and I can run the demo’s fine. However, I am having problems with “picking” on models that are loaded eitheir with TDSLoader or the ASE loader.

I thought it may have been my code so went back and “moded” the example for picking (http://www.xith.org/tutes/GettingStarted/html/picking.html).

Specifically I took out left, middle and right plane shapes, and loaded an ase model, which displays fine, but I cant pick it!

This is the code I have used to get the model out, the rest of the code is the same as the picking example:

AseFile af = new AseFile();
try
{
  AseReader r = new AseReader(new BufferedReader(new FileReader("model/cube.ase")), af);
  af.parse(r);
}
catch (IOException e)
{
  System.out.println("Error reading ase file");
}

// Extracts list of named nodes
java.util.Hashtable views = af.getNamedNodes();

for (Enumeration e = views.keys(); e.hasMoreElements();)
{
  String current = (String)e.nextElement();
  BranchGroup group = (BranchGroup)views.get((Object)current);
  group.setPickable(true);
  sw.addChild(group);
}

Or something along those lines, basically from the tank example.

I have gone through and recursively got the parents to make sure that they are all set to pickable, and tried numerous other things but it just wont work!

Please help, what am I missing here?

Cheers,
Pinkman!


  BranchGroup group = (BranchGroup)views.get((Object)current); 

Should be:


  Group group = (Group)views.get((Object)current); 

That’s a mistake in the tute which has been fixed and must be re-uploaded.

Will.

Thanks William, but still no luck. I thought it may have been something todo with the model I am using, so I changed it to the origincube.ase, and again no luck. This is the exact code I am using:

AseFile af = new AseFile();
FileReader fileReader = null;
BufferedReader bufferedReader = null;
AseReader r = null;
try
{
  fileReader = new FileReader("C:/origincube.ASE");
  bufferedReader = new BufferedReader(fileReader);
  r = new AseReader(bufferedReader, af);
  af.parse(r);
}
catch (IOException e)
{
  log.error("Error reading ase file");
}
finally
{
  try
  {
    fileReader.close();
    bufferedReader.close();
    r.close();
  }
  catch (IOException e1)
  {
    e1.printStackTrace(System.err);
  }
}
// Extracts list of named nodes
java.util.Hashtable views = af.getNamedNodes();

for (Enumeration e = views.keys(); e.hasMoreElements();)
{
  String current = (String)e.nextElement();
  System.out.println("Node name: " + current);
  Group group = (Group)views.get((Object)current); 
  group.setPickable(true);
  sw.addChild(group);
}

I gets the group fine, outputs the name (“Box01”) and even displays it, but I still cannot “pick it”, I get zero hits on it.

Any ideas?

Not sure I’m afraid - I don’t use picking myself. Jens (who wrote that tute) should see this thread in a few hours and might be able to help you :slight_smile:

Will.

Do Xith3D picking tests (Xith3DSwitchNodeTest and Xith3DPickRenderTest) work for you?

Yuri

Did you issue “setPickable(true)” to the Shape3D as well as all its parent transform/branch groups?

That did the trick Preston ta ;D. I could have sworn I had tried that, but there you go.

To me it would make more sense if you could set a whole group pickable and it would recurse through the children to the leaf nodes.

I understand that this would not always be usefull, and could be annoying, but maybe a setGroupPickable() would be handy.

Anyway, thanks a lot guys, back to Xith…

This might help then:


public void setPickable(Node n) {
    n.setPickable(true);
    if (n instanceof Group) {
         Group g = (Group) n;

         for (int i=0;i<g.numChildren();i++) {
                  setPickable(g.getChild(i));
              }
    }
}

Assuming I haven’t screwed anything up there then that’ll do recursive pickable set.

Kev

I have just writen this code, perhaps not as elegant:

/**

  • Simon Pink
  • Sets all children nodes to pickable
  • @param group
    */
    private void setGroupPickable(Group group)
    {
    Node child = null;
for (Enumeration childrenEnum = group.getAllChildren(); childrenEnum.hasMoreElements();)
{
  child = (Node)childrenEnum.nextElement();
  child.setPickable(true);
  if (child.getClass() != Shape3D.class)
    setGroupPickable((Group)child);
}

}

Seems to do the trick nicely tho.

P.S. how do I inset the code when I post (yes I am a n00b to these forums :slight_smile: )

You can use the tags:

[ code ]

Code in here
[ /code ]

(without spaces) to indent code blocks

Kev

Thanks Kev.

I cant believe how active this forum is! Really is great. Cheers for help guys.

this would be a good tip to add to the tute :slight_smile:

Will.

Yeah I agree, it seems like a bit of a trap for new commers like me. Eitheir that or add the “setGroupPickable()” method to the API, or both…

[quote]Not sure I’m afraid - I don’t use picking myself. Jens (who wrote that tute) should see this thread in a few hours and might be able to help you :slight_smile:
[/quote]
Currently I’m not doing any coding (it’s christmas :)), but I wrote similar helper methods like the ones mentioned above. If I don’t forget it, I can include this in the tutorial when I have access to my dev machine again. Some helper methods for this in Xith3D would be nice, because scenegraph traversal is needed quite often.

As of scene traversal, I would vote for Visitor design pattern: define unified traverser and Visitor interface which one will implement to perform application-specific tasks.

Yuri