I am attempting to create a target dot that changes its color / animation based on what object group it comes in contact with inside of a certain radius. It does most of what I want it to except detect the object group it is in contact with. Right now all objects in the scene cause it to have one state(blue) and if it is not touching anything it is in another state(yellow). I need to figure out how to get the object group and compare it to a list of groups so I can change the state of the object based on the group. Right now I am using nodes to group the objects and I only have two groups that I am testing with selectable and fixed. When the selection dot comes in contact with the selectable group it is blue and when it is not touching anything it is yellow. I would like to make it turn yellow when it is touching the terrain which is in the fixed node. I have tried several methods to create this effect.
here is my most recent try:
[java]
CollisionResults results = new CollisionResults();
Ray ray = new Ray(cam.getLocation(), cam.getDirection());
selectables.collideWith(ray, results);
CollisionResult selected = results.getClosestCollision();
if(results.size() > 0 && selected.getDistance() < 25 && selectionMode == true){
if(!selected.getGeometry().getParent().equals(fixed)){
rootNode.detachChild(selectorInactive);
selectorActive.setLocalTranslation(selected.getContactPoint());
rootNode.attachChild(selectorActive);
}else{
rootNode.detachChild(selectorActive);
selectorInactive.setLocalTranslation(selected.getContactPoint());
rootNode.attachChild(selectorInactive);
}
}else if(selectionMode == true){
rootNode.detachChild(selectorActive);
selectorInactive.setLocalTranslation(cam.getLocation().add(cam.getDirection().normalize().mult(25)));
rootNode.attachChild(selectorInactive);
}else{
rootNode.detachChild(selectorActive);
rootNode.detachChild(selectorInactive);
}[/java]
Note: The entire code segment is inside simpleupdate().
I don’t understand why this method does not work. It just generates the selection sphere at the max distance instead of on the terrain when the terrain is within the max distance. How do I fix this problem and is there a better way to do this?
If you need to see any other part of my code to answer this question please just ask will post it asap.
Thanks.
Finding/setting an object group and changing the state of an object based on what group it is touchi
how about picking the nodes in succession?
[java]if(terrainNode.collideWith(ray).size()>0){
print("terrain hit");
}else if(redNode.collideWith(ray).size()>0{
print("red hit");
}
etc…[/java]
thanks normen it worked.
one more question related to this. Performance wise is it better to create a ray that will interact with all objects within the render distance or is there some way to create a vector that will only interact with objects within a certain distance and have better performance?
If so how would you do that?
here is what I ended with:
[java]
CollisionResults selectableResults = new CollisionResults();
Ray ray = new Ray(cam.getLocation(), cam.getDirection());
selectables.collideWith(ray, selectableResults);
CollisionResult selectedResult = selectableResults.getClosestCollision();
CollisionResults fixedResults = new CollisionResults();
fixed.collideWith(ray, fixedResults);
CollisionResult fixedResult = fixedResults.getClosestCollision();
if(selectableResults.size() > 0 && selectedResult.getDistance() < 25 && selectionMode == true && selectedResult.getDistance() < fixedResult.getDistance()){
rootNode.detachChild(selectorInactive);
selectorActive.setLocalTranslation(selectedResult.getContactPoint());
rootNode.attachChild(selectorActive);
}else if(fixedResults.size() > 0 && selectionMode == true && fixedResult.getDistance() < 25){
rootNode.detachChild(selectorActive);
selectorInactive.setLocalTranslation(fixedResult.getContactPoint());
rootNode.attachChild(selectorInactive);
}else if(selectionMode == true){
rootNode.detachChild(selectorActive);
selectorInactive.setLocalTranslation(cam.getLocation().add(cam.getDirection().normalize().mult(25)));
rootNode.attachChild(selectorInactive);
}else{
rootNode.detachChild(selectorActive);
rootNode.detachChild(selectorInactive);
}
[/java]
Thanks for the help.
You don’t save anything in the picking there… selectables.collideWith() and fixed.collideWith() is where the work happens. If you know the player is in one room or something then make a node for that room as a child of the “fixed” node and only .collideWith() that.
so there is no performance difference between using a ray or using a vector of a short length to find objects within a certain range? If I am using a ray when finding collision .collideWith() will find all collisions within the render distance correct?
If I was able to use a vector of 25 world units length instead to do the same thing would it not use less resources since the engine only has to search inside that distance for collisions?
Or does it use more because of how the engine handles vectors?
I know this is a very small difference in resource use if any but I am just curious as to which one is more efficient in jme.
Thanks.
Oh duh, you change the range, right… Well I guess there isn’t too much to save as afaik there is no real broadphase in the jme picking but empirical data is your best bet.
It depends entirely on how your scene graph is constructed. If certain branches can be ruled out of intersection with a shorter Ray then you will save time.
At any rate, it doesn’t hurt to set the limit of the vector if you only want objects in a certain range.
Since I’m not sure if you know how to find the javadocs, I will post a link here:
http://hub.jmonkeyengine.org/javadoc/com/jme3/math/Ray.html
If you scroll down then you can see the getLimit() and setLimit() methods.
Thanks. That is exactly what I needed.
Another issue related to this I am getting a NullPointerException when I go from a selectable object to a fixed one or to out of range quickly. I am not sure of the exact combination of events that causes this exception in my code because it is semi hard to recreate and only appears to happen when the selector is changing states quickly. I have tried changing the ray length thinking it is caused by the limit on the selection distance being larger than the ray length so creating a null result size when there is an object in range and I have played around with the result comparisons to see if there is a hole in them.
Here is the output that I get when the problem comes up
[java]INFO: Root Node (Node): Child removed.
May 21, 2012 3:18:32 PM com.jme3.scene.Node attachChild
INFO: Child (SelectorActive) attached to this node (Root Node)
May 21, 2012 3:18:32 PM com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NullPointerException
at mygame.BasicGame.simpleUpdate(BasicGame.java:161)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:244)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:149)
at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:182)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:223)
at java.lang.Thread.run(Thread.java:722)
May 21, 2012 3:18:32 PM com.jme3.renderer.lwjgl.LwjglRenderer cleanup
INFO: Deleting objects and invalidating state
May 21, 2012 3:18:32 PM com.jme3.scene.Node detachChildAt
INFO: Gui Node (Node): Child removed.
May 21, 2012 3:18:32 PM com.jme3.scene.Node detachChildAt
INFO: Gui Node (Node): Child removed.
May 21, 2012 3:18:32 PM com.jme3.input.lwjgl.LwjglMouseInput destroy
INFO: Mouse destroyed.
May 21, 2012 3:18:32 PM com.jme3.input.lwjgl.LwjglKeyInput destroy
INFO: Keyboard destroyed.
May 21, 2012 3:18:32 PM com.jme3.system.lwjgl.LwjglAbstractDisplay deinitInThread
INFO: Display destroyed.
BUILD SUCCESSFUL (total time: 11 seconds)[/java]
Here is the code that is causing the exception:
[java]
CollisionResults selectableResults = new CollisionResults();
Ray ray = new Ray(cam.getLocation(), cam.getDirection());
ray.setLimit(25);
selectable.collideWith(ray, selectableResults);
CollisionResult selectedResult = selectableResults.getClosestCollision();
CollisionResults fixedResults = new CollisionResults();
fixed.collideWith(ray, fixedResults);
CollisionResult fixedResult = fixedResults.getClosestCollision();
if( selectionMode == true && selectableResults.size() > 0 && selectedResult.getDistance() < 25 && selectedResult.getDistance() < fixedResult.getDistance()){
rootNode.detachChild(selectorInactive);
selectorActive.setLocalTranslation(selectedResult.getContactPoint());
rootNode.attachChild(selectorActive);
}else if(selectionMode == true && fixedResults.size() > 0 && fixedResult.getDistance() < 25){
rootNode.detachChild(selectorActive);
selectorInactive.setLocalTranslation(fixedResult.getContactPoint());
rootNode.attachChild(selectorInactive);
}else if(selectionMode == true){
rootNode.detachChild(selectorActive);
selectorInactive.setLocalTranslation(cam.getLocation().add(cam.getDirection().normalize().mult(25)));
rootNode.attachChild(selectorInactive);
}else{
rootNode.detachChild(selectorActive);
rootNode.detachChild(selectorInactive);
}
[/java]
the first if statement is line 161 in the code. any clues as to what is causing the exception would be great thanks.
Ummm… the ray has no length unless you set the limit.
But anyway, seems like your NPE comes because you didn’t hit anything. A simple log statement or println before line 161 will tell you.
I did set the limit and the selectableRessults.size() > 0 and fixedResults.size() > 0 provision in the if statement should take care of the exception when nothing is hit unless there is something I am missing. Also there are many times in the simulation when I am not looking at anything and I don’t get that error. It almost always happens when I am switching between looking at one of the “selectable” objects and the ground but even under these conditions the NPE is rare.
I am currently experimenting with putting print statements in different places to see where it is failing exactly and what is failing.
Thanks for the suggestion.
“if( selectionMode == true && selectableResults.size() GREATER_THAN 0 && selectedResult.getDistance() LESS_THAN 25 && selectedResult.getDistance() LESS_THAN fixedResult.getDistance()){”
It is possible to not have a fixedResult even though the selectableResults.size() GREATER_THAN 0.
edit: edited to show the whole post by removing the greater than and less than symbols.
I know that is where the compiler says it fails but I have had more than a few times where the line that the compiler tells you is not actually the problem or causing the error or even related to the error. Thanks though. I have narrowed it down to that line now after some testing just need to find which part now.
I think I found the problem I am not testing to see if the fixedResults>0 so when I test the selectedResult.getDistance() < fixedResult.getDistance() it was occasionally coming up with a null distance for fixedResult.getDistance(). It was ofly hard to get the npe though so it is making me a little suspicious if that was the problem. After making that simple change I have been unable to replicate the problem but because of its inconsistent reproduction nature it may be that it has not come up yet.
Thanks for all the help.
I actually said exactly what the error was but my post got cut off because our forum is incredibly stupid.
@pspeed said:
I actually said exactly what the error was but my post got cut off because our forum is incredibly stupid. ;)
@darklightning7: Yeah quote him for the truth ;)
Edit: Ah, now its visible w/o quoting the text out of the db :)
@pspeed Now my posts seem really goofy, like I did not even read your post. :roll:
Thanks again for the help.