Mouse Picking Advanced Trouble

Hi, so i have a problem. I’m currently on a simple game, wich the mouse is involved. So i set up the mouse event and it works :

[java]@Override

public void mouseEvent(String name, float value, float tpf, InputManager input) {

Vector2f temp = new Vector2f(input.getCursorPosition());

Player2D temp2 = (Player2D) player;

Vector3f pos = new Vector3f(getCamLocation().x - (temp.x - main.getWidth()),

getCamLocation().y - (temp.y - main.getHeight()),

getCamLocation().z);



Ray ray = new Ray(getCamLocation(),pos);



CollisionResults results = new CollisionResults();



getSelectNode().collideWith(ray, results);



for (int i = 0; i < results.size(); i++) {

// For each “hit”, we know distance, impact point, geometry.

float dist = results.getCollision(i).getDistance();

Vector3f pt = results.getCollision(i).getContactPoint();

String target = results.getCollision(i).getGeometry().getName();

System.out.println(“Selection #” + i + ": " + target + " at " + pt + “, " + dist + " WU away.”);

}

// 5. Use the results – we rotate the selected geometry.

if (results.size() > 0) {

// Here comes the action:

System.out.println(“THIS WOKRS :smiley: SO FLUFY”);

for(int i = 0; i < enemy.length; i++) {

//if() {



//}

}

}

}[/java]

This method i called once the right mouse button is clicked. But i can’t convert the mouse position to an Ray or there is something wrong with my object wich need to be clicked :

[java]private void createEnemy(float x, float y, float z) {

CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(sx, sy, sz);

enemy = new CharacterControl(capsuleShape, 0.05f);

enemy.setJumpSpeed(20);

enemy.setFallSpeed(30);

enemy.setGravity(30);

enemy.setPhysicsLocation(new Vector3f(x,y,z));



physics().getPhysicsSpace().add(enemy);



enemyAnim = new Animation(getRoom().main.getAssetManager(), getRoom().getSelectNode());

enemyAnim.setPosition(new Vector3f(enemy.getPhysicsLocation().x,enemy.getPhysicsLocation().y + 2, enemy.getPhysicsLocation().z));



}[/java]

So i am using an getSelectNode() method to get a node wich will only contain things that can be selected. And i want each time the right mouse button is pressed that it finds whatever class is holding the object to make it do something, Thanks in advanced :smiley:

you convert the mouse click to a ray by:

[java]

Vector2f click2d = inputManager.getCursorPosition();

Vector3f click3d = cam.getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 0f).clone();

Vector3f dir = cam.getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 1f).subtractLocal(click3d);

// Aim the ray from the clicked spot forwards.

Ray ray = new Ray(click3d, dir);[/java]



https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:mouse_picking

Ok fixed that, thanks. But it still have a problem :

Like i will have multiple instances of the class “enemy” i need a way to determine wich class contains the geometry you have just clicked to tell this class you have been clicked, Thanks :smiley:

So you have a class which contains a geometry? and you want to find which instance was selected?



then do [java]geometry.setUserData("class", this);[/java] when you create your spatial. You need to implement Savable tho:



https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:spatial#how_to_add_fields_and_methods_to_a_spatial



then do



[java]

Geometry target = results.getClosestCollision().getGeometry();

ClassName instance = (ClassName) target.getUserData("class");



instance.suicide();[/java]

What are Savable ? i did everything except the savable thing that i don’t know ( i’ve looked at your link but didnt find the savable section ) and my game crashed at the moment where it was setting the userData. Thanks :smiley:

@wezrule, don’t forget he might have to scan back up the node tree to find the user data unless he really is attaching it to the final displayed geometry.

[java]geometry.setUserData("class", this);[/java]

This makes my game crash :

[java]public class Animation {



private AnimChannel channel;

private AnimControl control;

private Spatial player;

Listener lis = new Listener();



public Animation( AssetManager asset, Node node, Object superClass ) {

player = asset.loadModel("Models/Oto/Oto.j3o");

player.center();

player.setLocalScale(0.5f);

player.setUserData("class", superClass);



node.attachChild(player);

control = player.getControl(AnimControl.class);

control.addListener(new Listener());

channel = control.createChannel();

channel.setAnim("Walk");

}[/java]



So how can i fix it? This is the error :

SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]

java.lang.IllegalArgumentException: Unsupported type: Objects.Player2D

at com.jme3.scene.UserData.getObjectType(UserData.java:98)

at com.jme3.scene.Spatial.setUserData(Spatial.java:1202)

at Animations.Animation.(Animation.java:33)

at Objects.Player2D.createPlayer(Player2D.java:72)

Any suggestions?

Objects.Player2D does not implement Savable.



It’s probably easier not to do it this way. I’m not sure why others are steering you down this path, actually.



If you have some Node/Spatial that represents your “object” then add a custom control to it or a String of some kind to the user-data (not a custom object because that’s 100x more trouble than it’s worth).



When a Geometry is clicked look up the parent chain until you find the spatial with your user-data tag or your custom control.

I have a class that represent the object.

Then i have an animation class that gets the animation and put it in the scene, but the animation class is controlled by the object class.

and i have x number of object, so i need to know how to make the click on my animation refer to the class object.

@mathieu-roux222 said:
I have a class that represent the object.
Then i have an animation class that gets the animation and put it in the scene, but the animation class is controlled by the object class.
and i have x number of object, so i need to know how to make the click on my animation refer to the class object.


I have trouble following what you are saying because I feel like the word "class" is overused. If you are referring to something other than a "Java class" then please use a different word or there will just be endless confusion.

I can tell you that the easiest way to do this is to have a custom control.

[java]
public class MyControlToDoMyStuff extends AbstractControl {
....
}
[/java]

Then if you have a "thing that is the root of your 'model' and has animation" then you add that control to it.

[java]
myThing.addControl( new MyControlToDoMyStuff() );
[/java]

Then when you get a Geometry as a collision result look up the parent hierarchy for the Spatial that has that control:
[java]
for( Spatial s = clickGeometry; s != null; s = s.getParent() {
if( s.getControl( MyControlToDoMyStuff.class ) != null ) {
// Do your stuff with whatatever data you put in your control
}
}
[/java]

Ok since i tried to implement your thing, the game is giving me errors like it cannot load my room :

http://www.mediafire.com/?r4pl3knij0g1tj6

Here is the files from my whole project, it is not that messy, but it was working until i added your suggestion, so i am really confused, maybe by lloking at it you can help me. Anyway thanks.

@mathieu-roux222 said:
Ok since i tried to implement your thing, the game is giving me errors like it cannot load my room :
http://www.mediafire.com/?r4pl3knij0g1tj6
Here is the files from my whole project, it is not that messy, but it was working until i added your suggestion, so i am really confused, maybe by lloking at it you can help me. Anyway thanks.


I'm afraid I don't have time to download and run peoples' projects. Can you at least tell us what the error is?